summaryrefslogtreecommitdiffstats
path: root/web_src/css
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web_src/css/actions.css96
-rw-r--r--web_src/css/admin.css51
-rw-r--r--web_src/css/base.css1585
-rw-r--r--web_src/css/chroma/base.css46
-rw-r--r--web_src/css/chroma/dark.css76
-rw-r--r--web_src/css/chroma/light.css76
-rw-r--r--web_src/css/codemirror/base.css49
-rw-r--r--web_src/css/codemirror/dark.css106
-rw-r--r--web_src/css/codemirror/light.css1
-rw-r--r--web_src/css/dashboard.css81
-rw-r--r--web_src/css/editor/combomarkdowneditor.css136
-rw-r--r--web_src/css/editor/fileeditor.css85
-rw-r--r--web_src/css/explore.css31
-rw-r--r--web_src/css/features/codeeditor.css48
-rw-r--r--web_src/css/features/colorpicker.css47
-rw-r--r--web_src/css/features/console.css338
-rw-r--r--web_src/css/features/dropzone.css59
-rw-r--r--web_src/css/features/gitgraph.css285
-rw-r--r--web_src/css/features/heatmap.css58
-rw-r--r--web_src/css/features/imagediff.css114
-rw-r--r--web_src/css/features/projects.css108
-rw-r--r--web_src/css/features/tribute.css42
-rw-r--r--web_src/css/font_i18n.css393
-rw-r--r--web_src/css/form.css472
-rw-r--r--web_src/css/helpers.css60
-rw-r--r--web_src/css/home.css87
-rw-r--r--web_src/css/index.css78
-rw-r--r--web_src/css/install.css62
-rw-r--r--web_src/css/markup/asciicast.css8
-rw-r--r--web_src/css/markup/codecopy.css35
-rw-r--r--web_src/css/markup/content.css585
-rw-r--r--web_src/css/markup/dark.css13
-rw-r--r--web_src/css/markup/filepreview.css41
-rw-r--r--web_src/css/markup/light.css6
-rw-r--r--web_src/css/modules/animations.css116
-rw-r--r--web_src/css/modules/breadcrumb.css14
-rw-r--r--web_src/css/modules/button.css756
-rw-r--r--web_src/css/modules/card.css134
-rw-r--r--web_src/css/modules/checkbox.css121
-rw-r--r--web_src/css/modules/comment.css90
-rw-r--r--web_src/css/modules/container.css59
-rw-r--r--web_src/css/modules/divider.css43
-rw-r--r--web_src/css/modules/flexcontainer.css33
-rw-r--r--web_src/css/modules/grid.css513
-rw-r--r--web_src/css/modules/header.css176
-rw-r--r--web_src/css/modules/input.css197
-rw-r--r--web_src/css/modules/label.css303
-rw-r--r--web_src/css/modules/list.css193
-rw-r--r--web_src/css/modules/message.css114
-rw-r--r--web_src/css/modules/modal.css86
-rw-r--r--web_src/css/modules/navbar.css147
-rw-r--r--web_src/css/modules/normalize.css243
-rw-r--r--web_src/css/modules/segment.css203
-rw-r--r--web_src/css/modules/select.css25
-rw-r--r--web_src/css/modules/svg.css41
-rw-r--r--web_src/css/modules/table.css385
-rw-r--r--web_src/css/modules/tippy.css170
-rw-r--r--web_src/css/modules/toast.css77
-rw-r--r--web_src/css/org.css193
-rw-r--r--web_src/css/repo.css2997
-rw-r--r--web_src/css/repo/header.css68
-rw-r--r--web_src/css/repo/issue-card.css40
-rw-r--r--web_src/css/repo/issue-label.css52
-rw-r--r--web_src/css/repo/issue-list.css112
-rw-r--r--web_src/css/repo/linebutton.css19
-rw-r--r--web_src/css/repo/list-header.css58
-rw-r--r--web_src/css/repo/release-tag.css125
-rw-r--r--web_src/css/repo/wiki.css72
-rw-r--r--web_src/css/review.css297
-rw-r--r--web_src/css/shared/flex-list.css108
-rw-r--r--web_src/css/shared/milestone.css62
-rw-r--r--web_src/css/shared/repoorg.css18
-rw-r--r--web_src/css/shared/settings.css37
-rw-r--r--web_src/css/standalone/devtest.css16
-rw-r--r--web_src/css/standalone/swagger.css42
-rw-r--r--web_src/css/themes/theme-forgejo-auto-deuteranopia-protanopia.css2
-rw-r--r--web_src/css/themes/theme-forgejo-auto-tritanopia.css2
-rw-r--r--web_src/css/themes/theme-forgejo-auto.css2
-rw-r--r--web_src/css/themes/theme-forgejo-dark-deuteranopia-protanopia.css11
-rw-r--r--web_src/css/themes/theme-forgejo-dark-tritanopia.css11
-rw-r--r--web_src/css/themes/theme-forgejo-dark.css340
-rw-r--r--web_src/css/themes/theme-forgejo-light-deuteranopia-protanopia.css11
-rw-r--r--web_src/css/themes/theme-forgejo-light-tritanopia.css11
-rw-r--r--web_src/css/themes/theme-forgejo-light.css308
-rw-r--r--web_src/css/themes/theme-gitea-auto.css2
-rw-r--r--web_src/css/themes/theme-gitea-dark.css271
-rw-r--r--web_src/css/themes/theme-gitea-light.css247
-rw-r--r--web_src/css/user.css149
88 files changed, 15280 insertions, 0 deletions
diff --git a/web_src/css/actions.css b/web_src/css/actions.css
new file mode 100644
index 00000000..c89a70ec
--- /dev/null
+++ b/web_src/css/actions.css
@@ -0,0 +1,96 @@
+.runner-container {
+ padding-bottom: 30px;
+}
+
+.runner-container .ui.table.segment {
+ overflow-x: auto;
+}
+
+.runner-container .runner-ops > a {
+ margin-left: 0.5em;
+}
+
+.runner-container .runner-ops-delete {
+ color: var(--color-red-light);
+}
+
+.runner-container .runner-new-text {
+ color: var(--color-white);
+}
+
+.runner-container #runner-new:hover .runner-new-text {
+ color: var(--color-white) !important;
+}
+
+.runner-container .task-status-success {
+ background-color: var(--color-green);
+ color: var(--color-white);
+}
+
+.runner-container .task-status-failure {
+ background-color: var(--color-red-light);
+ color: var(--color-white);
+}
+
+.runner-container .task-status-running {
+ background-color: var(--color-blue);
+ color: var(--color-white);
+}
+
+.runner-container .task-status-cancelled,
+.runner-container .task-status-blocked {
+ background-color: var(--color-yellow);
+ color: var(--color-white);
+}
+
+.run-list-item-right {
+ width: 130px;
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ gap: 3px;
+ color: var(--color-text-light);
+}
+
+.run-list-item-right .run-list-meta {
+ display: flex;
+ flex-wrap: nowrap;
+ gap: .25rem;
+ align-items: center;
+}
+
+.run-list .flex-item-trailing {
+ flex-wrap: nowrap;
+ width: 280px;
+ flex: 0 0 280px;
+}
+
+.run-list-ref {
+ display: inline-block !important;
+}
+
+@media (max-width: 767.98px) {
+ .run-list .flex-item-trailing {
+ flex-direction: column;
+ align-items: flex-end;
+ width: auto;
+ flex-basis: auto;
+ }
+ .run-list-item-right,
+ .run-list-ref {
+ max-width: 110px;
+ }
+}
+
+#workflow_dispatch_dropdown {
+ min-width: min-content;
+}
+#workflow_dispatch_dropdown > button {
+ white-space: nowrap;
+}
+@media (max-width: 640px) or (767.98px < width < 854px) {
+ #workflow_dispatch_dropdown .menu {
+ left: auto;
+ right: 0;
+ }
+}
diff --git a/web_src/css/admin.css b/web_src/css/admin.css
new file mode 100644
index 00000000..e6866b27
--- /dev/null
+++ b/web_src/css/admin.css
@@ -0,0 +1,51 @@
+.admin.hooks .list > .item:not(:first-child) {
+ border-top: 1px solid var(--color-secondary);
+ padding: 0.25rem 1rem;
+ margin: 12px -1rem -1rem;
+}
+
+.admin dl.admin-dl-horizontal {
+ padding: 1em;
+ margin: 0;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.admin dl.admin-dl-horizontal dt,
+.admin dl.admin-dl-horizontal dd {
+ line-height: var(--line-height-default);
+ padding: 5px 0;
+}
+
+.admin dl.admin-dl-horizontal dt {
+ width: 300px;
+ max-width: calc(100% - 100px - 1em);
+ font-weight: var(--font-weight-semibold);
+}
+
+.admin dl.admin-dl-horizontal dd {
+ margin-left: auto;
+ width: calc(100% - 300px - 1em);
+ min-width: 100px;
+}
+
+.admin code,
+.admin pre {
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+.admin .ui.table.segment {
+ overflow-x: auto; /* if the screen width is small, many wide tables (eg: user list) need scroll bars */
+}
+
+.admin .table th {
+ white-space: nowrap;
+}
+
+.admin-responsive-columns {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
diff --git a/web_src/css/base.css b/web_src/css/base.css
new file mode 100644
index 00000000..7b503612
--- /dev/null
+++ b/web_src/css/base.css
@@ -0,0 +1,1585 @@
+:root {
+ /* fonts */
+ --fonts-proportional: -apple-system, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial;
+ --fonts-monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace, var(--fonts-emoji);
+ --fonts-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla";
+ /* font weights - use between 400 and 600 for general purposes. Avoid 700 as it is perceived too bold */
+ --font-weight-light: 300;
+ --font-weight-normal: 400;
+ --font-weight-medium: 500;
+ --font-weight-semibold: 600;
+ --font-weight-bold: 700;
+ /* line-height: use the default value as "modules/normalize.css" */
+ --line-height-default: normal;
+ /* images */
+ --checkbox-mask-checked: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 18 18" width="16" height="16"><path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>');
+ --checkbox-mask-indeterminate: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 7.75A.75.75 0 012.75 7h10a.75.75 0 010 1.5h-10A.75.75 0 012 7.75z"></path></svg>');
+ --octicon-chevron-right: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg>');
+ /* other variables */
+ --border-radius: 4px;
+ --border-radius-medium: 6px;
+ --border-radius-full: 99999px; /* TODO: use calc(infinity * 1px) */
+ --opacity-disabled: 0.55;
+ --height-loading: 16rem;
+ --repo-header-issue-min-height: 41px;
+ --min-height-textarea: 132px; /* padding + 6 lines + border = calc(1.57142em + 6lh + 2px), but lh is not fully supported */
+ --tab-size: 4;
+ --checkbox-size: 15px; /* height and width of checkbox and radio inputs */
+ --page-spacing: 16px; /* space between page elements */
+ --page-margin-x: 32px; /* minimum space on left and right side of page */
+}
+
+@media (min-width: 768px) and (max-width: 1200px) {
+ :root {
+ --page-margin-x: 16px;
+ }
+}
+
+@media (max-width: 767.98px) {
+ :root {
+ --page-margin-x: 8px;
+ }
+}
+
+:root * {
+ --fonts-regular: var(--fonts-override, var(--fonts-proportional)), "Noto Sans", "Liberation Sans", sans-serif, var(--fonts-emoji);
+}
+
+*, ::before, ::after {
+ /* these are needed for tailwind borders to work because we do not load tailwind's base
+ https://github.com/tailwindlabs/tailwindcss/blob/master/src/css/preflight.css */
+ border-width: 0;
+ border-style: solid;
+ border-color: currentcolor;
+}
+
+html, body {
+ height: 100%;
+ font-size: 14px;
+}
+
+body {
+ line-height: 20px;
+ font-family: var(--fonts-regular);
+ color: var(--color-text);
+ background-color: var(--color-body);
+ tab-size: var(--tab-size);
+ display: flex;
+ flex-direction: column;
+ overflow-x: visible;
+ overflow-wrap: break-word;
+}
+
+textarea {
+ font-family: var(--fonts-regular);
+}
+
+pre,
+code,
+kbd,
+samp {
+ font-family: var(--fonts-monospace);
+}
+
+pre,
+code,
+kbd,
+samp,
+.tw-font-mono {
+ font-size: 0.95em; /* compensate for monospace fonts being usually slightly larger */
+}
+
+b,
+strong,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-weight: var(--font-weight-semibold);
+}
+
+h1,
+h2,
+h3,
+h4,
+h5 {
+ line-height: 1.28571429;
+ margin: calc(2rem - 0.1428571428571429em) 0 1rem;
+ font-weight: var(--font-weight-medium);
+ padding: 0;
+}
+
+h1 {
+ min-height: 1rem;
+ font-size: 2rem;
+}
+
+h2 {
+ font-size: 1.71428571rem;
+}
+
+h3 {
+ font-size: 1.28571429rem;
+}
+
+h4 {
+ font-size: 1.07142857rem;
+}
+
+h5 {
+ font-size: 1rem;
+}
+
+h1:first-child,
+h2:first-child,
+h3:first-child,
+h4:first-child,
+h5:first-child {
+ margin-top: 0;
+}
+
+h1:last-child,
+h2:last-child,
+h3:last-child,
+h4:last-child,
+h5:last-child {
+ margin-bottom: 0;
+}
+
+p {
+ margin: 0 0 1em;
+ line-height: 1.4285;
+}
+
+p:first-child {
+ margin-top: 0;
+}
+
+p:last-child {
+ margin-bottom: 0;
+}
+
+table {
+ border-collapse: collapse;
+}
+
+button {
+ cursor: pointer;
+}
+
+details summary {
+ cursor: pointer;
+}
+
+details summary > * {
+ display: inline;
+}
+
+progress {
+ background: var(--color-secondary-dark-1);
+ border-radius: var(--border-radius);
+ border: none;
+ overflow: hidden;
+}
+
+progress::-webkit-progress-bar {
+ background: var(--color-secondary-dark-1);
+}
+
+progress::-webkit-progress-value {
+ background-color: var(--color-accent);
+}
+
+progress::-moz-progress-bar {
+ background-color: var(--color-accent);
+}
+
+h1.error-code {
+ font-size: 15em;
+ font-weight: var(--font-weight-bold);
+ color: transparent;
+ --error-code-color-1: #a2a2a2;
+ --error-code-color-2: #797979;
+ --gradient: repeating-linear-gradient(45deg, var(--error-code-color-1), var(--error-code-color-1) 10px, var(--error-code-color-2) 10px, var(--error-code-color-2) 20px);
+ background: var(--gradient);
+ background-clip: text;
+}
+
+* {
+ caret-color: var(--color-caret);
+}
+
+::file-selector-button {
+ border: 1px solid var(--color-light-border);
+ color: var(--color-text-light);
+ background: var(--color-light);
+ border-radius: var(--border-radius);
+}
+
+::file-selector-button:hover {
+ color: var(--color-text);
+ background: var(--color-hover);
+}
+
+::selection {
+ background: var(--color-primary-light-1);
+ color: var(--color-white);
+}
+
+::placeholder,
+.ui.dropdown:not(.button) > .default.text,
+.ui.default.dropdown:not(.button) > .text {
+ color: var(--color-placeholder-text) !important;
+ opacity: 1 !important;
+}
+
+.unselectable,
+.button,
+.lines-num,
+.lines-commit,
+.lines-commit .blame-info,
+.ellipsis-button {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ user-select: none;
+}
+
+.button-row {
+ gap: 0.5rem;
+}
+
+.button-row .ui.button {
+ margin-right: 0;
+}
+
+.ui.partial.secondary.menu {
+ margin-bottom: 0;
+}
+
+a {
+ color: var(--color-primary);
+ cursor: pointer;
+ text-decoration-line: none;
+ text-decoration-skip-ink: all;
+}
+
+a:hover {
+ text-decoration-line: underline;
+}
+
+/* a = always colored, underlined on hover */
+/* a.muted = colored on hover, underlined on hover */
+/* a.suppressed = never colored, underlined on hover */
+/* a.silenced = never colored, never underlined */
+
+a.muted,
+a.suppressed,
+a.silenced,
+.muted-links a {
+ color: inherit;
+}
+
+a:hover,
+a.suppressed:hover,
+a.muted:hover,
+a.muted:hover [class*="color-text"],
+.muted-links a:hover {
+ color: var(--color-primary);
+}
+
+a.silenced:hover,
+a.suppressed:hover {
+ color: inherit;
+}
+
+a.silenced:hover {
+ text-decoration-line: none;
+}
+
+a.label,
+.ui.search .results a,
+.ui .menu a,
+.ui.cards a.card,
+.issue-keyword a {
+ text-decoration-line: none !important;
+}
+
+.ui.search > .results {
+ background: var(--color-body);
+ border-color: var(--color-secondary);
+ overflow-wrap: anywhere; /* allow text to wrap as fomantic limits this to 18em width */
+}
+
+.ui.search > .results .result {
+ background: var(--color-body);
+ border-color: var(--color-secondary);
+ display: flex;
+ align-items: center;
+}
+
+.ui.search > .results .result .title {
+ color: var(--color-text-dark);
+}
+
+.ui.search > .results .result .description {
+ color: var(--color-text-light-2);
+}
+
+.ui.search > .results .result .image {
+ width: auto;
+ height: auto;
+}
+
+.ui.search > .results .result:hover,
+.ui.category.search > .results .category .result:hover {
+ background: var(--color-hover);
+}
+
+.inline-code-block {
+ padding: 2px 4px;
+ border-radius: .24em;
+ background-color: var(--color-label-bg);
+}
+
+.ui.menu {
+ display: flex;
+}
+
+.ui.menu,
+.ui.vertical.menu {
+ background: var(--color-menu);
+ border-color: var(--color-secondary);
+ box-shadow: none;
+}
+
+.ui.menu .item {
+ color: var(--color-text);
+ user-select: auto;
+ line-height: var(--line-height-default); /* fomantic uses "1" which causes overflow problems because "1" doesn't consider the descent part */
+}
+
+.ui.menu .item > .svg {
+ margin-right: 0.35em;
+}
+
+.ui.menu .dropdown.item:hover,
+.ui.menu a.item:hover,
+.ui.menu details.item summary:hover {
+ color: var(--color-text);
+ background: var(--color-hover);
+}
+
+.ui.menu .active.item,
+.ui.menu .active.item:hover,
+.ui.vertical.menu .active.item,
+.ui.vertical.menu .active.item:hover {
+ color: var(--color-text);
+ background: var(--color-active);
+}
+
+.ui.menu a.item:active {
+ color: var(--color-text);
+ background: none;
+}
+
+.ui.ui.menu .item.disabled {
+ color: var(--color-text-light-3);
+}
+
+.ui.menu .item::before, .ui.vertical.menu .item::before {
+ background: var(--color-secondary);
+}
+
+/* sub menu of vertical menu */
+.ui.vertical.menu .item .menu .item {
+ color: var(--color-text-light-2);
+ text-indent: 16px;
+}
+
+.ui.vertical.menu .item .menu .item:hover,
+.ui.vertical.menu .item .menu a.item:hover {
+ color: var(--color-text-light-1);
+}
+
+.ui.vertical.menu .item .menu .active.item {
+ color: var(--color-text);
+}
+
+/* slightly more contrast for filters on issue list */
+.ui.ui.menu .dropdown.item.disabled {
+ color: var(--color-text-light-2);
+}
+
+.ui.dropdown .menu {
+ background: var(--color-menu);
+ border-color: var(--color-secondary);
+}
+
+.ui.dropdown .menu > .header:not(.ui) {
+ color: var(--color-text);
+}
+
+.ui.dropdown .menu > .item {
+ color: var(--color-text);
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.ui.dropdown .menu > .item:hover {
+ color: var(--color-text);
+ background: var(--color-hover);
+}
+
+.ui.dropdown .menu > .item:active {
+ color: var(--color-text);
+ background: var(--color-active);
+}
+
+.ui.dropdown .menu .active.item {
+ color: var(--color-text);
+ background: var(--color-active);
+ border-radius: 0;
+ font-weight: var(--font-weight-normal);
+}
+
+/* fix misaligned images in webhook dropdown */
+.ui.dropdown .menu > .item > img {
+ margin-top: -0.25rem;
+ margin-bottom: -0.25rem;
+}
+.ui.dropdown .menu > .item > svg {
+ margin-right: .78rem; /* use the same margin as for <img> */
+}
+
+.ui.selection.dropdown .menu > .item {
+ border-color: var(--color-secondary);
+ white-space: nowrap;
+}
+
+.ui.selection.visible.dropdown > .text:not(.default) {
+ color: var(--color-text);
+}
+
+.ui.dropdown.selected,
+.ui.dropdown .menu .selected.item {
+ color: var(--color-text);
+ background: var(--color-hover);
+}
+
+.ui.menu .ui.dropdown .menu > .selected.item {
+ color: var(--color-text) !important;
+ background: var(--color-hover) !important;
+}
+
+.ui.dropdown .menu > .message:not(.ui) {
+ color: var(--color-text-light-2);
+}
+
+/* extend fomantic style '.ui.dropdown > .text > img' to include svg.img */
+.ui.dropdown > .text > .img {
+ margin-left: 0;
+ float: none;
+ margin-right: 0.78571429rem;
+}
+
+.ui.dropdown > .text > .description,
+.ui.dropdown .menu > .item > .description {
+ color: var(--color-text-light-2);
+}
+
+/* replace item margin on secondary menu items with gap and remove both the
+ negative margins on the menu as well as margin on the items */
+.ui.secondary.menu {
+ margin-left: 0;
+ margin-right: 0;
+ gap: .35714286em;
+}
+.ui.secondary.menu .item {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+.ui.secondary.menu .dropdown.item:hover,
+.ui.secondary.menu a.item:hover {
+ color: var(--color-text);
+ background: var(--color-hover);
+}
+
+.ui.secondary.menu .active.item,
+.ui.secondary.menu .active.item:hover {
+ color: var(--color-text);
+ background: var(--color-active);
+}
+
+.ui.secondary.menu.tight .item {
+ padding-left: 0.85714286em;
+ padding-right: 0.85714286em;
+}
+
+/* remove the menu clearfix so that it won't add undesired gaps when using "gap" */
+.ui.menu::after {
+ content: normal;
+}
+
+.ui.menu .dropdown.item .menu {
+ background: var(--color-body);
+}
+
+.ui.menu .ui.dropdown .menu > .item {
+ color: var(--color-text) !important;
+}
+
+.ui.menu .ui.dropdown .menu > .item:hover {
+ color: var(--color-text) !important;
+ background: var(--color-hover) !important;
+}
+
+.ui.menu .ui.dropdown .menu > .active.item {
+ color: var(--color-text) !important;
+ background: var(--color-active) !important;
+}
+
+.ui.form textarea:not([rows]) {
+ height: var(--min-height-textarea); /* override fomantic default 12em */
+ min-height: var(--min-height-textarea); /* override fomantic default 8em */
+}
+
+/* styles from removed fomantic transition module */
+.hidden.transition {
+ visibility: hidden;
+ display: none;
+}
+.visible.transition {
+ display: block !important;
+ visibility: visible !important;
+}
+
+.ui.selection.active.dropdown,
+.ui.selection.active.dropdown:hover,
+.ui.selection.active.dropdown .menu,
+.ui.selection.active.dropdown:hover .menu {
+ border-color: var(--color-primary);
+}
+
+.ui.pointing.dropdown > .menu:not(.hidden)::after {
+ background: var(--color-menu);
+ box-shadow: -1px -1px 0 0 var(--color-secondary);
+}
+
+.ui.pointing.upward.dropdown .menu::after,
+.ui.top.pointing.upward.dropdown .menu::after {
+ box-shadow: 1px 1px 0 0 var(--color-secondary);
+}
+
+.ui.comments .comment .text {
+ margin: 0;
+}
+
+.ui.comments .comment .text,
+.ui.comments .comment .author {
+ color: var(--color-text);
+}
+
+.ui.comments .comment a.author:hover {
+ color: var(--color-primary);
+}
+
+.ui.comments .comment .metadata {
+ color: var(--color-text-light-2);
+}
+
+.ui.comments .comment .actions a {
+ color: var(--color-text-light);
+}
+
+.ui.comments .comment .actions a.active,
+.ui.comments .comment .actions a:hover {
+ color: var(--color-primary);
+}
+
+img.ui.avatar,
+.ui.avatar img,
+.ui.avatar svg {
+ border-radius: var(--border-radius);
+ object-fit: contain;
+ aspect-ratio: 1;
+}
+
+.ui.error.message .header,
+.ui.warning.message .header {
+ color: inherit;
+ filter: saturate(2);
+}
+
+.full.height {
+ flex-grow: 1;
+ padding-bottom: 80px;
+}
+
+/* add margin below .secondary nav when it is the first child */
+.page-content > :first-child.secondary-nav {
+ margin-bottom: 14px;
+}
+
+/* add margin to all pages when there is no .secondary.nav */
+.page-content > :first-child:not(.secondary-nav) {
+ margin-top: var(--page-spacing);
+}
+/* if .ui.grid is the first child the first grid-column has 'padding-top: 1rem' which we need
+ to compensate here */
+.page-content > :first-child.ui.grid {
+ margin-top: calc(var(--page-spacing) - 1rem);
+}
+
+.ui.pagination.menu .active.item {
+ color: var(--color-text);
+ background: var(--color-active);
+}
+
+.ui.form .fields.error .field textarea,
+.ui.form .fields.error .field select,
+.ui.form .fields.error .field input:not([type]),
+.ui.form .fields.error .field input[type="date"],
+.ui.form .fields.error .field input[type="datetime-local"],
+.ui.form .fields.error .field input[type="email"],
+.ui.form .fields.error .field input[type="number"],
+.ui.form .fields.error .field input[type="password"],
+.ui.form .fields.error .field input[type="search"],
+.ui.form .fields.error .field input[type="tel"],
+.ui.form .fields.error .field input[type="time"],
+.ui.form .fields.error .field input[type="text"],
+.ui.form .fields.error .field input[type="file"],
+.ui.form .fields.error .field input[type="url"],
+.ui.form .fields.error .field .ui.dropdown,
+.ui.form .fields.error .field .ui.dropdown .item,
+.ui.form .field.error .ui.dropdown,
+.ui.form .field.error .ui.dropdown .text,
+.ui.form .field.error .ui.dropdown .item,
+.ui.form .field.error textarea,
+.ui.form .field.error select,
+.ui.form .field.error input:not([type]),
+.ui.form .field.error input[type="date"],
+.ui.form .field.error input[type="datetime-local"],
+.ui.form .field.error input[type="email"],
+.ui.form .field.error input[type="number"],
+.ui.form .field.error input[type="password"],
+.ui.form .field.error input[type="search"],
+.ui.form .field.error input[type="tel"],
+.ui.form .field.error input[type="time"],
+.ui.form .field.error input[type="text"],
+.ui.form .field.error input[type="file"],
+.ui.form .field.error input[type="url"],
+.ui.form .field.error select:focus,
+.ui.form .field.error input:not([type]):focus,
+.ui.form .field.error input[type="date"]:focus,
+.ui.form .field.error input[type="datetime-local"]:focus,
+.ui.form .field.error input[type="email"]:focus,
+.ui.form .field.error input[type="number"]:focus,
+.ui.form .field.error input[type="password"]:focus,
+.ui.form .field.error input[type="search"]:focus,
+.ui.form .field.error input[type="tel"]:focus,
+.ui.form .field.error input[type="time"]:focus,
+.ui.form .field.error input[type="text"]:focus,
+.ui.form .field.error input[type="file"]:focus,
+.ui.form .field.error input[type="url"]:focus {
+ background-color: var(--color-error-bg);
+ border-color: var(--color-error-border);
+ color: var(--color-error-text);
+}
+
+.ui.form .fields.error .field .ui.dropdown,
+.ui.form .field.error .ui.dropdown,
+.ui.form .fields.error .field .ui.dropdown:hover,
+.ui.form .field.error .ui.dropdown:hover {
+ border-color: var(--color-error-border) !important;
+}
+
+.ui.form .fields.error .field .ui.dropdown .menu .item:hover,
+.ui.form .field.error .ui.dropdown .menu .item:hover {
+ background-color: var(--color-error-bg-hover);
+}
+
+.ui.form .fields.error .field .ui.dropdown .menu .active.item,
+.ui.form .field.error .ui.dropdown .menu .active.item {
+ background-color: var(--color-error-bg-active) !important;
+}
+
+.ui.form .fields.error .dropdown .menu,
+.ui.form .field.error .dropdown .menu {
+ border-color: var(--color-error-border) !important;
+}
+
+input:-webkit-autofill,
+input:-webkit-autofill:focus,
+input:-webkit-autofill:hover,
+input:-webkit-autofill:active,
+.ui.form .field.field input:-webkit-autofill,
+.ui.form .field.field input:-webkit-autofill:focus,
+.ui.form .field.field input:-webkit-autofill:hover,
+.ui.form .field.field input:-webkit-autofill:active {
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: var(--color-text);
+ box-shadow: 0 0 0 100px var(--color-primary-light-6) inset !important;
+ border-color: var(--color-primary-light-4) !important;
+}
+
+.ui.form .field.muted {
+ opacity: var(--opacity-disabled);
+}
+
+.text.primary {
+ color: var(--color-primary) !important;
+}
+
+.text.red {
+ color: var(--color-red) !important;
+}
+
+.text.orange {
+ color: var(--color-orange) !important;
+}
+
+.text.yellow {
+ color: var(--color-yellow) !important;
+}
+
+.text.olive {
+ color: var(--color-olive) !important;
+}
+
+.text.green {
+ color: var(--color-green) !important;
+}
+
+.text.teal {
+ color: var(--color-teal) !important;
+}
+
+.text.blue {
+ color: var(--color-blue) !important;
+}
+
+.text.violet {
+ color: var(--color-violet) !important;
+}
+
+.text.purple {
+ color: var(--color-purple) !important;
+}
+
+.text.pink {
+ color: var(--color-pink) !important;
+}
+
+.text.brown {
+ color: var(--color-brown) !important;
+}
+
+.text.black {
+ color: var(--color-text) !important;
+}
+
+.text.grey {
+ color: var(--color-text-light) !important;
+}
+
+.text.light {
+ color: var(--color-text-light) !important;
+}
+
+.text.light-2 {
+ color: var(--color-text-light-2) !important;
+}
+
+.text.light-3 {
+ color: var(--color-text-light-3) !important;
+}
+
+.text.light.grey {
+ color: var(--color-grey-light) !important;
+}
+
+.text.gold {
+ color: var(--color-gold) !important;
+}
+
+.text.small {
+ font-size: 0.75em;
+}
+
+.ui.form .ui.button {
+ font-weight: var(--font-weight-normal);
+}
+
+/* replace fomantic popover box shadows */
+.ui.dropdown .menu,
+.ui.upward.dropdown > .menu,
+.ui.menu .dropdown.item .menu,
+.ui.selection.active.dropdown .menu,
+.ui.upward.selection.dropdown .menu,
+.ui.selection.active.dropdown:hover .menu,
+.ui.upward.active.selection.dropdown:hover .menu {
+ box-shadow: 0 6px 18px var(--color-shadow);
+}
+.ui.floating.dropdown .menu {
+ box-shadow: 0 6px 18px var(--color-shadow) !important;
+}
+
+.ui.dimmer {
+ background: var(--color-overlay-backdrop);
+}
+
+/* Override semantic selector '.ui.menu:not(.vertical) .item > .button' */
+/* This fixes the commit graph button on the commits page */
+/* modal svg icons, copied from fomantic except width and height */
+/* center text in fomantic modal dialogs */
+.ui .menu:not(.vertical) .item > .button.compact {
+ padding: 0.58928571em 1.125em;
+}
+
+.ui .menu:not(.vertical) .item > .button.small {
+ font-size: 0.92857143rem;
+}
+
+.ui.menu .ui.dropdown.item .menu .item {
+ width: 100%;
+}
+
+.ui.dropdown .menu > .header {
+ font-size: 0.8em;
+}
+
+.ui .text.left {
+ text-align: left !important;
+}
+
+.ui .text.right {
+ text-align: right !important;
+}
+
+.ui .text.truncate {
+ overflow-x: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ display: inline-block;
+}
+
+.ui .message.flash-message {
+ text-align: center;
+}
+
+.ui .message > ul {
+ margin-left: auto;
+ margin-right: auto;
+ display: table;
+ text-align: left;
+}
+
+.ui .header > i + .content {
+ padding-left: 0.75rem;
+ vertical-align: middle;
+}
+
+.ui .form .autofill-dummy {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ overflow: hidden;
+ z-index: -10000;
+}
+
+.ui .form .sub.field {
+ margin-left: 25px;
+}
+
+.ui .sha.label {
+ font-family: var(--fonts-monospace);
+ font-size: 13px;
+ font-weight: var(--font-weight-normal);
+ margin: 0 6px;
+ padding: 5px 10px;
+ flex-shrink: 0;
+}
+
+.ui .sha.label .shortsha {
+ display: inline-block; /* not sure whether it is still needed */
+}
+
+.ui .button.truncate {
+ display: inline-block;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ vertical-align: top;
+ white-space: nowrap;
+ margin-right: 6px;
+}
+
+.ui.status.buttons .svg {
+ margin-right: 4px;
+}
+
+.ui.inline.delete-button {
+ padding: 8px 15px;
+ font-weight: var(--font-weight-normal);
+}
+
+.ui .background.red {
+ background-color: var(--color-red) !important;
+}
+
+.ui .background.blue {
+ background-color: var(--color-blue) !important;
+}
+
+.ui .background.black {
+ background-color: var(--color-black) !important;
+}
+
+.ui .background.grey {
+ background-color: var(--color-grey) !important;
+}
+
+.ui .background.light.grey {
+ background-color: var(--color-grey) !important;
+}
+
+.ui .background.green {
+ background-color: var(--color-green) !important;
+}
+
+.ui .background.purple {
+ background-color: var(--color-purple) !important;
+}
+
+.ui .background.yellow {
+ background-color: var(--color-yellow) !important;
+}
+
+.ui .background.orange {
+ background-color: var(--color-orange) !important;
+}
+
+.ui .background.gold {
+ background-color: var(--color-gold) !important;
+}
+
+.ui .migrate {
+ color: var(--color-text-light-2) !important;
+}
+
+.ui .migrate a {
+ color: var(--color-text-light) !important;
+}
+
+.ui .migrate a:hover {
+ color: var(--color-text) !important;
+}
+
+.ui .border {
+ border: 1px solid;
+}
+
+.ui .border.red {
+ border-color: var(--color-red) !important;
+}
+
+.ui .border.blue {
+ border-color: var(--color-blue) !important;
+}
+
+.ui .border.black {
+ border-color: var(--color-black) !important;
+}
+
+.ui .border.grey {
+ border-color: var(--color-grey) !important;
+}
+
+.ui .border.light.grey {
+ border-color: var(--color-grey) !important;
+}
+
+.ui .border.green {
+ border-color: var(--color-green) !important;
+}
+
+.ui .border.purple {
+ border-color: var(--color-purple) !important;
+}
+
+.ui .border.yellow {
+ border-color: var(--color-yellow) !important;
+}
+
+.ui .border.orange {
+ border-color: var(--color-orange) !important;
+}
+
+.ui .border.gold {
+ border-color: var(--color-gold) !important;
+}
+
+@media (max-width: 767.98px) {
+ .ui.pagination.menu .item:not(.active,.navigation),
+ .ui.pagination.menu .item.navigation span.navigation_label {
+ display: none;
+ }
+}
+
+.ui.pagination.menu.narrow .item {
+ padding-left: 8px;
+ padding-right: 8px;
+ min-width: 1em;
+ text-align: center;
+}
+
+.ui.pagination.menu.narrow .item .icon {
+ margin-right: 0;
+}
+
+.ui.floating.dropdown .overflow.menu .scrolling.menu.items {
+ border-radius: 0 !important;
+ box-shadow: none !important;
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.user-menu > .item {
+ width: 100%;
+ border-radius: 0 !important;
+}
+
+.scrolling.menu .item.selected {
+ font-weight: var(--font-weight-semibold) !important;
+}
+
+.ui.dropdown .scrolling.menu {
+ border-color: var(--color-secondary);
+}
+
+.color-preview {
+ display: inline-block;
+ margin-left: 0.4em;
+ height: 0.67em;
+ width: 0.67em;
+ border-radius: var(--border-radius);
+}
+
+.attention-icon {
+ margin: auto 0.5em auto 0;
+}
+
+.attention-title {
+ align-items: center;
+ display: flex;
+}
+
+blockquote.attention-note {
+ border-left-color: var(--color-blue-dark-1);
+}
+strong.attention-note, svg.attention-note {
+ color: var(--color-blue-dark-1);
+}
+
+blockquote.attention-tip {
+ border-left-color: var(--color-success-text);
+}
+strong.attention-tip, svg.attention-tip {
+ color: var(--color-success-text);
+}
+
+blockquote.attention-important {
+ border-left-color: var(--color-violet-dark-1);
+}
+strong.attention-important, svg.attention-important {
+ color: var(--color-violet-dark-1);
+}
+
+blockquote.attention-warning {
+ border-left-color: var(--color-warning-text);
+}
+strong.attention-warning, svg.attention-warning {
+ color: var(--color-warning-text);
+}
+
+blockquote.attention-caution {
+ border-left-color: var(--color-red-dark-1);
+}
+strong.attention-caution, svg.attention-caution {
+ color: var(--color-red-dark-1);
+}
+
+.center:not(.popup) {
+ text-align: center;
+}
+
+overflow-menu {
+ border-bottom: 1px solid var(--color-secondary) !important;
+ display: flex;
+}
+
+overflow-menu .overflow-menu-items {
+ display: flex;
+ flex: 1;
+}
+
+overflow-menu .overflow-menu-items .item {
+ margin-bottom: 0 !important; /* reset fomantic's margin, because the active menu has special bottom border */
+}
+
+overflow-menu .ui.label {
+ margin-left: 7px !important; /* save some space */
+}
+
+.activity-bar-graph {
+ background-color: var(--color-primary);
+ color: var(--color-primary-contrast);
+}
+
+.archived-icon {
+ color: var(--color-secondary-dark-2) !important;
+}
+
+/* colors of colorful icons */
+svg.text.green,
+.text.green svg {
+ color: var(--color-icon-green) !important;
+}
+svg.text.red,
+.text.red svg {
+ color: var(--color-icon-red) !important;
+}
+svg.text.purple,
+.text.purple svg {
+ color: var(--color-icon-purple) !important;
+}
+
+.oauth2-authorize-application-box {
+ margin-top: 3em !important;
+}
+
+/* multiple radio or checkboxes as inline element */
+.inline-grouped-list {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.inline-grouped-list > .ui {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+}
+
+.inline-grouped-list > .ui:first-child {
+ margin-top: 1px;
+}
+
+.ui.menu .item > .label {
+ background: var(--color-label-bg);
+ color: var(--color-label-text);
+}
+
+.ui.menu .active.item > .label {
+ background: var(--color-label-bg-alt, var(--color-label-bg));
+}
+
+.lines-blame-btn {
+ padding: 0 0 0 5px;
+ display: flex;
+ justify-content: center;
+}
+
+.lines-num {
+ padding: 0 8px;
+ text-align: right !important;
+ color: var(--color-text-light-2);
+ width: 1%;
+ font-family: var(--fonts-monospace);
+}
+
+.lines-num span.bottom-line::after {
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.lines-num span::after {
+ content: attr(data-line-number);
+ line-height: 20px !important;
+ padding: 0 10px;
+ cursor: pointer;
+ display: block;
+}
+
+.lines-type-marker {
+ vertical-align: top;
+}
+
+.lines-num,
+.lines-code {
+ font-size: 12px;
+ font-family: var(--fonts-monospace);
+ line-height: 20px;
+ padding-top: 0;
+ padding-bottom: 0;
+ vertical-align: top;
+}
+
+.lines-num pre,
+.lines-code pre,
+.lines-num ol,
+.lines-code ol {
+ background-color: inherit;
+ margin: 0;
+ padding: 0 !important;
+}
+
+.lines-num pre li,
+.lines-code pre li,
+.lines-num ol li,
+.lines-code ol li {
+ display: block;
+ width: calc(100% - 1ch);
+ padding-left: 1ch;
+}
+
+.lines-escape {
+ width: 0;
+}
+
+.lines-code {
+ padding-left: 5px;
+}
+
+.file-view tr.active {
+ color: inherit !important;
+ background: inherit !important;
+}
+
+.file-view tr.active .lines-num,
+.file-view tr.active .lines-code {
+ background: var(--color-highlight-bg) !important;
+}
+
+.file-view tr.active:last-of-type .lines-code {
+ border-bottom-right-radius: var(--border-radius);
+}
+
+.file-view tr.active .lines-num {
+ position: relative;
+}
+
+.file-view tr.active .lines-num::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ width: 2px;
+ height: 100%;
+ background: var(--color-highlight-fg);
+}
+
+.code-inner {
+ font: 12px var(--fonts-monospace);
+ white-space: pre-wrap;
+ word-break: break-all;
+ overflow-wrap: anywhere;
+ line-height: inherit; /* needed for inline code preview in markup */
+}
+
+.blame .code-inner {
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
+}
+
+.lines-commit {
+ vertical-align: top;
+ color: var(--color-text-light-1);
+ padding: 0 !important;
+ width: 1%;
+}
+
+.lines-commit .blame-info {
+ width: min(26vw, 300px);
+ display: block;
+ padding: 0 0 0 6px;
+ line-height: 20px;
+ box-sizing: content-box;
+}
+
+.lines-commit .blame-info .blame-data {
+ display: flex;
+ font-family: var(--fonts-regular);
+}
+
+.lines-commit .blame-info .blame-data .blame-message {
+ flex-grow: 2;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.lines-commit .blame-info .blame-data .blame-time,
+.lines-commit .blame-info .blame-data .blame-avatar {
+ flex-shrink: 0;
+}
+
+.blame-avatar {
+ display: flex;
+ align-items: center;
+ margin-right: 4px;
+}
+
+.top-line-blame {
+ border-top: 1px solid var(--color-secondary);
+}
+
+.code-view tr.top-line-blame:first-of-type {
+ border-top: none;
+}
+
+.lines-code .bottom-line,
+.lines-commit .bottom-line {
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.code-view {
+ background: var(--color-code-bg);
+ border-radius: var(--border-radius);
+}
+
+.code-view table {
+ width: 100%;
+}
+
+.migrate .svg.gitea-git {
+ color: var(--color-git);
+}
+
+.color-icon {
+ display: inline-block;
+ border-radius: var(--border-radius-full);
+ height: 14px;
+ width: 14px;
+}
+
+.rss-icon {
+ display: inline-flex;
+ color: var(--color-text-light-1);
+}
+
+table th[data-sortt-asc]:hover,
+table th[data-sortt-desc]:hover {
+ background: var(--color-hover) !important;
+ cursor: pointer !important;
+}
+
+table th[data-sortt-asc] .svg,
+table th[data-sortt-desc] .svg {
+ margin-left: 0.25rem;
+}
+
+.ui.dropdown .menu .item {
+ border-radius: 0;
+}
+
+.ui.dropdown .menu .item:first-of-type {
+ border-radius: var(--border-radius) var(--border-radius) 0 0;
+}
+
+.ui.dropdown .menu .item:last-of-type {
+ border-radius: 0 0 var(--border-radius) var(--border-radius);
+}
+
+.ui.multiple.dropdown > .label {
+ box-shadow: 0 0 0 1px var(--color-secondary) inset;
+}
+
+.emoji,
+.reaction {
+ font-size: 1.25em;
+ line-height: var(--line-height-default);
+ font-style: normal !important;
+ font-weight: var(--font-weight-normal) !important;
+ vertical-align: -0.075em;
+}
+
+.emoji img,
+.reaction img {
+ border-width: 0 !important;
+ margin: 0 !important;
+ width: 1em !important;
+ height: 1em !important;
+ vertical-align: -0.15em;
+}
+
+.ui.tabular.menu {
+ border-color: var(--color-secondary);
+}
+
+.ui.tabular.menu .active.item,
+.ui.tabular.menu .active.item:hover {
+ background: var(--color-body);
+ border-color: var(--color-secondary);
+ color: var(--color-text);
+}
+
+.ui.segment .ui.tabular.menu .active.item,
+.ui.segment .ui.tabular.menu .active.item:hover {
+ background: var(--color-box-body);
+}
+
+.ui.secondary.pointing.menu {
+ border-color: var(--color-secondary);
+}
+
+.ui.tabular.menu .item,
+.ui.secondary.pointing.menu .item {
+ padding: 11px 12px !important;
+ color: var(--color-text-light-2);
+}
+
+.ui.tabular.menu .item:hover,
+.ui.secondary.pointing.menu a.item:hover, .ui.secondary.pointing.menu a.item:focus {
+ color: var(--color-text);
+}
+
+.ui.secondary.pointing.menu .active.item,
+.ui.secondary.pointing.menu .active.item:hover, .ui.secondary.pointing.menu .active.item:focus,
+.ui.secondary.pointing.menu .dropdown.item:hover, .ui.secondary.pointing.menu .dropdown.item:focus {
+ color: var(--color-text-dark);
+}
+
+.ui.tabular.menu .active.item,
+.ui.secondary.pointing.menu .active.item,
+.resize-for-semibold::before {
+ font-weight: var(--font-weight-semibold);
+}
+
+.resize-for-semibold::before {
+ content: attr(data-text);
+ visibility: hidden;
+ display: block;
+ height: 0;
+}
+
+.flash-error details code,
+.flash-warning details code {
+ display: block;
+ text-align: left;
+}
+
+.truncated-item-container {
+ display: flex !important;
+ align-items: center;
+}
+
+.ellipsis-button {
+ padding: 0 5px 8px !important;
+ display: inline-block !important;
+ font-weight: var(--font-weight-semibold) !important;
+ line-height: 6px !important;
+ vertical-align: middle !important;
+}
+
+.truncated-item-name {
+ line-height: 2;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ margin-top: -0.5em;
+ margin-bottom: -0.5em;
+}
+
+.precolors {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-left: 1em;
+}
+
+.precolors .color {
+ display: inline-block;
+ width: 15px;
+ height: 15px;
+}
+
+.ui.dropdown:not(.button) {
+ line-height: var(--line-height-default); /* the dropdown doesn't have default line-height, use this to make the dropdown icon align with plain dropdown */
+}
+
+/* dropdown has some kinds of icons:
+- "> .dropdown.icon": the arrow for opening the dropdown
+- "> .remove.icon": the "x" icon for clearing the dropdown, only used in selection dropdown
+- "> .ui.label > .delete.icon": the "x" icon for removing a label item in multiple selection dropdown
+*/
+
+.ui.dropdown.mini.button,
+.ui.dropdown.tiny.button {
+ padding-right: 20px;
+}
+.ui.dropdown.button {
+ padding-right: 22px;
+}
+.ui.dropdown.large.button {
+ padding-right: 24px;
+}
+
+/* Gitea uses SVG images instead of Fomantic builtin "<i>" font icons, so we need to reset the icon styles */
+.ui.ui.dropdown > .icon.icon {
+ position: initial; /* plain dropdown and button dropdown use flex layout for icons */
+ padding: 0;
+ margin: 0;
+ height: auto;
+}
+
+.ui.ui.dropdown > .icon.icon:hover {
+ opacity: 1;
+}
+
+.ui.ui.button.dropdown > .icon.icon,
+.ui.ui.selection.dropdown > .icon.icon {
+ position: absolute; /* selection dropdown uses absolute layout for icons */
+ top: 50%;
+ transform: translateY(-50%);
+}
+
+.ui.ui.dropdown > .dropdown.icon {
+ right: 0.5em;
+}
+
+.ui.ui.dropdown > .remove.icon {
+ right: 2em;
+}
+
+.btn,
+.ui.ui.button,
+.ui.ui.dropdown,
+.flex-items-inline > .item,
+.flex-text-inline {
+ display: inline-flex;
+ align-items: center;
+ gap: .25rem;
+ vertical-align: middle;
+ min-width: 0;
+}
+
+.ui.ui.button {
+ justify-content: center;
+}
+
+.ui.dropdown .ui.label .svg {
+ vertical-align: middle;
+}
+
+.ui.ui.labeled.button {
+ gap: 0;
+ align-items: stretch;
+}
+
+.flex-items-block > .item,
+.flex-text-block {
+ display: flex;
+ align-items: center;
+ gap: .25rem;
+ min-width: 0;
+}
diff --git a/web_src/css/chroma/base.css b/web_src/css/chroma/base.css
new file mode 100644
index 00000000..bce13332
--- /dev/null
+++ b/web_src/css/chroma/base.css
@@ -0,0 +1,46 @@
+/* LineTableTD */
+.chroma .lntd {
+ vertical-align: top;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+/* LineTable */
+.chroma .lntable {
+ border-spacing: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+ width: auto;
+ overflow: auto;
+ display: block;
+}
+
+/* LineHighlight */
+.chroma .hl {
+ display: block;
+ width: 100%;
+}
+
+/* LineNumbersTable */
+.chroma .lnt {
+ margin-right: 0.4em;
+ padding: 0 0.4em;
+}
+
+/* LineNumbers */
+.chroma .ln {
+ margin-right: 0.4em;
+ padding: 0 0.4em;
+}
+
+/* GenericStrong */
+.chroma .gs {
+ font-weight: var(--font-weight-semibold);
+}
+
+/* GenericUnderline */
+.chroma .gl {
+ text-decoration: underline;
+}
diff --git a/web_src/css/chroma/dark.css b/web_src/css/chroma/dark.css
new file mode 100644
index 00000000..bfe9d69f
--- /dev/null
+++ b/web_src/css/chroma/dark.css
@@ -0,0 +1,76 @@
+/* https://github.com/alecthomas/chroma/blob/6428fb4e65f3c1493491571c8a6a8f1add1da822/types.go#L208 */
+.chroma .bp { color: #fabd2f; } /* NameBuiltinPseudo */
+.chroma .c { color: #777e94; } /* Comment */
+.chroma .c1 { color: #777e94; } /* CommentSingle */
+.chroma .ch { color: #777e94; } /* CommentHashbang */
+.chroma .cm { color: #777e94; } /* CommentMultiline */
+.chroma .cp { color: #8ec07c; } /* CommentPreproc */
+.chroma .cpf { color: #649bc4; } /* CommentPreprocFile */
+.chroma .cs { color: #9075cd; } /* CommentSpecial */
+.chroma .dl { color: #649bc4; } /* LiteralStringDelimiter */
+.chroma .fm {} /* NameFunctionMagic */
+.chroma .g {} /* Generic */
+.chroma .gd { color: #ffffff; background-color: #5f3737; } /* GenericDeleted */
+.chroma .ge { color: #ddee30; } /* GenericEmph */
+.chroma .gh { color: #ffaa10; } /* GenericHeading */
+.chroma .gi { color: #ffffff; background-color: #3a523a; } /* GenericInserted */
+.chroma .gl {} /* GenericUnderline */
+.chroma .go { color: #777e94; } /* GenericOutput */
+.chroma .gp { color: #ebdbb2; } /* GenericPrompt */
+.chroma .gr { color: #ff4433; } /* GenericError */
+.chroma .gs { color: #ebdbb2; } /* GenericStrong */
+.chroma .gt { color: #ff7540; } /* GenericTraceback */
+.chroma .gu { color: #b8bb26; } /* GenericSubheading */
+.chroma .il { color: #649bc4; } /* LiteralNumberIntegerLong */
+.chroma .k { color: #ff7540; } /* Keyword */
+.chroma .kc { color: #649bc4; } /* KeywordConstant */
+.chroma .kd { color: #ff7540; } /* KeywordDeclaration */
+.chroma .kn { color: #ffaa10; } /* KeywordNamespace */
+.chroma .kp { color: #5f8700; } /* KeywordPseudo */
+.chroma .kr { color: #ff7540; } /* KeywordReserved */
+.chroma .kt { color: #ff7b72; } /* KeywordType */
+.chroma .l {} /* Literal */
+.chroma .ld {} /* LiteralDate */
+.chroma .m { color: #649bc4; } /* LiteralNumber */
+.chroma .mb { color: #649bc4; } /* LiteralNumberBin */
+.chroma .mf { color: #649bc4; } /* LiteralNumberFloat */
+.chroma .mh { color: #649bc4; } /* LiteralNumberHex */
+.chroma .mi { color: #649bc4; } /* LiteralNumberInteger */
+.chroma .mo { color: #649bc4; } /* LiteralNumberOct */
+.chroma .n { color: #c9d1d9; } /* Name */
+.chroma .na { color: #fabd2f; } /* NameAttribute */
+.chroma .nb { color: #fabd2f; } /* NameBuiltin */
+.chroma .nc { color: #ffaa10; } /* NameClass */
+.chroma .nd { color: #8ec07c; } /* NameDecorator */
+.chroma .ne { color: #ff7540; } /* NameException */
+.chroma .nf { color: #fabd2f; } /* NameFunction */
+.chroma .ni { color: #fabd2f; } /* NameEntity */
+.chroma .nl { color: #ff7540; } /* NameLabel */
+.chroma .nn { color: #c9d1d9; } /* NameNamespace */
+.chroma .no { color: #649bc4; } /* NameConstant */
+.chroma .nt { color: #ff7540; } /* NameTag */
+.chroma .nv { color: #ebdbb2; } /* NameVariable */
+.chroma .nx { color: #b6bac5; } /* NameOther */
+.chroma .o { color: #ff7540; } /* Operator */
+.chroma .ow { color: #5f8700; } /* OperatorWord */
+.chroma .p { color: #d2d4db; } /* Punctuation */
+.chroma .py {} /* NameProperty */
+.chroma .s { color: #b8bb26; } /* LiteralString */
+.chroma .s1 { color: #b8bb26; } /* LiteralStringSingle */
+.chroma .s2 { color: #b8bb26; } /* LiteralStringDouble */
+.chroma .sa { color: #ffaa10; } /* LiteralStringAffix */
+.chroma .sb { color: #b8bb26; } /* LiteralStringBacktick */
+.chroma .sc { color: #ffaa10; } /* LiteralStringChar */
+.chroma .sd { color: #b8bb26; } /* LiteralStringDoc */
+.chroma .se { color: #ff8540; } /* LiteralStringEscape */
+.chroma .sh { color: #b8bb26; } /* LiteralStringHeredoc */
+.chroma .si { color: #ffaa10; } /* LiteralStringInterpol */
+.chroma .sr { color: #9075cd; } /* LiteralStringRegex */
+.chroma .ss { color: #ff8540; } /* LiteralStringSymbol */
+.chroma .sx { color: #ffaa10; } /* LiteralStringOther */
+.chroma .vc { color: #649bee; } /* NameVariableClass */
+.chroma .vg { color: #649bee; } /* NameVariableGlobal */
+.chroma .vi { color: #649bee; } /* NameVariableInstance */
+.chroma .vm {} /* NameVariableMagic */
+.chroma .w { color: #7f8699; } /* TextWhitespace */
+.chroma .err {/* not styled because Chroma uses it on too many things like JSX */} /* Error */
diff --git a/web_src/css/chroma/light.css b/web_src/css/chroma/light.css
new file mode 100644
index 00000000..c1e4cb35
--- /dev/null
+++ b/web_src/css/chroma/light.css
@@ -0,0 +1,76 @@
+/* https://github.com/alecthomas/chroma/blob/6428fb4e65f3c1493491571c8a6a8f1add1da822/types.go#L208 */
+.chroma .bp { color: #999999; } /* NameBuiltinPseudo */
+.chroma .c { color: #6a737d; } /* Comment */
+.chroma .c1 { color: #6a737d; } /* CommentSingle */
+.chroma .ch { color: #6a737d; } /* CommentHashbang */
+.chroma .cm { color: #999988; } /* CommentMultiline */
+.chroma .cp { color: #109295; } /* CommentPreproc */
+.chroma .cpf { color: #4c4dbc; } /* CommentPreprocFile */
+.chroma .cs { color: #999999; } /* CommentSpecial */
+.chroma .dl { color: #106303; } /* LiteralStringDelimiter */
+.chroma .fm {} /* NameFunctionMagic */
+.chroma .g {} /* Generic */
+.chroma .gd { color: #000000; background-color: #ffdddd; } /* GenericDeleted */
+.chroma .ge { color: #000000; } /* GenericEmph */
+.chroma .gh { color: #999999; } /* GenericHeading */
+.chroma .gi { color: #000000; background-color: #ddffdd; } /* GenericInserted */
+.chroma .gl {} /* GenericUnderline */
+.chroma .go { color: #888888; } /* GenericOutput */
+.chroma .gp { color: #555555; } /* GenericPrompt */
+.chroma .gr { color: #aa0000; } /* GenericError */
+.chroma .gs {} /* GenericStrong */
+.chroma .gt { color: #aa0000; } /* GenericTraceback */
+.chroma .gu { color: #aaaaaa; } /* GenericSubheading */
+.chroma .il { color: #009999; } /* LiteralNumberIntegerLong */
+.chroma .k { color: #d73a49; } /* Keyword */
+.chroma .kc { color: #d73a49; } /* KeywordConstant */
+.chroma .kd { color: #d73a49; } /* KeywordDeclaration */
+.chroma .kn { color: #d73a49; } /* KeywordNamespace */
+.chroma .kp { color: #d73a49; } /* KeywordPseudo */
+.chroma .kr { color: #d73a49; } /* KeywordReserved */
+.chroma .kt { color: #445588; } /* KeywordType */
+.chroma .l {} /* Literal */
+.chroma .ld {} /* LiteralDate */
+.chroma .m { color: #009999; } /* LiteralNumber */
+.chroma .mb { color: #009999; } /* LiteralNumberBin */
+.chroma .mf { color: #009999; } /* LiteralNumberFloat */
+.chroma .mh { color: #009999; } /* LiteralNumberHex */
+.chroma .mi { color: #009999; } /* LiteralNumberInteger */
+.chroma .mo { color: #009999; } /* LiteralNumberOct */
+.chroma .n {} /* Name */
+.chroma .na { color: #d73a49; } /* NameAttribute */
+.chroma .nb { color: #005cc5; } /* NameBuiltin */
+.chroma .nc { color: #445588; } /* NameClass */
+.chroma .nd { color: #3c5d5d; } /* NameDecorator */
+.chroma .ne { color: #990000; } /* NameException */
+.chroma .nf { color: #005cc5; } /* NameFunction */
+.chroma .ni { color: #6f42c1; } /* NameEntity */
+.chroma .nl { color: #990000; } /* NameLabel */
+.chroma .nn { color: #555555; } /* NameNamespace */
+.chroma .no { color: #008080; } /* NameConstant */
+.chroma .nt { color: #22863a; } /* NameTag */
+.chroma .nv { color: #008080; } /* NameVariable */
+.chroma .nx { color: #24292e; } /* NameOther */
+.chroma .o { color: #d73a49; } /* Operator */
+.chroma .ow { color: #d73a49; } /* OperatorWord */
+.chroma .p {} /* Punctuation */
+.chroma .py {} /* NameProperty */
+.chroma .s { color: #106303; } /* LiteralString */
+.chroma .s1 { color: #106303; } /* LiteralStringSingle */
+.chroma .s2 { color: #106303; } /* LiteralStringDouble */
+.chroma .sa { color: #cc7a00; } /* LiteralStringAffix */
+.chroma .sb { color: #106303; } /* LiteralStringBacktick */
+.chroma .sc { color: #cc7a00; } /* LiteralStringChar */
+.chroma .sd { color: #106303; } /* LiteralStringDoc */
+.chroma .se { color: #994400; } /* LiteralStringEscape */
+.chroma .sh { color: #106303; } /* LiteralStringHeredoc */
+.chroma .si { color: #cc7a00; } /* LiteralStringInterpol */
+.chroma .sr { color: #4c4dbc; } /* LiteralStringRegex */
+.chroma .ss { color: #994400; } /* LiteralStringSymbol */
+.chroma .sx { color: #106303; } /* LiteralStringOther */
+.chroma .vc { color: #008080; } /* NameVariableClass */
+.chroma .vg { color: #008080; } /* NameVariableGlobal */
+.chroma .vi { color: #008080; } /* NameVariableInstance */
+.chroma .vm {} /* NameVariableMagic */
+.chroma .w { color: #bbbbbb; } /* TextWhitespace */
+.chroma .err {/* not styled because Chroma uses it on too many things like JSX */} /* Error */
diff --git a/web_src/css/codemirror/base.css b/web_src/css/codemirror/base.css
new file mode 100644
index 00000000..aedf7d85
--- /dev/null
+++ b/web_src/css/codemirror/base.css
@@ -0,0 +1,49 @@
+.ui .field:not(:last-child) .EasyMDEContainer .editor-statusbar {
+ margin-bottom: -1em; /* when there is a statusbar, the "margin-bottom: 1em" of the "field" is not needed, because the statusbar is likely a blank line */
+}
+
+.EasyMDEContainer .CodeMirror {
+ color: var(--color-input-text);
+ background-color: var(--color-input-background);
+ border-color: var(--color-secondary);
+ font: 14px var(--fonts-monospace);
+}
+
+.EasyMDEContainer .CodeMirror.cm-s-default {
+ border-radius: var(--border-radius);
+ padding: 0 !important;
+}
+
+.EasyMDEContainer .CodeMirror.CodeMirror-fullscreen.CodeMirror-focused {
+ border-right: 1px solid var(--color-primary) !important;
+}
+
+.CodeMirror-cursor {
+ border-color: var(--color-caret) !important;
+}
+
+.CodeMirror .cm-comment {
+ background: inherit !important;
+}
+
+.CodeMirror .CodeMirror-code {
+ font: 14px var(--fonts-monospace);
+}
+
+.CodeMirror-selected {
+ background: var(--color-primary-light-1) !important;
+ color: var(--color-white) !important;
+}
+
+.CodeMirror-placeholder {
+ color: var(--color-placeholder-text) !important;
+ opacity: 1 !important;
+}
+
+.CodeMirror-focused {
+ border-color: var(--color-primary) !important;
+}
+
+.CodeMirror :focus {
+ outline: none;
+}
diff --git a/web_src/css/codemirror/dark.css b/web_src/css/codemirror/dark.css
new file mode 100644
index 00000000..8a20d1c0
--- /dev/null
+++ b/web_src/css/codemirror/dark.css
@@ -0,0 +1,106 @@
+.CodeMirror.cm-s-default .cm-property,
+.CodeMirror.cm-s-paper .cm-property {
+ color: #a0cc75;
+}
+
+.CodeMirror.cm-s-default .cm-header,
+.CodeMirror.cm-s-paper .cm-header {
+ color: #9daccc;
+}
+
+.CodeMirror.cm-s-default .cm-quote,
+.CodeMirror.cm-s-paper .cm-quote {
+ color: #009900;
+}
+
+.CodeMirror.cm-s-default .cm-keyword,
+.CodeMirror.cm-s-paper .cm-keyword {
+ color: #cc8a61;
+}
+
+.CodeMirror.cm-s-default .cm-atom,
+.CodeMirror.cm-s-paper .cm-atom {
+ color: #ef5e77;
+}
+
+.CodeMirror.cm-s-default .cm-number,
+.CodeMirror.cm-s-paper .cm-number {
+ color: #ff5656;
+}
+
+.CodeMirror.cm-s-default .cm-def,
+.CodeMirror.cm-s-paper .cm-def {
+ color: #e4e4e4;
+}
+
+.CodeMirror.cm-s-default .cm-variable-2,
+.CodeMirror.cm-s-paper .cm-variable-2 {
+ color: #00bdbf;
+}
+
+.CodeMirror.cm-s-default .cm-variable-3,
+.CodeMirror.cm-s-paper .cm-variable-3 {
+ color: #008855;
+}
+
+.CodeMirror.cm-s-default .cm-comment,
+.CodeMirror.cm-s-paper .cm-comment {
+ color: #8e9ab3;
+}
+
+.CodeMirror.cm-s-default .cm-string,
+.CodeMirror.cm-s-paper .cm-string {
+ color: #a77272;
+}
+
+.CodeMirror.cm-s-default .cm-string-2,
+.CodeMirror.cm-s-paper .cm-string-2 {
+ color: #ff5500;
+}
+
+.CodeMirror.cm-s-default .cm-meta,
+.CodeMirror.cm-s-paper .cm-meta,
+.CodeMirror.cm-s-default .cm-qualifier,
+.CodeMirror.cm-s-paper .cm-qualifier {
+ color: #ffb176;
+}
+
+.CodeMirror.cm-s-default .cm-builtin,
+.CodeMirror.cm-s-paper .cm-builtin {
+ color: #b7c951;
+}
+
+.CodeMirror.cm-s-default .cm-bracket,
+.CodeMirror.cm-s-paper .cm-bracket {
+ color: #999977;
+}
+
+.CodeMirror.cm-s-default .cm-tag,
+.CodeMirror.cm-s-paper .cm-tag {
+ color: #f1d273;
+}
+
+.CodeMirror.cm-s-default .cm-attribute,
+.CodeMirror.cm-s-paper .cm-attribute {
+ color: #bfcc70;
+}
+
+.CodeMirror.cm-s-default .cm-hr,
+.CodeMirror.cm-s-paper .cm-hr {
+ color: #999999;
+}
+
+.CodeMirror.cm-s-default .cm-url,
+.CodeMirror.cm-s-paper .cm-url {
+ color: #c5cfd0;
+}
+
+.CodeMirror.cm-s-default .cm-link,
+.CodeMirror.cm-s-paper .cm-link {
+ color: #d8c792;
+}
+
+.CodeMirror.cm-s-default .cm-error,
+.CodeMirror.cm-s-paper .cm-error {
+ color: #dbdbeb;
+}
diff --git a/web_src/css/codemirror/light.css b/web_src/css/codemirror/light.css
new file mode 100644
index 00000000..aa89263b
--- /dev/null
+++ b/web_src/css/codemirror/light.css
@@ -0,0 +1 @@
+/* Placeholder, there is no light theme, it uses CM defaults */
diff --git a/web_src/css/dashboard.css b/web_src/css/dashboard.css
new file mode 100644
index 00000000..4bb9fa38
--- /dev/null
+++ b/web_src/css/dashboard.css
@@ -0,0 +1,81 @@
+.dashboard.feeds .context.user.menu,
+.dashboard.issues .context.user.menu {
+ z-index: 101;
+ min-width: 200px;
+}
+
+.dashboard.feeds .context.user.menu .ui.header,
+.dashboard.issues .context.user.menu .ui.header {
+ font-size: 1rem;
+ text-transform: none;
+}
+
+.dashboard.feeds .filter.menu,
+.dashboard.issues .filter.menu {
+ width: initial;
+}
+
+.dashboard.feeds .filter.menu .item,
+.dashboard.issues .filter.menu .item {
+ text-align: left;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.dashboard.feeds .filter.menu .item .text.truncate,
+.dashboard.issues .filter.menu .item .text.truncate {
+ width: 75%;
+}
+
+/* Sort */
+.dashboard.feeds .filter.menu .jump.item,
+.dashboard.issues .filter.menu .jump.item {
+ margin: 1px;
+ padding-right: 0;
+}
+
+.dashboard.feeds .filter.menu .menu,
+.dashboard.issues .filter.menu .menu {
+ max-height: 300px;
+ overflow-x: auto;
+ right: 0 !important;
+ left: auto !important;
+}
+
+@media (max-width: 767.98px) {
+ .dashboard.feeds .filter.menu,
+ .dashboard.issues .filter.menu {
+ width: 100%;
+ }
+}
+
+.dashboard.feeds .right.stackable.menu > .item.active,
+.dashboard.issues .right.stackable.menu > .item.active {
+ color: var(--color-red);
+}
+
+.dashboard .dashboard-repos,
+.dashboard .dashboard-orgs {
+ margin: 0 1px; /* Accommodate for Semantic's 1px hacks on .attached elements */
+}
+
+.dashboard .secondary-nav {
+ padding: 1px 12px; /* match .overflow-menu-items in height */
+}
+
+.dashboard .secondary-nav .right.menu {
+ gap: .35714286em;
+}
+
+.dashboard .secondary-nav .right.menu div.item {
+ padding-left: 0.5rem;
+}
+
+.dashboard .secondary-nav .org-visibility .label {
+ margin-left: 5px;
+}
+
+.dashboard .secondary-nav .ui.dropdown {
+ max-width: 100%;
+}
diff --git a/web_src/css/editor/combomarkdowneditor.css b/web_src/css/editor/combomarkdowneditor.css
new file mode 100644
index 00000000..f190c7eb
--- /dev/null
+++ b/web_src/css/editor/combomarkdowneditor.css
@@ -0,0 +1,136 @@
+.combo-markdown-editor {
+ width: 100%;
+}
+
+.combo-markdown-editor markdown-toolbar {
+ cursor: default;
+ display: flex;
+ align-items: center;
+ padding-bottom: 10px;
+ gap: .5rem;
+ flex-wrap: wrap;
+}
+
+.combo-markdown-editor .markdown-toolbar-group {
+ display: flex;
+}
+
+.combo-markdown-editor .markdown-toolbar-group:last-child {
+ flex: 1;
+ justify-content: flex-end;
+}
+
+.combo-markdown-editor .markdown-toolbar-button {
+ border: none;
+ background: none;
+ user-select: none;
+ padding: 5px;
+ cursor: pointer;
+ color: var(--color-text);
+ line-height: 20px;
+}
+
+.combo-markdown-editor .markdown-toolbar-button:hover {
+ color: var(--color-primary);
+}
+
+.ui.form .combo-markdown-editor textarea.markdown-text-editor,
+.combo-markdown-editor textarea.markdown-text-editor {
+ display: block;
+ width: 100%;
+ max-height: calc(100vh - var(--min-height-textarea));
+ resize: vertical;
+}
+
+.combo-markdown-editor .CodeMirror-scroll {
+ max-height: calc(100vh - var(--min-height-textarea));
+}
+
+/* use the same styles as markup/content.css */
+.combo-markdown-editor .CodeMirror-scroll .cm-header-1 {
+ font-size: 2em;
+}
+
+.combo-markdown-editor .CodeMirror-scroll .cm-header-2 {
+ font-size: 1.5em;
+}
+
+.combo-markdown-editor .CodeMirror-scroll .cm-header-3 {
+ font-size: 1.25em;
+}
+
+.combo-markdown-editor .CodeMirror-scroll .cm-header-4 {
+ font-size: 1em;
+}
+
+.combo-markdown-editor .CodeMirror-scroll .cm-header-5 {
+ font-size: 0.875em;
+}
+
+.combo-markdown-editor .CodeMirror-scroll .cm-header-6 {
+ font-size: 0.85em;
+}
+
+text-expander {
+ display: block;
+ position: relative;
+}
+
+text-expander .suggestions {
+ position: absolute;
+ min-width: 180px;
+ padding: 0;
+ margin-top: 24px;
+ list-style: none;
+ background: var(--color-box-body);
+ border-radius: var(--border-radius);
+ border: 1px solid var(--color-secondary);
+ box-shadow: 0 .5rem 1rem var(--color-shadow);
+ z-index: 100; /* needs to be > 20 to be on top of dropzone's .dz-details */
+}
+
+text-expander .suggestions li {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ padding: 4px 8px;
+ font-weight: var(--font-weight-medium);
+}
+
+text-expander .suggestions li + li {
+ border-top: 1px solid var(--color-secondary-alpha-40);
+}
+
+text-expander .suggestions li:first-child {
+ border-radius: var(--border-radius) var(--border-radius) 0 0;
+}
+
+text-expander .suggestions li:last-child {
+ border-radius: 0 0 var(--border-radius) var(--border-radius);
+}
+
+text-expander .suggestions li:only-child {
+ border-radius: var(--border-radius);
+}
+
+text-expander .suggestions li:hover {
+ background: var(--color-hover);
+}
+
+text-expander .suggestions .fullname {
+ font-weight: var(--font-weight-normal);
+ margin-left: 4px;
+ color: var(--color-text-light-1);
+}
+
+text-expander .suggestions li[aria-selected="true"],
+text-expander .suggestions li[aria-selected="true"] span {
+ background: var(--color-primary);
+ color: var(--color-primary-contrast);
+}
+
+text-expander .suggestions img {
+ width: 24px;
+ height: 24px;
+ margin-right: 8px;
+}
diff --git a/web_src/css/editor/fileeditor.css b/web_src/css/editor/fileeditor.css
new file mode 100644
index 00000000..444ee8c7
--- /dev/null
+++ b/web_src/css/editor/fileeditor.css
@@ -0,0 +1,85 @@
+.repository.file.editor .tab[data-tab="write"] {
+ padding: 0 !important;
+}
+
+.repository.file.editor .tab[data-tab="write"] .editor-toolbar {
+ border: 0 !important;
+}
+
+.repository.file.editor .tab[data-tab="write"] .CodeMirror {
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0;
+}
+
+.repo-editor-header {
+ display: flex;
+ margin: 1rem 0;
+ padding: 3px 0;
+}
+
+.editor-toolbar {
+ border-color: var(--color-secondary);
+}
+
+.editor-toolbar.fullscreen {
+ background: var(--color-body);
+}
+
+.editor-toolbar button {
+ border: none !important;
+ color: var(--color-text-light);
+}
+
+.editor-toolbar button:not(:hover) {
+ background-color: transparent !important;
+}
+
+.editor-toolbar i.separator {
+ border-left: none;
+ border-right-color: var(--color-secondary);
+}
+
+.editor-toolbar button:hover {
+ background: var(--color-hover);
+}
+
+.editor-toolbar button.active {
+ background: var(--color-active);
+}
+
+/* hide preview button, we have the preview tab for this */
+.editor-toolbar:not(.fullscreen) .preview {
+ display: none;
+}
+
+/* hide revert button in fullscreen, it breaks the page */
+.editor-toolbar.fullscreen .revert-to-textarea {
+ display: none;
+}
+
+.editor-preview {
+ background-color: var(--color-body);
+}
+
+.editor-preview-side {
+ border-color: var(--color-secondary);
+}
+
+.editor-statusbar {
+ color: var(--color-text-light);
+}
+
+.editor-loading {
+ padding: 1rem;
+ text-align: center;
+}
+
+.edit-diff {
+ padding: 0 !important;
+}
+
+.edit-diff > div > .ui.table {
+ border-top: none !important;
+ border-bottom: none !important;
+}
diff --git a/web_src/css/explore.css b/web_src/css/explore.css
new file mode 100644
index 00000000..5cdee823
--- /dev/null
+++ b/web_src/css/explore.css
@@ -0,0 +1,31 @@
+.explore .secondary-nav {
+ border-width: 1px !important;
+}
+
+.explore .secondary-nav .svg {
+ width: 16px;
+ text-align: center;
+ margin-right: 5px;
+}
+
+.ui.repository.branches .info {
+ font-size: 12px;
+ color: var(--color-text-light);
+ display: flex;
+ white-space: pre;
+}
+
+.ui.repository.branches .info .commit-message {
+ max-width: 72em;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.ui.repository.branches .overflow-visible {
+ overflow: visible;
+}
+
+/* fix alignment of PR popup in branches table */
+.ui.repository.branches table .ui.popup {
+ text-align: left;
+}
diff --git a/web_src/css/features/codeeditor.css b/web_src/css/features/codeeditor.css
new file mode 100644
index 00000000..34a104c8
--- /dev/null
+++ b/web_src/css/features/codeeditor.css
@@ -0,0 +1,48 @@
+.monaco-editor-container,
+.editor-loading.is-loading {
+ width: 100%;
+ min-height: 200px;
+ height: 90vh;
+}
+
+.edit.githook .monaco-editor-container {
+ border: 1px solid var(--color-secondary);
+ height: 70vh;
+}
+
+/* overwrite conflicting styles from fomantic */
+.monaco-editor-container .inputarea {
+ min-height: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ resize: none !important;
+ border: none !important;
+ color: transparent !important;
+ background-color: transparent !important;
+}
+
+/* these seem unthemeable */
+.monaco-scrollable-element > .scrollbar > .slider {
+ background: var(--color-primary) !important;
+}
+.monaco-scrollable-element > .scrollbar > .slider:hover {
+ background: var(--color-primary-dark-1) !important;
+}
+.monaco-scrollable-element > .scrollbar > .slider:active {
+ background: var(--color-primary-dark-2) !important;
+}
+
+/* fomantic styles destroy this element only visible on IOS, restore it */
+.monaco-editor .iPadShowKeyboard {
+ border: none !important;
+ width: 58px !important;
+ min-width: 0 !important;
+ height: 36px !important;
+ min-height: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ position: absolute !important;
+ resize: none !important;
+ overflow: hidden !important;
+ border-radius: var(--border-radius-medium) !important;
+}
diff --git a/web_src/css/features/colorpicker.css b/web_src/css/features/colorpicker.css
new file mode 100644
index 00000000..b7436783
--- /dev/null
+++ b/web_src/css/features/colorpicker.css
@@ -0,0 +1,47 @@
+.js-color-picker-input {
+ display: flex;
+ position: relative;
+}
+
+.js-color-picker-input input {
+ padding-top: 8px !important;
+ padding-bottom: 8px !important;
+ padding-left: 32px !important;
+}
+
+.js-color-picker-input .preview-square {
+ position: absolute;
+ aspect-ratio: 1;
+ height: 16px;
+ left: 10px;
+ top: 50%;
+ transform: translateY(-50%);
+ border-radius: 2px;
+ background: repeating-linear-gradient(45deg, #aaa 25%, transparent 25%, transparent 75%, #aaa 75%, #aaa), repeating-linear-gradient(45deg, #aaa 25%, #fff 25%, #fff 75%, #aaa 75%, #aaa); /* stylelint-disable-line scale-unlimited/declaration-strict-value */
+ background-position: 0 0, 4px 4px;
+ background-size: 8px 8px;
+}
+
+.js-color-picker-input .preview-square::after {
+ content: "";
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ border-radius: inherit;
+ background-color: currentcolor;
+}
+
+hex-color-picker {
+ width: 180px;
+ height: 120px;
+}
+
+hex-color-picker::part(hue-pointer),
+hex-color-picker::part(saturation-pointer) {
+ width: 22px;
+ height: 22px;
+}
+
+hex-color-picker::part(hue) {
+ flex-basis: 16px;
+}
diff --git a/web_src/css/features/console.css b/web_src/css/features/console.css
new file mode 100644
index 00000000..e2d3327c
--- /dev/null
+++ b/web_src/css/features/console.css
@@ -0,0 +1,338 @@
+/* Based on https://github.com/buildkite/terminal-to-html/blob/697ff23bd8dc48b9d23f11f259f5256dae2455f0/assets/terminal.css */
+
+.console {
+ background: var(--color-console-bg);
+ color: var(--color-console-fg);
+ font-family: var(--fonts-monospace);
+ border-radius: var(--border-radius);
+ overflow-wrap: anywhere;
+}
+
+.console img { max-width: 100%; }
+
+.console a {
+ color: inherit;
+ text-decoration: underline;
+ text-decoration-style: dashed;
+}
+.console a:hover { color: var(--color-primary); }
+
+@keyframes blink-animation {
+ to {
+ visibility: hidden;
+ }
+}
+
+/* ansi_up colors used in actions */
+
+.ansi-black-fg { color: var(--color-ansi-black); }
+.ansi-red-fg { color: var(--color-ansi-red); }
+.ansi-green-fg { color: var(--color-ansi-green); }
+.ansi-yellow-fg { color: var(--color-ansi-yellow); }
+.ansi-blue-fg { color: var(--color-ansi-blue); }
+.ansi-magenta-fg { color: var(--color-ansi-magenta); }
+.ansi-cyan-fg { color: var(--color-ansi-cyan); }
+.ansi-white-fg { color: var(--color-ansi-white); }
+
+.ansi-bright-black-fg { color: var(--color-ansi-bright-black); }
+.ansi-bright-red-fg { color: var(--color-ansi-bright-red); }
+.ansi-bright-green-fg { color: var(--color-ansi-bright-green); }
+.ansi-bright-yellow-fg { color: var(--color-ansi-bright-yellow); }
+.ansi-bright-blue-fg { color: var(--color-ansi-bright-blue); }
+.ansi-bright-magenta-fg { color: var(--color-ansi-bright-magenta); }
+.ansi-bright-cyan-fg { color: var(--color-ansi-bright-cyan); }
+.ansi-bright-white-fg { color: var(--color-ansi-bright-white); }
+
+.ansi-black-bg { background-color: var(--color-ansi-black); }
+.ansi-red-bg { background-color: var(--color-ansi-red); }
+.ansi-green-bg { background-color: var(--color-ansi-green); }
+.ansi-yellow-bg { background-color: var(--color-ansi-yellow); }
+.ansi-blue-bg { background-color: var(--color-ansi-blue); }
+.ansi-magenta-bg { background-color: var(--color-ansi-magenta); }
+.ansi-cyan-bg { background-color: var(--color-ansi-cyan); }
+.ansi-white-bg { background-color: var(--color-ansi-white); }
+
+.ansi-bright-black-bg { background-color: var(--color-ansi-bright-black); }
+.ansi-bright-red-bg { background-color: var(--color-ansi-bright-red); }
+.ansi-bright-green-bg { background-color: var(--color-ansi-bright-green); }
+.ansi-bright-yellow-bg { background-color: var(--color-ansi-bright-yellow); }
+.ansi-bright-blue-bg { background-color: var(--color-ansi-bright-blue); }
+.ansi-bright-magenta-bg { background-color: var(--color-ansi-bright-magenta); }
+.ansi-bright-cyan-bg { background-color: var(--color-ansi-bright-cyan); }
+.ansi-bright-white-bg { background-color: var(--color-ansi-bright-white); }
+
+/* term colors used in console rendering */
+
+.term-fg2 { color: var(--color-ansi-bright-black); } /* faint (decreased intensity) - same as gray really */
+.term-fg3 { font-style: italic; } /* italic */
+.term-fg4 { text-decoration: underline; } /* underline */
+.term-fg5 { animation: blink-animation 1s steps(3, start) infinite; } /* blink */
+.term-fg9 { text-decoration: line-through; } /* crossed-out */
+
+.term-fg30 { color: var(--color-ansi-black); } /* black (but we can't use black, so a diff color) */
+.term-fg31 { color: var(--color-ansi-red); } /* red */
+.term-fg32 { color: var(--color-ansi-green); } /* green */
+.term-fg33 { color: var(--color-ansi-yellow); } /* yellow */
+.term-fg34 { color: var(--color-ansi-blue); } /* blue */
+.term-fg35 { color: var(--color-ansi-magenta); } /* magenta */
+.term-fg36 { color: var(--color-ansi-cyan); } /* cyan */
+
+/* high intense colors */
+.term-fgi1 { color: var(--color-ansi-bright-green); }
+.term-fgi90 { color: var(--color-ansi-bright-black); } /* grey */
+.term-fgi91 { color: var(--color-ansi-bright-red); } /* red */
+.term-fgi92 { color: var(--color-ansi-bright-green); } /* green */
+.term-fgi93 { color: var(--color-ansi-bright-yellow); } /* yellow */
+.term-fgi94 { color: var(--color-ansi-bright-blue); } /* blue */
+.term-fgi95 { color: var(--color-ansi-bright-magenta); } /* magenta */
+.term-fgi96 { color: var(--color-ansi-bright-cyan); } /* cyan */
+
+/* background colors */
+.term-bg40 { background: var(--color-ansi-bright-black); } /* grey */
+.term-bg41 { background: var(--color-ansi-red); } /* red */
+.term-bg42 { background: var(--color-ansi-green); } /* green */
+
+/* custom foreground/background combos for readability */
+.term-fg31.term-bg40 { color: var(--color-ansi-bright-red); }
+
+/* xterm colors */
+.term-fgx16 { color: #000000; }
+.term-fgx17 { color: #00005f; }
+.term-fgx18 { color: #000087; }
+.term-fgx19 { color: #0000af; }
+.term-fgx20 { color: #0000d7; }
+.term-fgx21 { color: #0000ff; }
+.term-fgx22 { color: #005f00; }
+.term-fgx23 { color: #005f5f; }
+.term-fgx24 { color: #005f87; }
+.term-fgx25 { color: #005faf; }
+.term-fgx26 { color: #005fd7; }
+.term-fgx27 { color: #005fff; }
+.term-fgx28 { color: #008700; }
+.term-fgx29 { color: #00875f; }
+.term-fgx30 { color: #008787; }
+.term-fgx31 { color: #0087af; }
+.term-fgx32 { color: #0087d7; }
+.term-fgx33 { color: #0087ff; }
+.term-fgx34 { color: #00af00; }
+.term-fgx35 { color: #00af5f; }
+.term-fgx36 { color: #00af87; }
+.term-fgx37 { color: #00afaf; }
+.term-fgx38 { color: #00afd7; }
+.term-fgx39 { color: #00afff; }
+.term-fgx40 { color: #00d700; }
+.term-fgx41 { color: #00d75f; }
+.term-fgx42 { color: #00d787; }
+.term-fgx43 { color: #00d7af; }
+.term-fgx44 { color: #00d7d7; }
+.term-fgx45 { color: #00d7ff; }
+.term-fgx46 { color: #00ff00; }
+.term-fgx47 { color: #00ff5f; }
+.term-fgx48 { color: #00ff87; }
+.term-fgx49 { color: #00ffaf; }
+.term-fgx50 { color: #00ffd7; }
+.term-fgx51 { color: #00ffff; }
+.term-fgx52 { color: #5f0000; }
+.term-fgx53 { color: #5f005f; }
+.term-fgx54 { color: #5f0087; }
+.term-fgx55 { color: #5f00af; }
+.term-fgx56 { color: #5f00d7; }
+.term-fgx57 { color: #5f00ff; }
+.term-fgx58 { color: #5f5f00; }
+.term-fgx59 { color: #5f5f5f; }
+.term-fgx60 { color: #5f5f87; }
+.term-fgx61 { color: #5f5faf; }
+.term-fgx62 { color: #5f5fd7; }
+.term-fgx63 { color: #5f5fff; }
+.term-fgx64 { color: #5f8700; }
+.term-fgx65 { color: #5f875f; }
+.term-fgx66 { color: #5f8787; }
+.term-fgx67 { color: #5f87af; }
+.term-fgx68 { color: #5f87d7; }
+.term-fgx69 { color: #5f87ff; }
+.term-fgx70 { color: #5faf00; }
+.term-fgx71 { color: #5faf5f; }
+.term-fgx72 { color: #5faf87; }
+.term-fgx73 { color: #5fafaf; }
+.term-fgx74 { color: #5fafd7; }
+.term-fgx75 { color: #5fafff; }
+.term-fgx76 { color: #5fd700; }
+.term-fgx77 { color: #5fd75f; }
+.term-fgx78 { color: #5fd787; }
+.term-fgx79 { color: #5fd7af; }
+.term-fgx80 { color: #5fd7d7; }
+.term-fgx81 { color: #5fd7ff; }
+.term-fgx82 { color: #5fff00; }
+.term-fgx83 { color: #5fff5f; }
+.term-fgx84 { color: #5fff87; }
+.term-fgx85 { color: #5fffaf; }
+.term-fgx86 { color: #5fffd7; }
+.term-fgx87 { color: #5fffff; }
+.term-fgx88 { color: #870000; }
+.term-fgx89 { color: #87005f; }
+.term-fgx90 { color: #870087; }
+.term-fgx91 { color: #8700af; }
+.term-fgx92 { color: #8700d7; }
+.term-fgx93 { color: #8700ff; }
+.term-fgx94 { color: #875f00; }
+.term-fgx95 { color: #875f5f; }
+.term-fgx96 { color: #875f87; }
+.term-fgx97 { color: #875faf; }
+.term-fgx98 { color: #875fd7; }
+.term-fgx99 { color: #875fff; }
+.term-fgx100 { color: #878700; }
+.term-fgx101 { color: #87875f; }
+.term-fgx102 { color: #878787; }
+.term-fgx103 { color: #8787af; }
+.term-fgx104 { color: #8787d7; }
+.term-fgx105 { color: #8787ff; }
+.term-fgx106 { color: #87af00; }
+.term-fgx107 { color: #87af5f; }
+.term-fgx108 { color: #87af87; }
+.term-fgx109 { color: #87afaf; }
+.term-fgx110 { color: #87afd7; }
+.term-fgx111 { color: #87afff; }
+.term-fgx112 { color: #87d700; }
+.term-fgx113 { color: #87d75f; }
+.term-fgx114 { color: #87d787; }
+.term-fgx115 { color: #87d7af; }
+.term-fgx116 { color: #87d7d7; }
+.term-fgx117 { color: #87d7ff; }
+.term-fgx118 { color: #87ff00; }
+.term-fgx119 { color: #87ff5f; }
+.term-fgx120 { color: #87ff87; }
+.term-fgx121 { color: #87ffaf; }
+.term-fgx122 { color: #87ffd7; }
+.term-fgx123 { color: #87ffff; }
+.term-fgx124 { color: #af0000; }
+.term-fgx125 { color: #af005f; }
+.term-fgx126 { color: #af0087; }
+.term-fgx127 { color: #af00af; }
+.term-fgx128 { color: #af00d7; }
+.term-fgx129 { color: #af00ff; }
+.term-fgx130 { color: #af5f00; }
+.term-fgx131 { color: #af5f5f; }
+.term-fgx132 { color: #af5f87; }
+.term-fgx133 { color: #af5faf; }
+.term-fgx134 { color: #af5fd7; }
+.term-fgx135 { color: #af5fff; }
+.term-fgx136 { color: #af8700; }
+.term-fgx137 { color: #af875f; }
+.term-fgx138 { color: #af8787; }
+.term-fgx139 { color: #af87af; }
+.term-fgx140 { color: #af87d7; }
+.term-fgx141 { color: #af87ff; }
+.term-fgx142 { color: #afaf00; }
+.term-fgx143 { color: #afaf5f; }
+.term-fgx144 { color: #afaf87; }
+.term-fgx145 { color: #afafaf; }
+.term-fgx146 { color: #afafd7; }
+.term-fgx147 { color: #afafff; }
+.term-fgx148 { color: #afd700; }
+.term-fgx149 { color: #afd75f; }
+.term-fgx150 { color: #afd787; }
+.term-fgx151 { color: #afd7af; }
+.term-fgx152 { color: #afd7d7; }
+.term-fgx153 { color: #afd7ff; }
+.term-fgx154 { color: #afff00; }
+.term-fgx155 { color: #afff5f; }
+.term-fgx156 { color: #afff87; }
+.term-fgx157 { color: #afffaf; }
+.term-fgx158 { color: #afffd7; }
+.term-fgx159 { color: #afffff; }
+.term-fgx160 { color: #d70000; }
+.term-fgx161 { color: #d7005f; }
+.term-fgx162 { color: #d70087; }
+.term-fgx163 { color: #d700af; }
+.term-fgx164 { color: #d700d7; }
+.term-fgx165 { color: #d700ff; }
+.term-fgx166 { color: #d75f00; }
+.term-fgx167 { color: #d75f5f; }
+.term-fgx168 { color: #d75f87; }
+.term-fgx169 { color: #d75faf; }
+.term-fgx170 { color: #d75fd7; }
+.term-fgx171 { color: #d75fff; }
+.term-fgx172 { color: #d78700; }
+.term-fgx173 { color: #d7875f; }
+.term-fgx174 { color: #d78787; }
+.term-fgx175 { color: #d787af; }
+.term-fgx176 { color: #d787d7; }
+.term-fgx177 { color: #d787ff; }
+.term-fgx178 { color: #d7af00; }
+.term-fgx179 { color: #d7af5f; }
+.term-fgx180 { color: #d7af87; }
+.term-fgx181 { color: #d7afaf; }
+.term-fgx182 { color: #d7afd7; }
+.term-fgx183 { color: #d7afff; }
+.term-fgx184 { color: #d7d700; }
+.term-fgx185 { color: #d7d75f; }
+.term-fgx186 { color: #d7d787; }
+.term-fgx187 { color: #d7d7af; }
+.term-fgx188 { color: #d7d7d7; }
+.term-fgx189 { color: #d7d7ff; }
+.term-fgx190 { color: #d7ff00; }
+.term-fgx191 { color: #d7ff5f; }
+.term-fgx192 { color: #d7ff87; }
+.term-fgx193 { color: #d7ffaf; }
+.term-fgx194 { color: #d7ffd7; }
+.term-fgx195 { color: #d7ffff; }
+.term-fgx196 { color: #ff0000; }
+.term-fgx197 { color: #ff005f; }
+.term-fgx198 { color: #ff0087; }
+.term-fgx199 { color: #ff00af; }
+.term-fgx200 { color: #ff00d7; }
+.term-fgx201 { color: #ff00ff; }
+.term-fgx202 { color: #ff5f00; }
+.term-fgx203 { color: #ff5f5f; }
+.term-fgx204 { color: #ff5f87; }
+.term-fgx205 { color: #ff5faf; }
+.term-fgx206 { color: #ff5fd7; }
+.term-fgx207 { color: #ff5fff; }
+.term-fgx208 { color: #ff8700; }
+.term-fgx209 { color: #ff875f; }
+.term-fgx210 { color: #ff8787; }
+.term-fgx211 { color: #ff87af; }
+.term-fgx212 { color: #ff87d7; }
+.term-fgx213 { color: #ff87ff; }
+.term-fgx214 { color: #ffaf00; }
+.term-fgx215 { color: #ffaf5f; }
+.term-fgx216 { color: #ffaf87; }
+.term-fgx217 { color: #ffafaf; }
+.term-fgx218 { color: #ffafd7; }
+.term-fgx219 { color: #ffafff; }
+.term-fgx220 { color: #ffd700; }
+.term-fgx221 { color: #ffd75f; }
+.term-fgx222 { color: #ffd787; }
+.term-fgx223 { color: #ffd7af; }
+.term-fgx224 { color: #ffd7d7; }
+.term-fgx225 { color: #ffd7ff; }
+.term-fgx226 { color: #ffff00; }
+.term-fgx227 { color: #ffff5f; }
+.term-fgx228 { color: #ffff87; }
+.term-fgx229 { color: #ffffaf; }
+.term-fgx230 { color: #ffffd7; }
+.term-fgx231 { color: #ffffff; }
+.term-fgx232 { color: #080808; }
+.term-fgx233 { color: #121212; }
+.term-fgx234 { color: #1c1c1c; }
+.term-fgx235 { color: #262626; }
+.term-fgx236 { color: #303030; }
+.term-fgx237 { color: #3a3a3a; }
+.term-fgx238 { color: #444444; }
+.term-fgx239 { color: #4e4e4e; }
+.term-fgx240 { color: #585858; }
+.term-fgx241 { color: #626262; }
+.term-fgx242 { color: #6c6c6c; }
+.term-fgx243 { color: #767676; }
+.term-fgx244 { color: #808080; }
+.term-fgx245 { color: #8a8a8a; }
+.term-fgx246 { color: #949494; }
+.term-fgx247 { color: #9e9e9e; }
+.term-fgx248 { color: #a8a8a8; }
+.term-fgx249 { color: #b2b2b2; }
+.term-fgx250 { color: #bcbcbc; }
+.term-fgx251 { color: #c6c6c6; }
+.term-fgx252 { color: #d0d0d0; }
+.term-fgx253 { color: #dadada; }
+.term-fgx254 { color: #e4e4e4; }
+.term-fgx255 { color: #eeeeee; }
diff --git a/web_src/css/features/dropzone.css b/web_src/css/features/dropzone.css
new file mode 100644
index 00000000..cbc32df2
--- /dev/null
+++ b/web_src/css/features/dropzone.css
@@ -0,0 +1,59 @@
+.ui .field .dropzone {
+ border: 2px dashed var(--color-secondary);
+ background: none;
+ box-shadow: none;
+ padding: 0;
+ border-radius: var(--border-radius-medium);
+ min-height: 0;
+}
+
+.ui .field .dropzone .dz-message {
+ margin: 10px 0;
+}
+
+.dropzone .dz-button {
+ color: var(--color-text-light) !important;
+}
+
+.dropzone:hover .dz-button {
+ color: var(--color-text) !important;
+}
+
+.dropzone .dz-error-message {
+ top: 145px !important;
+}
+
+.dropzone .dz-image {
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ border-radius: 0 !important;
+}
+
+.dropzone .dz-image img {
+ max-width: 100% !important;
+ max-height: 100% !important;
+ object-fit: contain !important;
+}
+
+.dropzone .dz-preview.dz-image-preview,
+.dropzone-attachments .thumbnails img {
+ background: transparent !important;
+}
+
+.dropzone-attachments .thumbnails img {
+ height: 120px !important;
+ width: 120px !important;
+ object-fit: contain !important;
+ margin-bottom: 0 !important;
+}
+
+.dropzone .dz-preview:hover .dz-image img {
+ filter: opacity(0.5) !important;
+}
+
+.ui .field .dropzone .dz-preview .dz-progress {
+ /* by default the progress-bar is vertically centered (top: 50%), it's better to put it after the "details (size, filename)",
+ then the layout from top to bottom is: size, filename, progress */
+ top: 7em;
+}
diff --git a/web_src/css/features/gitgraph.css b/web_src/css/features/gitgraph.css
new file mode 100644
index 00000000..45fb2d95
--- /dev/null
+++ b/web_src/css/features/gitgraph.css
@@ -0,0 +1,285 @@
+#git-graph-container {
+ overflow-x: auto;
+ width: 100%;
+ min-height: 350px;
+}
+
+#git-graph-container h2 {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+#git-graph-container .ui.header.dividing {
+ padding-bottom: 10px;
+}
+
+#git-graph-container #flow-select-refs-dropdown {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ min-width: 250px;
+ border-right: none;
+}
+
+#git-graph-container #flow-select-refs-dropdown .ui.label {
+ max-width: 180px;
+ display: inline-flex !important;
+ align-items: center;
+}
+
+#git-graph-container #flow-select-refs-dropdown .default.text {
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+#git-graph-container #flow-select-refs-dropdown input.search {
+ position: relative;
+ top: 1px;
+}
+
+#git-graph-container li {
+ list-style-type: none;
+ height: 24px;
+ line-height: 24px;
+ white-space: nowrap;
+ display: flex;
+ align-items: center;
+}
+
+#git-graph-container li .node-relation {
+ font-family: var(--fonts-monospace);
+}
+
+#git-graph-container li .author {
+ color: var(--color-text-light);
+}
+
+#git-graph-container li .time {
+ color: var(--color-text-light-3);
+}
+
+#git-graph-container li a:not(.ui):hover {
+ text-decoration: underline;
+}
+
+#git-graph-container li a em {
+ color: var(--color-red);
+ border-bottom: 1px dotted var(--color-secondary);
+ text-decoration: none;
+ font-style: normal;
+}
+
+#git-graph-container #rel-container {
+ max-width: 30%;
+ overflow-x: auto;
+ float: left;
+}
+
+#git-graph-container #rev-list {
+ margin: 0;
+ padding: 0;
+}
+
+#git-graph-container #rev-list li.highlight.hover {
+ background-color: var(--color-secondary-alpha-30);
+}
+
+#git-graph-container #rev-list .commit-refs .button {
+ padding: 2px 4px;
+ margin-right: 0.25em;
+ display: inline-block;
+ max-width: 200px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+#git-graph-container #rev-list .sha.label {
+ padding-top: 5px;
+ padding-bottom: 3px;
+}
+
+#git-graph-container #rev-list .sha.label .ui.detail.icon.button {
+ padding-top: 3px;
+ margin-top: -5px;
+ padding-bottom: 1px;
+}
+
+#git-graph-container #rev-list .author img.ui.avatar {
+ width: auto;
+ height: 18px;
+ max-width: none;
+}
+
+#git-graph-container #graph-raw-list {
+ margin: 0;
+}
+
+#git-graph-container.monochrome #rel-container .flow-group {
+ stroke: var(--color-secondary-dark-5);
+ fill: var(--color-secondary-dark-5);
+}
+
+#git-graph-container.monochrome #rel-container .flow-group.highlight {
+ stroke: var(--color-secondary-dark-12);
+ fill: var(--color-secondary-dark-12);
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-1 {
+ stroke: #499a37;
+ fill: #499a37;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-2 {
+ stroke: #ce4751;
+ fill: #ce4751;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-3 {
+ stroke: #8f9121;
+ fill: #8f9121;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-4 {
+ stroke: #ac32a6;
+ fill: #ac32a6;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-5 {
+ stroke: #7445e9;
+ fill: #7445e9;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-6 {
+ stroke: #c67d28;
+ fill: #c67d28;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-7 {
+ stroke: #4db392;
+ fill: #4db392;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-8 {
+ stroke: #aa4d30;
+ fill: #aa4d30;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-9 {
+ stroke: #2a6f84;
+ fill: #2a6f84;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-10 {
+ stroke: #c45327;
+ fill: #c45327;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-11 {
+ stroke: #3d965c;
+ fill: #3d965c;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-12 {
+ stroke: #792a93;
+ fill: #792a93;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-13 {
+ stroke: #439d73;
+ fill: #439d73;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-14 {
+ stroke: #103aad;
+ fill: #103aad;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-15 {
+ stroke: #982e85;
+ fill: #982e85;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.flow-color-16-0 {
+ stroke: #7db233;
+ fill: #7db233;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-1 {
+ stroke: #5ac144;
+ fill: #5ac144;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-2 {
+ stroke: #ed5a8b;
+ fill: #ed5a8b;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-3 {
+ stroke: #ced049;
+ fill: #ced048;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-4 {
+ stroke: #db61d7;
+ fill: #db62d6;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-5 {
+ stroke: #8455f9;
+ fill: #8455f9;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-6 {
+ stroke: #e6a151;
+ fill: #e6a151;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-7 {
+ stroke: #44daaa;
+ fill: #44daaa;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-8 {
+ stroke: #dd7a5c;
+ fill: #dd7a5c;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-9 {
+ stroke: #38859c;
+ fill: #38859c;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-10 {
+ stroke: #d95520;
+ fill: #d95520;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-11 {
+ stroke: #42ae68;
+ fill: #42ae68;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-12 {
+ stroke: #9126b5;
+ fill: #9126b5;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-13 {
+ stroke: #4ab080;
+ fill: #4ab080;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-14 {
+ stroke: #284fb8;
+ fill: #284fb8;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-15 {
+ stroke: #971c80;
+ fill: #971c80;
+}
+
+#git-graph-container:not(.monochrome) #rel-container .flow-group.highlight.flow-color-16-0 {
+ stroke: #87ca28;
+ fill: #87ca28;
+}
diff --git a/web_src/css/features/heatmap.css b/web_src/css/features/heatmap.css
new file mode 100644
index 00000000..c064590c
--- /dev/null
+++ b/web_src/css/features/heatmap.css
@@ -0,0 +1,58 @@
+#user-heatmap {
+ width: 100%;
+ font-size: 9px;
+ position: relative;
+}
+
+/* before the Vue component is mounted, show a loading indicator with dummy size */
+/* the ratio is guesswork, see https://github.com/razorness/vue3-calendar-heatmap/issues/26 */
+#user-heatmap.is-loading {
+ aspect-ratio: 5.415; /* the size is about 790 x 145 */
+}
+.user.profile #user-heatmap.is-loading {
+ aspect-ratio: 5.645; /* the size is about 953 x 169 */
+}
+
+#user-heatmap text {
+ fill: currentcolor !important;
+}
+
+/* for the "Less" and "More" legend */
+#user-heatmap .vch__legend .vch__legend {
+ display: flex;
+ font-size: 11px;
+ align-items: center;
+ justify-content: right;
+}
+
+#user-heatmap .vch__legend .vch__legend div:first-child,
+#user-heatmap .vch__legend .vch__legend div:last-child {
+ display: inline-block;
+ padding: 0 5px;
+}
+
+#user-heatmap .vch__day__square:hover {
+ outline: 1.5px solid var(--color-text);
+}
+
+/* move the "? contributions in the last ? months" text from top to bottom */
+#user-heatmap .total-contributions {
+ font-size: 11px;
+ position: absolute;
+ bottom: 0;
+ left: 25px;
+}
+
+@media (max-width: 1200px) {
+ #user-heatmap .total-contributions {
+ left: 21px;
+ }
+}
+
+@media (max-width: 1000px) {
+ #user-heatmap .total-contributions {
+ font-size: 10px;
+ left: 17px;
+ bottom: -4px;
+ }
+}
diff --git a/web_src/css/features/imagediff.css b/web_src/css/features/imagediff.css
new file mode 100644
index 00000000..c8ead2ba
--- /dev/null
+++ b/web_src/css/features/imagediff.css
@@ -0,0 +1,114 @@
+.image-diff-tabs {
+ min-height: 60px;
+
+}
+.image-diff-tabs.is-loading .tab {
+ display: none;
+}
+
+.image-diff-container {
+ text-align: center;
+ padding: 0.5em 0 1em;
+}
+
+.image-diff-container img {
+ border: 1px solid var(--color-primary-light-7);
+ --gradient: conic-gradient(var(--checkerboard-color-1) 90deg, var(--checkerboard-color-2) 90deg 180deg, var(--checkerboard-color-1) 180deg 270deg, var(--checkerboard-color-2) 270deg);
+ background: var(--gradient);
+ background-size: 20px 20px;
+}
+
+.image-diff-container .before-container {
+ border: 1px solid var(--color-red);
+ display: block;
+}
+
+.image-diff-container .after-container {
+ border: 1px solid var(--color-green);
+ display: block;
+}
+
+.image-diff-container .diff-side-by-side .side {
+ display: inline-block;
+ line-height: 0;
+ vertical-align: top;
+ margin: 0 1em;
+}
+
+.image-diff-container .diff-side-by-side .side .side-header {
+ font-weight: var(--font-weight-semibold);
+}
+
+.image-diff-container .diff-swipe {
+ margin: auto;
+ padding: 1em 0;
+}
+
+.image-diff-container .diff-swipe .swipe-frame {
+ position: absolute;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .before-container {
+ position: absolute;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .swipe-container {
+ position: absolute;
+ right: 0;
+ display: block;
+ border-left: 2px solid var(--color-secondary-dark-8);
+ height: 100%;
+ overflow: hidden;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .swipe-container .after-container {
+ position: absolute;
+ right: 0;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .swipe-bar {
+ position: absolute;
+ height: 100%;
+ top: 0;
+ left: 0;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .swipe-bar .handle {
+ background: var(--color-secondary-dark-8);
+ left: -5px;
+ height: 12px;
+ width: 12px;
+ position: absolute;
+ transform: rotate(45deg);
+ box-sizing: border-box;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .swipe-bar .top-handle {
+ top: -12px;
+}
+
+.image-diff-container .diff-swipe .swipe-frame .swipe-bar .bottom-handle {
+ bottom: -14px;
+}
+
+.image-diff-container .diff-overlay {
+ margin: 0 auto;
+}
+
+.image-diff-container .diff-overlay .overlay-frame {
+ margin: 1em auto 0;
+ position: relative;
+}
+
+.image-diff-container .diff-overlay .before-container,
+.image-diff-container .diff-overlay .after-container {
+ position: absolute;
+}
+
+.image-diff-container .diff-overlay input {
+ max-width: 300px;
+}
diff --git a/web_src/css/features/projects.css b/web_src/css/features/projects.css
new file mode 100644
index 00000000..1401916e
--- /dev/null
+++ b/web_src/css/features/projects.css
@@ -0,0 +1,108 @@
+.board {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ margin: 0 0.5em;
+}
+
+.project-column {
+ background-color: var(--color-project-column-bg) !important;
+ border: 1px solid var(--color-secondary) !important;
+ border-radius: var(--border-radius);
+ margin: 0 0.5rem !important;
+ padding: 0.5rem !important;
+ width: 320px;
+ height: calc(100vh - 450px);
+ min-height: 60vh;
+ overflow-y: scroll;
+ flex: 0 0 auto;
+ overflow: visible;
+ display: flex;
+ flex-direction: column;
+ cursor: default;
+}
+
+.project-column .issue-card {
+ color: var(--color-text);
+}
+
+.project-column-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.project-column-title {
+ background: none !important;
+ line-height: 1.25 !important;
+ color: inherit !important;
+ cursor: inherit;
+}
+
+.project-column-title-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.project-column-header > .dropdown {
+ flex-shrink: 0;
+}
+
+.project-column > .cards {
+ flex: 1;
+ display: flex;
+ align-content: baseline;
+ margin: 0 !important;
+ padding: 0 !important;
+ flex-wrap: nowrap !important;
+ flex-direction: column;
+ overflow-x: auto;
+ gap: .25rem;
+}
+
+.project-column > .divider {
+ margin: 5px 0;
+ border-color: currentcolor;
+ opacity: .5;
+}
+
+.project-column:first-child {
+ margin-left: auto !important;
+}
+
+.project-column:last-child {
+ margin-right: auto !important;
+}
+
+.card-attachment-images {
+ display: inline-block;
+ white-space: nowrap;
+ overflow: scroll;
+ cursor: default;
+ text-align: center;
+}
+
+.card-attachment-images img {
+ display: inline-block;
+ max-height: 50px;
+ border-radius: var(--border-radius);
+ text-align: left;
+ margin-right: 2px;
+ aspect-ratio: 1;
+}
+
+.card-attachment-images img:only-child {
+ max-height: 90px;
+ margin: auto;
+}
+
+.card-ghost {
+ border-color: var(--color-secondary-dark-4) !important;
+ border-style: dashed !important;
+ background: none !important;
+}
+
+.card-ghost * {
+ opacity: 0;
+}
diff --git a/web_src/css/features/tribute.css b/web_src/css/features/tribute.css
new file mode 100644
index 00000000..bd843675
--- /dev/null
+++ b/web_src/css/features/tribute.css
@@ -0,0 +1,42 @@
+@import "tributejs/dist/tribute.css";
+
+.tribute-container {
+ box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.25);
+ border-radius: var(--border-radius);
+}
+
+.tribute-container ul {
+ margin-top: 0 !important;
+ background: var(--color-body) !important;
+}
+
+.tribute-container li {
+ padding: 3px 0.5rem !important;
+}
+
+.tribute-container li span.fullname {
+ font-weight: var(--font-weight-normal);
+ font-size: 0.8rem;
+ margin-left: 3px;
+}
+
+.tribute-container li.highlight,
+.tribute-container li:hover {
+ background: var(--color-primary) !important;
+ color: var(--color-primary-contrast) !important;
+}
+
+.tribute-item {
+ display: flex;
+ align-items: center;
+}
+
+.tribute-item .emoji,
+.tribute-item img[src*="/avatar/"] {
+ margin-right: 0.5rem;
+}
+
+.tribute-container img {
+ width: 1.5rem !important;
+ height: 1.5rem !important;
+}
diff --git a/web_src/css/font_i18n.css b/web_src/css/font_i18n.css
new file mode 100644
index 00000000..0ac4c83b
--- /dev/null
+++ b/web_src/css/font_i18n.css
@@ -0,0 +1,393 @@
+:root :lang(ja) {
+ --fonts-override: var(--fonts-default-override-ja);
+}
+
+:root :lang(zh-CN) {
+ --fonts-override: var(--fonts-default-override-zh-cn);
+}
+
+:root :lang(zh-TW) {
+ --fonts-override: var(--fonts-default-override-zh-tw);
+}
+
+:root :lang(zh-HK) {
+ --fonts-override: var(--fonts-default-override-zh-hk);
+}
+
+:root :lang(ko) {
+ --fonts-override: var(--fonts-default-override-ko);
+}
+
+[lang] {
+ font-family: var(--fonts-regular);
+}
+
+:root {
+ --fonts-default-override-ja: system-ui-ja, var(--fonts-proportional);
+ --fonts-default-override-zh-cn: system-ui-zh-cn, var(--fonts-proportional);
+ --fonts-default-override-zh-tw: system-ui-zh-tw, var(--fonts-proportional);
+ --fonts-default-override-zh-hk: system-ui-zh-hk, var(--fonts-proportional);
+ --fonts-default-override-ko: system-ui-ko, var(--fonts-proportional);
+}
+
+/* Special handling for Firefox on Windows/Linux */
+@supports (-moz-appearance: none) {
+ :root {
+ --fonts-default-override-ja: var(--fonts-proportional), system-ui-ja;
+ --fonts-default-override-zh-cn: var(--fonts-proportional), system-ui-zh-cn;
+ --fonts-default-override-zh-tw: var(--fonts-proportional), system-ui-zh-tw;
+ --fonts-default-override-zh-hk: var(--fonts-proportional), system-ui-zh-hk;
+ --fonts-default-override-ko: var(--fonts-proportional), system-ui-ko;
+ }
+}
+
+@font-face {
+ font-family: system-ui-ja;
+ src: local("HiraKakuProN-W3"), local("Hiragino Kaku Gothic ProN W3"),
+ local("HiraginoSans-W2"), local("Source Han Sans JP Light"),
+ local("SourceHanSansJP-Light"), local("Source Han Sans J Light"),
+ local("SourceHanSansJ-Light"), local("Noto Sans CJK JP Light"),
+ local("NotoSansCJKJP-Light"), local("Source Han Sans Light"),
+ local("SourceHanSans-Light"), local("Yu Gothic Regular"),
+ local("YuGothic Regular"), local("Droid Sans Japanese"), local("Meiryo"),
+ local("MS PGothic");
+ font-weight: 300;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-ja;
+ src: local("HiraKakuProN-W3"), local("Hiragino Kaku Gothic ProN W3"),
+ local("HiraginoSans-W4"), local("Source Han Sans JP Regular"),
+ local("SourceHanSansJP-Regular"), local("Source Han Sans J Regular"),
+ local("SourceHanSansJ-Regular"), local("Noto Sans CJK JP Regular"),
+ local("NotoSansCJKJP-Regular"), local("Source Han Sans Regular"),
+ local("SourceHanSans-Regular"), local("Yu Gothic Medium"),
+ local("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
+ local("MS PGothic");
+ font-weight: 400;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-ja;
+ src: local("HiraKakuProN-W3"), local("Hiragino Kaku Gothic ProN W3"),
+ local("HiraginoSans-W5"), local("Source Han Sans JP Medium"),
+ local("SourceHanSansJP-Medium"), local("Source Han Sans J Medium"),
+ local("SourceHanSansJ-Medium"), local("Noto Sans CJK JP Medium"),
+ local("NotoSansCJKJP-Medium"), local("Source Han Sans Medium"),
+ local("SourceHanSans-Medium"), local("Yu Gothic Medium"),
+ local("YuGothic Medium"), local("Droid Sans Japanese"), local("Meiryo"),
+ local("MS PGothic");
+ font-weight: 500;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-ja;
+ src: local("HiraKakuProN-W6"), local("Hiragino Kaku Gothic ProN W6"),
+ local("HiraginoSans-W6"), local("Source Han Sans JP Bold"),
+ local("SourceHanSansJP-Bold"), local("Source Han Sans J Bold"),
+ local("SourceHanSansJ-Bold"), local("Noto Sans CJK JP Bold"),
+ local("NotoSansCJKJP-Bold"), local("Source Han Sans Bold"),
+ local("SourceHanSans-Bold"), local("Yu Gothic Bold"), local("YuGothic Bold"),
+ local("Droid Sans Japanese"), local("Meiryo Bold"), local("MS PGothic");
+ font-weight: 600;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+/* Safari on macOS/iOS */
+@font-face {
+ font-family: system-ui-ja;
+ src: local("HelveticaNeue");
+ unicode-range: U+A0;
+}
+
+/* Other browsers on macOS/iOS */
+@supports not (-webkit-hyphens: none) {
+ @font-face {
+ font-family: system-ui-ja;
+ src: local("HelveticaNeue");
+ unicode-range: U+20;
+ }
+}
+
+@font-face {
+ font-family: system-ui-zh-cn;
+ src: local("PingFangSC-Light"), local("Source Han Sans CN Light"),
+ local("SourceHanSansCN-Light"), local("Source Han Sans SC Light"),
+ local("SourceHanSansSC-Light"), local("Noto Sans CJK SC Light"),
+ local("NotoSansCJKSC-Light"), local("HiraginoSansGB-W3"),
+ local("Hiragino Sans GB W3"), local("Microsoft YaHei Light"),
+ local("Heiti SC Light"), local("SimHei");
+ font-weight: 300;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-cn;
+ src: local("PingFangSC-Regular"), local("Source Han Sans CN Regular"),
+ local("SourceHanSansCN-Regular"), local("Source Han Sans SC Regular"),
+ local("SourceHanSansSC-Regular"), local("Noto Sans CJK SC Regular"),
+ local("NotoSansCJKSC-Regular"), local("HiraginoSansGB-W3"),
+ local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
+ local("Heiti SC Light"), local("SimHei");
+ font-weight: 400;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-cn;
+ src: local("PingFangSC-Medium"), local("Source Han Sans CN Medium"),
+ local("SourceHanSansCN-Medium"), local("Source Han Sans SC Medium"),
+ local("SourceHanSansSC-Medium"), local("Noto Sans CJK SC Medium"),
+ local("NotoSansCJKSC-Medium"), local("HiraginoSansGB-W3"),
+ local("Hiragino Sans GB W3"), local("Microsoft YaHei"),
+ local("Heiti SC Light"), local("SimHei");
+ font-weight: 500;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-cn;
+ src: local("PingFangSC-Semibold"), local("Source Han Sans CN Bold"),
+ local("SourceHanSansCN-Bold"), local("Source Han Sans SC Bold"),
+ local("SourceHanSansSC-Bold"), local("Noto Sans CJK SC Bold"),
+ local("NotoSansCJKSC-Bold"), local("HiraginoSansGB-W6"),
+ local("Hiragino Sans GB W6"), local("Microsoft YaHei Bold"),
+ local("Heiti SC Medium"), local("SimHei");
+ font-weight: 600;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+/* Safari on macOS/iOS */
+@font-face {
+ font-family: system-ui-zh-cn;
+ src: local("HelveticaNeue");
+ unicode-range: U+A0;
+}
+
+/* Other browsers on macOS/iOS */
+@supports not (-webkit-hyphens: none) {
+ @font-face {
+ font-family: system-ui-zh-cn;
+ src: local("HelveticaNeue");
+ unicode-range: U+20;
+ }
+}
+
+@font-face {
+ font-family: system-ui-zh-tw;
+ src: local("PingFangTC-Light"), local("Source Han Sans TW Light"),
+ local("SourceHanSansTW-Light"), local("Source Han Sans TC Light"),
+ local("SourceHanSansTC-Light"), local("Noto Sans CJK TC Light"),
+ local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
+ local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
+ local("Heiti TC Light"), local("PMingLiU");
+ font-weight: 300;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-tw;
+ src: local("PingFangTC-Regular"), local("Source Han Sans TW Regular"),
+ local("SourceHanSansTW-Regular"), local("Source Han Sans TC Regular"),
+ local("SourceHanSansTC-Regular"), local("Noto Sans CJK TC Regular"),
+ local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
+ local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
+ local("Heiti TC Light"), local("PMingLiU");
+ font-weight: 400;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-tw;
+ src: local("PingFangTC-Medium"), local("Source Han Sans TW Medium"),
+ local("SourceHanSansTW-Medium"), local("Source Han Sans TC Medium"),
+ local("SourceHanSansTC-Medium"), local("Noto Sans CJK TC Medium"),
+ local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
+ local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
+ local("Heiti TC Light"), local("PMingLiU");
+ font-weight: 500;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-tw;
+ src: local("PingFangTC-Semibold"), local("Source Han Sans TW Bold"),
+ local("SourceHanSansTW-Bold"), local("Source Han Sans TC Bold"),
+ local("SourceHanSansTC-Bold"), local("Noto Sans CJK TC Bold"),
+ local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
+ local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
+ local("Heiti TC Medium"), local("PMingLiU");
+ font-weight: 600;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+/* Safari on macOS/iOS */
+@font-face {
+ font-family: system-ui-zh-tw;
+ src: local("HelveticaNeue");
+ unicode-range: U+A0;
+}
+
+/* Other browsers on macOS/iOS */
+@supports not (-webkit-hyphens: none) {
+ @font-face {
+ font-family: system-ui-zh-tw;
+ src: local("HelveticaNeue");
+ unicode-range: U+20;
+ }
+}
+
+@font-face {
+ font-family: system-ui-zh-hk;
+ src: local("PingFangHK-Light"), local("Source Han Sans HK Light"),
+ local("SourceHanSansHK-Light"), local("Source Han Sans HC Light"),
+ local("SourceHanSansHC-Light"), local("Noto Sans CJK HK Light"),
+ local("NotoSansCJKHK-Light"), local("Source Han Sans TC Light"),
+ local("SourceHanSansTC-Light"), local("Noto Sans CJK TC Light"),
+ local("NotoSansCJKTC-Light"), local("HiraginoSansTC-W3"),
+ local("Hiragino Sans TC W3"), local("Microsoft JhengHei Light"),
+ local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
+ font-weight: 300;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-hk;
+ src: local("PingFangHK-Regular"), local("Source Han Sans HK Regular"),
+ local("SourceHanSansHK-Regular"), local("Source Han Sans HC Regular"),
+ local("SourceHanSansHC-Regular"), local("Noto Sans CJK HK Regular"),
+ local("NotoSansCJKHK-Regular"), local("Source Han Sans TC Regular"),
+ local("SourceHanSansTC-Regular"), local("Noto Sans CJK TC Regular"),
+ local("NotoSansCJKTC-Regular"), local("HiraginoSansTC-W3"),
+ local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
+ local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
+ font-weight: 400;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-hk;
+ src: local("PingFangHK-Medium"), local("Source Han Sans HK Medium"),
+ local("SourceHanSansHK-Medium"), local("Source Han Sans HC Medium"),
+ local("SourceHanSansHC-Medium"), local("Noto Sans CJK HK Medium"),
+ local("NotoSansCJKHK-Medium"), local("Source Han Sans TC Medium"),
+ local("SourceHanSansTC-Medium"), local("Noto Sans CJK TC Medium"),
+ local("NotoSansCJKTC-Medium"), local("HiraginoSansTC-W3"),
+ local("Hiragino Sans TC W3"), local("Microsoft JhengHei"),
+ local("Heiti TC Light"), local("PMingLiU_HKSCS"), local("PMingLiU");
+ font-weight: 500;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-zh-hk;
+ src: local("PingFangHK-Semibold"), local("Source Han Sans HK Bold"),
+ local("SourceHanSansHK-Bold"), local("Source Han Sans HC Bold"),
+ local("SourceHanSansHC-Bold"), local("Noto Sans CJK HK Bold"),
+ local("NotoSansCJKHK-Bold"), local("Source Han Sans TC Bold"),
+ local("SourceHanSansTC-Bold"), local("Noto Sans CJK TC Bold"),
+ local("NotoSansCJKTC-Bold"), local("HiraginoSansTC-W6"),
+ local("Hiragino Sans TC W6"), local("Microsoft JhengHei Bold"),
+ local("Heiti TC Medium"), local("PMingLiU_HKSCS"), local("PMingLiU");
+ font-weight: 600;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+/* Safari on macOS/iOS */
+@font-face {
+ font-family: system-ui-zh-hk;
+ src: local("HelveticaNeue");
+ unicode-range: U+A0;
+}
+
+/* Other browsers on macOS/iOS */
+@supports not (-webkit-hyphens: none) {
+ @font-face {
+ font-family: system-ui-zh-hk;
+ src: local("HelveticaNeue");
+ unicode-range: U+20;
+ }
+}
+
+@font-face {
+ font-family: system-ui-ko;
+ src: local("AppleSDGothicNeo-Light"), local("Source Han Sans KR Light"),
+ local("SourceHanSansKR-Light"), local("Source Han Sans K Light"),
+ local("SourceHanSansK-Light"), local("Noto Sans CJK KR Light"),
+ local("NotoSansCJKKR-Light"), local("NanumBarunGothic Light"),
+ local("Malgun Gothic Semilight"), local("Nanum Gothic"), local("Dotum");
+ font-weight: 300;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-ko;
+ src: local("AppleSDGothicNeo-Regular"), local("Source Han Sans KR Regular"),
+ local("SourceHanSansKR-Regular"), local("Source Han Sans K Regular"),
+ local("SourceHanSansK-Regular"), local("Noto Sans CJK KR Regular"),
+ local("NotoSansCJKKR-Regular"), local("NanumBarunGothic"),
+ local("Malgun Gothic"), local("Nanum Gothic"), local("Dotum");
+ font-weight: 400;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-ko;
+ src: local("AppleSDGothicNeo-Medium"), local("Source Han Sans KR Medium"),
+ local("SourceHanSansKR-Medium"), local("Source Han Sans K Medium"),
+ local("SourceHanSansK-Medium"), local("Noto Sans CJK KR Medium"),
+ local("NotoSansCJKKR-Medium"), local("NanumBarunGothic"),
+ local("Malgun Gothic"), local("Nanum Gothic"), local("Dotum");
+ font-weight: 500;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+@font-face {
+ font-family: system-ui-ko;
+ src: local("AppleSDGothicNeo-SemiBold"), local("Source Han Sans KR Bold"),
+ local("SourceHanSansKR-Bold"), local("Source Han Sans K Bold"),
+ local("SourceHanSansK-Bold"), local("Noto Sans CJK KR Bold"),
+ local("NotoSansCJKKR-Bold"), local("NanumBarunGothic Bold"),
+ local("Malgun Gothic Bold"), local("Nanum Gothic Bold"), local("Dotum");
+ font-weight: 600;
+ unicode-range: U+11??, U+2E80-4DBF, U+4E00-9FFF, U+A960-A97F, U+AC00-D7FF,
+ U+F900-FAFF, U+FE00-FE6F, U+FF00-FFEF, U+1F2??, U+2????;
+}
+
+/* Safari on macOS/iOS */
+@font-face {
+ font-family: system-ui-ko;
+ src: local("HelveticaNeue");
+ unicode-range: U+A0;
+}
+
+/* Other browsers on macOS/iOS */
+@supports not (-webkit-hyphens: none) {
+ @font-face {
+ font-family: system-ui-ko;
+ src: local("HelveticaNeue");
+ unicode-range: U+20;
+ }
+}
diff --git a/web_src/css/form.css b/web_src/css/form.css
new file mode 100644
index 00000000..d8239c5d
--- /dev/null
+++ b/web_src/css/form.css
@@ -0,0 +1,472 @@
+.ui.input textarea,
+.ui.form textarea,
+.ui.form input:not([type]),
+.ui.form input[type="date"],
+.ui.form input[type="datetime-local"],
+.ui.form input[type="email"],
+.ui.form input[type="number"],
+.ui.form input[type="password"],
+.ui.form input[type="search"],
+.ui.form input[type="tel"],
+.ui.form input[type="time"],
+.ui.form input[type="text"],
+.ui.form input[type="file"],
+.ui.form input[type="url"] {
+ transition: none;
+}
+
+input,
+textarea,
+.ui.input > input,
+.ui.form input:not([type]),
+.ui.form select,
+.ui.form textarea,
+.ui.form input[type="date"],
+.ui.form input[type="datetime-local"],
+.ui.form input[type="email"],
+.ui.form input[type="file"],
+.ui.form input[type="number"],
+.ui.form input[type="password"],
+.ui.form input[type="search"],
+.ui.form input[type="tel"],
+.ui.form input[type="text"],
+.ui.form input[type="time"],
+.ui.form input[type="url"],
+.ui.selection.dropdown {
+ background: var(--color-input-background);
+ border-color: var(--color-input-border);
+ color: var(--color-input-text);
+}
+
+/* fix fomantic small dropdown having inconsistent padding with input */
+.ui.small.selection.dropdown {
+ padding: .67857143em 1.6em .67857143em 1em;
+}
+
+input:hover,
+textarea:hover,
+.ui.input input:hover,
+.ui.form input:not([type]):hover,
+.ui.form select:hover,
+.ui.form textarea:hover,
+.ui.form input[type="date"]:hover,
+.ui.form input[type="datetime-local"]:hover,
+.ui.form input[type="email"]:hover,
+.ui.form input[type="file"]:hover,
+.ui.form input[type="number"]:hover,
+.ui.form input[type="password"]:hover,
+.ui.form input[type="search"]:hover,
+.ui.form input[type="tel"]:hover,
+.ui.form input[type="text"]:hover,
+.ui.form input[type="time"]:hover,
+.ui.form input[type="url"]:hover,
+.ui.selection.dropdown:hover {
+ background: var(--color-input-background);
+ border-color: var(--color-input-border-hover);
+ color: var(--color-input-text);
+}
+
+input:focus,
+textarea:focus,
+.ui.input input:focus,
+.ui.form input:not([type]):focus,
+.ui.form select:focus,
+.ui.form textarea:focus,
+.ui.form input[type="date"]:focus,
+.ui.form input[type="datetime-local"]:focus,
+.ui.form input[type="email"]:focus,
+.ui.form input[type="file"]:focus,
+.ui.form input[type="number"]:focus,
+.ui.form input[type="password"]:focus,
+.ui.form input[type="search"]:focus,
+.ui.form input[type="tel"]:focus,
+.ui.form input[type="text"]:focus,
+.ui.form input[type="time"]:focus,
+.ui.form input[type="url"]:focus,
+.ui.selection.dropdown:focus {
+ background: var(--color-input-background);
+ border-color: var(--color-primary);
+ color: var(--color-input-text);
+}
+
+.ui.form .field > label,
+.ui.form .inline.fields > label,
+.ui.form .inline.fields .field > label,
+.ui.form .inline.fields .field > p,
+.ui.form .inline.field > label,
+.ui.form .inline.field > p {
+ color: var(--color-text);
+}
+
+.ui.form .required.fields:not(.grouped) > .field > label::after,
+.ui.form .required.fields.grouped > label::after,
+.ui.form .required.field > label::after,
+.ui.form label.required::after {
+ color: var(--color-red);
+}
+
+.ui.input {
+ color: var(--color-input-text);
+}
+
+/* match <select> padding to <input> */
+.ui.form select {
+ padding: 0.67857143em 1em;
+}
+
+.form .help {
+ color: var(--color-secondary-dark-8);
+ padding-bottom: 0.6em;
+ display: inline-block;
+}
+
+#create-page-form form {
+ margin: auto;
+}
+
+#create-page-form form .ui.message {
+ text-align: center;
+}
+
+@media (min-width: 768px) {
+ #create-page-form form {
+ width: 800px !important;
+ }
+ #create-page-form form .header {
+ padding-left: 280px !important;
+ }
+ #create-page-form form .inline.field > label {
+ text-align: right;
+ width: 250px !important;
+ word-wrap: break-word;
+ }
+ #create-page-form form .help {
+ margin-left: 265px !important;
+ }
+ #create-page-form form .optional .title {
+ margin-left: 250px !important;
+ }
+ #create-page-form form .inline.field > input,
+ #create-page-form form .inline.field > textarea {
+ width: 50%;
+ }
+}
+
+@media (max-width: 767.98px) {
+ #create-page-form form .optional .title {
+ margin-left: 15px;
+ }
+ #create-page-form form .inline.field > label {
+ display: block;
+ }
+}
+
+.m-captcha-style {
+ width: 100%;
+ height: 5em;
+ vertical-align: middle;
+ display: inline-block;
+}
+
+@media (min-width: 768px) {
+ .g-recaptcha-style,
+ .h-captcha-style {
+ margin: 0 auto !important;
+ width: 304px;
+ padding-left: 30px;
+ }
+ .g-recaptcha-style iframe,
+ .h-captcha-style iframe {
+ border-radius: var(--border-radius) !important;
+ width: 302px !important;
+ height: 76px !important;
+ }
+ .m-captcha-style {
+ width: 50%;
+ }
+}
+
+@media (max-height: 575px) {
+ #rc-imageselect,
+ .g-recaptcha-style,
+ .h-captcha-style {
+ transform: scale(0.77);
+ transform-origin: 0 0;
+ }
+}
+
+.user.forgot.password form,
+.user.reset.password form,
+.user.signup form {
+ margin: auto;
+ width: 700px !important;
+}
+
+.user.activate form .ui.message,
+.user.forgot.password form .ui.message,
+.user.reset.password form .ui.message,
+.user.link-account form .ui.message,
+.user.signin form .ui.message,
+.user.signup form .ui.message {
+ text-align: center;
+}
+
+@media (min-width: 768px) {
+ .user.activate form,
+ .user.forgot.password form,
+ .user.reset.password form,
+ .user.link-account form,
+ .user.signin form,
+ .user.signup form {
+ width: 800px !important;
+ }
+ .user.activate form .header,
+ .user.forgot.password form .header,
+ .user.reset.password form .header,
+ .user.link-account form .header,
+ .user.signin form .header,
+ .user.signup form .header {
+ padding-left: 280px !important;
+ }
+ .user.activate form .inline.field > label {
+ text-align: right;
+ width: 250px !important;
+ word-wrap: break-word;
+ }
+ .user.activate form .help,
+ .user.forgot.password form .help,
+ .user.reset.password form .help,
+ .user.link-account form .help,
+ .user.signin form .help,
+ .user.signup form .help {
+ margin-left: 265px !important;
+ }
+ .user.activate form .optional .title,
+ .user.forgot.password form .optional .title,
+ .user.reset.password form .optional .title,
+ .user.link-account form .optional .title,
+ .user.signin form .optional .title,
+ .user.signup form .optional .title {
+ margin-left: 250px !important;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .user.activate form .optional .title,
+ .user.forgot.password form .optional .title,
+ .user.reset.password form .optional .title,
+ .user.link-account form .optional .title,
+ .user.signin form .optional .title,
+ .user.signup form .optional .title {
+ margin-left: 15px;
+ }
+ .user.activate form .inline.field > label,
+ .user.forgot.password form .inline.field > label,
+ .user.reset.password form .inline.field > label,
+ .user.link-account form .inline.field > label,
+ .user.signin form .inline.field > label,
+ .user.signup form .inline.field > label {
+ display: block;
+ }
+}
+
+.user.activate form .header,
+.user.forgot.password form .header,
+.user.reset.password form .header,
+.user.link-account form .header,
+.user.signin form .header,
+.user.signup form .header {
+ padding-left: 0 !important;
+ text-align: center;
+}
+
+.user.activate form .inline.field > label,
+.user.forgot.password form .inline.field > label,
+.user.reset.password form .inline.field > label,
+.user.link-account form .inline.field > label,
+.user.signin form .inline.field > label,
+.user.signup form .inline.field > label {
+ width: 200px;
+}
+
+@media (max-width: 767.98px) {
+ .user.activate form .inline.field > label,
+ .user.forgot.password form .inline.field > label,
+ .user.reset.password form .inline.field > label,
+ .user.link-account form .inline.field > label,
+ .user.signin form .inline.field > label,
+ .user.signup form .inline.field > label {
+ width: 100% !important;
+ }
+}
+
+.user.activate form input[type="number"],
+.user.forgot.password form input[type="number"],
+.user.reset.password form input[type="number"],
+.user.link-account form input[type="number"],
+.user.signin form input[type="number"],
+.user.signup form input[type="number"] {
+ -moz-appearance: textfield;
+}
+
+.user.activate form input::-webkit-outer-spin-button,
+.user.forgot.password form input::-webkit-outer-spin-button,
+.user.reset.password form input::-webkit-outer-spin-button,
+.user.link-account form input::-webkit-outer-spin-button,
+.user.signin form input::-webkit-outer-spin-button,
+.user.signup form input::-webkit-outer-spin-button,
+.user.activate form input::-webkit-inner-spin-button,
+.user.forgot.password form input::-webkit-inner-spin-button,
+.user.reset.password form input::-webkit-inner-spin-button,
+.user.link-account form input::-webkit-inner-spin-button,
+.user.signin form input::-webkit-inner-spin-button,
+.user.signup form input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.repository.new.repo form,
+.repository.new.migrate form,
+.repository.new.fork form {
+ margin: auto;
+}
+
+.repository.new.repo form .ui.message,
+.repository.new.migrate form .ui.message,
+.repository.new.fork form .ui.message {
+ text-align: center;
+}
+
+@media (min-width: 768px) {
+ .repository.new.repo form,
+ .repository.new.migrate form,
+ .repository.new.fork form {
+ width: 800px !important;
+ }
+ .repository.new.repo form .header,
+ .repository.new.migrate form .header,
+ .repository.new.fork form .header {
+ padding-left: 280px !important;
+ }
+ .repository.new.repo form .inline.field > label,
+ .repository.new.migrate form .inline.field > label,
+ .repository.new.fork form .inline.field > label {
+ text-align: right;
+ width: 250px !important;
+ word-wrap: break-word;
+ }
+ .repository.new.repo form .help,
+ .repository.new.migrate form .help,
+ .repository.new.fork form .help {
+ margin-left: 265px !important;
+ }
+ .repository.new.repo form .optional .title,
+ .repository.new.migrate form .optional .title,
+ .repository.new.fork form .optional .title {
+ margin-left: 250px !important;
+ }
+ .repository.new.repo form .inline.field > input,
+ .repository.new.migrate form .inline.field > input,
+ .repository.new.fork form .inline.field > input,
+ .repository.new.repo form .inline.field > textarea,
+ .repository.new.migrate form .inline.field > textarea,
+ .repository.new.fork form .inline.field > textarea {
+ width: 50%;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .repository.new.repo form .optional .title,
+ .repository.new.migrate form .optional .title,
+ .repository.new.fork form .optional .title {
+ margin-left: 15px;
+ }
+ .repository.new.repo form .inline.field > label,
+ .repository.new.migrate form .inline.field > label,
+ .repository.new.fork form .inline.field > label {
+ display: block;
+ }
+}
+
+.repository.new.repo form .dropdown .text,
+.repository.new.migrate form .dropdown .text,
+.repository.new.fork form .dropdown .text {
+ margin-right: 0 !important;
+}
+
+.repository.new.repo form .header,
+.repository.new.migrate form .header,
+.repository.new.fork form .header {
+ padding-left: 0 !important;
+ text-align: center;
+}
+
+.repository.new.repo form .selection.dropdown,
+.repository.new.migrate form .selection.dropdown,
+.repository.new.fork form .selection.dropdown,
+.repository.new.fork form .field a {
+ vertical-align: middle;
+ width: 50% !important;
+}
+
+@media (max-width: 767.98px) {
+ .repository.new.repo form label,
+ .repository.new.migrate form label,
+ .repository.new.fork form label,
+ .repository.new.repo form .inline.field > input,
+ .repository.new.migrate form .inline.field > input,
+ .repository.new.fork form .inline.field > input,
+ .repository.new.fork form .field a,
+ .repository.new.repo form .selection.dropdown,
+ .repository.new.migrate form .selection.dropdown,
+ .repository.new.fork form .selection.dropdown {
+ width: 100% !important;
+ }
+ .repository.new.repo form .field button,
+ .repository.new.migrate form .field button,
+ .repository.new.fork form .field button,
+ .repository.new.repo form .field a,
+ .repository.new.migrate form .field a {
+ margin-bottom: 1em;
+ width: 100%;
+ }
+}
+
+@media (min-width: 768px) {
+ .repository.new.repo .ui.form #auto-init {
+ margin-left: 265px !important;
+ }
+}
+
+.repository.new.repo .ui.form .selection.dropdown:not(.owner) {
+ width: 50% !important;
+}
+
+@media (max-width: 767.98px) {
+ .repository.new.repo .ui.form .selection.dropdown:not(.owner) {
+ width: 100% !important;
+ }
+}
+
+.new.webhook form .help {
+ margin-left: 25px;
+}
+
+.new.webhook .events.fields .column {
+ padding-left: 40px;
+}
+
+.githook textarea {
+ font-family: var(--fonts-monospace);
+}
+
+@media (max-width: 767.98px) {
+ .new.org .ui.form .field button,
+ .new.org .ui.form .field a {
+ margin-bottom: 1em;
+ width: 100%;
+ }
+ .new.org .ui.form .field input:not([type="checkbox"], [type="radio"]) {
+ width: 100% !important;
+ }
+}
diff --git a/web_src/css/helpers.css b/web_src/css/helpers.css
new file mode 100644
index 00000000..42d06e2e
--- /dev/null
+++ b/web_src/css/helpers.css
@@ -0,0 +1,60 @@
+/*
+Gitea's tailwind-style CSS helper classes have `gt-` prefix.
+Gitea's private styles use `g-` prefix.
+*/
+
+.gt-ellipsis {
+ overflow: hidden !important;
+ white-space: nowrap !important;
+ text-overflow: ellipsis !important;
+}
+
+.g-table-auto-ellipsis td.auto-ellipsis {
+ position: relative;
+}
+
+.g-table-auto-ellipsis td.auto-ellipsis span {
+ position: absolute;
+ inset: 0;
+ padding: inherit;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.interact-fg { color: inherit !important; }
+.interact-fg:hover { color: var(--color-primary) !important; }
+.interact-fg:active { color: var(--color-primary-active) !important; }
+
+.interact-bg { background: transparent !important; }
+.interact-bg:hover { background: var(--color-hover) !important; }
+.interact-bg:active { background: var(--color-active) !important; }
+
+@media (max-width: 767.98px) {
+ /* double selector so it wins over .tw-flex (old .gt-df) etc */
+ .not-mobile.not-mobile {
+ display: none !important;
+ }
+}
+@media (min-width: 767.98px) {
+ .only-mobile.only-mobile {
+ display: none !important;
+ }
+}
+
+.tab-size-1 { tab-size: 1 !important; }
+.tab-size-2 { tab-size: 2 !important; }
+.tab-size-3 { tab-size: 3 !important; }
+.tab-size-4 { tab-size: 4 !important; }
+.tab-size-5 { tab-size: 5 !important; }
+.tab-size-6 { tab-size: 6 !important; }
+.tab-size-7 { tab-size: 7 !important; }
+.tab-size-8 { tab-size: 8 !important; }
+.tab-size-9 { tab-size: 9 !important; }
+.tab-size-10 { tab-size: 10 !important; }
+.tab-size-11 { tab-size: 11 !important; }
+.tab-size-12 { tab-size: 12 !important; }
+.tab-size-13 { tab-size: 13 !important; }
+.tab-size-14 { tab-size: 14 !important; }
+.tab-size-15 { tab-size: 15 !important; }
+.tab-size-16 { tab-size: 16 !important; }
diff --git a/web_src/css/home.css b/web_src/css/home.css
new file mode 100644
index 00000000..22f1a2dc
--- /dev/null
+++ b/web_src/css/home.css
@@ -0,0 +1,87 @@
+.home .logo {
+ max-width: 220px;
+}
+
+@media (max-width: 767.98px) {
+ .home .hero h1 {
+ font-size: 3.5em;
+ }
+ .home .hero h2 {
+ font-size: 2em;
+ }
+}
+
+@media (min-width: 768px) {
+ .home .hero h1 {
+ font-size: 5.5em;
+ }
+ .home .hero h2 {
+ font-size: 3em;
+ }
+}
+
+.home .hero .svg {
+ color: var(--color-primary);
+ height: 40px;
+ width: 50px;
+ vertical-align: bottom;
+}
+
+.home .hero.header {
+ font-size: 20px;
+}
+
+.home p.large {
+ font-size: 16px;
+}
+
+.home .stackable {
+ padding-top: 30px;
+}
+
+.home a {
+ color: var(--color-primary);
+}
+
+.page-footer {
+ display: flex;
+ justify-content: space-between;
+ background-color: var(--color-footer);
+ border-top: 1px solid var(--color-secondary);
+ padding: 8px 20px;
+}
+
+.page-footer .left-links {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 0.25em;
+}
+
+.page-footer .right-links {
+ min-width: 180px; /* make sure the menu dropdown doesn't overflow horizontally when language name is short */
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+}
+
+.page-footer .right-links > a {
+ border-left: 1px solid var(--color-secondary-dark-1);
+ padding-left: 8px;
+ margin-left: 5px;
+}
+
+.page-footer .ui.dropdown.language .menu {
+ max-height: min(500px, calc(100vh - 60px));
+ overflow-y: auto;
+ margin-bottom: 10px;
+}
+
+@media (max-width: 880px) {
+ .page-footer {
+ flex-direction: column;
+ gap: 0.5em;
+ }
+}
diff --git a/web_src/css/index.css b/web_src/css/index.css
new file mode 100644
index 00000000..49ceb2c8
--- /dev/null
+++ b/web_src/css/index.css
@@ -0,0 +1,78 @@
+@import "./modules/normalize.css";
+@import "./modules/animations.css";
+
+/* fomantic replacements */
+@import "./modules/button.css";
+@import "./modules/container.css";
+@import "./modules/divider.css";
+@import "./modules/header.css";
+@import "./modules/input.css";
+@import "./modules/label.css";
+@import "./modules/list.css";
+@import "./modules/segment.css";
+@import "./modules/grid.css";
+@import "./modules/message.css";
+@import "./modules/table.css";
+@import "./modules/card.css";
+@import "./modules/checkbox.css";
+@import "./modules/modal.css";
+
+@import "./modules/select.css";
+@import "./modules/tippy.css";
+@import "./modules/breadcrumb.css";
+@import "./modules/comment.css";
+@import "./modules/navbar.css";
+@import "./modules/toast.css";
+@import "./modules/svg.css";
+@import "./modules/flexcontainer.css";
+
+@import "./shared/flex-list.css";
+@import "./shared/milestone.css";
+@import "./shared/repoorg.css";
+@import "./shared/settings.css";
+
+@import "./features/dropzone.css";
+@import "./features/gitgraph.css";
+@import "./features/heatmap.css";
+@import "./features/imagediff.css";
+@import "./features/codeeditor.css";
+@import "./features/projects.css";
+@import "./features/tribute.css";
+@import "./features/console.css";
+
+@import "./markup/content.css";
+@import "./markup/codecopy.css";
+@import "./markup/asciicast.css";
+@import "./markup/filepreview.css";
+
+@import "./chroma/base.css";
+@import "./codemirror/base.css";
+@import "./font_i18n.css";
+@import "./base.css";
+@import "./home.css";
+@import "./install.css";
+@import "./form.css";
+
+@import "./repo.css";
+@import "./repo/release-tag.css";
+@import "./repo/issue-card.css";
+@import "./repo/issue-label.css";
+@import "./repo/issue-list.css";
+@import "./repo/list-header.css";
+@import "./repo/linebutton.css";
+@import "./repo/wiki.css";
+@import "./repo/header.css";
+
+@import "./editor/fileeditor.css";
+@import "./editor/combomarkdowneditor.css";
+
+@import "./org.css";
+@import "./user.css";
+@import "./dashboard.css";
+@import "./admin.css";
+@import "./explore.css";
+@import "./review.css";
+@import "./actions.css";
+
+@tailwind utilities;
+@import "./helpers.css";
diff --git a/web_src/css/install.css b/web_src/css/install.css
new file mode 100644
index 00000000..df2a7cb5
--- /dev/null
+++ b/web_src/css/install.css
@@ -0,0 +1,62 @@
+.page-content.install .install-config-container {
+ max-width: 900px;
+ margin: auto;
+}
+
+.page-content.install form.ui.form .inline.field > label {
+ text-align: right;
+ width: 30%;
+ padding-right: 10px;
+ margin-right: 0;
+}
+
+.page-content.install .ui.form .field > .help,
+.page-content.install .ui.form .field > .ui.checkbox:first-child,
+.page-content.install .ui.form .field > .right-content {
+ margin-left: calc(30% + 5px);
+ width: auto;
+}
+
+.page-content.install form.ui.form input:not([type="checkbox"],[type="radio"]),
+.page-content.install form.ui.form .ui.selection.dropdown {
+ width: 60%;
+}
+
+.page-content.install form.ui.form details.optional.field[open] {
+ padding-bottom: 10px;
+}
+.page-content.install form.ui.form details.optional.field[open] summary {
+ margin-bottom: 10px;
+}
+
+.page-content.install form.ui.form details.optional.field * {
+ box-sizing: border-box;
+}
+
+.page-content.install form.ui.form .field {
+ text-align: left;
+}
+
+.page-content.install .ui .reinstall-message {
+ width: 70%;
+ margin: 20px auto;
+ color: var(--color-red);
+ text-align: left;
+ font-weight: var(--font-weight-semibold);
+}
+
+.page-content.install .ui .reinstall-confirm {
+ width: 70%;
+ text-align: left;
+ margin: 10px auto;
+}
+
+.page-content.install details.collapsible {
+ border: 1px solid var(--color-light-border);
+ border-radius: 0.28571429rem;
+}
+.page-content.install .collapsible summary {
+ background: transparent;
+ margin: auto;
+ text-align: center;
+}
diff --git a/web_src/css/markup/asciicast.css b/web_src/css/markup/asciicast.css
new file mode 100644
index 00000000..89696bc7
--- /dev/null
+++ b/web_src/css/markup/asciicast.css
@@ -0,0 +1,8 @@
+.asciinema-player-container {
+ width: 100%;
+ height: auto;
+}
+
+.ap-terminal {
+ overflow: hidden !important;
+}
diff --git a/web_src/css/markup/codecopy.css b/web_src/css/markup/codecopy.css
new file mode 100644
index 00000000..e3017ae9
--- /dev/null
+++ b/web_src/css/markup/codecopy.css
@@ -0,0 +1,35 @@
+.markup .code-block,
+.markup .mermaid-block {
+ position: relative;
+}
+
+.markup .code-copy {
+ position: absolute;
+ top: 8px;
+ right: 6px;
+ padding: 9px;
+ visibility: hidden;
+ animation: fadeout 0.2s both;
+}
+
+/* adjustments for comment content having only 14px font size */
+.repository.view.issue .comment-list .comment .markup .code-copy {
+ right: 5px;
+ padding: 8px;
+}
+
+/* can not use regular transparent button colors for hover and active states because
+ we need opaque colors here as code can appear behind the button */
+.markup .code-copy:hover {
+ background: var(--color-secondary) !important;
+}
+
+.markup .code-copy:active {
+ background: var(--color-secondary-dark-1) !important;
+}
+
+.markup .code-block:hover .code-copy,
+.markup .mermaid-block:hover .code-copy {
+ visibility: visible;
+ animation: fadein 0.2s both;
+}
diff --git a/web_src/css/markup/content.css b/web_src/css/markup/content.css
new file mode 100644
index 00000000..947480a7
--- /dev/null
+++ b/web_src/css/markup/content.css
@@ -0,0 +1,585 @@
+.markup {
+ overflow: hidden;
+ font-size: 16px;
+ line-height: 1.5 !important;
+ word-wrap: break-word;
+}
+
+.markup > *:first-child {
+ margin-top: 0 !important;
+}
+
+.markup > *:last-child {
+ margin-bottom: 0 !important;
+}
+
+.markup a:not([href]) {
+ color: inherit;
+ text-decoration: none;
+}
+
+.markup .absent {
+ color: var(--color-red);
+}
+
+.markup .anchor {
+ float: left;
+ padding-right: 4px;
+ margin-left: -20px;
+ color: inherit;
+}
+
+.markup .anchor .svg {
+ vertical-align: middle;
+}
+
+.markup .anchor:focus {
+ outline: none;
+}
+
+.markup h1 .anchor {
+ margin-top: -2px; /* re-align to center */
+}
+
+.markup h1 .anchor .svg,
+.markup h2 .anchor .svg,
+.markup h3 .anchor .svg,
+.markup h4 .anchor .svg,
+.markup h5 .anchor .svg,
+.markup h6 .anchor .svg {
+ visibility: hidden;
+}
+
+.markup h1:hover .anchor .svg,
+.markup h2:hover .anchor .svg,
+.markup h3:hover .anchor .svg,
+.markup h4:hover .anchor .svg,
+.markup h5:hover .anchor .svg,
+.markup h6:hover .anchor .svg {
+ visibility: visible;
+}
+
+.markup h2 .anchor .svg,
+.markup h3 .anchor .svg,
+.markup h4 .anchor .svg {
+ position: relative;
+ top: -2px;
+}
+
+.markup h1,
+.markup h2,
+.markup h3,
+.markup h4,
+.markup h5,
+.markup h6 {
+ margin-top: 24px !important;
+ margin-bottom: 16px;
+ font-weight: var(--font-weight-semibold);
+ line-height: 1.25;
+}
+
+.markup h1 tt,
+.markup h1 code,
+.markup h2 tt,
+.markup h2 code,
+.markup h3 tt,
+.markup h3 code,
+.markup h4 tt,
+.markup h4 code,
+.markup h5 tt,
+.markup h5 code,
+.markup h6 tt,
+.markup h6 code {
+ font-size: inherit;
+}
+
+.markup h1 {
+ padding-bottom: 0.3em;
+ font-size: 2em;
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.markup h2 {
+ padding-bottom: 0.3em;
+ font-size: 1.5em;
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.markup h3 {
+ font-size: 1.25em;
+}
+
+.markup h4 {
+ font-size: 1em;
+}
+
+.markup h5 {
+ font-size: 0.875em;
+}
+
+.markup h6 {
+ font-size: 0.85em;
+ color: var(--color-text-light-2);
+}
+
+.markup p,
+.markup blockquote,
+.markup details,
+.markup ul,
+.markup ol,
+.markup dl,
+.markup table,
+.markup pre {
+ margin-top: 0;
+ margin-bottom: 16px;
+}
+
+.markup hr {
+ height: 4px;
+ padding: 0;
+ margin: 16px 0;
+ background-color: var(--color-secondary);
+ border: 0;
+}
+
+.markup ul,
+.markup ol {
+ padding-left: 2em;
+}
+
+.markup ul.no-list,
+.markup ol.no-list {
+ padding: 0;
+ list-style-type: none;
+}
+
+.markup .task-list-item {
+ list-style-type: none;
+}
+
+.markup .task-list-item p + ul {
+ margin-top: 16px;
+}
+
+.markup .task-list-item input[type="checkbox"] {
+ margin: 0 .3em .25em -1.4em;
+ vertical-align: middle;
+ padding: 0;
+}
+
+.markup .task-list-item input[type="checkbox"] + p {
+ margin-left: -0.2em;
+ display: inline;
+}
+
+.markup .task-list-item > p {
+ margin-inline: 16px;
+}
+
+.markup .task-list-item + .task-list-item {
+ margin-top: 4px;
+}
+
+.markup input[type="checkbox"] {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ position: relative;
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ background: var(--color-input-background);
+ height: 14px;
+ width: 14px;
+ opacity: 1 !important; /* override fomantic on edit preview */
+ pointer-events: auto !important; /* override fomantic on edit preview */
+ vertical-align: middle !important; /* override fomantic on edit preview */
+ -webkit-print-color-adjust: exact;
+ color-adjust: exact;
+}
+
+.markup input[type="checkbox"]:not([disabled]):hover,
+.markup input[type="checkbox"]:not([disabled]):active {
+ border-color: var(--color-primary);
+}
+
+.markup input[type="checkbox"]::after {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ background: var(--color-text);
+ mask-size: cover;
+ -webkit-mask-size: cover;
+}
+
+.markup input[type="checkbox"]:checked::after {
+ content: "";
+ mask-image: var(--checkbox-mask-checked);
+ -webkit-mask-image: var(--checkbox-mask-checked);
+ -webkit-print-color-adjust: exact;
+ color-adjust: exact;
+}
+
+.markup input[type="checkbox"]:indeterminate::after {
+ content: "";
+ mask-image: var(--checkbox-mask-indeterminate);
+ -webkit-mask-image: var(--checkbox-mask-indeterminate);
+}
+
+.markup ul ul,
+.markup ul ol,
+.markup ol ol,
+.markup ol ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markup ol ol,
+.markup ul ol {
+ list-style-type: lower-roman;
+}
+
+.markup li > p {
+ margin-top: 16px;
+}
+
+.markup li + li {
+ margin-top: 0.25em;
+}
+
+.markup dl {
+ padding: 0;
+}
+
+.markup dl dt {
+ padding: 0;
+ margin-top: 16px;
+ font-size: 1em;
+ font-style: italic;
+ font-weight: var(--font-weight-semibold);
+}
+
+.markup dl dd {
+ padding: 0 16px;
+ margin-bottom: 16px;
+}
+
+.markup blockquote {
+ margin-left: 0;
+ padding: 0 15px;
+ color: var(--color-text-light-2);
+ border-left: 0.25em solid var(--color-secondary);
+}
+
+.markup blockquote > :first-child {
+ margin-top: 0;
+}
+
+.markup blockquote > :last-child {
+ margin-bottom: 0;
+}
+
+.markup table {
+ display: block;
+ width: 100%;
+ width: max-content;
+ max-width: 100%;
+ overflow: auto;
+}
+
+.markup table th {
+ font-weight: var(--font-weight-semibold);
+}
+
+.markup table th,
+.markup table td {
+ padding: 6px 13px !important;
+ border: 1px solid var(--color-secondary) !important;
+}
+
+.markup table tr {
+ border-top: 1px solid var(--color-secondary);
+}
+
+.markup table tr:nth-child(2n) {
+ background-color: var(--color-markup-table-row);
+}
+
+.markup img,
+.markup video {
+ max-width: 100%;
+ box-sizing: initial;
+}
+
+/* this background ensures images can break <hr>. We can only do this on
+ cases where the background is known and not transparent. */
+.markup.file-view img,
+.markup.file-view video,
+.comment-body .markup img, /* regular comment */
+.comment-body .markup video,
+.comment-content .markup img, /* code comment */
+.comment-content .markup video,
+.wiki .markup img,
+.wiki .markup video {
+ background: var(--color-box-body);
+}
+
+.markup img[align="right"],
+.markup video[align="right"] {
+ padding-left: 20px;
+}
+
+.markup img[align="left"],
+.markup video[align="left"] {
+ padding-right: 28px;
+}
+
+.markup .emoji {
+ max-width: none;
+ vertical-align: text-top;
+}
+
+.markup span.frame {
+ display: block;
+ overflow: hidden;
+}
+
+.markup span.frame > span {
+ display: block;
+ float: left;
+ width: auto;
+ padding: 7px;
+ margin: 13px 0 0;
+ overflow: hidden;
+ border: 1px solid var(--color-secondary);
+}
+
+.markup span.frame span img,
+.markup span.frame span video {
+ display: block;
+ float: left;
+}
+
+.markup span.frame span span {
+ display: block;
+ padding: 5px 0 0;
+ clear: both;
+ color: var(--color-text);
+}
+
+.markup span.align-center {
+ display: block;
+ overflow: hidden;
+ clear: both;
+}
+
+.markup span.align-center > span {
+ display: block;
+ margin: 13px auto 0;
+ overflow: hidden;
+ text-align: center;
+}
+
+.markup span.align-center span img
+.markup span.align-center span video {
+ margin: 0 auto;
+ text-align: center;
+}
+
+.markup span.align-right {
+ display: block;
+ overflow: hidden;
+ clear: both;
+}
+
+.markup span.align-right > span {
+ display: block;
+ margin: 13px 0 0;
+ overflow: hidden;
+ text-align: right;
+}
+
+.markup span.align-right span img,
+.markup span.align-right span video {
+ margin: 0;
+ text-align: right;
+}
+
+.markup span.float-left {
+ display: block;
+ float: left;
+ margin-right: 13px;
+ overflow: hidden;
+}
+
+.markup span.float-left span {
+ margin: 13px 0 0;
+}
+
+.markup span.float-right {
+ display: block;
+ float: right;
+ margin-left: 13px;
+ overflow: hidden;
+}
+
+.markup span.float-right > span {
+ display: block;
+ margin: 13px auto 0;
+ overflow: hidden;
+ text-align: right;
+}
+
+.markup code,
+.markup tt {
+ padding: 0.2em 0.4em;
+ margin: 0;
+ font-size: 85%;
+ white-space: break-spaces;
+ background-color: var(--color-markup-code-inline);
+ border-radius: var(--border-radius);
+}
+
+.markup code br,
+.markup tt br {
+ display: none;
+}
+
+.markup del code {
+ text-decoration: inherit;
+}
+
+.markup pre > code,
+.markup .file-preview code {
+ padding: 0;
+ margin: 0;
+ font-size: 100%;
+ white-space: pre-wrap;
+ word-break: break-all;
+ overflow-wrap: break-word;
+ background: transparent;
+ border: 0;
+}
+
+.markup .highlight {
+ margin-bottom: 16px;
+}
+
+.markup .highlight pre,
+.markup pre {
+ padding: 16px;
+ font-size: 85%;
+ line-height: 1.45;
+ background-color: var(--color-markup-code-block);
+ border-radius: var(--border-radius);
+}
+
+.markup .highlight pre {
+ margin-bottom: 0;
+ word-break: normal;
+}
+
+.markup pre {
+ word-wrap: normal;
+}
+
+.markup pre code,
+.markup pre tt {
+ display: inline;
+ padding: 0;
+ line-height: inherit;
+ word-wrap: normal;
+ background-color: transparent;
+ border: 0;
+}
+
+.markup pre code::before,
+.markup pre code::after,
+.markup pre tt::before,
+.markup pre tt::after {
+ content: normal;
+}
+
+.markup kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font-size: 11px;
+ line-height: 10px;
+ color: var(--color-text-light);
+ vertical-align: middle;
+ background-color: var(--color-markup-code-inline);
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ box-shadow: inset 0 -1px 0 var(--color-secondary);
+}
+
+.markup .ui.list .list,
+.markup ol.ui.list ol,
+.markup ul.ui.list ul {
+ padding-left: 2em;
+}
+
+.file-revisions-btn {
+ display: block;
+ float: left;
+ margin-bottom: 2px !important;
+ padding: 11px !important;
+ margin-right: 10px !important;
+}
+
+.file-revisions-btn i {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ user-select: none;
+}
+
+.markup-render {
+ display: block;
+ border: none;
+ width: 100%;
+ height: var(--height-loading); /* actual height is set in JS after loading */
+ overflow: hidden;
+ color-scheme: normal; /* match the value inside the iframe to allow it to become transparent */
+}
+
+.markup-block-error {
+ display: block !important; /* override fomantic .ui.form .error.message {display: none} */
+ border: none !important;
+ margin-bottom: 0 !important;
+ border-bottom-left-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+ box-shadow: none !important;
+ font-size: 85% !important;
+ white-space: pre-wrap !important;
+ padding: 0.5rem 1rem !important;
+ text-align: left !important;
+}
+
+.markup-block-error + pre {
+ border-top: none !important;
+ margin-top: 0 !important;
+ border-top-left-radius: 0 !important;
+ border-top-right-radius: 0 !important;
+}
+
+.file-view.markup.orgmode li.unchecked::before {
+ content: "[ ] ";
+}
+
+.file-view.markup.orgmode li.checked::before {
+ content: "[x] ";
+}
+
+.file-view.markup.orgmode li.indeterminate::before {
+ content: "[-] ";
+}
+
+/* This is only needed for <p> because they are literally acting as paragraphs,
+ * and thus having an ::before on the same line would force the paragraph to
+ * move to the next line. This can be avoided by an inline-block display that
+ * avoids that property while still having the other properties of the block
+ * display. */
+.file-view.markup.orgmode li.unchecked > p,
+.file-view.markup.orgmode li.checked > p,
+.file-view.markup.orgmode li.indeterminate > p {
+ display: inline-block;
+}
diff --git a/web_src/css/markup/dark.css b/web_src/css/markup/dark.css
new file mode 100644
index 00000000..700a4851
--- /dev/null
+++ b/web_src/css/markup/dark.css
@@ -0,0 +1,13 @@
+.markup [src$="#gh-light-mode-only"],
+.markup [src$="#light-mode-only"],
+.markup [href$="#gh-light-mode-only"],
+.markup [href$="#light-mode-only"] {
+ display: none;
+}
+
+.markup [src$="#gh-dark-mode-only"],
+.markup [src$="#dark-mode-only"],
+.markup [href$="#gh-dark-mode-only"],
+.markup [href$="#dark-mode-only"] {
+ display: unset;
+}
diff --git a/web_src/css/markup/filepreview.css b/web_src/css/markup/filepreview.css
new file mode 100644
index 00000000..d2ec16ea
--- /dev/null
+++ b/web_src/css/markup/filepreview.css
@@ -0,0 +1,41 @@
+.markup table.file-preview {
+ margin-bottom: 0;
+}
+
+.markup table.file-preview td {
+ padding: 0 10px !important;
+ border: none !important;
+}
+
+.markup table.file-preview tr {
+ border-top: none;
+ background-color: inherit !important;
+}
+
+.markup .file-preview-box {
+ margin-bottom: 16px;
+}
+
+.markup .file-preview-box .header {
+ padding: .5rem;
+ padding-left: 1rem;
+ border: 1px solid var(--color-secondary);
+ border-bottom: none;
+ border-radius: 0.28571429rem 0.28571429rem 0 0;
+ background: var(--color-box-header);
+}
+
+.markup .file-preview-box .warning {
+ border-radius: 0;
+ margin: 0;
+ padding: .5rem .5rem .5rem 1rem;
+}
+
+.markup .file-preview-box .header > a {
+ display: block;
+}
+
+.markup .file-preview-box .table {
+ margin-top: 0;
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
diff --git a/web_src/css/markup/light.css b/web_src/css/markup/light.css
new file mode 100644
index 00000000..88fc4b74
--- /dev/null
+++ b/web_src/css/markup/light.css
@@ -0,0 +1,6 @@
+.markup [src$="#gh-dark-mode-only"],
+.markup [src$="#dark-mode-only"],
+.markup [href$="#gh-dark-mode-only"],
+.markup [href$="#dark-mode-only"] {
+ display: none;
+}
diff --git a/web_src/css/modules/animations.css b/web_src/css/modules/animations.css
new file mode 100644
index 00000000..a86c9234
--- /dev/null
+++ b/web_src/css/modules/animations.css
@@ -0,0 +1,116 @@
+@keyframes isloadingspin {
+ 0% { transform: translate(-50%, -50%) rotate(0deg); }
+ 100% { transform: translate(-50%, -50%) rotate(360deg); }
+}
+
+.is-loading {
+ pointer-events: none !important;
+ position: relative !important;
+}
+
+.is-loading > * {
+ opacity: 0.3;
+}
+
+.btn.is-loading > *,
+.button.is-loading > * {
+ opacity: 0;
+}
+
+.is-loading::after {
+ content: "";
+ position: absolute;
+ display: block;
+ left: 50%;
+ top: 50%;
+ height: min(4em, 66.6%);
+ width: fit-content; /* compat: safari - https://bugs.webkit.org/show_bug.cgi?id=267625 */
+ aspect-ratio: 1;
+ transform: translate(-50%, -50%);
+ animation: isloadingspin 1000ms infinite linear;
+ border-width: 4px;
+ border-style: solid;
+ border-color: var(--color-secondary) var(--color-secondary) var(--color-secondary-dark-8) var(--color-secondary-dark-8);
+ border-radius: var(--border-radius-full);
+}
+
+.is-loading.loading-icon-2px::after {
+ border-width: 2px;
+}
+
+.is-loading.loading-icon-3px::after {
+ border-width: 3px;
+}
+
+/* for single form button, the loading state should be on the button, but not go semi-transparent, just replace the text on the button with the loader. */
+form.single-button-form.is-loading > * {
+ opacity: 1;
+}
+
+form.single-button-form.is-loading .button {
+ color: transparent;
+}
+
+.markup pre.is-loading,
+.editor-loading.is-loading,
+.pdf-content.is-loading {
+ height: var(--height-loading);
+}
+
+.markup .is-loading > * {
+ visibility: hidden;
+}
+
+.markup .is-loading {
+ color: transparent;
+ background: transparent;
+}
+
+/* TODO: not needed, use "is-loading loading-icon-2px" instead */
+code.language-math.is-loading::after {
+ padding: 0;
+ border-width: 2px;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+@keyframes fadein {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+
+@keyframes fadeout {
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
+
+@keyframes pulse {
+ 0% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.8);
+ }
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.pulse {
+ animation: pulse 2s linear;
+}
+
+.ui.modal,
+.ui.dimmer.transition {
+ animation-name: fadein;
+ animation-duration: 100ms;
+ animation-timing-function: ease-in-out;
+}
diff --git a/web_src/css/modules/breadcrumb.css b/web_src/css/modules/breadcrumb.css
new file mode 100644
index 00000000..ca488c21
--- /dev/null
+++ b/web_src/css/modules/breadcrumb.css
@@ -0,0 +1,14 @@
+.breadcrumb {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 3px;
+}
+
+.breadcrumb .breadcrumb-divider {
+ color: var(--color-text-light-2);
+}
+
+.breadcrumb > * {
+ display: inline;
+}
diff --git a/web_src/css/modules/button.css b/web_src/css/modules/button.css
new file mode 100644
index 00000000..0799ab80
--- /dev/null
+++ b/web_src/css/modules/button.css
@@ -0,0 +1,756 @@
+/* this contains override styles for buttons and related elements */
+
+/* these styles changed the Fomantic UI's rules, Fomantic UI expects only "basic" buttons have borders */
+.ui.button {
+ background: var(--color-button);
+ border: 1px solid var(--color-light-border);
+ color: var(--color-text);
+}
+
+.ui.button:hover,
+.ui.button:focus {
+ background: var(--color-hover);
+ color: var(--color-text);
+}
+
+.page-content .ui.button {
+ box-shadow: none !important;
+}
+
+.ui.active.button,
+.ui.button:active,
+.ui.active.button:active,
+.ui.active.button:hover,
+.ui.active.button:focus {
+ background: var(--color-active);
+ color: var(--color-text);
+}
+
+.delete-button,
+.delete-button:hover,
+.delete-button:focus {
+ color: var(--color-red);
+}
+
+/* btn is a plain button without any opinionated styling, it only uses flex for vertical alignment like ".ui.button" in base.css */
+
+.btn {
+ background: transparent;
+ border-radius: var(--border-radius);
+ border: none;
+ color: inherit;
+ margin: 0;
+ padding: 0;
+}
+
+.btn:hover,
+.btn:active,
+.btn:focus {
+ background: none;
+ border: none;
+}
+
+a.btn,
+a.btn:hover {
+ color: inherit;
+}
+
+/* By default, Fomantic UI doesn't support "bordered" buttons group, but Gitea would like to use it.
+And the default buttons always have borders now (not the same as Fomantic UI's default buttons, see above).
+It needs some tricks to tweak the left/right borders with active state */
+
+.ui.buttons .button {
+ border-right: none;
+}
+
+.ui.buttons .button:hover {
+ border-color: var(--color-secondary-dark-2);
+}
+
+.ui.buttons .button:hover + .button {
+ border-left: 1px solid var(--color-secondary-dark-2);
+}
+
+/* TODO: these "tw-hidden" selectors are only used by "blame.tmpl" buttons: Raw/Normal View/History/Unescape, need to be refactored to a clear solution later */
+.ui.buttons .button:first-child,
+.ui.buttons .button.tw-hidden:first-child + .button {
+ border-left: 1px solid var(--color-light-border);
+}
+
+.ui.buttons .button:last-child,
+.ui.buttons .button:nth-last-child(2):has(+ .button.tw-hidden) {
+ border-right: 1px solid var(--color-light-border);
+}
+
+.ui.buttons .button.active {
+ border-left: 1px solid var(--color-light-border);
+ border-right: 1px solid var(--color-light-border);
+}
+
+.ui.buttons .button.active + .button {
+ border-left: none;
+}
+
+.ui.basic.buttons .button,
+.ui.basic.button,
+.ui.basic.buttons .button:hover,
+.ui.basic.button:hover {
+ box-shadow: none;
+}
+
+/* apply the vertical padding of .compact to non-compact buttons when they contain a svg as they
+ would otherwise appear too large. Seen on "RSS Feed" button on repo releases tab. */
+.ui.small.button:not(.compact):has(.svg) {
+ padding-top: 0.58928571em;
+ padding-bottom: 0.58928571em;
+}
+
+.ui.labeled.button.disabled > .button,
+.ui.basic.buttons .button,
+.ui.basic.button {
+ color: var(--color-text-light);
+ background: var(--color-button);
+}
+
+.ui.basic.buttons .button:hover,
+.ui.basic.button:hover,
+.ui.basic.buttons .button:focus,
+.ui.basic.button:focus {
+ color: var(--color-text);
+ background: var(--color-hover);
+ border-color: var(--color-secondary-dark-2);
+}
+
+.ui.basic.buttons .button:active,
+.ui.basic.button:active,
+.ui.basic.buttons .active.button,
+.ui.basic.active.button,
+.ui.basic.buttons .active.button:hover,
+.ui.basic.active.button:hover,
+.ui.basic.buttons .active.button:focus,
+.ui.basic.active.button:focus {
+ color: var(--color-text);
+ background: var(--color-active);
+}
+
+.ui.labeled.button > .label {
+ border-color: var(--color-light-border);
+}
+
+.ui.labeled.icon.buttons > .button > .icon,
+.ui.labeled.icon.button > .icon {
+ background: var(--color-hover);
+}
+
+/* primary */
+
+.ui.primary.labels .label,
+.ui.ui.ui.primary.label,
+.ui.primary.button,
+.ui.primary.buttons .button {
+ background: var(--color-primary);
+ color: var(--color-primary-contrast);
+}
+
+.ui.primary.button:hover,
+.ui.primary.buttons .button:hover,
+.ui.primary.button:focus,
+.ui.primary.buttons .button:focus {
+ background: var(--color-primary-hover);
+ color: var(--color-primary-contrast);
+}
+
+.ui.primary.button:active,
+.ui.primary.buttons .button:active {
+ background: var(--color-primary-active);
+}
+
+.ui.basic.primary.buttons .button,
+.ui.basic.primary.button {
+ color: var(--color-primary);
+ border-color: var(--color-primary);
+}
+
+.ui.basic.primary.buttons .button:hover,
+.ui.basic.primary.button:hover,
+.ui.basic.primary.buttons .button:focus,
+.ui.basic.primary.button:focus {
+ color: var(--color-primary-hover);
+ border-color: var(--color-primary-hover);
+}
+
+.ui.basic.primary.buttons .button:active,
+.ui.basic.primary.button:active {
+ color: var(--color-primary-active);
+ border-color: var(--color-primary-active);
+}
+
+/* secondary */
+
+.ui.secondary.labels .label,
+.ui.ui.ui.secondary.label,
+.ui.secondary.button,
+.ui.secondary.buttons .button,
+.ui.secondary.button:focus,
+.ui.secondary.buttons .button:focus {
+ background: var(--color-secondary-button);
+}
+
+.ui.secondary.button:hover,
+.ui.secondary.buttons .button:hover {
+ background: var(--color-secondary-hover);
+}
+
+.ui.secondary.button:active,
+.ui.secondary.buttons .button:active {
+ background: var(--color-secondary-active);
+}
+
+.ui.basic.secondary.buttons .button,
+.ui.basic.secondary.button {
+ color: var(--color-secondary-button);
+ border-color: var(--color-secondary-button);
+}
+
+.ui.basic.secondary.buttons .button:hover,
+.ui.basic.secondary.button:hover,
+.ui.basic.secondary.button:focus,
+.ui.basic.secondary.buttons .button:focus {
+ color: var(--color-secondary-hover);
+ border-color: var(--color-secondary-hover);
+}
+
+.ui.basic.secondary.buttons .button:active,
+.ui.basic.secondary.button:active {
+ color: var(--color-secondary-active);
+ border-color: var(--color-secondary-active);
+}
+
+/* red */
+
+.ui.red.labels .label,
+.ui.ui.ui.red.label,
+.ui.red.button,
+.ui.red.buttons .button {
+ background: var(--color-red);
+}
+
+.ui.red.button:hover,
+.ui.red.buttons .button:hover,
+.ui.red.button:focus,
+.ui.red.buttons .button:focus {
+ background: var(--color-red-dark-1);
+}
+
+.ui.red.button:active,
+.ui.red.buttons .button:active {
+ background: var(--color-red-dark-2);
+}
+
+.ui.basic.red.buttons .button,
+.ui.basic.red.button {
+ color: var(--color-red);
+ border-color: var(--color-red);
+}
+
+.ui.basic.red.buttons .button:hover,
+.ui.basic.red.button:hover,
+.ui.basic.red.buttons .button:focus,
+.ui.basic.red.button:focus {
+ color: var(--color-red-dark-1);
+ border-color: var(--color-red-dark-1);
+}
+
+.ui.basic.red.buttons .button:active,
+.ui.basic.red.button:active {
+ color: var(--color-red-dark-2);
+ border-color: var(--color-red-dark-2);
+}
+
+/* orange */
+
+.ui.orange.labels .label,
+.ui.ui.ui.orange.label,
+.ui.orange.button,
+.ui.orange.buttons .button,
+.ui.orange.button:focus,
+.ui.orange.buttons .button:focus {
+ background: var(--color-orange);
+}
+
+.ui.orange.button:hover,
+.ui.orange.buttons .button:hover {
+ background: var(--color-orange-dark-1);
+}
+
+.ui.orange.button:active,
+.ui.orange.buttons .button:active {
+ background: var(--color-orange-dark-2);
+}
+
+.ui.basic.orange.buttons .button,
+.ui.basic.orange.button,
+.ui.basic.orange.buttons .button:focus,
+.ui.basic.orange.button:focus {
+ color: var(--color-orange);
+ border-color: var(--color-orange);
+}
+
+.ui.basic.orange.buttons .button:hover,
+.ui.basic.orange.button:hover {
+ color: var(--color-orange-dark-1);
+ border-color: var(--color-orange-dark-1);
+}
+
+.ui.basic.orange.buttons .button:active,
+.ui.basic.orange.button:active {
+ color: var(--color-orange-dark-2);
+ border-color: var(--color-orange-dark-2);
+}
+
+/* yellow */
+
+.ui.yellow.labels .label,
+.ui.ui.ui.yellow.label,
+.ui.yellow.button,
+.ui.yellow.buttons .button,
+.ui.yellow.button:focus,
+.ui.yellow.buttons .button:focus {
+ background: var(--color-yellow);
+}
+
+.ui.yellow.button:hover,
+.ui.yellow.buttons .button:hover {
+ background: var(--color-yellow-dark-1);
+}
+
+.ui.yellow.button:active,
+.ui.yellow.buttons .button:active {
+ background: var(--color-yellow-dark-2);
+}
+
+.ui.basic.yellow.buttons .button,
+.ui.basic.yellow.button,
+.ui.basic.yellow.buttons .button:focus,
+.ui.basic.yellow.button:focus {
+ color: var(--color-yellow);
+ border-color: var(--color-yellow);
+}
+
+.ui.basic.yellow.buttons .button:hover,
+.ui.basic.yellow.button:hover {
+ color: var(--color-yellow-dark-1);
+ border-color: var(--color-yellow-dark-1);
+}
+
+.ui.basic.yellow.buttons .button:active,
+.ui.basic.yellow.button:active {
+ color: var(--color-yellow-dark-2);
+ border-color: var(--color-yellow-dark-2);
+}
+
+/* olive */
+
+.ui.olive.labels .label,
+.ui.ui.ui.olive.label,
+.ui.olive.button,
+.ui.olive.buttons .button,
+.ui.olive.button:focus,
+.ui.olive.buttons .button:focus {
+ background: var(--color-olive);
+}
+
+.ui.olive.button:hover,
+.ui.olive.buttons .button:hover {
+ background: var(--color-olive-dark-1);
+}
+
+.ui.olive.button:active,
+.ui.olive.buttons .button:active {
+ background: var(--color-olive-dark-2);
+}
+
+.ui.basic.olive.buttons .button,
+.ui.basic.olive.button,
+.ui.basic.olive.buttons .button:focus,
+.ui.basic.olive.button:focus {
+ color: var(--color-olive);
+ border-color: var(--color-olive);
+}
+
+.ui.basic.olive.buttons .button:hover,
+.ui.basic.olive.button:hover {
+ color: var(--color-olive-dark-1);
+ border-color: var(--color-olive-dark-1);
+}
+
+.ui.basic.olive.buttons .button:active,
+.ui.basic.olive.button:active {
+ color: var(--color-olive-dark-2);
+ border-color: var(--color-olive-dark-2);
+}
+
+/* green */
+
+.ui.green.labels .label,
+.ui.ui.ui.green.label,
+.ui.green.button,
+.ui.green.buttons .button,
+.ui.green.button:focus,
+.ui.green.buttons .button:focus {
+ background: var(--color-green);
+}
+
+.ui.green.button:hover,
+.ui.green.buttons .button:hover {
+ background: var(--color-green-dark-1);
+}
+
+.ui.green.button:active,
+.ui.green.buttons .button:active {
+ background: var(--color-green-dark-2);
+}
+
+.ui.basic.green.buttons .button,
+.ui.basic.green.button,
+.ui.basic.green.buttons .button:focus,
+.ui.basic.green.button:focus {
+ color: var(--color-green);
+ border-color: var(--color-green);
+}
+
+.ui.basic.green.buttons .button:hover,
+.ui.basic.green.button:hover {
+ color: var(--color-green-dark-1);
+ border-color: var(--color-green-dark-1);
+}
+
+.ui.basic.green.buttons .button:active,
+.ui.basic.green.button:active {
+ color: var(--color-green-dark-2);
+ border-color: var(--color-green-dark-2);
+}
+
+/* teal */
+
+.ui.teal.labels .label,
+.ui.ui.ui.teal.label,
+.ui.teal.button,
+.ui.teal.buttons .button,
+.ui.teal.button:focus,
+.ui.teal.buttons .button:focus {
+ background: var(--color-teal);
+}
+
+.ui.teal.button:hover,
+.ui.teal.buttons .button:hover {
+ background: var(--color-teal-dark-1);
+}
+
+.ui.teal.button:active,
+.ui.teal.buttons .button:active {
+ background: var(--color-teal-dark-2);
+}
+
+.ui.basic.teal.buttons .button,
+.ui.basic.teal.button,
+.ui.basic.teal.buttons .button:focus,
+.ui.basic.teal.button:focus {
+ color: var(--color-teal);
+ border-color: var(--color-teal);
+}
+
+.ui.basic.teal.buttons .button:hover,
+.ui.basic.teal.button:hover {
+ color: var(--color-teal-dark-1);
+ border-color: var(--color-teal-dark-1);
+}
+
+.ui.basic.teal.buttons .button:active,
+.ui.basic.teal.button:active {
+ color: var(--color-teal-dark-2);
+ border-color: var(--color-teal-dark-2);
+}
+
+/* blue */
+
+.ui.blue.labels .label,
+.ui.ui.ui.blue.label,
+.ui.blue.button,
+.ui.blue.buttons .button,
+.ui.blue.button:focus,
+.ui.blue.buttons .button:focus {
+ background: var(--color-blue);
+}
+
+.ui.blue.button:hover,
+.ui.blue.buttons .button:hover {
+ background: var(--color-blue-dark-1);
+}
+
+.ui.blue.button:active,
+.ui.blue.buttons .button:active {
+ background: var(--color-blue-dark-2);
+}
+
+.ui.basic.blue.buttons .button,
+.ui.basic.blue.button,
+.ui.basic.blue.buttons .button:focus,
+.ui.basic.blue.button:focus {
+ color: var(--color-blue);
+ border-color: var(--color-blue);
+}
+
+.ui.basic.blue.buttons .button:hover,
+.ui.basic.blue.button:hover {
+ color: var(--color-blue-dark-1);
+ border-color: var(--color-blue-dark-1);
+}
+
+.ui.basic.blue.buttons .button:active,
+.ui.basic.blue.button:active {
+ color: var(--color-blue-dark-2);
+ border-color: var(--color-blue-dark-2);
+}
+
+/* violet */
+
+.ui.violet.labels .label,
+.ui.ui.ui.violet.label,
+.ui.violet.button,
+.ui.violet.buttons .button,
+.ui.violet.button:focus,
+.ui.violet.buttons .button:focus {
+ background: var(--color-violet);
+}
+
+.ui.violet.button:hover,
+.ui.violet.buttons .button:hover {
+ background: var(--color-violet-dark-1);
+}
+
+.ui.violet.button:active,
+.ui.violet.buttons .button:active {
+ background: var(--color-violet-dark-2);
+}
+
+.ui.basic.violet.buttons .button,
+.ui.basic.violet.button,
+.ui.basic.violet.buttons .button:focus,
+.ui.basic.violet.button:focus {
+ color: var(--color-violet);
+ border-color: var(--color-violet);
+}
+
+.ui.basic.violet.buttons .button:hover,
+.ui.basic.violet.button:hover {
+ color: var(--color-violet-dark-1);
+ border-color: var(--color-violet-dark-1);
+}
+
+.ui.basic.violet.buttons .button:active,
+.ui.basic.violet.button:active {
+ color: var(--color-violet-dark-2);
+ border-color: var(--color-violet-dark-2);
+}
+
+/* purple */
+
+.ui.purple.labels .label,
+.ui.ui.ui.purple.label,
+.ui.purple.button,
+.ui.purple.buttons .button,
+.ui.purple.button:focus,
+.ui.purple.buttons .button:focus {
+ background: var(--color-purple);
+}
+
+.ui.purple.button:hover,
+.ui.purple.buttons .button:hover {
+ background: var(--color-purple-dark-1);
+}
+
+.ui.purple.button:active,
+.ui.purple.buttons .button:active {
+ background: var(--color-purple-dark-2);
+}
+
+.ui.basic.purple.buttons .button,
+.ui.basic.purple.button,
+.ui.basic.purple.buttons .button:focus,
+.ui.basic.purple.button:focus {
+ color: var(--color-purple);
+ border-color: var(--color-purple);
+}
+
+.ui.basic.purple.buttons .button:hover,
+.ui.basic.purple.button:hover {
+ color: var(--color-purple-dark-1);
+ border-color: var(--color-purple-dark-1);
+}
+
+.ui.basic.purple.buttons .button:active,
+.ui.basic.purple.button:active {
+ color: var(--color-purple-dark-2);
+ border-color: var(--color-purple-dark-2);
+}
+
+/* pink */
+
+.ui.pink.labels .label,
+.ui.ui.ui.pink.label,
+.ui.pink.button,
+.ui.pink.buttons .button,
+.ui.pink.button:focus,
+.ui.pink.buttons .button:focus {
+ background: var(--color-pink);
+}
+
+.ui.pink.button:hover,
+.ui.pink.buttons .button:hover {
+ background: var(--color-pink-dark-1);
+}
+
+.ui.pink.button:active,
+.ui.pink.buttons .button:active {
+ background: var(--color-pink-dark-2);
+}
+
+.ui.basic.pink.buttons .button,
+.ui.basic.pink.button,
+.ui.basic.pink.buttons .button:focus,
+.ui.basic.pink.button:focus {
+ color: var(--color-pink);
+ border-color: var(--color-pink);
+}
+
+.ui.basic.pink.buttons .button:hover,
+.ui.basic.pink.button:hover {
+ color: var(--color-pink-dark-1);
+ border-color: var(--color-pink-dark-1);
+}
+
+.ui.basic.pink.buttons .button:active,
+.ui.basic.pink.button:active {
+ color: var(--color-pink-dark-2);
+ border-color: var(--color-pink-dark-2);
+}
+
+/* brown */
+
+.ui.brown.labels .label,
+.ui.ui.ui.brown.label,
+.ui.brown.button,
+.ui.brown.buttons .button,
+.ui.brown.button:focus,
+.ui.brown.buttons .button:focus {
+ background: var(--color-brown);
+}
+
+.ui.brown.button:hover,
+.ui.brown.buttons .button:hover {
+ background: var(--color-brown-dark-1);
+}
+
+.ui.brown.button:active,
+.ui.brown.buttons .button:active {
+ background: var(--color-brown-dark-2);
+}
+
+.ui.basic.brown.buttons .button,
+.ui.basic.brown.button,
+.ui.basic.brown.buttons .button:focus,
+.ui.basic.brown.button:focus {
+ color: var(--color-brown);
+ border-color: var(--color-brown);
+}
+
+.ui.basic.brown.buttons .button:hover,
+.ui.basic.brown.button:hover {
+ color: var(--color-brown-dark-1);
+ border-color: var(--color-brown-dark-1);
+}
+
+.ui.basic.brown.buttons .button:active,
+.ui.basic.brown.button:active {
+ color: var(--color-brown-dark-2);
+ border-color: var(--color-brown-dark-2);
+}
+
+/* negative */
+
+.ui.negative.buttons .button,
+.ui.negative.button,
+.ui.negative.buttons .button:focus,
+.ui.negative.button:focus {
+ background: var(--color-red);
+}
+
+.ui.negative.buttons .button:hover,
+.ui.negative.button:hover {
+ background: var(--color-red-dark-1);
+}
+
+.ui.negative.buttons .button:active,
+.ui.negative.button:active {
+ background: var(--color-red-dark-2);
+}
+
+.ui.basic.negative.buttons .button,
+.ui.basic.negative.button,
+.ui.basic.negative.buttons .button:focus,
+.ui.basic.negative.button:focus {
+ color: var(--color-red);
+ border-color: var(--color-red);
+}
+
+.ui.basic.negative.buttons .button:hover,
+.ui.basic.negative.button:hover {
+ color: var(--color-red-dark-1);
+ border-color: var(--color-red-dark-1);
+}
+
+.ui.basic.negative.buttons .button:active,
+.ui.basic.negative.button:active {
+ color: var(--color-red-dark-2);
+ border-color: var(--color-red-dark-2);
+}
+
+/* positive */
+
+.ui.positive.buttons .button,
+.ui.positive.button,
+.ui.positive.buttons .button:focus,
+.ui.positive.button:focus {
+ background: var(--color-green);
+}
+
+.ui.positive.buttons .button:hover,
+.ui.positive.button:hover {
+ background: var(--color-green-dark-1);
+}
+
+.ui.positive.buttons .button:active,
+.ui.positive.button:active {
+ background: var(--color-green-dark-2);
+}
+
+.ui.basic.positive.buttons .button,
+.ui.basic.positive.button,
+.ui.basic.positive.buttons .button:focus,
+.ui.basic.positive.button:focus {
+ color: var(--color-green);
+ border-color: var(--color-green);
+}
+
+.ui.basic.positive.buttons .button:hover,
+.ui.basic.positive.button:hover {
+ color: var(--color-green-dark-1);
+ border-color: var(--color-green-dark-1);
+}
+
+.ui.basic.positive.buttons .button:active,
+.ui.basic.positive.button:active {
+ color: var(--color-green-dark-2);
+ border-color: var(--color-green-dark-2);
+}
diff --git a/web_src/css/modules/card.css b/web_src/css/modules/card.css
new file mode 100644
index 00000000..2406def6
--- /dev/null
+++ b/web_src/css/modules/card.css
@@ -0,0 +1,134 @@
+/* Below styles are a subset of the full fomantic card styles which are */
+/* needed to get all current uses of fomantic cards working. */
+/* TODO: remove all these styles and use custom styling instead */
+
+.ui.card:last-child {
+ margin-bottom: 0;
+}
+.ui.card:first-child {
+ margin-top: 0;
+}
+
+.ui.cards > .card,
+.ui.card {
+ display: flex;
+ flex-direction: column;
+ max-width: 100%;
+ width: 290px;
+ min-height: 0;
+ padding: 0;
+ background: var(--color-card);
+ border: 1px solid var(--color-secondary);
+ box-shadow: none;
+ word-wrap: break-word;
+}
+
+.ui.card {
+ margin: 1em 0;
+}
+
+.ui.cards {
+ display: flex;
+ margin: -0.875em -0.5em;
+ flex-wrap: wrap;
+}
+
+.ui.cards > .card {
+ display: flex;
+ margin: 0.875em 0.5em;
+ float: none;
+}
+
+.ui.cards > .card > .content,
+.ui.card > .content {
+ border-top: 1px solid var(--color-secondary);
+ max-width: 100%;
+ padding: 1em;
+ font-size: 1em;
+}
+
+.ui.cards > .card > .content > .meta + .description,
+.ui.cards > .card > .content > .header + .description,
+.ui.card > .content > .meta + .description,
+.ui.card > .content > .header + .description {
+ margin-top: .5em;
+}
+
+.ui.cards > .card > .content > .header:not(.ui),
+.ui.card > .content > .header:not(.ui) {
+ font-weight: var(--font-weight-medium);
+ font-size: 1.28571429em;
+ margin-top: -.21425em;
+ line-height: 1.28571429;
+}
+
+.ui.cards > .card > .content:first-child,
+.ui.card > .content:first-child {
+ border-top: none;
+ border-radius: var(--border-radius) var(--border-radius) 0 0;
+}
+
+.ui.cards > .card > :last-child,
+.ui.card > :last-child {
+ border-radius: 0 0 var(--border-radius) var(--border-radius);
+}
+
+.ui.cards > .card > :only-child,
+.ui.card > :only-child {
+ border-radius: var(--border-radius) !important;
+}
+
+.ui.cards > .card > .extra,
+.ui.card > .extra,
+.ui.cards > .card > .extra a:not(.ui),
+.ui.card > .extra a:not(.ui) {
+ color: var(--color-text);
+}
+
+.ui.cards > .card > .extra a:not(.ui):hover,
+.ui.card > .extra a:not(.ui):hover {
+ color: var(--color-primary);
+}
+
+.ui.cards > .card > .content > .header,
+.ui.card > .content > .header {
+ color: var(--color-text);
+}
+
+.ui.cards > .card > .content > .description,
+.ui.card > .content > .description {
+ color: var(--color-text);
+}
+
+.ui.cards > .card .meta > a:not(.ui),
+.ui.card .meta > a:not(.ui) {
+ color: var(--color-text-light-2);
+}
+
+.ui.cards > .card .meta > a:not(.ui):hover,
+.ui.card .meta > a:not(.ui):hover {
+ color: var(--color-text);
+}
+
+.ui.cards a.card:hover,
+a.ui.card:hover {
+ border: 1px solid var(--color-secondary);
+ background: var(--color-card);
+}
+
+.ui.cards > .card > .extra,
+.ui.card > .extra {
+ color: var(--color-text);
+ border-top-color: var(--color-secondary-light-1) !important;
+}
+
+.ui.three.cards {
+ margin-left: -1em;
+ margin-right: -1em;
+}
+
+.ui.three.cards > .card {
+ width: calc(33.33333333333333% - 2em);
+ margin-left: 1em;
+ margin-right: 1em;
+}
diff --git a/web_src/css/modules/checkbox.css b/web_src/css/modules/checkbox.css
new file mode 100644
index 00000000..8d73573b
--- /dev/null
+++ b/web_src/css/modules/checkbox.css
@@ -0,0 +1,121 @@
+/* based on Fomantic UI checkbox module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+input[type="checkbox"],
+input[type="radio"] {
+ width: var(--checkbox-size);
+ height: var(--checkbox-size);
+}
+
+.ui.checkbox {
+ position: relative;
+ display: inline-block;
+ vertical-align: baseline;
+ min-height: var(--checkbox-size);
+ line-height: var(--checkbox-size);
+ min-width: var(--checkbox-size);
+ padding: 1px;
+}
+
+.ui.checkbox input[type="checkbox"],
+.ui.checkbox input[type="radio"] {
+ position: absolute;
+ top: 1px;
+ left: 0;
+ width: var(--checkbox-size);
+ height: var(--checkbox-size);
+}
+
+.ui.checkbox input[type="checkbox"]:enabled,
+.ui.checkbox input[type="radio"]:enabled,
+.ui.checkbox label:enabled {
+ cursor: pointer;
+}
+
+.ui.checkbox label {
+ cursor: auto;
+ position: relative;
+ display: block;
+ user-select: none;
+}
+
+.ui.checkbox label,
+.ui.radio.checkbox label {
+ margin-left: 1.85714em;
+}
+
+.ui.checkbox + label {
+ vertical-align: middle;
+}
+
+.ui.disabled.checkbox label,
+.ui.checkbox input[disabled] ~ label {
+ cursor: default !important;
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+.ui.radio.checkbox {
+ min-height: var(--checkbox-size);
+}
+
+/* "switch" styled checkbox */
+
+.ui.toggle.checkbox {
+ min-height: 1.5rem;
+}
+.ui.toggle.checkbox input {
+ width: 3.5rem;
+ height: 21px;
+ opacity: 0;
+ z-index: 3;
+}
+.ui.toggle.checkbox label {
+ min-height: 1.5rem;
+ padding-left: 4.5rem;
+ padding-top: 0.15em;
+}
+.ui.toggle.checkbox label::before {
+ display: block;
+ position: absolute;
+ content: "";
+ z-index: 1;
+ top: 0;
+ width: 49px;
+ height: 21px;
+ border-radius: 500rem;
+ left: 0;
+}
+.ui.toggle.checkbox label::after {
+ background: var(--color-white);
+ box-shadow: 1px 1px 4px 1px var(--color-shadow);
+ position: absolute;
+ content: "";
+ opacity: 1;
+ z-index: 2;
+ width: 18px;
+ height: 18px;
+ top: 1.5px;
+ left: 1.5px;
+ border-radius: 500rem;
+ transition: background 0.3s ease, left 0.3s ease;
+}
+.ui.toggle.checkbox input ~ label::after {
+ left: 1.5px;
+}
+.ui.toggle.checkbox input:checked ~ label::after {
+ left: 29px;
+}
+.ui.toggle.checkbox input:focus ~ label::before,
+.ui.toggle.checkbox label::before {
+ background: var(--color-input-toggle-background);
+}
+.ui.toggle.checkbox label,
+.ui.toggle.checkbox input:checked ~ label,
+.ui.toggle.checkbox input:focus:checked ~ label {
+ color: var(--color-text) !important;
+}
+.ui.toggle.checkbox input:checked ~ label::before,
+.ui.toggle.checkbox input:focus:checked ~ label::before {
+ background: var(--color-primary) !important;
+}
diff --git a/web_src/css/modules/comment.css b/web_src/css/modules/comment.css
new file mode 100644
index 00000000..799eeb85
--- /dev/null
+++ b/web_src/css/modules/comment.css
@@ -0,0 +1,90 @@
+/* These are the remnants of the fomantic comment module */
+/* TODO: remove all of these rules */
+
+.ui.comments {
+ margin: 1.5em 0;
+}
+
+.ui.comments:first-child {
+ margin-top: 0;
+}
+
+.ui.comments:last-child {
+ margin-bottom: 0;
+}
+
+.ui.comments .comment {
+ position: relative;
+ background: none;
+ margin: 0.5em 0 0;
+ padding: 0.5em 0 0;
+ border: none;
+ border-top: none;
+ line-height: 1.2;
+}
+
+.ui.comments .comment:first-child {
+ margin-top: 0;
+ padding-top: 0;
+}
+
+.ui.comments .comment > .comments {
+ margin: 0 0 0.5em 0.5em;
+ padding: 1em 0 1em 1em;
+}
+
+.ui.comments .comment > .comments::before {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.ui.comments .comment > .comments .comment {
+ border: none;
+ border-top: none;
+ background: none;
+}
+
+.ui.comments .comment .avatar {
+ float: left;
+ width: 2.5em;
+}
+
+.ui.comments .comment > .content {
+ display: block;
+}
+
+.ui.comments .comment > .avatar ~ .content {
+ margin-left: 3.5em;
+}
+
+.ui.comments .comment .author {
+ font-size: 1em;
+ font-weight: var(--font-weight-medium);
+}
+
+.ui.comments .comment a.author {
+ cursor: pointer;
+}
+
+.ui.comments .comment .metadata {
+ display: inline-block;
+ margin-left: 0.5em;
+ font-size: 0.875em;
+}
+
+.ui.comments .comment .metadata > * {
+ display: inline-block;
+ margin: 0 0.5em 0 0;
+}
+
+.ui.comments .comment .metadata > :last-child {
+ margin-right: 0;
+}
+
+.ui.comments .comment .text {
+ margin: 0.25em 0 0.5em;
+ font-size: 1em;
+ word-wrap: break-word;
+ line-height: 1.3;
+}
diff --git a/web_src/css/modules/container.css b/web_src/css/modules/container.css
new file mode 100644
index 00000000..f394d6c0
--- /dev/null
+++ b/web_src/css/modules/container.css
@@ -0,0 +1,59 @@
+/* based on Fomantic UI container module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.container {
+ display: block;
+ max-width: 100%;
+}
+
+@media (max-width: 767.98px) {
+ .ui.ui.ui.container:not(.fluid) {
+ width: auto;
+ margin-left: 1em;
+ margin-right: 1em;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991.98px) {
+ .ui.ui.ui.container:not(.fluid) {
+ width: 723px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199.98px) {
+ .ui.ui.ui.container:not(.fluid) {
+ width: 933px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+
+@media (min-width: 1200px) {
+ .ui.ui.ui.container:not(.fluid) {
+ width: 1127px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+
+.ui.fluid.container {
+ width: 100%;
+}
+
+.ui[class*="center aligned"].container {
+ text-align: center;
+}
+
+/* overwrite width of containers inside the main page content div (div with class "page-content") */
+.page-content .ui.ui.ui.container:not(.fluid) {
+ width: 1280px;
+ max-width: calc(100% - calc(2 * var(--page-margin-x)));
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.ui.container.fluid.padded {
+ padding: 0 var(--page-margin-x);
+}
diff --git a/web_src/css/modules/divider.css b/web_src/css/modules/divider.css
new file mode 100644
index 00000000..acc8408f
--- /dev/null
+++ b/web_src/css/modules/divider.css
@@ -0,0 +1,43 @@
+.divider {
+ margin: 10px 0;
+ height: 0;
+ font-weight: var(--font-weight-medium);
+ color: var(--color-text);
+ font-size: 1rem;
+ width: 100%;
+}
+
+h4.divider {
+ margin-top: 1.25rem;
+ margin-bottom: 1.25rem;
+}
+
+.divider:not(.divider-text) {
+ border-top: 1px solid var(--color-secondary);
+}
+
+.divider.divider-text {
+ display: flex;
+ align-items: center;
+ padding: 5px 0;
+}
+
+.divider.divider-text::before,
+.divider.divider-text::after {
+ content: "";
+ flex: 1;
+ border-top: 1px solid var(--color-secondary);
+}
+
+.divider.divider-text::before {
+ margin-right: .75em;
+}
+
+.divider.divider-text::after {
+ margin-left: .75em;
+}
+
+.ui.dropdown .menu > .divider {
+ border-top: 1px solid var(--color-secondary);
+ margin: 4px 0;
+}
diff --git a/web_src/css/modules/flexcontainer.css b/web_src/css/modules/flexcontainer.css
new file mode 100644
index 00000000..5d4e12cc
--- /dev/null
+++ b/web_src/css/modules/flexcontainer.css
@@ -0,0 +1,33 @@
+/* container for full-page content with sidebar on left */
+
+.flex-container {
+ display: flex !important;
+ gap: var(--page-spacing);
+ margin-top: var(--page-spacing);
+}
+
+/* small options menu on the left, used in settings/admin pages */
+.flex-container-nav {
+ width: 240px;
+}
+
+/* wide sidebar on the right, used in frontpage */
+.flex-container-sidebar {
+ width: 35%;
+}
+
+.flex-container-main {
+ flex: 1;
+ min-width: 0; /* make the "text truncate" work, otherwise the flex axis is not limited and the text just overflows */
+}
+
+@media (max-width: 767.98px) {
+ .flex-container {
+ flex-direction: column;
+ }
+ .flex-container-nav,
+ .flex-container-sidebar {
+ order: -1;
+ width: auto;
+ }
+}
diff --git a/web_src/css/modules/grid.css b/web_src/css/modules/grid.css
new file mode 100644
index 00000000..a2c55804
--- /dev/null
+++ b/web_src/css/modules/grid.css
@@ -0,0 +1,513 @@
+/* based on Fomantic UI grid module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.grid {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: stretch;
+ padding: 0;
+ margin: -1rem;
+}
+
+.ui.relaxed.grid {
+ margin-left: -1.5rem;
+ margin-right: -1.5rem;
+}
+.ui[class*="very relaxed"].grid {
+ margin-left: -2.5rem;
+ margin-right: -2.5rem;
+}
+
+.ui.grid + .grid {
+ margin-top: 1rem;
+}
+
+.ui.grid > .column:not(.row),
+.ui.grid > .row > .column {
+ position: relative;
+ display: inline-block;
+ width: 6.25%;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ vertical-align: top;
+}
+.ui.grid > * {
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+.ui.grid > .row {
+ position: relative;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: inherit;
+ align-items: stretch;
+ width: 100% !important;
+ padding: 0;
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+
+.ui.grid > .column:not(.row) {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+.ui.grid > .row > .column {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.ui.grid > .row > img,
+.ui.grid > .row > .column > img {
+ max-width: 100%;
+}
+
+.ui.grid > .ui.grid:first-child {
+ margin-top: 0;
+}
+.ui.grid > .ui.grid:last-child {
+ margin-bottom: 0;
+}
+
+.ui.grid .aligned.row > .column > .segment:not(.compact):not(.attached),
+.ui.aligned.grid .column > .segment:not(.compact):not(.attached) {
+ width: 100%;
+}
+
+.ui.grid .row + .ui.divider {
+ flex-grow: 1;
+ margin: 1rem;
+}
+.ui.grid .column + .ui.vertical.divider {
+ height: calc(50% - 1rem);
+}
+
+.ui.grid > .row > .column:last-child > .horizontal.segment,
+.ui.grid > .column:last-child > .horizontal.segment {
+ box-shadow: none;
+}
+
+@media only screen and (max-width: 767.98px) {
+ .ui.page.grid {
+ width: auto;
+ padding-left: 0;
+ padding-right: 0;
+ margin-left: 0;
+ margin-right: 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991.98px) {
+ .ui.page.grid {
+ width: auto;
+ margin-left: 0;
+ margin-right: 0;
+ padding-left: 2em;
+ padding-right: 2em;
+ }
+}
+@media only screen and (min-width: 992px) and (max-width: 1199.98px) {
+ .ui.page.grid {
+ width: auto;
+ margin-left: 0;
+ margin-right: 0;
+ padding-left: 3%;
+ padding-right: 3%;
+ }
+}
+@media only screen and (min-width: 1200px) and (max-width: 1919.98px) {
+ .ui.page.grid {
+ width: auto;
+ margin-left: 0;
+ margin-right: 0;
+ padding-left: 15%;
+ padding-right: 15%;
+ }
+}
+@media only screen and (min-width: 1920px) {
+ .ui.page.grid {
+ width: auto;
+ margin-left: 0;
+ margin-right: 0;
+ padding-left: 23%;
+ padding-right: 23%;
+ }
+}
+
+.ui.grid > .column:only-child,
+.ui.grid > .row > .column:only-child {
+ width: 100%;
+}
+
+.ui[class*="one column"].grid > .row > .column,
+.ui[class*="one column"].grid > .column:not(.row) {
+ width: 100%;
+}
+.ui[class*="two column"].grid > .row > .column,
+.ui[class*="two column"].grid > .column:not(.row) {
+ width: 50%;
+}
+.ui[class*="three column"].grid > .row > .column,
+.ui[class*="three column"].grid > .column:not(.row) {
+ width: 33.33333333%;
+}
+.ui[class*="four column"].grid > .row > .column,
+.ui[class*="four column"].grid > .column:not(.row) {
+ width: 25%;
+}
+.ui[class*="five column"].grid > .row > .column,
+.ui[class*="five column"].grid > .column:not(.row) {
+ width: 20%;
+}
+.ui[class*="six column"].grid > .row > .column,
+.ui[class*="six column"].grid > .column:not(.row) {
+ width: 16.66666667%;
+}
+.ui[class*="seven column"].grid > .row > .column,
+.ui[class*="seven column"].grid > .column:not(.row) {
+ width: 14.28571429%;
+}
+.ui[class*="eight column"].grid > .row > .column,
+.ui[class*="eight column"].grid > .column:not(.row) {
+ width: 12.5%;
+}
+.ui[class*="nine column"].grid > .row > .column,
+.ui[class*="nine column"].grid > .column:not(.row) {
+ width: 11.11111111%;
+}
+.ui[class*="ten column"].grid > .row > .column,
+.ui[class*="ten column"].grid > .column:not(.row) {
+ width: 10%;
+}
+.ui[class*="eleven column"].grid > .row > .column,
+.ui[class*="eleven column"].grid > .column:not(.row) {
+ width: 9.09090909%;
+}
+.ui[class*="twelve column"].grid > .row > .column,
+.ui[class*="twelve column"].grid > .column:not(.row) {
+ width: 8.33333333%;
+}
+.ui[class*="thirteen column"].grid > .row > .column,
+.ui[class*="thirteen column"].grid > .column:not(.row) {
+ width: 7.69230769%;
+}
+.ui[class*="fourteen column"].grid > .row > .column,
+.ui[class*="fourteen column"].grid > .column:not(.row) {
+ width: 7.14285714%;
+}
+.ui[class*="fifteen column"].grid > .row > .column,
+.ui[class*="fifteen column"].grid > .column:not(.row) {
+ width: 6.66666667%;
+}
+.ui[class*="sixteen column"].grid > .row > .column,
+.ui[class*="sixteen column"].grid > .column:not(.row) {
+ width: 6.25%;
+}
+
+.ui.grid > [class*="one column"].row > .column {
+ width: 100% !important;
+}
+.ui.grid > [class*="two column"].row > .column {
+ width: 50% !important;
+}
+.ui.grid > [class*="three column"].row > .column {
+ width: 33.33333333% !important;
+}
+.ui.grid > [class*="four column"].row > .column {
+ width: 25% !important;
+}
+.ui.grid > [class*="five column"].row > .column {
+ width: 20% !important;
+}
+.ui.grid > [class*="six column"].row > .column {
+ width: 16.66666667% !important;
+}
+.ui.grid > [class*="seven column"].row > .column {
+ width: 14.28571429% !important;
+}
+.ui.grid > [class*="eight column"].row > .column {
+ width: 12.5% !important;
+}
+.ui.grid > [class*="nine column"].row > .column {
+ width: 11.11111111% !important;
+}
+.ui.grid > [class*="ten column"].row > .column {
+ width: 10% !important;
+}
+.ui.grid > [class*="eleven column"].row > .column {
+ width: 9.09090909% !important;
+}
+.ui.grid > [class*="twelve column"].row > .column {
+ width: 8.33333333% !important;
+}
+.ui.grid > [class*="thirteen column"].row > .column {
+ width: 7.69230769% !important;
+}
+.ui.grid > [class*="fourteen column"].row > .column {
+ width: 7.14285714% !important;
+}
+.ui.grid > [class*="fifteen column"].row > .column {
+ width: 6.66666667% !important;
+}
+.ui.grid > [class*="sixteen column"].row > .column {
+ width: 6.25% !important;
+}
+
+.ui.grid > .row > [class*="one wide"].column,
+.ui.grid > .column.row > [class*="one wide"].column,
+.ui.grid > [class*="one wide"].column,
+.ui.column.grid > [class*="one wide"].column {
+ width: 6.25% !important;
+}
+.ui.grid > .row > [class*="two wide"].column,
+.ui.grid > .column.row > [class*="two wide"].column,
+.ui.grid > [class*="two wide"].column,
+.ui.column.grid > [class*="two wide"].column {
+ width: 12.5% !important;
+}
+.ui.grid > .row > [class*="three wide"].column,
+.ui.grid > .column.row > [class*="three wide"].column,
+.ui.grid > [class*="three wide"].column,
+.ui.column.grid > [class*="three wide"].column {
+ width: 18.75% !important;
+}
+.ui.grid > .row > [class*="four wide"].column,
+.ui.grid > .column.row > [class*="four wide"].column,
+.ui.grid > [class*="four wide"].column,
+.ui.column.grid > [class*="four wide"].column {
+ width: 25% !important;
+}
+.ui.grid > .row > [class*="five wide"].column,
+.ui.grid > .column.row > [class*="five wide"].column,
+.ui.grid > [class*="five wide"].column,
+.ui.column.grid > [class*="five wide"].column {
+ width: 31.25% !important;
+}
+.ui.grid > .row > [class*="six wide"].column,
+.ui.grid > .column.row > [class*="six wide"].column,
+.ui.grid > [class*="six wide"].column,
+.ui.column.grid > [class*="six wide"].column {
+ width: 37.5% !important;
+}
+.ui.grid > .row > [class*="seven wide"].column,
+.ui.grid > .column.row > [class*="seven wide"].column,
+.ui.grid > [class*="seven wide"].column,
+.ui.column.grid > [class*="seven wide"].column {
+ width: 43.75% !important;
+}
+.ui.grid > .row > [class*="eight wide"].column,
+.ui.grid > .column.row > [class*="eight wide"].column,
+.ui.grid > [class*="eight wide"].column,
+.ui.column.grid > [class*="eight wide"].column {
+ width: 50% !important;
+}
+.ui.grid > .row > [class*="nine wide"].column,
+.ui.grid > .column.row > [class*="nine wide"].column,
+.ui.grid > [class*="nine wide"].column,
+.ui.column.grid > [class*="nine wide"].column {
+ width: 56.25% !important;
+}
+.ui.grid > .row > [class*="ten wide"].column,
+.ui.grid > .column.row > [class*="ten wide"].column,
+.ui.grid > [class*="ten wide"].column,
+.ui.column.grid > [class*="ten wide"].column {
+ width: 62.5% !important;
+}
+.ui.grid > .row > [class*="eleven wide"].column,
+.ui.grid > .column.row > [class*="eleven wide"].column,
+.ui.grid > [class*="eleven wide"].column,
+.ui.column.grid > [class*="eleven wide"].column {
+ width: 68.75% !important;
+}
+.ui.grid > .row > [class*="twelve wide"].column,
+.ui.grid > .column.row > [class*="twelve wide"].column,
+.ui.grid > [class*="twelve wide"].column,
+.ui.column.grid > [class*="twelve wide"].column {
+ width: 75% !important;
+}
+.ui.grid > .row > [class*="thirteen wide"].column,
+.ui.grid > .column.row > [class*="thirteen wide"].column,
+.ui.grid > [class*="thirteen wide"].column,
+.ui.column.grid > [class*="thirteen wide"].column {
+ width: 81.25% !important;
+}
+.ui.grid > .row > [class*="fourteen wide"].column,
+.ui.grid > .column.row > [class*="fourteen wide"].column,
+.ui.grid > [class*="fourteen wide"].column,
+.ui.column.grid > [class*="fourteen wide"].column {
+ width: 87.5% !important;
+}
+.ui.grid > .row > [class*="fifteen wide"].column,
+.ui.grid > .column.row > [class*="fifteen wide"].column,
+.ui.grid > [class*="fifteen wide"].column,
+.ui.column.grid > [class*="fifteen wide"].column {
+ width: 93.75% !important;
+}
+.ui.grid > .row > [class*="sixteen wide"].column,
+.ui.grid > .column.row > [class*="sixteen wide"].column,
+.ui.grid > [class*="sixteen wide"].column,
+.ui.column.grid > [class*="sixteen wide"].column {
+ width: 100% !important;
+}
+
+.ui.centered.grid,
+.ui.centered.grid > .row,
+.ui.grid > .centered.row {
+ text-align: center;
+ justify-content: center;
+}
+.ui.centered.grid > .column:not(.aligned):not(.justified):not(.row),
+.ui.centered.grid > .row > .column:not(.aligned):not(.justified),
+.ui.grid .centered.row > .column:not(.aligned):not(.justified) {
+ text-align: left;
+}
+.ui.grid > .centered.column,
+.ui.grid > .row > .centered.column {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.ui.relaxed.grid > .column:not(.row),
+.ui.relaxed.grid > .row > .column,
+.ui.grid > .relaxed.row > .column {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+}
+.ui[class*="very relaxed"].grid > .column:not(.row),
+.ui[class*="very relaxed"].grid > .row > .column,
+.ui.grid > [class*="very relaxed"].row > .column {
+ padding-left: 2.5rem;
+ padding-right: 2.5rem;
+}
+
+.ui.relaxed.grid .row + .ui.divider,
+.ui.grid .relaxed.row + .ui.divider {
+ margin-left: 1.5rem;
+ margin-right: 1.5rem;
+}
+.ui[class*="very relaxed"].grid .row + .ui.divider,
+.ui.grid [class*="very relaxed"].row + .ui.divider {
+ margin-left: 2.5rem;
+ margin-right: 2.5rem;
+}
+
+.ui[class*="middle aligned"].grid > .column:not(.row),
+.ui[class*="middle aligned"].grid > .row > .column,
+.ui.grid > [class*="middle aligned"].row > .column,
+.ui.grid > [class*="middle aligned"].column:not(.row),
+.ui.grid > .row > [class*="middle aligned"].column {
+ flex-direction: column;
+ vertical-align: middle;
+ align-self: center !important;
+}
+
+.ui[class*="left aligned"].grid > .column,
+.ui[class*="left aligned"].grid > .row > .column,
+.ui.grid > [class*="left aligned"].row > .column,
+.ui.grid > [class*="left aligned"].column.column,
+.ui.grid > .row > [class*="left aligned"].column.column {
+ text-align: left;
+ align-self: inherit;
+}
+
+.ui[class*="center aligned"].grid > .column,
+.ui[class*="center aligned"].grid > .row > .column,
+.ui.grid > [class*="center aligned"].row > .column,
+.ui.grid > [class*="center aligned"].column.column,
+.ui.grid > .row > [class*="center aligned"].column.column {
+ text-align: center;
+ align-self: inherit;
+}
+.ui[class*="center aligned"].grid {
+ justify-content: center;
+}
+
+.ui[class*="right aligned"].grid > .column,
+.ui[class*="right aligned"].grid > .row > .column,
+.ui.grid > [class*="right aligned"].row > .column,
+.ui.grid > [class*="right aligned"].column.column,
+.ui.grid > .row > [class*="right aligned"].column.column {
+ text-align: right;
+ align-self: inherit;
+}
+
+.ui[class*="equal width"].grid > .column:not(.row),
+.ui[class*="equal width"].grid > .row > .column,
+.ui.grid > [class*="equal width"].row > .column {
+ display: inline-block;
+ flex-grow: 1;
+}
+.ui[class*="equal width"].grid > .wide.column,
+.ui[class*="equal width"].grid > .row > .wide.column,
+.ui.grid > [class*="equal width"].row > .wide.column {
+ flex-grow: 0;
+}
+
+@media only screen and (max-width: 767.98px) {
+ .ui[class*="mobile reversed"].grid,
+ .ui[class*="mobile reversed"].grid > .row,
+ .ui.grid > [class*="mobile reversed"].row {
+ flex-direction: row-reverse;
+ }
+ .ui.stackable[class*="mobile reversed"] {
+ flex-direction: column-reverse;
+ }
+}
+
+@media only screen and (max-width: 767.98px) {
+ .ui.stackable.grid {
+ width: auto;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+ }
+ .ui.stackable.grid > .row > .wide.column,
+ .ui.stackable.grid > .wide.column,
+ .ui.stackable.grid > .column.grid > .column,
+ .ui.stackable.grid > .column.row > .column,
+ .ui.stackable.grid > .row > .column,
+ .ui.stackable.grid > .column:not(.row),
+ .ui.grid > .stackable.stackable.stackable.row > .column {
+ width: 100% !important;
+ margin: 0 !important;
+ box-shadow: none !important;
+ padding: 1rem;
+ }
+ .ui.stackable.grid:not(.vertically) > .row {
+ margin: 0;
+ padding: 0;
+ }
+
+ .ui.container > .ui.stackable.grid > .column,
+ .ui.container > .ui.stackable.grid > .row > .column {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ }
+
+ .ui.grid .ui.stackable.grid,
+ .ui.segment:not(.vertical) .ui.stackable.page.grid {
+ margin-left: -1rem !important;
+ margin-right: -1rem !important;
+ }
+}
+
+.ui.ui.ui.compact.grid > .column:not(.row),
+.ui.ui.ui.compact.grid > .row > .column {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+.ui.ui.ui.compact.grid > * {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+
+.ui.ui.ui.compact.grid > .row {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.ui.ui.ui.compact.grid > .column:not(.row) {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
diff --git a/web_src/css/modules/header.css b/web_src/css/modules/header.css
new file mode 100644
index 00000000..9cec5fcb
--- /dev/null
+++ b/web_src/css/modules/header.css
@@ -0,0 +1,176 @@
+/* based on Fomantic UI header module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.header {
+ color: var(--color-text);
+ border: none;
+ margin: calc(2rem - 0.1428571428571429em) 0 1rem;
+ padding: 0;
+ font-family: var(--fonts-regular);
+ font-weight: var(--font-weight-medium);
+ line-height: 1.28571429;
+}
+
+.ui.header:first-child {
+ margin-top: -0.14285714em;
+}
+
+.ui.header:last-child {
+ margin-bottom: 0;
+}
+
+.ui.header .ui.label {
+ margin-left: 0.25rem;
+ vertical-align: middle;
+}
+
+.ui.header > .ui.label.compact {
+ margin-top: inherit;
+}
+
+.ui.header .sub.header {
+ display: block;
+ font-weight: var(--font-weight-normal);
+ padding: 0;
+ margin: 0;
+ font-size: 1rem;
+ line-height: 1.2;
+ color: var(--color-text-light-1);
+}
+
+.ui.header > i.icon {
+ display: table-cell;
+ opacity: 1;
+ font-size: 1.5em;
+ padding-top: 0;
+ vertical-align: middle;
+}
+
+.ui.header > i.icon:only-child {
+ display: inline-block;
+ padding: 0;
+ margin-right: 0.75rem;
+}
+
+.ui.header + p {
+ margin-top: 0;
+}
+
+h2.ui.header {
+ font-size: 1.71428571rem;
+}
+h2.ui.header .sub.header {
+ font-size: 1.14285714rem;
+}
+
+h4.ui.header {
+ font-size: 1.07142857rem;
+}
+h4.ui.header .sub.header {
+ font-size: 1rem;
+}
+
+.ui.sub.header {
+ padding: 0;
+ margin-bottom: 0.14285714rem;
+ font-weight: var(--font-weight-normal);
+ font-size: 0.85714286em;
+}
+
+.ui.icon.header svg {
+ width: 3em;
+ height: 3em;
+ float: none;
+ display: block;
+ line-height: var(--line-height-default);
+ padding: 0;
+ margin: 0 auto 0.5rem;
+ opacity: 1;
+}
+
+.ui.header:not(h1,h2,h3,h4,h5,h6) {
+ font-size: 1.28571429em;
+}
+
+.ui.attached.header {
+ position: relative;
+ background: var(--color-box-header);
+ padding: 0.78571429rem 1rem;
+ margin: 0 -1px;
+ border-radius: 0;
+ border: 1px solid var(--color-secondary);
+}
+
+.ui.attached:not(.top).header {
+ border-top: none;
+}
+
+.ui.top.attached.header {
+ border-radius: 0.28571429rem 0.28571429rem 0 0;
+}
+
+.ui.bottom.attached.header {
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
+
+.ui.attached.header:not(h1,h2,h3,h4,h5,h6) {
+ font-size: 1em;
+}
+
+/* fix misaligned right buttons on box headers */
+.ui.attached.header > .ui.right {
+ position: absolute;
+ right: 0.78571429rem;
+ top: 0;
+ bottom: 0;
+ display: flex;
+ align-items: center;
+ gap: 0.25em;
+}
+
+/* the default ".ui.attached.header > .ui.right" is only able to contain "tiny" buttons, other buttons are too large */
+.ui.attached.header > .ui.right .ui.tiny.button {
+ padding: 6px 10px;
+ font-weight: var(--font-weight-normal);
+}
+
+/* open dropdown menus to the left in right-attached headers */
+.ui.attached.header > .ui.right .ui.dropdown .menu {
+ right: 0;
+ left: auto;
+}
+
+/* if a .top.attached.header is followed by a .segment, add some margin */
+.ui.segments + .ui.top.attached.header,
+.ui.attached.segment + .ui.top.attached.header {
+ margin-top: 1rem;
+}
+
+.ui.dividing.header {
+ border-bottom-color: var(--color-secondary);
+}
+
+.ui.dividing.header .sub.header {
+ padding-bottom: 0.21428571rem;
+}
+
+.ui.dividing.header i.icon {
+ margin-bottom: 0;
+}
+
+.ui.error.header {
+ background: var(--color-error-bg) !important;
+ color: var(--color-error-text) !important;
+ border-color: var(--color-error-border) !important;
+}
+
+.ui.warning.header {
+ background: var(--color-warning-bg) !important;
+ color: var(--color-warning-text) !important;
+ border-color: var(--color-warning-border) !important;
+}
+
+.attention-header {
+ padding: 0.5em 0.75em !important;
+ color: var(--color-text) !important;
+}
diff --git a/web_src/css/modules/input.css b/web_src/css/modules/input.css
new file mode 100644
index 00000000..18b785ac
--- /dev/null
+++ b/web_src/css/modules/input.css
@@ -0,0 +1,197 @@
+/* based on Fomantic UI input module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.input {
+ position: relative;
+ font-weight: var(--font-weight-normal);
+ display: inline-flex;
+ color: var(--color-input-text);
+}
+.ui.input > input {
+ margin: 0;
+ max-width: 100%;
+ flex: 1 0 auto;
+ outline: none;
+ font-family: var(--fonts-regular);
+ padding: 0.67857143em 1em;
+ border: 1px solid var(--color-input-border);
+ color: var(--color-input-text);
+ border-radius: 0.28571429rem;
+ line-height: var(--line-height-default);
+ text-align: start;
+}
+
+.ui.disabled.input,
+.ui.input:not(.disabled) input[disabled] {
+ opacity: var(--opacity-disabled);
+}
+.ui.disabled.input > input,
+.ui.input:not(.disabled) input[disabled] {
+ pointer-events: none;
+}
+
+.ui.input.focus > input,
+.ui.input > input:focus {
+ border-color: var(--color-primary);
+}
+
+.ui.input.error > input {
+ background: var(--color-error-bg);
+ border-color: var(--color-error-border);
+ color: var(--color-error-text);
+}
+
+.ui.icon.input > i.icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: default;
+ position: absolute;
+ text-align: center;
+ top: 0;
+ right: 0;
+ margin: 0;
+ height: 100%;
+ width: 2.67142857em;
+ opacity: 0.5;
+ border-radius: 0 0.28571429rem 0.28571429rem 0;
+ pointer-events: none;
+ padding: 4px;
+}
+
+.ui.icon.input > i.icon.is-loading {
+ position: absolute !important;
+ height: 28px;
+ top: 4px;
+}
+
+.ui.icon.input > i.icon.is-loading > * {
+ visibility: hidden;
+}
+
+.ui.ui.ui.ui.icon.input > textarea,
+.ui.ui.ui.ui.icon.input > input {
+ padding-right: 2.67142857em;
+}
+.ui.icon.input > i.link.icon {
+ cursor: pointer;
+}
+.ui.icon.input > i.circular.icon {
+ top: 0.35em;
+ right: 0.5em;
+}
+
+.ui[class*="left icon"].input > i.icon {
+ right: auto;
+ left: 1px;
+ border-radius: 0.28571429rem 0 0 0.28571429rem;
+}
+.ui[class*="left icon"].input > i.circular.icon {
+ right: auto;
+ left: 0.5em;
+}
+.ui.ui.ui.ui[class*="left icon"].input > textarea,
+.ui.ui.ui.ui[class*="left icon"].input > input {
+ padding-left: 2.67142857em;
+ padding-right: 1em;
+}
+
+.ui.icon.input > textarea:focus ~ .icon,
+.ui.icon.input > input:focus ~ .icon {
+ opacity: 1;
+}
+
+.ui.icon.input > textarea ~ i.icon {
+ height: 3em;
+}
+
+.ui.form .field.error > .ui.action.input > .ui.button,
+.ui.action.input.error > .ui.button {
+ border-top: 1px solid var(--color-error-border);
+ border-bottom: 1px solid var(--color-error-border);
+}
+
+.ui.action.input > .button,
+.ui.action.input > .buttons {
+ display: flex;
+ align-items: center;
+ flex: 0 0 auto;
+}
+.ui.action.input > .button,
+.ui.action.input > .buttons > .button {
+ padding-top: 0.78571429em;
+ padding-bottom: 0.78571429em;
+ margin: 0;
+}
+
+.ui.action.input:not([class*="left action"]) > input {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-right-color: transparent;
+}
+
+.ui.action.input > .dropdown:first-child,
+.ui.action.input > .button:first-child,
+.ui.action.input > .buttons:first-child > .button {
+ border-radius: 0.28571429rem 0 0 0.28571429rem;
+}
+.ui.action.input > .dropdown:not(:first-child),
+.ui.action.input > .button:not(:first-child),
+.ui.action.input > .buttons:not(:first-child) > .button {
+ border-radius: 0;
+}
+.ui.action.input > .dropdown:last-child,
+.ui.action.input > .button:last-child,
+.ui.action.input > .buttons:last-child > .button {
+ border-radius: 0 0.28571429rem 0.28571429rem 0;
+}
+
+.ui.fluid.input {
+ display: flex;
+}
+.ui.fluid.input > input {
+ width: 0 !important;
+}
+
+.ui.tiny.input {
+ font-size: 0.85714286em;
+}
+.ui.small.input {
+ font-size: 0.92857143em;
+}
+
+.ui.action.input .ui.ui.button {
+ border-color: var(--color-input-border);
+ padding-top: 0; /* the ".action.input" is "flex + stretch", so let the buttons layout themselves */
+ padding-bottom: 0;
+}
+
+/* currently used for search bar dropdowns in repo search and explore code */
+.ui.action.input:not([class*="left action"]) > .ui.dropdown.selection {
+ min-width: 10em;
+}
+.ui.action.input:not([class*="left action"]) > .ui.dropdown.selection:not(:focus) {
+ border-right: none;
+}
+.ui.action.input:not([class*="left action"]) > .ui.dropdown.selection:not(.active):hover {
+ border-color: var(--color-input-border);
+}
+.ui.action.input:not([class*="left action"]) .ui.dropdown.selection.upward.visible {
+ border-bottom-left-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+}
+.ui.action.input:not([class*="left action"]) > input,
+.ui.action.input:not([class*="left action"]) > input:hover {
+ border-right: none;
+}
+.ui.action.input:not([class*="left action"]) > input:focus + .ui.dropdown.selection,
+.ui.action.input:not([class*="left action"]) > input:focus + .ui.dropdown.selection:hover,
+.ui.action.input:not([class*="left action"]) > input:focus + .button,
+.ui.action.input:not([class*="left action"]) > input:focus + .button:hover,
+.ui.action.input:not([class*="left action"]) > input:focus + .icon + .button,
+.ui.action.input:not([class*="left action"]) > input:focus + .icon + .button:hover {
+ border-left-color: var(--color-primary);
+}
+.ui.action.input:not([class*="left action"]) > input:focus {
+ border-right-color: var(--color-primary);
+}
diff --git a/web_src/css/modules/label.css b/web_src/css/modules/label.css
new file mode 100644
index 00000000..bc30baaf
--- /dev/null
+++ b/web_src/css/modules/label.css
@@ -0,0 +1,303 @@
+/* based on Fomantic UI label module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.label {
+ display: inline-flex;
+ align-items: center;
+ gap: .25rem;
+ min-width: 0;
+ vertical-align: middle;
+ line-height: 1;
+ background: var(--color-label-bg);
+ color: var(--color-label-text);
+ padding: 0.3em 0.5em;
+ font-size: 0.85714286rem;
+ font-weight: var(--font-weight-medium);
+ border: 0 solid transparent;
+ border-radius: 0.28571429rem;
+ white-space: nowrap;
+}
+
+.ui.label:first-child {
+ margin-left: 0;
+}
+.ui.label:last-child {
+ margin-right: 0;
+}
+
+a.ui.label {
+ cursor: pointer;
+}
+
+.ui.label > a {
+ cursor: pointer;
+ color: inherit;
+ opacity: 0.75;
+}
+.ui.label > a:hover {
+ opacity: 1;
+}
+
+.ui.label > img {
+ width: auto;
+ vertical-align: middle;
+ height: 2.1666em;
+}
+
+.ui.label > .color-icon {
+ margin-left: 0;
+}
+
+.ui.label > .icon {
+ width: auto;
+ margin: 0 0.75em 0 0;
+}
+
+.ui.label > .detail {
+ display: inline-block;
+ vertical-align: top;
+ font-weight: var(--font-weight-medium);
+ margin-left: 1em;
+ opacity: 0.8;
+}
+.ui.label > .detail .icon {
+ margin: 0 0.25em 0 0;
+}
+
+.ui.label > .close.icon,
+.ui.label > .delete.icon {
+ cursor: pointer;
+ font-size: 0.92857143em;
+ opacity: 0.5;
+}
+.ui.label > .close.icon:hover,
+.ui.label > .delete.icon:hover {
+ opacity: 1;
+}
+
+.ui.label.left.icon > .close.icon,
+.ui.label.left.icon > .delete.icon {
+ margin: 0 0.5em 0 0;
+}
+.ui.label:not(.icon) > .close.icon,
+.ui.label:not(.icon) > .delete.icon {
+ margin: 0 0 0 0.5em;
+}
+
+.ui.header > .ui.label {
+ margin-top: -0.29165em;
+}
+
+a.ui.label:hover {
+ background: var(--color-label-hover-bg);
+ border-color: var(--color-label-hover-bg);
+ color: var(--color-label-text);
+}
+
+.ui.label.visible:not(.dropdown) {
+ display: inline-block !important;
+}
+
+.ugc-labels .item {
+ text-overflow: unset !important;
+}
+
+.ugc-labels .item .ui.label {
+ text-wrap: auto;
+ overflow-wrap: anywhere;
+}
+
+.ui.basic.label {
+ background: var(--color-button);
+ border: 1px solid var(--color-light-border);
+ color: var(--color-text-light);
+ padding: calc(0.5833em - 1px) calc(0.833em - 1px);
+}
+a.ui.basic.label:hover {
+ text-decoration: none;
+ color: var(--color-text);
+ border-color: var(--color-light-border);
+ background: var(--color-hover);
+}
+
+.ui.ui.ui.primary.label {
+ background: var(--color-primary);
+ border-color: var(--color-primary-dark-2);
+ color: var(--color-primary-contrast);
+}
+a.ui.ui.ui.primary.label:hover {
+ background: var(--color-primary-dark-3);
+ border-color: var(--color-primary-dark-3);
+ color: var(--color-primary-contrast);
+}
+.ui.ui.ui.basic.primary.label {
+ background: transparent;
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+a.ui.ui.ui.basic.primary.label:hover {
+ background: var(--color-hover);
+ border-color: var(--color-primary-dark-1);
+ color: var(--color-primary-dark-1);
+}
+
+.ui.ui.ui.red.label {
+ background: var(--color-red);
+ border-color: var(--color-red);
+ color: var(--color-white);
+}
+a.ui.ui.ui.red.label:hover {
+ background: var(--color-red-dark-1);
+ border-color: var(--color-red-dark-1);
+ color: var(--color-white);
+}
+.ui.ui.ui.basic.red.label {
+ background: transparent;
+ border-color: var(--color-red);
+ color: var(--color-red);
+}
+a.ui.ui.ui.basic.red.label:hover {
+ background: transparent;
+ border-color: var(--color-red-dark-1);
+ color: var(--color-red-dark-1);
+}
+
+.ui.ui.ui.orange.label {
+ background: var(--color-orange);
+ border-color: var(--color-orange);
+ color: var(--color-white);
+}
+a.ui.ui.ui.orange.label:hover {
+ background: var(--color-orange-dark-1);
+ border-color: var(--color-orange-dark-1);
+ color: var(--color-white);
+}
+.ui.ui.ui.basic.orange.label {
+ background: transparent;
+ border-color: var(--color-orange);
+ color: var(--color-orange);
+}
+a.ui.ui.ui.basic.orange.label:hover {
+ background: transparent;
+ border-color: var(--color-orange-dark-1);
+ color: var(--color-orange-dark-1);
+}
+
+.ui.ui.ui.yellow.label {
+ background: var(--color-yellow);
+ border-color: var(--color-yellow);
+ color: var(--color-white);
+}
+a.ui.ui.ui.yellow.label:hover {
+ background: var(--color-yellow-dark-1);
+ border-color: var(--color-yellow-dark-1);
+ color: var(--color-white);
+}
+.ui.ui.ui.basic.yellow.label {
+ background: transparent;
+ border-color: var(--color-yellow);
+ color: var(--color-yellow);
+}
+a.ui.ui.ui.basic.yellow.label:hover {
+ background: transparent;
+ border-color: var(--color-yellow-dark-1);
+ color: var(--color-yellow-dark-1);
+}
+.ui.ui.ui.olive.label {
+ background: var(--color-olive);
+ border-color: var(--color-olive);
+ color: var(--color-white);
+}
+
+.ui.ui.ui.green.label {
+ background: var(--color-green);
+ border-color: var(--color-green);
+ color: var(--color-white);
+}
+a.ui.ui.ui.green.label:hover {
+ background: var(--color-green-dark-1);
+ border-color: var(--color-green-dark-1);
+ color: var(--color-white);
+}
+.ui.ui.ui.basic.green.label {
+ background: transparent;
+ border-color: var(--color-green);
+ color: var(--color-green);
+}
+a.ui.ui.ui.basic.green.label:hover {
+ background: transparent;
+ border-color: var(--color-green-dark-1);
+ color: var(--color-green-dark-1);
+}
+
+.ui.ui.ui.purple.label {
+ background: var(--color-purple);
+ border-color: var(--color-purple);
+ color: var(--color-white);
+}
+a.ui.ui.ui.purple.label:hover {
+ background: var(--color-purple-dark-1);
+ border-color: var(--color-purple-dark-1);
+ color: var(--color-white);
+}
+.ui.ui.ui.basic.purple.label {
+ background: transparent;
+ border-color: var(--color-purple);
+ color: var(--color-purple);
+}
+a.ui.ui.ui.basic.purple.label:hover {
+ background: transparent;
+ border-color: var(--color-purple-dark-1);
+ color: var(--color-purple-dark-1);
+}
+
+.ui.ui.ui.grey.label {
+ background: var(--color-label-bg);
+ border-color: var(--color-label-bg);
+ color: var(--color-label-text);
+}
+a.ui.ui.ui.grey.label:hover {
+ background: var(--color-label-hover-bg);
+ border-color: var(--color-label-hover-bg);
+ color: var(--color-white);
+}
+.ui.ui.ui.basic.grey.label {
+ background: transparent;
+ border-color: var(--color-label-bg);
+ color: var(--color-label-text);
+}
+a.ui.ui.ui.basic.grey.label:hover {
+ background: transparent;
+ border-color: var(--color-label-hover-bg);
+ color: var(--color-label-hover-bg);
+}
+
+.ui.horizontal.label {
+ margin: 0 0.5em 0 0;
+ padding: 0.4em 0.833em;
+ min-width: 3em;
+ text-align: center;
+}
+
+.ui.circular.label {
+ min-width: 2em;
+ min-height: 2em;
+ padding: 0.5em !important;
+ line-height: 1;
+ text-align: center;
+ border-radius: 500rem;
+ justify-content: center;
+}
+
+.ui.mini.label {
+ font-size: 0.64285714rem;
+}
+.ui.tiny.label {
+ font-size: 0.71428571rem;
+}
+.ui.small.label {
+ font-size: 0.78571429rem;
+}
+.ui.large.label {
+ font-size: 1rem;
+}
diff --git a/web_src/css/modules/list.css b/web_src/css/modules/list.css
new file mode 100644
index 00000000..32c71e80
--- /dev/null
+++ b/web_src/css/modules/list.css
@@ -0,0 +1,193 @@
+/* based on Fomantic UI list module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.list {
+ list-style-type: none;
+ margin: 1em 0;
+ padding: 0;
+ font-size: 1em;
+}
+
+.ui.list:first-child {
+ margin-top: 0;
+ padding-top: 0;
+}
+
+.ui.list:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+}
+
+.ui.list > .item,
+.ui.list .list > .item {
+ display: list-item;
+ table-layout: fixed;
+ list-style-type: none;
+ list-style-position: outside;
+}
+
+.ui.list > .list > .item::after,
+.ui.list > .item::after {
+ content: "";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+.ui.list .list:not(.icon) {
+ clear: both;
+ margin: 0;
+ padding: 0.75em 0 0.25em 0.5em;
+}
+
+.ui.list .list > .item {
+ padding: 0.14285714em 0;
+}
+
+.ui.list .list > .item > i.icon,
+.ui.list > .item > i.icon {
+ display: table-cell;
+ min-width: 1.55em;
+ padding-top: 0;
+ transition: color 0.1s ease;
+ padding-right: 0.28571429em;
+ vertical-align: top;
+}
+.ui.list .list > .item > i.icon:only-child,
+.ui.list > .item > i.icon:only-child {
+ display: inline-block;
+ min-width: auto;
+ vertical-align: top;
+}
+
+.ui.list .list > .item > .image,
+.ui.list > .item > .image {
+ display: table-cell;
+ background-color: transparent;
+ vertical-align: top;
+}
+.ui.list .list > .item > .image:not(:only-child):not(img),
+.ui.list > .item > .image:not(:only-child):not(img) {
+ padding-right: 0.5em;
+}
+.ui.list .list > .item > .image img,
+.ui.list > .item > .image img {
+ vertical-align: top;
+}
+.ui.list .list > .item > img.image,
+.ui.list .list > .item > .image:only-child,
+.ui.list > .item > img.image,
+.ui.list > .item > .image:only-child {
+ display: inline-block;
+}
+
+.ui.list .list > .item > .content,
+.ui.list > .item > .content {
+ color: var(--color-text);
+}
+.ui.list .list > .item > .image + .content,
+.ui.list .list > .item > i.icon + .content,
+.ui.list > .item > .image + .content,
+.ui.list > .item > i.icon + .content {
+ display: table-cell;
+ width: 100%;
+ padding: 0 0 0 0.5em;
+ vertical-align: top;
+}
+.ui.list .list > .item > img.image + .content,
+.ui.list > .item > img.image + .content {
+ display: inline-block;
+ width: auto;
+}
+.ui.list .list > .item > .content > .list,
+.ui.list > .item > .content > .list {
+ margin-left: 0;
+ padding-left: 0;
+}
+
+.ui.list .list > .item .header,
+.ui.list > .item .header {
+ display: block;
+ margin: 0;
+ font-family: var(--fonts-regular);
+ font-weight: var(--font-weight-medium);
+ color: var(--color-text-dark);
+}
+
+.ui.list .list > .item .description,
+.ui.list > .item .description {
+ display: block;
+ color: var(--color-text);
+}
+
+.ui.list > .item a,
+.ui.list .list > .item a {
+ cursor: pointer;
+}
+
+.ui.list .list > .item [class*="right floated"],
+.ui.list > .item [class*="right floated"] {
+ float: right;
+ margin: 0 0 0 1em;
+}
+
+.ui.menu .ui.list > .item,
+.ui.menu .ui.list .list > .item {
+ display: list-item;
+ table-layout: fixed;
+ background-color: transparent;
+ list-style-type: none;
+ list-style-position: outside;
+ padding: 0.21428571em 0;
+}
+.ui.menu .ui.list .list > .item::before,
+.ui.menu .ui.list > .item::before {
+ border: none;
+ background: none;
+}
+.ui.menu .ui.list .list > .item:first-child,
+.ui.menu .ui.list > .item:first-child {
+ padding-top: 0;
+}
+.ui.menu .ui.list .list > .item:last-child,
+.ui.menu .ui.list > .item:last-child {
+ padding-bottom: 0;
+}
+
+.ui.list .list > .disabled.item,
+.ui.list > .disabled.item {
+ pointer-events: none;
+ opacity: var(--opacity-disabled);
+}
+
+.ui.list .list > a.item:hover > .icons,
+.ui.list > a.item:hover > .icons,
+.ui.list .list > a.item:hover > i.icon,
+.ui.list > a.item:hover > i.icon {
+ color: var(--color-text-dark);
+}
+
+.ui.divided.list > .item {
+ border-top: 1px solid var(--color-secondary);
+}
+.ui.divided.list .list > .item {
+ border-top: none;
+}
+.ui.divided.list .item .list > .item {
+ border-top: none;
+}
+.ui.divided.list .list > .item:first-child,
+.ui.divided.list > .item:first-child {
+ border-top: none;
+}
+.ui.divided.list .list > .item:first-child {
+ border-top-width: 1px;
+}
+
+.ui.relaxed.list > .item:not(:first-child) {
+ padding-top: 0.42857143em;
+}
+.ui.relaxed.list > .item:not(:last-child) {
+ padding-bottom: 0.42857143em;
+}
diff --git a/web_src/css/modules/message.css b/web_src/css/modules/message.css
new file mode 100644
index 00000000..c62dbddd
--- /dev/null
+++ b/web_src/css/modules/message.css
@@ -0,0 +1,114 @@
+/* based on Fomantic UI message module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.message {
+ background: var(--color-box-body);
+ color: var(--color-text);
+ border: 1px solid var(--color-secondary);
+ position: relative;
+ min-height: 1em;
+ margin: 1em 0;
+ padding: 1em 1.5em;
+ border-radius: var(--border-radius);
+}
+
+.ui.message:first-child {
+ margin-top: 0;
+}
+
+.ui.message:last-child {
+ margin-bottom: 0;
+}
+
+.ui.attached.message {
+ margin-bottom: -1px;
+ border-radius: var(--border-radius) var(--border-radius) 0 0;
+ margin-left: -1px;
+ margin-right: -1px;
+}
+
+.ui.attached + .ui.attached.message:not(.top):not(.bottom) {
+ margin-top: -1px;
+ border-radius: 0;
+}
+
+.ui.bottom.attached.message {
+ margin-top: -1px;
+ border-radius: 0 0 var(--border-radius) var(--border-radius);
+}
+
+.ui.bottom.attached.message:not(:last-child) {
+ margin-bottom: 1em;
+}
+
+.ui.info.message .header,
+.ui.blue.message .header {
+ color: var(--color-blue);
+}
+
+.ui.info.message,
+.ui.attached.info.message,
+.ui.blue.message,
+.ui.attached.blue.message {
+ background: var(--color-info-bg);
+ color: var(--color-info-text);
+ border-color: var(--color-info-border);
+}
+
+.ui.success.message .header,
+.ui.positive.message .header,
+.ui.green.message .header {
+ color: var(--color-green);
+}
+
+.ui.success.message,
+.ui.attached.success.message,
+.ui.positive.message,
+.ui.attached.positive.message {
+ background: var(--color-success-bg);
+ color: var(--color-success-text);
+ border-color: var(--color-success-border);
+}
+
+.ui.error.message .header,
+.ui.negative.message .header,
+.ui.red.message .header {
+ color: var(--color-red);
+}
+
+.ui.error.message,
+.ui.attached.error.message,
+.ui.red.message,
+.ui.attached.red.message,
+.ui.negative.message,
+.ui.attached.negative.message {
+ background: var(--color-error-bg);
+ color: var(--color-error-text);
+ border-color: var(--color-error-border);
+}
+
+.ui.warning.message .header,
+.ui.yellow.message .header {
+ color: var(--color-yellow);
+}
+
+.ui.warning.message,
+.ui.attached.warning.message,
+.ui.yellow.message,
+.ui.attached.yellow.message {
+ background: var(--color-warning-bg);
+ color: var(--color-warning-text);
+ border-color: var(--color-warning-border);
+}
+
+.ui.message > .close.icon {
+ cursor: pointer;
+ position: absolute;
+ top: 9px;
+ right: 9px;
+ opacity: .7;
+}
+
+.ui.message > .close.icon:hover {
+ opacity: 1;
+}
diff --git a/web_src/css/modules/modal.css b/web_src/css/modules/modal.css
new file mode 100644
index 00000000..54a4ef81
--- /dev/null
+++ b/web_src/css/modules/modal.css
@@ -0,0 +1,86 @@
+.ui.modal.g-modal-confirm {
+ max-width: min(800px, 90vw);
+ width: fit-content;
+}
+
+.ui.modal.g-modal-confirm > .inside.close.icon {
+ padding: 0;
+ width: 1em;
+ height: 1em;
+ top: 1.2em;
+}
+
+.ui.modal > .close.icon[height="16"] {
+ top: 0.7em; /* fomantic uses absolute layout, so if we have special icon size, it needs this trick to align vertically */
+ color: var(--color-text-dark);
+}
+
+.ui.modal > .header {
+ /* can't use display:flex, because some headers have space-separated elements, eg: delete branch modal */
+ color: var(--color-text-dark);
+ background: var(--color-body);
+ border-color: var(--color-secondary);
+ border-top-left-radius: var(--border-radius);
+ border-top-right-radius: var(--border-radius);
+ vertical-align: middle;
+}
+
+.ui.modal > .header .svg {
+ vertical-align: middle;
+ display: inline-block;
+}
+
+.ui.modal {
+ background: var(--color-body);
+ box-shadow: 1px 3px 3px 0 var(--color-shadow), 1px 3px 15px 2px var(--color-shadow);
+}
+
+/* Gitea sometimes use a form in a modal dialog, then the "positive" button could submit the form directly
+Fomantic UI only supports the layout: <div .modal><div .content/><div .actions/></div>
+However, Gitea uses the following layouts:
+* <div .modal><div .content><div .actions/></div></div>
+* <div .modal><form><div .content/><div .actions/></form></div>
+* <div .modal><div .content><form><div .actions/></form></div></div>
+* <div .modal><div .content></div><form><div .actions/></form></div>
+* ...
+These inconsistent layouts should be refactored to simple ones.
+*/
+
+.ui.modal > .content,
+.ui.modal form > .content {
+ padding: 1.5em;
+ background: var(--color-body);
+}
+
+.ui.modal > .actions,
+.ui.modal .content + .actions,
+.ui.modal .content + form > .actions {
+ background: var(--color-secondary-bg);
+ border-color: var(--color-secondary);
+ padding: 1rem;
+ text-align: right;
+}
+
+.ui.modal .content > .actions {
+ padding-top: 1em; /* if the "actions" is in the "content", some paddings are already added by the "content" */
+ text-align: right;
+}
+
+/* positive/negative action buttons */
+.ui.modal .actions > .ui.button {
+ display: inline-flex;
+ align-items: center;
+ padding: 10px 12px 10px 10px;
+ margin-right: 0;
+}
+
+.ui.modal .actions > .ui.button.danger {
+ display: block;
+ width: 100%;
+ margin: 0 auto;
+ text-align: center;
+}
+
+.ui.modal .actions > .ui.button .svg {
+ margin-right: 5px;
+}
diff --git a/web_src/css/modules/navbar.css b/web_src/css/modules/navbar.css
new file mode 100644
index 00000000..02d470f5
--- /dev/null
+++ b/web_src/css/modules/navbar.css
@@ -0,0 +1,147 @@
+#navbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: var(--color-nav-bg);
+ border-bottom: 1px solid var(--color-secondary);
+ margin: 0 !important;
+ padding: 0 10px;
+}
+
+#navbar,
+#navbar .navbar-left,
+#navbar .navbar-right {
+ min-height: 49px; /* +1px border-bottom */
+}
+
+#navbar .navbar-left,
+#navbar .navbar-right {
+ margin: 0;
+ display: flex;
+ align-items: center;
+}
+
+#navbar-logo {
+ margin: 0;
+}
+
+#navbar .item {
+ min-height: 36px;
+ min-width: 36px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ display: flex;
+}
+
+#navbar > .menu > .item {
+ color: var(--color-nav-text);
+}
+
+#navbar .dropdown .item {
+ justify-content: stretch;
+}
+
+#navbar a.item:hover, #navbar a.item:focus,
+#navbar button.item:hover, #navbar button.item:focus {
+ background: var(--color-nav-hover-bg);
+}
+
+#navbar .secondary.menu > .item > .svg,
+#navbar .right.menu > .item > .svg {
+ margin-right: 0;
+}
+
+@media (max-width: 767.98px) {
+ #navbar {
+ align-items: stretch;
+ }
+ /* hide all items */
+ #navbar .item {
+ display: none;
+ }
+ #navbar #navbar-logo {
+ display: flex;
+ }
+ /* show the first navbar item (logo and its mobile right items) */
+ #navbar .navbar-left {
+ flex: 1;
+ display: flex;
+ justify-content: space-between;
+ }
+ #navbar .navbar-mobile-right {
+ display: flex;
+ margin-left: auto !important;
+ width: auto !important;
+ }
+ #navbar .navbar-mobile-right > .item {
+ display: flex;
+ width: auto !important;
+ }
+ /* show items if the navbar is open */
+ #navbar.navbar-menu-open {
+ padding-bottom: 8px;
+ }
+ #navbar.navbar-menu-open,
+ #navbar.navbar-menu-open .navbar-right {
+ flex-direction: column;
+ }
+ #navbar.navbar-menu-open .navbar-left {
+ display: flex;
+ flex-wrap: wrap;
+ }
+ #navbar.navbar-menu-open .item {
+ display: flex;
+ width: 100%;
+ margin: 0;
+ }
+ #navbar.navbar-menu-open .navbar-left #navbar-logo {
+ justify-content: flex-start;
+ width: auto;
+ }
+ #navbar.navbar-menu-open .navbar-left .navbar-mobile-right {
+ justify-content: flex-end;
+ width: 50%;
+ min-height: 48px;
+ }
+ #navbar #mobile-notifications-icon {
+ margin-right: 6px !important;
+ }
+}
+
+#navbar a.item .notification_count {
+ color: var(--color-nav-bg);
+ padding: 0 3.75px;
+ font-size: 12px;
+ line-height: 12px;
+ font-weight: var(--font-weight-bold);
+}
+
+#navbar a.item:hover .notification_count,
+#navbar a.item:hover .header-stopwatch-dot {
+ border-color: var(--color-nav-hover-bg);
+}
+
+#navbar a.item .notification_count,
+#navbar a.item .header-stopwatch-dot {
+ background: var(--color-primary);
+ border: 2px solid var(--color-nav-bg);
+ position: absolute;
+ left: 6px;
+ top: -9px;
+ min-width: 17px;
+ height: 17px;
+ border-radius: 11px; /* (height + 2 * borderThickness) / 2 */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1; /* prevent menu button background from overlaying icon */
+}
+
+.secondary-nav {
+ background: var(--color-secondary-nav-bg) !important; /* important because of .ui.secondary.menu */
+}
+
+.issue-navbar {
+ display: flex;
+ justify-content: space-between;
+}
diff --git a/web_src/css/modules/normalize.css b/web_src/css/modules/normalize.css
new file mode 100644
index 00000000..63fb04a5
--- /dev/null
+++ b/web_src/css/modules/normalize.css
@@ -0,0 +1,243 @@
+/*
+ This is copy of modern-normalize with these changes done:
+
+ - Remove html font-family, we set our own
+ - Remove html tab-size, we set our own
+ - Remove b,strong font-weight, we set our own
+ - Remove b,code,samp,pre font-size, we set our own
+*/
+
+/*! modern-normalize v2.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
+
+/*
+Document
+========
+*/
+
+/**
+Use a better box model (opinionated).
+*/
+
+*,
+::before,
+::after {
+ box-sizing: border-box;
+}
+
+html {
+ line-height: normal; /* 1. (not following the "modern-normalize") Do not change the browser's default line-height, the default value is font-dependent and roughly 1.2 */
+ -webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */
+}
+
+/*
+Sections
+========
+*/
+
+body {
+ margin: 0; /* Remove the margin in all browsers. */
+}
+
+/*
+Grouping content
+================
+*/
+
+/**
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+*/
+
+hr {
+ height: 0; /* 1 */
+ color: inherit; /* 2 */
+}
+
+/*
+Text-level semantics
+====================
+*/
+
+/**
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr[title] {
+ text-decoration: underline dotted;
+}
+
+/**
+Add the correct font size in all browsers.
+*/
+
+small {
+ font-size: 80%;
+}
+
+/**
+Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/*
+Tabular data
+============
+*/
+
+/**
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+*/
+
+table {
+ text-indent: 0; /* 1 */
+ border-color: inherit; /* 2 */
+}
+
+/*
+Forms
+=====
+*/
+
+/**
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+}
+
+/**
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+ text-transform: none;
+}
+
+/**
+Correct the inability to style clickable types in iOS and Safari.
+*/
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+/**
+Remove the inner border and padding in Firefox.
+*/
+
+::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+Restore the focus styles unset by the previous rule.
+*/
+
+:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+Remove the additional ':invalid' styles in Firefox.
+See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737
+*/
+
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+/**
+Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
+*/
+
+legend {
+ padding: 0;
+}
+
+/**
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to 'inherit' in Safari.
+*/
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/*
+Interactive
+===========
+*/
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+ display: list-item;
+}
diff --git a/web_src/css/modules/segment.css b/web_src/css/modules/segment.css
new file mode 100644
index 00000000..04543f09
--- /dev/null
+++ b/web_src/css/modules/segment.css
@@ -0,0 +1,203 @@
+/* based on Fomantic UI segment module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.segment {
+ position: relative;
+ margin: 1rem 0;
+ padding: 1em;
+ border-radius: 0.28571429rem;
+ border: 1px solid var(--color-secondary);
+ background: var(--color-box-body);
+ color: var(--color-text);
+}
+.ui.segment:first-child {
+ margin-top: 0;
+}
+.ui.segment:last-child {
+ margin-bottom: 0;
+}
+
+.ui.grid.segment {
+ margin: 1rem 0;
+ border-radius: 0.28571429rem;
+}
+
+.ui.segment.tab:last-child {
+ margin-bottom: 1rem;
+}
+
+.ui.segments {
+ flex-direction: column;
+ position: relative;
+ margin: 1rem 0;
+ border: 1px solid var(--color-secondary);
+ border-radius: 0.28571429rem;
+ background: var(--color-box-body);
+ color: var(--color-text);
+}
+.ui.segments:first-child {
+ margin-top: 0;
+}
+.ui.segments:last-child {
+ margin-bottom: 0;
+}
+
+.ui.segments > .segment {
+ top: 0;
+ bottom: 0;
+ border-radius: 0;
+ margin: 0;
+ width: auto;
+ box-shadow: none;
+ border: none;
+ border-top: 1px solid var(--color-secondary);
+}
+.ui.segments:not(.horizontal) > .segment:first-child {
+ top: 0;
+ bottom: 0;
+ border-top: none;
+ margin-top: 0;
+ margin-bottom: 0;
+ border-radius: 0.28571429rem 0.28571429rem 0 0;
+}
+
+.ui.segments:not(.horizontal) > .segment:last-child {
+ top: 0;
+ bottom: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
+
+.ui.segments:not(.horizontal) > .segment:only-child {
+ border-radius: 0.214285717rem;
+}
+.ui.segments:not(.horizontal) > .segment:has(~ .tw-hidden) { /* workaround issue with :last-child ignoring hidden elements */
+ border-radius: 0.28571429rem;
+}
+
+.ui.segments > .ui.segments {
+ border-top: 1px solid var(--color-secondary);
+ margin: 1rem;
+}
+.ui.segments > .segments:first-child {
+ border-top: none;
+}
+.ui.segments > .segment + .segments:not(.horizontal) {
+ margin-top: 0;
+}
+
+.ui.horizontal.segments {
+ display: flex;
+ flex-direction: row;
+ background-color: transparent;
+ padding: 0;
+ margin: 1rem 0;
+ border-radius: 0.28571429rem;
+ border: 1px solid var(--color-secondary);
+}
+
+.ui.horizontal.segments > .segment {
+ margin: 0;
+ min-width: 0;
+ border-radius: 0;
+ border: none;
+ box-shadow: none;
+ border-left: 1px solid var(--color-secondary);
+}
+
+.ui.segments > .horizontal.segments:first-child {
+ border-top: none;
+}
+.ui.horizontal.segments:not(.stackable) > .segment:first-child {
+ border-left: none;
+}
+.ui.horizontal.segments > .segment:first-child {
+ border-radius: 0.28571429rem 0 0 0.28571429rem;
+}
+.ui.horizontal.segments > .segment:last-child {
+ border-radius: 0 0.28571429rem 0.28571429rem 0;
+}
+
+.ui.clearing.segment::after {
+ content: "";
+ display: block;
+ clear: both;
+}
+
+.ui[class*="left aligned"].segment {
+ text-align: left;
+}
+.ui[class*="center aligned"].segment {
+ text-align: center;
+}
+
+.ui.secondary.segment {
+ background: var(--color-secondary-bg);
+ color: var(--color-text-light);
+}
+
+.ui.attached.segment {
+ top: 0;
+ bottom: 0;
+ border-radius: 0;
+ margin: 0 -1px;
+ width: calc(100% + 2px);
+ max-width: calc(100% + 2px);
+ box-shadow: none;
+ border: 1px solid var(--color-secondary);
+ background: var(--color-box-body);
+ color: var(--color-text);
+}
+.ui.attached:not(.message) + .ui.attached.segment:not(.top) {
+ border-top: none;
+}
+
+.ui.attached.segment:has(+ .ui[class*="top attached"].header),
+.ui.attached.segment:last-child {
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
+
+.ui[class*="top attached"].segment {
+ bottom: 0;
+ margin-bottom: 0;
+ top: 0;
+ margin-top: 1rem;
+ border-radius: 0.28571429rem 0.28571429rem 0 0;
+}
+.ui.segment[class*="top attached"]:first-child {
+ margin-top: 0;
+}
+
+.ui.segment[class*="bottom attached"] {
+ bottom: 0;
+ margin-top: 0;
+ top: 0;
+ margin-bottom: 1rem;
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
+.ui.segment[class*="bottom attached"]:last-child {
+ margin-bottom: 1rem;
+}
+
+.ui.fitted.segment:not(.horizontally) {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+.ui.fitted.segment:not(.vertically) {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.ui.segments .segment,
+.ui.segment {
+ font-size: 1rem;
+}
+
+.ui.error.segment {
+ border-color: var(--color-error-border) !important;
+}
+
+.ui.warning.segment {
+ border-color: var(--color-warning-border) !important;
+}
diff --git a/web_src/css/modules/select.css b/web_src/css/modules/select.css
new file mode 100644
index 00000000..1d7d749d
--- /dev/null
+++ b/web_src/css/modules/select.css
@@ -0,0 +1,25 @@
+.gitea-select {
+ position: relative;
+}
+
+.gitea-select select {
+ appearance: none; /* hide default triangle */
+}
+
+/* ::before and ::after pseudo elements don't work on select elements,
+ so we need to put it on the parent. */
+.gitea-select::after {
+ position: absolute;
+ top: 12px;
+ right: 8px;
+ pointer-events: none;
+ content: "";
+ width: 14px;
+ height: 14px;
+ mask-size: cover;
+ -webkit-mask-size: cover;
+ mask-image: var(--octicon-chevron-right);
+ -webkit-mask-image: var(--octicon-chevron-right);
+ transform: rotate(90deg); /* point the chevron down */
+ background: currentcolor;
+}
diff --git a/web_src/css/modules/svg.css b/web_src/css/modules/svg.css
new file mode 100644
index 00000000..b3060bdd
--- /dev/null
+++ b/web_src/css/modules/svg.css
@@ -0,0 +1,41 @@
+.svg {
+ display: inline-block;
+ vertical-align: text-top;
+ fill: currentcolor;
+}
+
+.middle .svg {
+ vertical-align: middle;
+}
+
+/* prevent SVGs from shrinking, like in space-starved flexboxes. the sizes
+ here are cherry-picked for our use cases, feel free to add more. after
+ https://developer.mozilla.org/en-US/docs/Web/CSS/attr#type-or-unit is
+ supported in browsers, use `attr(width px)` instead for a generic
+ solution. */
+
+.svg[height="12"] { min-height: 12px; }
+.svg[height="13"] { min-height: 13px; }
+.svg[height="14"] { min-height: 14px; }
+.svg[height="15"] { min-height: 15px; }
+.svg[height="16"] { min-height: 16px; }
+.svg[height="18"] { min-height: 18px; }
+.svg[height="20"] { min-height: 20px; }
+.svg[height="22"] { min-height: 22px; }
+.svg[height="24"] { min-height: 24px; }
+.svg[height="36"] { min-height: 36px; }
+.svg[height="48"] { min-height: 48px; }
+.svg[height="56"] { min-height: 56px; }
+
+.svg[width="12"] { min-width: 12px; }
+.svg[width="13"] { min-width: 13px; }
+.svg[width="14"] { min-width: 14px; }
+.svg[width="15"] { min-width: 15px; }
+.svg[width="16"] { min-width: 16px; }
+.svg[width="18"] { min-width: 18px; }
+.svg[width="20"] { min-width: 20px; }
+.svg[width="22"] { min-width: 22px; }
+.svg[width="24"] { min-width: 24px; }
+.svg[width="36"] { min-width: 36px; }
+.svg[width="48"] { min-width: 48px; }
+.svg[width="56"] { min-width: 56px; }
diff --git a/web_src/css/modules/table.css b/web_src/css/modules/table.css
new file mode 100644
index 00000000..4fb9d421
--- /dev/null
+++ b/web_src/css/modules/table.css
@@ -0,0 +1,385 @@
+/* based on Fomantic UI segment module, with just the parts extracted that we use. If you find any
+ unused rules here after refactoring, please remove them. */
+
+.ui.table {
+ width: 100%;
+ margin: 1em 0;
+ border: 1px solid var(--color-secondary);
+ border-radius: 0.28571429rem;
+ vertical-align: middle;
+ border-collapse: separate;
+ border-spacing: 0;
+ color: var(--color-text);
+ background: var(--color-box-body);
+ border-color: var(--color-secondary);
+ text-align: start;
+}
+
+.ui.table:first-child {
+ margin-top: 0;
+}
+.ui.table:last-child {
+ margin-bottom: 0;
+}
+.ui.table > thead,
+.ui.table > tbody {
+ text-align: inherit;
+ vertical-align: inherit;
+}
+
+.ui.table > thead > tr > th {
+ background: var(--color-box-header);
+ text-align: inherit;
+ color: var(--color-text);
+ padding: 6px 5px;
+ vertical-align: inherit;
+ font-weight: var(--font-weight-normal);
+ border-bottom: 1px solid var(--color-secondary);
+ border-left: none;
+}
+.ui.table > thead > tr > th:first-child {
+ border-left: none;
+}
+.ui.table > thead > tr:first-child > th:first-child {
+ border-radius: 0.28571429rem 0 0;
+}
+.ui.table > thead > tr:first-child > th:last-child {
+ border-radius: 0 0.28571429rem 0 0;
+}
+.ui.table > thead > tr:first-child > th:only-child {
+ border-radius: 0.28571429rem 0.28571429rem 0 0;
+}
+
+.ui.table > tfoot > tr > th,
+.ui.table > tfoot > tr > td {
+ border-top: 1px solid var(--color-secondary);
+ background: var(--color-box-body);
+ text-align: inherit;
+ color: var(--color-text);
+ padding: 0.78571429em;
+ vertical-align: inherit;
+ font-weight: var(--font-weight-normal);
+}
+.ui.table > tfoot > tr > th:first-child,
+.ui.table > tfoot > tr > td:first-child {
+ border-left: none;
+}
+.ui.table > tfoot > tr:first-child > th:first-child,
+.ui.table > tfoot > tr:first-child > td:first-child {
+ border-radius: 0 0 0 0.28571429rem;
+}
+.ui.table > tfoot > tr:first-child > th:last-child,
+.ui.table > tfoot > tr:first-child > td:last-child {
+ border-radius: 0 0 0.28571429rem;
+}
+.ui.table > tfoot > tr:first-child > th:only-child,
+.ui.table > tfoot > tr:first-child > td:only-child {
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
+
+.ui.table > tr > td,
+.ui.table > tbody > tr > td {
+ border-top: 1px solid var(--color-secondary-alpha-50);
+ padding: 6px 5px;
+ text-align: inherit;
+}
+.ui.table > tr:first-child > td,
+.ui.table > tbody > tr:first-child > td {
+ border-top: none;
+}
+
+.ui.table.segment {
+ padding: 0;
+}
+.ui.table.segment::after {
+ display: none;
+}
+
+@media only screen and (max-width: 767.98px) {
+ .ui.table:not(.unstackable) {
+ width: 100%;
+ padding: 0;
+ }
+ .ui.table:not(.unstackable) > thead,
+ .ui.table:not(.unstackable) > thead > tr,
+ .ui.table:not(.unstackable) > tfoot,
+ .ui.table:not(.unstackable) > tfoot > tr,
+ .ui.table:not(.unstackable) > tbody,
+ .ui.table:not(.unstackable) > tr,
+ .ui.table:not(.unstackable) > tbody > tr,
+ .ui.table:not(.unstackable) > tr > th,
+ .ui.table:not(.unstackable) > thead > tr > th,
+ .ui.table:not(.unstackable) > tbody > tr > th,
+ .ui.table:not(.unstackable) > tfoot > tr > th,
+ .ui.table:not(.unstackable) > tr > td,
+ .ui.table:not(.unstackable) > tbody > tr > td,
+ .ui.table:not(.unstackable) > tfoot > tr > td {
+ display: block !important;
+ width: auto !important;
+ }
+ .ui.table:not(.unstackable) > thead {
+ display: block;
+ }
+ .ui.table:not(.unstackable) > tfoot {
+ display: block;
+ }
+ .ui.ui.ui.ui.table:not(.unstackable) > tr,
+ .ui.ui.ui.ui.table:not(.unstackable) > thead > tr,
+ .ui.ui.ui.ui.table:not(.unstackable) > tbody > tr,
+ .ui.ui.ui.ui.table:not(.unstackable) > tfoot > tr {
+ padding-top: 1em;
+ padding-bottom: 1em;
+ }
+ .ui.ui.ui.ui.table:not(.unstackable) > tr > th,
+ .ui.ui.ui.ui.table:not(.unstackable) > thead > tr > th,
+ .ui.ui.ui.ui.table:not(.unstackable) > tbody > tr > th,
+ .ui.ui.ui.ui.table:not(.unstackable) > tfoot > tr > th,
+ .ui.ui.ui.ui.table:not(.unstackable) > tr > td,
+ .ui.ui.ui.ui.table:not(.unstackable) > tbody > tr > td,
+ .ui.ui.ui.ui.table:not(.unstackable) > tfoot > tr > td {
+ background: none;
+ border: none;
+ padding: 0.25em 0.75em;
+ }
+ .ui.table:not(.unstackable) > tr > th:first-child,
+ .ui.table:not(.unstackable) > thead > tr > th:first-child,
+ .ui.table:not(.unstackable) > tbody > tr > th:first-child,
+ .ui.table:not(.unstackable) > tfoot > tr > th:first-child,
+ .ui.table:not(.unstackable) > tr > td:first-child,
+ .ui.table:not(.unstackable) > tbody > tr > td:first-child,
+ .ui.table:not(.unstackable) > tfoot > tr > td:first-child {
+ font-weight: var(--font-weight-normal);
+ }
+}
+
+.ui.table[class*="left aligned"],
+.ui.table [class*="left aligned"] {
+ text-align: left;
+}
+
+.ui.table[class*="center aligned"],
+.ui.table [class*="center aligned"] {
+ text-align: center;
+}
+
+.ui.table[class*="right aligned"],
+.ui.table [class*="right aligned"] {
+ text-align: right;
+}
+
+.ui.table[class*="top aligned"],
+.ui.table [class*="top aligned"] {
+ vertical-align: top;
+}
+
+.ui.table[class*="middle aligned"],
+.ui.table [class*="middle aligned"] {
+ vertical-align: middle;
+}
+
+.ui.table th.collapsing,
+.ui.table td.collapsing {
+ width: 1px;
+ white-space: nowrap;
+}
+
+.ui.fixed.table {
+ table-layout: fixed;
+}
+.ui.fixed.table th,
+.ui.fixed.table td {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.ui.attached.table {
+ top: 0;
+ bottom: 0;
+ border-radius: 0;
+ margin: 0 -1px;
+ width: calc(100% + 2px);
+ max-width: calc(100% + 2px);
+ border: 1px solid var(--color-secondary);
+}
+.ui.attached + .ui.attached.table:not(.top) {
+ border-top: none;
+}
+
+.ui[class*="bottom attached"].table {
+ bottom: 0;
+ margin-top: 0;
+ top: 0;
+ margin-bottom: 1em;
+ border-radius: 0 0 0.28571429rem 0.28571429rem;
+}
+.ui[class*="bottom attached"].table:last-child {
+ margin-bottom: 0;
+}
+
+.ui.striped.table > tr:nth-child(2n),
+.ui.striped.table > tbody > tr:nth-child(2n) {
+ background: var(--color-light);
+}
+
+.ui.table[class*="single line"],
+.ui.table [class*="single line"] {
+ white-space: nowrap;
+}
+
+/* Column Width */
+.ui.table th.one.wide,
+.ui.table td.one.wide {
+ width: 6.25%;
+}
+.ui.table th.two.wide,
+.ui.table td.two.wide {
+ width: 12.5%;
+}
+.ui.table th.three.wide,
+.ui.table td.three.wide {
+ width: 18.75%;
+}
+.ui.table th.four.wide,
+.ui.table td.four.wide {
+ width: 25%;
+}
+.ui.table th.five.wide,
+.ui.table td.five.wide {
+ width: 31.25%;
+}
+.ui.table th.six.wide,
+.ui.table td.six.wide {
+ width: 37.5%;
+}
+.ui.table th.seven.wide,
+.ui.table td.seven.wide {
+ width: 43.75%;
+}
+.ui.table th.eight.wide,
+.ui.table td.eight.wide {
+ width: 50%;
+}
+.ui.table th.nine.wide,
+.ui.table td.nine.wide {
+ width: 56.25%;
+}
+.ui.table th.ten.wide,
+.ui.table td.ten.wide {
+ width: 62.5%;
+}
+.ui.table th.eleven.wide,
+.ui.table td.eleven.wide {
+ width: 68.75%;
+}
+.ui.table th.twelve.wide,
+.ui.table td.twelve.wide {
+ width: 75%;
+}
+.ui.table th.thirteen.wide,
+.ui.table td.thirteen.wide {
+ width: 81.25%;
+}
+.ui.table th.fourteen.wide,
+.ui.table td.fourteen.wide {
+ width: 87.5%;
+}
+.ui.table th.fifteen.wide,
+.ui.table td.fifteen.wide {
+ width: 93.75%;
+}
+.ui.table th.sixteen.wide,
+.ui.table td.sixteen.wide {
+ width: 100%;
+}
+
+.ui.basic.table {
+ background: transparent;
+ border: 1px solid var(--color-secondary);
+}
+.ui.basic.table > thead > tr > th,
+.ui.basic.table > tbody > tr > th,
+.ui.basic.table > tfoot > tr > th,
+.ui.basic.table > tr > th {
+ background: transparent;
+ border-left: none;
+}
+.ui.basic.table > tbody > tr {
+ border-bottom: 1px solid var(--color-secondary);
+}
+.ui.basic.table > tbody > tr > td,
+.ui.basic.table > tfoot > tr > td,
+.ui.basic.table > tr > td {
+ background: transparent;
+}
+.ui.basic.striped.table > tbody > tr:nth-child(2n) {
+ background: var(--color-light);
+}
+
+.ui[class*="very basic"].table {
+ border: none;
+}
+.ui[class*="very basic"].table:not(.striped) > tr > th:first-child,
+.ui[class*="very basic"].table:not(.striped) > thead > tr > th:first-child,
+.ui[class*="very basic"].table:not(.striped) > tbody > tr > th:first-child,
+.ui[class*="very basic"].table:not(.striped) > tfoot > tr > th:first-child,
+.ui[class*="very basic"].table:not(.striped) > tr > td:first-child,
+.ui[class*="very basic"].table:not(.striped) > tbody > tr > td:first-child,
+.ui[class*="very basic"].table:not(.striped) > tfoot > tr > td:first-child {
+ padding-left: 0;
+}
+.ui[class*="very basic"].table:not(.striped) > tr > th:last-child,
+.ui[class*="very basic"].table:not(.striped) > thead > tr > th:last-child,
+.ui[class*="very basic"].table:not(.striped) > tbody > tr > th:last-child,
+.ui[class*="very basic"].table:not(.striped) > tfoot > tr > th:last-child,
+.ui[class*="very basic"].table:not(.striped) > tr > td:last-child,
+.ui[class*="very basic"].table:not(.striped) > tbody > tr > td:last-child,
+.ui[class*="very basic"].table:not(.striped) > tfoot > tr > td:last-child {
+ padding-right: 0;
+}
+.ui[class*="very basic"].table:not(.striped) > thead > tr:first-child > th {
+ padding-top: 0;
+}
+
+.ui.celled.table > tr > th,
+.ui.celled.table > thead > tr > th,
+.ui.celled.table > tbody > tr > th,
+.ui.celled.table > tfoot > tr > th,
+.ui.celled.table > tr > td,
+.ui.celled.table > tbody > tr > td,
+.ui.celled.table > tfoot > tr > td {
+ border-left: 1px solid var(--color-secondary-alpha-50);
+}
+.ui.celled.table > tr > th:first-child,
+.ui.celled.table > thead > tr > th:first-child,
+.ui.celled.table > tbody > tr > th:first-child,
+.ui.celled.table > tfoot > tr > th:first-child,
+.ui.celled.table > tr > td:first-child,
+.ui.celled.table > tbody > tr > td:first-child,
+.ui.celled.table > tfoot > tr > td:first-child {
+ border-left: none;
+}
+
+.ui.compact.table > tr > th,
+.ui.compact.table > thead > tr > th,
+.ui.compact.table > tbody > tr > th,
+.ui.compact.table > tfoot > tr > th {
+ padding-left: 0.7em;
+ padding-right: 0.7em;
+}
+.ui.compact.table > tr > td,
+.ui.compact.table > tbody > tr > td,
+.ui.compact.table > tfoot > tr > td {
+ padding: 0.5em 0.7em;
+}
+
+/* use more horizontal padding on first and last items for visuals */
+.ui.table > thead > tr > th:first-of-type,
+.ui.table > tbody > tr > td:first-of-type,
+.ui.table > tr > td:first-of-type {
+ padding-left: 10px;
+}
+.ui.table > thead > tr > th:last-of-type,
+.ui.table > tbody > tr > td:last-of-type,
+.ui.table > tr > td:last-of-type {
+ padding-right: 10px;
+}
diff --git a/web_src/css/modules/tippy.css b/web_src/css/modules/tippy.css
new file mode 100644
index 00000000..6ac7c37d
--- /dev/null
+++ b/web_src/css/modules/tippy.css
@@ -0,0 +1,170 @@
+/* styles are based on node_modules/tippy.js/dist/tippy.css */
+
+/* class to hide tippy target elements on page load */
+.tippy-target {
+ display: none !important;
+}
+
+/* show target element once it's been moved by tippy.js */
+.tippy-content .tippy-target {
+ display: unset !important;
+}
+
+[data-tippy-root] {
+ max-width: calc(100vw - 32px);
+}
+
+.tippy-box {
+ position: relative;
+ background-color: var(--color-body);
+ color: var(--color-secondary-dark-6);
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ font-size: 1rem;
+}
+
+.tippy-content {
+ position: relative;
+ padding: 1rem; /* if you need different padding, use different data-theme */
+ z-index: 1;
+}
+
+/* bare theme, no styling at all, except box-shadow */
+.tippy-box[data-theme="bare"] {
+ border: none;
+ box-shadow: 0 6px 18px var(--color-shadow);
+}
+
+.tippy-box[data-theme="bare"] .tippy-content {
+ padding: 0;
+ background: transparent;
+}
+
+/* tooltip theme for text tooltips */
+
+.tippy-box[data-theme="tooltip"] {
+ background-color: var(--color-tooltip-bg);
+ color: var(--color-tooltip-text);
+ border: none;
+}
+
+.tippy-box[data-theme="tooltip"] .tippy-content {
+ padding: 0.5rem 1rem;
+}
+
+.tippy-box[data-theme="tooltip"] .tippy-svg-arrow-inner,
+.tippy-box[data-theme="tooltip"] .tippy-svg-arrow-outer {
+ fill: var(--color-tooltip-bg);
+}
+
+/* menu theme for .ui.menu */
+
+.tippy-box[data-theme="menu"] {
+ background-color: var(--color-menu);
+ color: var(--color-text);
+ box-shadow: 0 6px 18px var(--color-shadow);
+}
+
+.tippy-box[data-theme="menu"] .tippy-content {
+ padding: 4px 0;
+}
+
+.tippy-box[data-theme="menu"] .tippy-svg-arrow-inner {
+ fill: var(--color-menu);
+}
+
+.tippy-box[data-theme="menu"] .item {
+ display: flex;
+ align-items: center;
+ padding: 9px 18px;
+ color: inherit;
+ text-decoration: none;
+ gap: 10px;
+}
+
+.tippy-box[data-theme="menu"] .item:hover {
+ background: var(--color-hover);
+}
+
+.tippy-box[data-theme="menu"] .item:focus {
+ background: var(--color-active);
+}
+
+/* box-with-header theme to look like .ui.attached.segment. can contain .ui.attached.header */
+
+.tippy-box[data-theme="box-with-header"] {
+ box-shadow: 0 6px 18px var(--color-shadow);
+}
+
+.tippy-box[data-theme="box-with-header"] .tippy-content {
+ background: var(--color-box-body);
+ border-radius: var(--border-radius);
+ padding: 0;
+}
+
+.tippy-box[data-theme="box-with-header"][data-placement^="top"] .tippy-svg-arrow-inner {
+ fill: var(--color-box-body);
+}
+
+.tippy-box[data-theme="box-with-header"][data-placement^="bottom"] .tippy-svg-arrow-inner {
+ fill: var(--color-box-header);
+}
+
+.tippy-box[data-placement^="top"] > .tippy-svg-arrow {
+ bottom: 0;
+}
+
+.tippy-box[data-placement^="top"] > .tippy-svg-arrow::after,
+.tippy-box[data-placement^="top"] > .tippy-svg-arrow > svg {
+ top: 16px;
+ transform: rotate(180deg);
+}
+
+.tippy-box[data-placement^="bottom"] > .tippy-svg-arrow {
+ top: 0;
+}
+
+.tippy-box[data-placement^="bottom"] > .tippy-svg-arrow > svg {
+ bottom: 16px;
+}
+
+.tippy-box[data-placement^="left"] > .tippy-svg-arrow {
+ right: 0;
+}
+
+.tippy-box[data-placement^="left"] > .tippy-svg-arrow::after,
+.tippy-box[data-placement^="left"] > .tippy-svg-arrow > svg {
+ transform: rotate(90deg);
+ top: calc(50% - 3px);
+ left: 11px;
+}
+
+.tippy-box[data-placement^="right"] > .tippy-svg-arrow {
+ left: 0;
+}
+
+.tippy-box[data-placement^="right"] > .tippy-svg-arrow::after,
+.tippy-box[data-placement^="right"] > .tippy-svg-arrow > svg {
+ transform: rotate(-90deg);
+ top: calc(50% - 3px);
+ right: 11px;
+}
+
+.tippy-svg-arrow {
+ width: 16px;
+ height: 16px;
+ text-align: initial;
+}
+
+.tippy-svg-arrow,
+.tippy-svg-arrow > svg {
+ position: absolute;
+}
+
+.tippy-svg-arrow-outer {
+ fill: var(--color-secondary);
+}
+
+.tippy-svg-arrow-inner {
+ fill: var(--color-body);
+}
diff --git a/web_src/css/modules/toast.css b/web_src/css/modules/toast.css
new file mode 100644
index 00000000..2a9f78e0
--- /dev/null
+++ b/web_src/css/modules/toast.css
@@ -0,0 +1,77 @@
+.toastify {
+ color: var(--color-white);
+ position: fixed;
+ opacity: 0;
+ transition: all .2s ease;
+ z-index: 500;
+ border-radius: var(--border-radius);
+ box-shadow: 0 8px 24px var(--color-shadow);
+ display: flex;
+ max-width: 50vw;
+ min-width: 300px;
+ padding: 4px;
+}
+
+.toastify.on {
+ opacity: 1;
+}
+
+.toast-body {
+ flex: 1;
+ padding: 5px 0;
+ overflow-wrap: anywhere;
+}
+
+.toast-close,
+.toast-icon {
+ color: currentcolor;
+ border-radius: var(--border-radius);
+ background: transparent;
+ border: none;
+ display: flex;
+ width: 30px;
+ height: 30px;
+ justify-content: center;
+ align-items: center;
+}
+
+.toast-close:hover {
+ background: var(--color-hover);
+}
+
+.toast-close:active {
+ background: var(--color-active);
+}
+
+.toastify-right {
+ right: 15px;
+}
+
+.toastify-left {
+ left: 15px;
+}
+
+.toastify-top {
+ top: -150px;
+}
+
+.toastify-bottom {
+ bottom: -150px;
+}
+
+.toastify-center {
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+@media (max-width: 360px) {
+ .toastify-right, .toastify-left {
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ max-width: fit-content;
+ }
+}
diff --git a/web_src/css/org.css b/web_src/css/org.css
new file mode 100644
index 00000000..e96b2bb8
--- /dev/null
+++ b/web_src/css/org.css
@@ -0,0 +1,193 @@
+#create-page-form form {
+ margin: auto;
+}
+
+#create-page-form form .ui.message {
+ text-align: center;
+}
+
+@media (min-width: 768px) {
+ #create-page-form form {
+ width: 800px !important;
+ }
+ #create-page-form form .header {
+ padding-left: 280px !important;
+ }
+ #create-page-form form .inline.field > label {
+ text-align: right;
+ width: 250px !important;
+ word-wrap: break-word;
+ }
+ #create-page-form form .help {
+ margin-left: 265px !important;
+ }
+ #create-page-form form .optional .title {
+ margin-left: 250px !important;
+ }
+ #create-page-form form .inline.field > input,
+ #create-page-form form .inline.field > textarea {
+ width: 50%;
+ }
+}
+
+@media (max-width: 767.98px) {
+ #create-page-form form .optional .title {
+ margin-left: 15px;
+ }
+ #create-page-form form .inline.field > label {
+ display: block;
+ }
+}
+
+.organization .head .ui.header .ui.right {
+ margin-top: 5px;
+}
+
+.organization.new.org form {
+ margin: auto;
+}
+
+.organization.new.org form .ui.message {
+ text-align: center;
+}
+
+@media (min-width: 768px) {
+ .organization.new.org form {
+ width: 800px !important;
+ }
+ .organization.new.org form .header {
+ padding-left: 280px !important;
+ }
+ .organization.new.org form .inline.field > label {
+ text-align: right;
+ width: 250px !important;
+ word-wrap: break-word;
+ }
+ .organization.new.org form .help {
+ margin-left: 265px !important;
+ }
+ .organization.new.org form .optional .title {
+ margin-left: 250px !important;
+ }
+ .organization.new.org form .inline.field > input,
+ .organization.new.org form .inline.field > textarea {
+ width: 50%;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .organization.new.org form .optional .title {
+ margin-left: 15px;
+ }
+ .organization.new.org form .inline.field > label {
+ display: block;
+ }
+}
+
+.organization.new.org form .header {
+ padding-left: 0 !important;
+ text-align: center;
+}
+
+.page-content.organization .org-avatar {
+ margin-right: 15px;
+}
+
+.page-content.organization #org-info {
+ overflow-wrap: anywhere;
+ flex: 1;
+ word-break: break-all;
+}
+
+.page-content.organization #org-info .ui.header {
+ display: flex;
+ align-items: center;
+ font-size: 36px;
+ margin-bottom: 0;
+}
+
+@media (max-width: 767.98px) {
+ .page-content.organization #org-info .ui.header {
+ flex-direction: column;
+ margin-bottom: 1rem;
+ }
+ .page-content.organization #org-info .org-title {
+ width: 100%;
+ margin-bottom: 0.5rem;
+ }
+}
+
+.page-content.organization #org-info .desc {
+ font-size: 16px;
+ margin-bottom: 10px;
+}
+
+.page-content.organization #org-info .meta {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.page-content.organization .ui.top.header .ui.right {
+ margin-top: 0;
+}
+
+.page-content.organization .teams .item {
+ padding: 10px 15px;
+}
+
+.page-content.organization .members .ui.avatar {
+ width: 48px;
+ height: 48px;
+ margin-right: 5px;
+ margin-bottom: 5px;
+}
+
+.organization.invite #invite-box {
+ margin: 50px auto auto;
+ width: 500px !important;
+}
+
+.organization.invite #invite-box #search-user-box input {
+ margin-left: 0;
+ width: 300px;
+}
+
+.organization.invite #invite-box .ui.button {
+ margin-left: 5px;
+ margin-top: -3px;
+}
+
+.organization.invite .ui.avatar {
+ width: 100%;
+ height: 100%;
+}
+
+.organization.teams .detail .item {
+ padding: 10px 15px;
+}
+
+.organization.teams .detail .item:not(:last-child) {
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.organization.teams .repositories .item,
+.organization.teams .members .item {
+ padding: 10px 19px;
+}
+
+.organization.teams .repositories .item:not(:last-child),
+.organization.teams .members .item:not(:last-child) {
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.organization.teams .repositories .item .button,
+.organization.teams .members .item .button {
+ padding: 9px 10px;
+ margin: 0;
+}
+
+.org-team-navbar .active.item {
+ background: var(--color-box-body) !important;
+}
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
new file mode 100644
index 00000000..56525aca
--- /dev/null
+++ b/web_src/css/repo.css
@@ -0,0 +1,2997 @@
+.repository .data-table .line-num,
+.repository .diff-file-box .file-body.file-code .lines-num,
+.repository .diff-file-box .code-diff tbody tr .lines-type-marker {
+ user-select: none;
+}
+
+.repository .owner.dropdown {
+ min-width: 40% !important;
+}
+
+.repository .unicode-escaped .escaped-code-point[data-escaped]::before {
+ visibility: visible;
+ content: attr(data-escaped);
+ font-family: var(--fonts-monospace);
+ color: var(--color-red);
+}
+
+.repository .unicode-escaped .escaped-code-point .char {
+ display: none;
+}
+
+.repository .broken-code-point {
+ font-family: var(--fonts-monospace);
+ color: var(--color-blue);
+}
+
+.repository .unicode-escaped .ambiguous-code-point {
+ border: 1px var(--color-yellow) solid;
+}
+
+.issue-content {
+ display: flex;
+ align-items: flex-start;
+ gap: 16px;
+}
+
+@media (max-width: 767.98px) {
+ .issue-content {
+ flex-direction: column;
+ }
+}
+
+.issue-content-left {
+ margin: 0 !important;
+ width: calc(100% - 316px);
+}
+
+.issue-content-right {
+ margin: 0 !important;
+ width: 300px;
+}
+
+.issue-content-right .dropdown > .menu {
+ max-width: 270px;
+ min-width: 0;
+}
+
+@media (max-width: 767.98px) {
+ .issue-content-left,
+ .issue-content-right {
+ width: 100%;
+ }
+}
+
+.repository .issue-content-right .ui.list .dependency {
+ padding: 0;
+ white-space: nowrap;
+}
+
+.repository .issue-content-right .ui.list .title {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.repository .issue-content-right #deadlineForm input {
+ width: 12.8rem;
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
+ border-right: 0;
+ white-space: nowrap;
+}
+
+.repository .issue-content-right .filter.menu {
+ max-height: 500px;
+ overflow-x: auto;
+}
+
+.repository .filter.menu.labels .label-filter .menu .info {
+ display: inline-block;
+ padding: 0.5rem 0;
+ font-size: 12px;
+ width: 100%;
+ white-space: nowrap;
+ margin-left: 10px;
+ margin-right: 8px;
+ text-align: left;
+}
+
+.repository .filter.menu.labels .label-filter .menu .info code {
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ padding: 1px 2px;
+ font-size: 11px;
+}
+
+/* make all issue filter dropdown menus popup leftward, to avoid go out the viewport (right side) */
+.repository .filter.menu .ui.dropdown .menu {
+ max-height: 500px;
+ max-width: 300px;
+ overflow-x: hidden;
+ right: 0;
+ left: auto;
+}
+
+/* the label-filter is the first dropdown, it shouldn't be shown leftward, otherwise it may go out the viewport (left side) */
+.repository .filter.menu .ui.dropdown.label-filter .menu {
+ min-width: max-content;
+ right: unset;
+ left: 0;
+}
+
+.repository .select-label .desc {
+ padding-left: 23px;
+}
+
+/* For the secondary pointing menu, respect its own border-bottom */
+/* style reference: https://semantic-ui.com/collections/menu.html#pointing */
+.repository .ui.tabs.container .ui.menu:not(.secondary.pointing) {
+ border-bottom: 0;
+}
+
+.repository .ui.tabs.divider {
+ margin-top: -1px;
+ margin-bottom: 12px;
+}
+
+.repository .clone-panel #repo-clone-url {
+ width: 320px;
+ border-radius: 0;
+}
+
+@media (max-width: 991.98px) {
+ .repository .clone-panel #repo-clone-url {
+ width: 200px;
+ }
+}
+
+.repository .ui.action.input.clone-panel > button + button,
+.repository .ui.action.input.clone-panel > button + input {
+ margin-left: -1px; /* make the borders overlap to avoid double borders */
+}
+
+.repository .clone-panel > button:first-of-type {
+ border-radius: var(--border-radius) 0 0 var(--border-radius) !important;
+}
+
+.repository .clone-panel > button:last-of-type {
+ border-radius: 0 var(--border-radius) var(--border-radius) 0 !important;
+}
+
+.repository .clone-panel .dropdown .menu {
+ right: 0 !important;
+ left: auto !important;
+}
+
+.repository.file.list .repo-description {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 5px;
+ margin-bottom: 5px;
+}
+
+@media (max-width: 767.98px) {
+ .repository.file.list .repo-description {
+ flex-direction: column;
+ align-items: stretch;
+ }
+}
+
+.commit-summary {
+ flex: 1;
+ overflow-wrap: anywhere;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.commit-header .commit-summary,
+td .commit-summary {
+ white-space: normal;
+}
+
+.commit-list .js-toggle-commit-body {
+ margin: 0 0 0 0.25em;
+}
+
+.commit-list .commit-status {
+ margin: 0 0 0 0.25em;
+}
+
+.latest-commit {
+ display: flex;
+ flex: 1;
+ align-items: center;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.latest-commit .commit-status {
+ margin-right: 0.25em;
+}
+
+@media (max-width: 767.98px) {
+ .latest-commit .sha {
+ display: none;
+ }
+ .latest-commit .commit-summary {
+ margin-left: 8px;
+ }
+}
+
+.repo-path {
+ display: flex;
+ overflow-wrap: anywhere;
+}
+
+/* this is what limits the commit table width to a value that works on all viewport sizes */
+#repo-files-table th:first-of-type {
+ max-width: calc(calc(min(100vw, 1280px)) - 145px - calc(2 * var(--page-margin-x)));
+}
+
+.repository.file.list #repo-files-table thead th {
+ font-weight: var(--font-weight-normal);
+}
+
+.repository.file.list #repo-files-table tbody .svg {
+ margin-left: 3px;
+ margin-right: 5px;
+}
+
+.repository.file.list #repo-files-table tbody .svg.octicon-reply {
+ margin-right: 10px;
+}
+
+.repository.file.list #repo-files-table tbody .svg.octicon-file-directory-fill,
+.repository.file.list #repo-files-table tbody .svg.octicon-file-submodule {
+ color: var(--color-primary);
+}
+
+.repository.file.list #repo-files-table tbody .svg.octicon-file,
+.repository.file.list #repo-files-table tbody .svg.octicon-file-symlink-file,
+.repository.file.list #repo-files-table tbody .svg.octicon-file-directory-symlink {
+ color: var(--color-secondary-dark-7);
+}
+
+.repository.file.list #repo-files-table td {
+ padding-top: 0;
+ padding-bottom: 0;
+ overflow: initial;
+}
+
+.repository.file.list #repo-files-table td.name {
+ width: 33%;
+ max-width: calc(100vw - 140px);
+}
+
+@media (min-width: 1201px) {
+ .repository.file.list #repo-files-table td.name {
+ max-width: 150px;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1200px) {
+ .repository.file.list #repo-files-table td.name {
+ max-width: 200px;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991.98px) {
+ .repository.file.list #repo-files-table td.name {
+ max-width: 300px;
+ }
+}
+
+.repository.file.list #repo-files-table td.message {
+ color: var(--color-text-light-1);
+ width: 66%;
+}
+
+@media (min-width: 1201px) {
+ .repository.file.list #repo-files-table td.message {
+ max-width: 400px;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1200px) {
+ .repository.file.list #repo-files-table td.message {
+ max-width: 350px;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991.98px) {
+ .repository.file.list #repo-files-table td.message {
+ max-width: 250px;
+ }
+}
+
+.repository.file.list #repo-files-table td.age {
+ color: var(--color-text-light-1);
+}
+
+.repository.file.list #repo-files-table td .truncate {
+ display: inline-block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ width: 100%;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+.repository.file.list #repo-files-table td a {
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+.repository.file.list #repo-files-table td .at {
+ margin-left: 3px;
+ margin-right: 3px;
+}
+
+.repository.file.list #repo-files-table td > * {
+ vertical-align: middle;
+}
+
+.repository.file.list #repo-files-table td.message .isSigned {
+ cursor: default;
+}
+
+.repository.file.list #repo-files-table tr:last-of-type td:first-child {
+ border-bottom-left-radius: var(--border-radius);
+}
+
+.repository.file.list #repo-files-table tr:last-of-type td:last-child {
+ border-bottom-right-radius: var(--border-radius);
+}
+
+.repository.file.list #repo-files-table tr:hover {
+ background-color: var(--color-hover);
+}
+
+.repository.file.list #repo-files-table tr.has-parent a {
+ display: inline-block;
+ padding-top: 8px;
+ padding-bottom: 8px;
+ width: calc(100% - 1.25rem);
+}
+
+.repository.file.list .non-diff-file-content .header .icon {
+ font-size: 1em;
+}
+
+.repository.file.list .non-diff-file-content .header .small.icon {
+ font-size: 0.75em;
+}
+
+.repository.file.list .non-diff-file-content .header .tiny.icon {
+ font-size: 0.5em;
+}
+
+.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon {
+ line-height: var(--line-height-default);
+ padding: 8px;
+ vertical-align: middle;
+ color: var(--color-text);
+}
+
+.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon:hover {
+ color: var(--color-primary);
+}
+
+.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon-danger:hover {
+ color: var(--color-red);
+}
+
+.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon.disabled {
+ color: inherit;
+ opacity: var(--opacity-disabled);
+ cursor: default;
+}
+
+.view-raw {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.view-raw > * {
+ max-width: 100%;
+}
+
+.view-raw audio,
+.view-raw video,
+.view-raw img {
+ margin: 1rem 0;
+ border-radius: 0;
+ object-fit: contain;
+}
+
+.view-raw img[src$=".svg" i] {
+ max-height: 600px !important;
+ max-width: 600px !important;
+}
+
+.pdf-content {
+ width: 100%;
+ height: 100vh;
+ border: none !important;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.pdf-content .pdf-fallback-button {
+ margin: 50px auto;
+}
+
+.repository.file.list .non-diff-file-content .plain-text {
+ padding: 1em 2em;
+}
+
+.repository.file.list .non-diff-file-content .plain-text pre {
+ overflow-wrap: anywhere;
+ white-space: pre-wrap;
+}
+
+.repository.file.list .non-diff-file-content .csv {
+ overflow-x: auto;
+ padding: 0 !important;
+}
+
+.repository.file.list .non-diff-file-content pre {
+ overflow: auto;
+}
+
+.repository.file.list .non-diff-file-content .asciicast {
+ padding: 0 !important;
+}
+
+.non-diff-file-content .pdfobject {
+ border-radius: 0 0 var(--border-radius) var(--border-radius);
+}
+
+.repository.file.list .sidebar {
+ padding-left: 0;
+}
+
+.repository.file.list .sidebar .svg {
+ width: 16px;
+}
+
+.repo-editor-header {
+ width: 100%;
+}
+
+.repo-editor-header input {
+ vertical-align: middle !important;
+ width: auto !important;
+ padding: 7px 8px !important;
+ margin-right: 5px !important;
+}
+
+.repository.file.editor .tabular.menu .svg {
+ margin-right: 5px;
+}
+
+.repository.file.editor .commit-form-wrapper {
+ padding-left: 64px;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-avatar {
+ float: left;
+ margin-left: -64px;
+ width: 3em;
+ height: auto;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form {
+ position: relative;
+ padding: 15px;
+ margin-bottom: 10px;
+ border: 1px solid var(--color-secondary);
+ background: var(--color-box-body);
+ border-radius: var(--border-radius);
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form::before,
+.repository.file.editor .commit-form-wrapper .commit-form::after {
+ right: 100%;
+ top: 20px;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form::before {
+ border-right-color: var(--color-secondary);
+ border-width: 9px;
+ margin-top: -9px;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form::after {
+ border-right-color: var(--color-box-body);
+ border-width: 8px;
+ margin-top: -8px;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form .quick-pull-choice .branch-name {
+ display: inline-block;
+ padding: 2px 4px;
+ font: 12px var(--fonts-monospace);
+ color: var(--color-text);
+ background: var(--color-secondary);
+ border-radius: var(--border-radius);
+ margin: 0 2px;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form .quick-pull-choice .new-branch-name-input {
+ position: relative;
+ margin-left: 25px;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form .quick-pull-choice .new-branch-name-input input {
+ width: 240px !important;
+ padding-left: 26px !important;
+}
+
+.repository.file.editor .commit-form-wrapper .commit-form .quick-pull-choice .octicon-git-branch {
+ position: absolute;
+ top: 9px;
+ left: 10px;
+ color: var(--color-grey);
+}
+
+.repository.options #interval {
+ width: 100px !important;
+ min-width: 100px;
+}
+
+.repository.new.issue .comment.form .comment .avatar {
+ width: 3em;
+}
+
+.repository.new.issue .comment.form .content {
+ margin-left: 4em;
+}
+
+.repository.new.issue .comment.form .content::before,
+.repository.new.issue .comment.form .content::after {
+ right: 100%;
+ top: 20px;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.repository.new.issue .comment.form .content::before {
+ border-right-color: var(--color-secondary);
+ border-width: 9px;
+ margin-top: -9px;
+}
+
+.repository.new.issue .comment.form .content::after {
+ border-right-color: var(--color-box-body);
+ border-width: 8px;
+ margin-top: -8px;
+}
+
+.repository.new.issue .comment.form .content .markup {
+ font-size: 14px;
+}
+
+.repository.view.issue .instruct-toggle {
+ display: inline-block;
+}
+
+.issue-title-header {
+ width: 100%;
+ padding-bottom: 4px;
+ margin-bottom: 1rem;
+}
+
+.issue-title-meta {
+ display: flex;
+ align-items: center;
+}
+
+.issue-title .button-row,
+.repository.releases .button-row {
+ display: flex;
+}
+
+@media (max-width: 767.98px) {
+ .repository.view.issue .issue-title {
+ flex-direction: column;
+ }
+ .issue-title .button-row {
+ width: 100%;
+ margin-top: .5rem;
+ justify-content: space-between;
+ }
+ .comment.form .issue-content-left .avatar {
+ display: none;
+ }
+ .comment.form .issue-content-left .content {
+ margin-left: 0 !important;
+ }
+ .comment.form .issue-content-left .content::before,
+ .comment.form .issue-content-left .content::after,
+ .comment.form .content .form::before,
+ .comment.form .content .form::after {
+ display: none;
+ }
+
+ .repository.view.issue .issue-title.edit-active h1 {
+ padding-right: 0;
+ }
+}
+
+.repository.view.issue .issue-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5em;
+ margin-bottom: 8px;
+ min-height: var(--repo-header-issue-min-height);
+}
+
+.repository.view.issue .issue-title h1 {
+ flex: 1;
+ width: 100%;
+ font-weight: var(--font-weight-normal);
+ font-size: 32px;
+ line-height: 40px;
+ margin: 0;
+ padding-right: 0.5rem;
+}
+
+.repository.view.issue .issue-title .ui.input {
+ font-size: 16px;
+}
+
+.repository.view.issue .issue-title .ui.input input {
+ font-size: 1.5em;
+ padding: 2px .5rem;
+}
+
+.repository.view.issue .issue-title .index {
+ color: var(--color-text-light-2);
+}
+
+.repository.view.issue .issue-title .label {
+ margin-right: 10px;
+}
+
+.issue-state-label {
+ display: flex !important;
+ align-items: center !important;
+ font-size: 14px !important;
+ padding: 7px 10px !important;
+ border-radius: var(--border-radius-medium) !important;
+ flex-shrink: 0;
+}
+
+.issue-state-label .svg {
+ margin-right: 4px;
+}
+
+.repository.view.issue .pull-desc code {
+ color: var(--color-primary);
+}
+
+.repository.view.issue .pull-desc a[data-clipboard-text] {
+ cursor: pointer;
+}
+
+.repository.view.issue .pull-desc a[data-clipboard-text] svg {
+ vertical-align: middle;
+ position: relative;
+ top: -2px;
+ right: 1px;
+}
+
+.repository.view.issue .pull.tabs.container {
+ width: 100%;
+ max-width: 100%;
+}
+
+.repository.view.issue .pull.tabular.menu {
+ margin-bottom: 0;
+ overflow-x: auto;
+ overflow-y: hidden;
+}
+
+.repository.view.issue .pull.tabular.menu .svg {
+ margin-right: 5px;
+}
+
+.repository.view.issue .merge.box .branch-update.grid .row {
+ padding-bottom: 1rem;
+}
+
+.repository.view.issue .merge.box .branch-update.grid .row .icon {
+ margin-top: 1.1rem;
+}
+
+.repository.view.issue .comment-list:not(.prevent-before-timeline)::before {
+ display: block;
+ content: "";
+ position: absolute;
+ margin-top: 12px;
+ margin-bottom: 14px;
+ top: 0;
+ bottom: 0;
+ left: 96px;
+ width: 2px;
+ background-color: var(--color-timeline);
+ z-index: -1;
+}
+
+.repository.view.issue .comment-list .timeline {
+ position: relative;
+ display: block;
+ margin-left: 40px;
+ padding-left: 16px;
+}
+
+.repository.view.issue .comment-list .timeline::before { /* ciara */
+ display: block;
+ content: "";
+ position: absolute;
+ margin-top: 12px;
+ margin-bottom: 14px;
+ top: 0;
+ bottom: 0;
+ left: 30px;
+ width: 2px;
+ background-color: var(--color-timeline);
+ z-index: -1;
+}
+
+.repository.view.issue .comment-list .timeline-item,
+.repository.view.issue .comment-list .timeline-item-group {
+ padding: 16px 0;
+}
+
+.repository.view.issue .comment-list .timeline-item-group .timeline-item {
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+.repository.view.issue .comment-list .timeline-avatar-offset {
+ margin-top: 48px;
+}
+
+.repository.view.issue .comment-list .timeline-item {
+ margin-left: 16px;
+ position: relative;
+}
+
+.repository.view.issue .comment-list .timeline-item .timeline-avatar {
+ position: absolute;
+ left: -68px;
+}
+
+/* Don't show the mobile oriented avatar ".inline-timeline-avatar" on desktop. Desktop uses the avatar with class ".timeline-avatar" */
+.repository.view.issue .comment-list .timeline-item .inline-timeline-avatar {
+ display: none;
+}
+
+.repository.view.issue .comment-list .timeline-item:first-child:not(.commit) {
+ padding-top: 0 !important;
+}
+
+.repository.view.issue .comment-list .timeline-item:last-child:not(.commit) {
+ padding-bottom: 0 !important;
+}
+
+.repository.view.issue .comment-list .timeline-item .badge.badge-commit {
+ border-color: transparent;
+ background: radial-gradient(var(--color-body) 40%, transparent 40%) no-repeat;
+}
+
+.repository.view.issue .comment-list .timeline-item .badge {
+ width: 34px;
+ height: 34px;
+ background-color: var(--color-timeline);
+ border-radius: var(--border-radius-full);
+ display: flex;
+ float: left;
+ margin-left: -33px;
+ margin-right: 8px;
+ color: var(--color-text);
+ align-items: center;
+ justify-content: center;
+}
+
+.repository.view.issue .comment-list .timeline-item .badge .svg {
+ width: 22px;
+ height: 22px;
+ padding: 3px;
+}
+
+.repository.view.issue .comment-list .timeline-item .badge .svg.octicon-comment {
+ margin-top: 2px;
+}
+
+.repository.view.issue .comment-list .timeline-item.comment > .content {
+ margin-left: -16px;
+}
+
+.repository.view.issue .comment-list .timeline-item.event > .text {
+ line-height: 32px;
+ vertical-align: middle;
+}
+
+.repository.view.issue .comment-list .timeline-item.commits-list {
+ padding-left: 15px;
+ padding-top: 0;
+}
+
+.repository.view.issue .comment-list .timeline-item.commits-list .ui.avatar,
+.repository.view.issue .comment-list .timeline-item.event .ui.avatar {
+ margin-right: 0.25em;
+}
+
+.singular-commit {
+ display: flex;
+ align-items: center;
+}
+
+.singular-commit .badge {
+ height: 30px !important;
+}
+
+.singular-commit .shabox .sha.label {
+ margin: 0;
+ border: 1px solid var(--color-light-border);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isWarning {
+ border: 1px solid var(--color-red-badge);
+ background: var(--color-red-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isWarning:hover {
+ background: var(--color-red-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerified {
+ border: 1px solid var(--color-green-badge);
+ background: var(--color-green-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerified:hover {
+ background: var(--color-green-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted {
+ border: 1px solid var(--color-yellow-badge);
+ background: var(--color-yellow-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted:hover {
+ background: var(--color-yellow-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched {
+ border: 1px solid var(--color-orange-badge);
+ background: var(--color-orange-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched:hover {
+ background: var(--color-orange-badge-hover-bg) !important;
+}
+
+.repository.view.issue .comment-list .timeline-item .comparebox {
+ line-height: 32px;
+ vertical-align: middle;
+}
+
+.repository.view.issue .comment-list .timeline-item .comparebox .compare.label {
+ font-size: 1rem;
+ margin: 0;
+ border: 1px solid var(--color-light-border);
+}
+
+@media (max-width: 767.98px) {
+ .repository.view.issue .comment-list .timeline-item .ui.segments {
+ margin-left: -2rem;
+ }
+}
+
+.repository.view.issue .comment-list .ui.comments {
+ max-width: 100%;
+}
+
+.repository.view.issue .comment-list .comment > .content > div:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.repository.view.issue .comment-list .comment > .content > div:last-child {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.repository.view.issue .comment-list .comment .comment-container {
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+}
+
+@media (max-width: 767.98px) {
+ .repository.view.issue .comment-list .comment .content .form .button {
+ width: 100%;
+ margin: 0;
+ }
+ .repository.view.issue .comment-list .comment .content .form .button:not(:last-child) {
+ margin-bottom: 1rem;
+ }
+}
+
+.repository.view.issue .comment-list .comment .merge-section {
+ background-color: var(--color-box-body);
+}
+
+.repository.view.issue .comment-list .comment .merge-section .item-section {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0;
+ gap: 0.5em;
+}
+
+.repository.view.issue .comment-list .comment .merge-section .divider {
+ margin-left: -1rem;
+ width: calc(100% + 2rem);
+}
+
+.repository.view.issue .comment-list .comment .merge-section.no-header::before,
+.repository.view.issue .comment-list .comment .merge-section.no-header::after {
+ right: 100%;
+ top: 20px;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.repository.view.issue .comment-list .comment .merge-section.no-header::before {
+ border-right-color: var(--color-secondary);
+ border-width: 9px;
+ margin-top: -9px;
+}
+
+.repository.view.issue .comment-list .comment .merge-section.no-header::after {
+ border-right-color: var(--color-box-body);
+ border-width: 8px;
+ margin-top: -8px;
+}
+
+.merge-section-info code {
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--border-radius);
+ padding: 2px 4px;
+ background: var(--color-light);
+}
+
+.repository.view.issue .comment-list .comment .markup {
+ font-size: 14px;
+}
+
+.repository.view.issue .comment-list .comment .no-content {
+ color: var(--color-text-light-2);
+ font-style: italic;
+}
+
+.repository.view.issue .comment-list .comment .ui.form .field:first-child {
+ clear: none;
+}
+
+.repository.view.issue .comment-list .comment .ui.form .field.footer {
+ overflow: hidden;
+}
+
+.repository.view.issue .comment-list .comment .ui.form .field .tab.markup {
+ min-height: 5rem;
+}
+
+.repository.view.issue .comment-list .comment .edit.buttons {
+ margin-top: 10px;
+}
+
+.repository.view.issue .comment-list .code-comment {
+ border: 1px solid transparent;
+ margin: 0;
+}
+
+.repository.view.issue .comment-list .code-comment .comment-header {
+ background: transparent;
+ border-bottom: 0 !important;
+ padding: 0 !important;
+}
+
+.repository.view.issue .comment-list .code-comment .comment-header::after,
+.repository.view.issue .comment-list .code-comment .comment-header::before {
+ display: none;
+}
+
+.repository.view.issue .comment-list .code-comment .comment-content {
+ margin-left: 36px;
+}
+
+.repository.view.issue .comment-list .comment > .avatar {
+ margin-top: 6px;
+}
+
+.repository.view.issue .comment-list .comment > .avatar ~ .content {
+ margin-left: 42px;
+}
+
+.repository.view.issue .comment-list .comment-code-cloud .segment.reactions {
+ margin-top: 16px !important;
+ margin-bottom: -8px !important;
+ border-top: none !important;
+}
+
+.repository.view.issue .comment-list .comment-code-cloud .segment.reactions .ui.label {
+ border: 1px solid;
+ padding: 5px 8px !important;
+ margin: 0 2px;
+ border-radius: var(--border-radius);
+ border-color: var(--color-secondary-dark-1) !important;
+}
+
+.repository.view.issue .comment-list .comment-code-cloud .segment.reactions .ui.label.basic.primary {
+ background-color: var(--color-reaction-active-bg) !important;
+ border-color: var(--color-primary-alpha-80) !important;
+}
+
+.repository.view.issue .comment-list .comment-code-cloud .segment.reactions .ui.label.basic.primary:hover {
+ background-color: var(--color-reaction-hover-bg) !important;
+ border-color: var(--color-primary-alpha-80) !important;
+}
+
+.repository.view.issue .comment-list .comment-code-cloud button.comment-form-reply {
+ margin: 0;
+}
+
+.repository.view.issue .comment-list .event {
+ padding-left: 15px;
+}
+
+.repository.view.issue .comment-list .event .detail {
+ margin-top: 4px;
+ margin-left: 15px;
+}
+
+.repository.view.issue .comment-list .event .detail .text {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.repository.view.issue .comment-list .event .segments {
+ box-shadow: none;
+}
+
+@media (max-width: 767.98px) {
+ .repository.view.issue .comment-list {
+ padding: 1rem 0 !important; /* Important is required here to override existing fomantic styles. */
+ }
+}
+
+.repository.view.issue .ui.depending .item.is-closed .title {
+ text-decoration: line-through;
+}
+
+.repository .comment.form .content .field:first-child {
+ clear: none;
+}
+
+.repository .comment.form .content .form::before,
+.repository .comment.form .content .form::after {
+ right: 100%;
+ top: 20px;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.repository .comment.form .content .form::before {
+ border-right-color: var(--color-secondary);
+ border-width: 9px;
+ margin-top: -9px;
+}
+
+.repository .comment.form .content .form::after {
+ border-right-color: var(--color-box-body);
+ border-width: 8px;
+ margin-top: -8px;
+}
+
+.repository.new.milestone textarea {
+ height: 200px;
+}
+
+.milestone-progress-big {
+ width: min(420px, 96vw);
+ height: 10px;
+}
+
+.repository.compare.pull .show-form-container {
+ text-align: left;
+}
+
+.repository .choose.branch {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+
+.repository .choose .compare-separator {
+ width: 100%;
+ margin-top: -1rem;
+ text-align: center;
+}
+
+.repository.compare.pull .comment.form .content::before,
+.repository.compare.pull .comment.form .content::after {
+ right: 100%;
+ top: 20px;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.repository.compare.pull .comment.form .content::before {
+ border-right-color: var(--color-secondary);
+ border-width: 9px;
+ margin-top: -9px;
+}
+
+.repository.compare.pull .comment.form .content::after {
+ border-right-color: var(--color-box-body);
+ border-width: 8px;
+ margin-top: -8px;
+}
+
+.repository.compare.pull .pullrequest-form {
+ margin-top: 16px;
+ margin-bottom: 16px;
+}
+
+.repository.compare.pull .markup {
+ font-size: 14px;
+}
+
+.repository.compare.pull .title .issue-title {
+ margin-bottom: 0.5rem;
+}
+
+.repository.compare.pull .title .issue-title .index {
+ color: var(--color-text-light-2);
+}
+
+.repository.branches .commit-divergence .bar-group {
+ position: relative;
+ float: left;
+ padding-bottom: 6px;
+ width: 50%;
+ max-width: 90px;
+}
+
+.repository.branches .commit-divergence .bar-group:last-child {
+ border-left: 1px solid var(--color-secondary-dark-2);
+}
+
+.repository.branches .commit-divergence .count {
+ margin: 0 3px;
+}
+
+.repository.branches .commit-divergence .count.count-ahead {
+ text-align: left;
+}
+
+.repository.branches .commit-divergence .count.count-behind {
+ text-align: right;
+}
+
+.repository.branches .commit-divergence .bar {
+ height: 4px;
+ position: absolute;
+ background-color: var(--color-secondary-dark-2);
+}
+
+.repository.branches .commit-divergence .bar.bar-behind {
+ right: 0;
+}
+
+.repository.branches .commit-divergence .bar.bar-ahead {
+ left: 0;
+}
+
+.repository.commits .header .search input {
+ font-weight: var(--font-weight-normal);
+ padding: 5px 10px;
+}
+
+.repository #commits-table td:not(.message) {
+ white-space: nowrap;
+}
+.repository #commits-table thead .sha {
+ width: 200px;
+}
+
+.repository #commits-table thead .shatd {
+ text-align: center;
+}
+
+.repository #commits-table td.sha .sha.label {
+ margin: 0;
+}
+
+.repository #commits-table.ui.basic.striped.table tbody tr:nth-child(2n) {
+ background-color: var(--color-light) !important;
+}
+
+.repository #commits-table td.sha .sha.label,
+.repository #repo-files-table .sha.label,
+.repository #repo-file-commit-box .sha.label,
+.repository #rev-list .sha.label,
+.repository .timeline-item.commits-list .singular-commit .sha.label {
+ border: 1px solid var(--color-light-border);
+}
+
+.repository #commits-table td.sha .sha.label .ui.signature.avatar,
+.repository #repo-files-table .sha.label .ui.signature.avatar,
+.repository #repo-file-commit-box .sha.label .ui.signature.avatar,
+.repository #rev-list .sha.label .ui.signature.avatar,
+.repository .timeline-item.commits-list .singular-commit .sha.label .ui.signature.avatar {
+ height: 16px;
+ margin-bottom: 0;
+ width: 16px;
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon,
+.repository #repo-files-table .sha.label .detail.icon,
+.repository #repo-file-commit-box .sha.label .detail.icon,
+.repository #rev-list .sha.label .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon {
+ background: var(--color-light);
+ margin: -6px -10px -4px 0;
+ padding: 5px 4px 5px 6px;
+ border-left: 1px solid var(--color-light-border);
+ border-top: 0;
+ border-right: 0;
+ border-bottom: 0;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon img,
+.repository #repo-files-table .sha.label .detail.icon img,
+.repository #repo-file-commit-box .sha.label .detail.icon img,
+.repository #rev-list .sha.label .detail.icon img,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon img {
+ margin-right: 0;
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon .svg,
+.repository #repo-files-table .sha.label .detail.icon .svg,
+.repository #repo-file-commit-box .sha.label .detail.icon .svg,
+.repository #rev-list .sha.label .detail.icon .svg,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon .svg {
+ margin: 0 0.25em 0 0;
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon > div,
+.repository #repo-files-table .sha.label .detail.icon > div,
+.repository #repo-file-commit-box .sha.label .detail.icon > div,
+.repository #rev-list .sha.label .detail.icon > div,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon > div {
+ display: flex;
+ align-items: center;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isWarning,
+.repository #repo-files-table .sha.label.isSigned.isWarning,
+.repository #repo-file-commit-box .sha.label.isSigned.isWarning,
+.repository #rev-list .sha.label.isSigned.isWarning,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning {
+ border: 1px solid var(--color-red-badge);
+ background: var(--color-red-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isWarning .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isWarning .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isWarning .detail.icon,
+.repository #rev-list .sha.label.isSigned.isWarning .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning .detail.icon {
+ border-left: 1px solid var(--color-red-badge);
+ color: var(--color-red-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isWarning:hover,
+.repository #repo-files-table .sha.label.isSigned.isWarning:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isWarning:hover,
+.repository #rev-list .sha.label.isSigned.isWarning:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning:hover {
+ background: var(--color-red-badge-hover-bg) !important;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerified,
+.repository #repo-files-table .sha.label.isSigned.isVerified,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerified,
+.repository #rev-list .sha.label.isSigned.isVerified,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified {
+ border: 1px solid var(--color-green-badge);
+ background: var(--color-green-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerified .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isVerified .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerified .detail.icon,
+.repository #rev-list .sha.label.isSigned.isVerified .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified .detail.icon {
+ border-left: 1px solid var(--color-green-badge);
+ color: var(--color-green-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerified:hover,
+.repository #repo-files-table .sha.label.isSigned.isVerified:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerified:hover,
+.repository #rev-list .sha.label.isSigned.isVerified:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified:hover {
+ background: var(--color-green-badge-hover-bg) !important;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted,
+.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted {
+ border: 1px solid var(--color-yellow-badge);
+ background: var(--color-yellow-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted .detail.icon {
+ border-left: 1px solid var(--color-yellow-badge);
+ color: var(--color-yellow-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted:hover {
+ background: var(--color-yellow-badge-hover-bg) !important;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched,
+.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched {
+ border: 1px solid var(--color-orange-badge);
+ background: var(--color-orange-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched .detail.icon {
+ border-left: 1px solid var(--color-orange-badge);
+ color: var(--color-orange-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched:hover {
+ background: var(--color-orange-badge-hover-bg) !important;
+}
+
+.repository .data-table {
+ width: 100%;
+}
+
+.repository .data-table tr {
+ border-top: 0;
+}
+
+.repository .data-table td,
+.repository .data-table th {
+ padding: 5px !important;
+ overflow: hidden;
+ font-size: 12px;
+ text-align: left;
+ white-space: nowrap;
+ border: 1px solid var(--color-secondary);
+}
+
+/* the border css competes with .markup where all tables have outer border which would add a double
+ border here, remove only the outer borders from this table */
+.repository .data-table tr:first-child :is(td,th) {
+ border-top: none !important;
+}
+.repository .data-table tr:last-child :is(td,th) {
+ border-bottom: none !important;
+}
+.repository .data-table tr :is(td,th):first-child {
+ border-left: none !important;
+}
+.repository .data-table tr :is(td,th):last-child {
+ border-right: none !important;
+}
+
+.repository .data-table td {
+ white-space: pre-line;
+}
+
+.repository .data-table th {
+ font-weight: var(--font-weight-semibold);
+ background: var(--color-box-header);
+ border-top: 0;
+}
+
+.repository .data-table td.added,
+.repository .data-table th.added,
+.repository .data-table tr.added {
+ background-color: var(--color-diff-added-row-bg) !important;
+}
+
+.repository .data-table td.removed,
+.repository .data-table th.removed,
+.repository .data-table tr.removed {
+ background-color: var(--color-diff-removed-row-bg) !important;
+}
+
+.repository .data-table td.moved,
+.repository .data-table th.moved,
+.repository .data-table tr.moved {
+ background-color: var(--color-diff-moved-row-bg) !important;
+}
+
+.repository .data-table tbody.section {
+ border-top: 2px solid var(--color-secondary);
+}
+
+.repository .data-table .line-num {
+ width: 1%;
+ min-width: 50px;
+ font-family: monospace;
+ line-height: 20px;
+ color: var(--color-text-light-1);
+ white-space: nowrap;
+ vertical-align: top;
+ cursor: pointer;
+ text-align: right;
+ background: var(--color-body);
+ border: 0;
+}
+
+.repository .diff-detail-box {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ position: sticky;
+ top: 0;
+ z-index: 8;
+ padding: 7px 5px;
+ margin: 0 -5px; /* negative margin so it covers active file shadow */
+ height: 44px; /* this height should match sticky-2nd-row */
+ background: var(--color-body);
+}
+
+@media (max-width: 480px) {
+ .repository .diff-detail-box {
+ flex-wrap: wrap;
+ }
+}
+.repository .diff-detail-box .diff-detail-stats strong {
+ margin-left: 0.25rem;
+ margin-right: 0.25rem;
+}
+
+/* Because the translations contain the <strong> we need to style with nth-of-type */
+
+.repository .diff-detail-box .diff-detail-stats strong:nth-of-type(1) {
+ color: var(--color-yellow);
+}
+
+.repository .diff-detail-box .diff-detail-stats strong:nth-of-type(2) {
+ color: var(--color-green);
+}
+
+.repository .diff-detail-box .diff-detail-stats strong:nth-of-type(3) {
+ color: var(--color-red);
+}
+
+@media (max-width: 800px) {
+ .repository .diff-detail-box .diff-detail-stats {
+ display: none !important;
+ }
+}
+
+.diff-detail-actions {
+ display: flex;
+ align-items: center;
+ justify-content: end;
+}
+
+.diff-detail-actions > *,
+.diff-detail-actions .button {
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
+.repository .diff-detail-box span.status {
+ display: inline-block;
+ width: 12px;
+ height: 12px;
+ margin-right: 8px;
+ vertical-align: middle;
+}
+
+.repository .diff-detail-box span.status.modify {
+ background-color: var(--color-yellow);
+}
+
+.repository .diff-detail-box span.status.add {
+ background-color: var(--color-green);
+}
+
+.repository .diff-detail-box span.status.del {
+ background-color: var(--color-red);
+}
+
+.repository .diff-detail-box span.status.rename {
+ background-color: var(--color-teal);
+}
+
+.repository .diff-detail-box .ui.button {
+ padding: 0 1.125em;
+ height: 30px;
+}
+
+.repository .diff-box .header:not(.resolved-placeholder) {
+ display: flex;
+ align-items: center;
+}
+
+.repository .diff-box .header:not(.resolved-placeholder) .file {
+ min-width: 0;
+}
+
+.repository .diff-box .header:not(.resolved-placeholder) .file .file-link {
+ max-width: fit-content;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+ overflow: hidden;
+}
+
+.repository .diff-box .header:not(.resolved-placeholder) .button {
+ padding: 0 1.125em;
+ flex: 0 0 auto;
+ margin-right: 0;
+ height: 30px;
+}
+
+.repository .diff-box .resolved-placeholder {
+ display: flex;
+ align-items: center;
+ font-size: 14px !important;
+ height: 36px;
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+.repository .diff-box .resolved-placeholder .button {
+ padding: 8px 12px;
+}
+
+.repository .diff-file-box .header {
+ background-color: var(--color-box-header);
+}
+
+.repository .diff-file-box .file-body.file-code {
+ background: var(--color-code-bg);
+}
+
+.repository .diff-file-box .file-body.file-code .lines-num {
+ text-align: right;
+ width: 1%;
+ min-width: 50px;
+}
+
+.repository .diff-file-box .file-body.file-code .lines-num span.fold {
+ display: block;
+ text-align: center;
+}
+
+.repository .diff-file-box .code-diff td {
+ padding: 0 0 0 10px !important;
+ border-top: 0;
+}
+
+.repository .diff-file-box .code-diff .lines-num {
+ padding: 0 5px !important;
+}
+
+.repository .diff-file-box .code-diff .tag-code .lines-num,
+.repository .diff-file-box .code-diff .tag-code td {
+ padding: 0 !important;
+}
+
+.repository .diff-file-box .code-diff table {
+ table-layout: fixed;
+}
+
+.repository .diff-file-box .code-diff tbody tr td.lines-num,
+.repository .diff-file-box .code-diff tbody tr td.lines-escape,
+.repository .diff-file-box .code-diff tbody tr td.lines-type-marker {
+ white-space: nowrap;
+}
+
+.repository .diff-file-box .code-diff tbody tr td.center {
+ text-align: center;
+}
+
+.repository .diff-file-box .code-diff tbody tr [data-line-num]::before {
+ content: attr(data-line-num);
+ text-align: right;
+}
+
+.repository .diff-file-box .code-diff tbody tr .lines-type-marker {
+ width: 10px;
+ min-width: 10px;
+}
+
+.repository .diff-file-box .code-diff tbody tr [data-type-marker]::before {
+ content: attr(data-type-marker);
+ text-align: right;
+ display: inline-block;
+}
+
+.repository .diff-file-box .code-diff-split .tag-code .lines-code code.code-inner {
+ padding-left: 10px !important;
+}
+
+.repository .diff-file-box .code-diff-split table,
+.repository .diff-file-box .code-diff-split tbody {
+ width: 100%;
+}
+
+.repository .diff-file-box.file-content {
+ clear: right;
+}
+
+.repository .diff-file-box.file-content .image-diff img {
+ max-width: 100%;
+ padding: 0;
+ border-radius: 0;
+}
+
+.repository .diff-file-box .ui.bottom.attached.table.segment {
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+.diff-file-box {
+ border: 1px solid transparent;
+ border-radius: var(--border-radius);
+ scroll-margin-top: 47px; /* match .repository .diff-detail-box */
+}
+
+.file.editor .diff-file-box {
+ border: none;
+}
+
+.file.editor .diff-file-box .ui.attached.table {
+ border: none;
+}
+
+/* TODO: this can potentially be made "global" by removing the class prefix */
+.diff-file-box .ui.attached.header,
+.diff-file-box .ui.attached.table {
+ margin: 0; /* remove fomantic negative margins */
+ width: initial; /* remove fomantic over 100% width */
+ max-width: initial; /* remove fomantic over 100% width */
+}
+
+.repository .diff-stats {
+ clear: both;
+ margin-bottom: 5px;
+ max-height: 200px;
+ height: fit-content;
+ overflow: auto;
+ padding-left: 0;
+}
+
+.repository .diff-stats li {
+ list-style: none;
+ padding-bottom: 4px;
+ margin-bottom: 4px;
+ padding-left: 6px;
+}
+
+.repository .diff-stats li + li {
+ border-top: 1px solid var(--color-secondary);
+}
+
+.repository .repo-search-result {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.repository .repo-search-result .lines-num a {
+ color: inherit;
+}
+
+.repository.quickstart .guide .item {
+ padding: 1em;
+}
+
+.repository.quickstart .guide .item small {
+ font-weight: var(--font-weight-normal);
+}
+
+.repository.quickstart .guide #repo-clone-url {
+ border-radius: 0;
+ padding: 5px 10px;
+ font-size: 1.2em;
+ line-height: 1.4;
+ flex: 1
+}
+
+.empty-placeholder {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding-top: 40px;
+ padding-bottom: 40px;
+}
+
+.repository.packages .file-size {
+ white-space: nowrap;
+}
+
+.file-view.markup {
+ padding: 2em;
+}
+.repository .activity-header {
+ display: flex;
+ justify-content: space-between;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+
+/* if the element is for a checkbox, then it should have a padding-left to align to the checkbox's text */
+.repository.settings.branches .branch-protection .ui.checkbox .help,
+.repository.settings.branches .branch-protection .checkbox-sub-item {
+ padding-left: 26px;
+}
+
+.repository.settings.branches .branch-protection .status-check-matched-mark {
+ font-weight: var(--font-weight-semibold);
+ font-style: italic;
+}
+
+.repository.settings.webhook .events .column {
+ padding-bottom: 0;
+}
+
+.repository.settings.webhook .events .help {
+ font-size: 13px;
+ margin-left: 26px;
+ padding-top: 0;
+}
+
+.repository .ui.attached.isSigned.isWarning {
+ border-left: 1px solid var(--color-error-border);
+ border-right: 1px solid var(--color-error-border);
+}
+
+.repository .ui.attached.isSigned.isWarning.top,
+.repository .ui.attached.isSigned.isWarning.message {
+ border-top: 1px solid var(--color-error-border);
+}
+
+.repository .ui.attached.isSigned.isWarning.message {
+ box-shadow: none;
+ background-color: var(--color-error-bg);
+ color: var(--color-error-text);
+}
+
+.repository .ui.attached.isSigned.isWarning.message .ui.text {
+ color: var(--color-error-text);
+}
+
+.repository .ui.attached.isSigned.isWarning:last-child,
+.repository .ui.attached.isSigned.isWarning.bottom {
+ border-bottom: 1px solid var(--color-error-border);
+}
+
+.repository .ui.attached.isSigned.isVerified {
+ border-left: 1px solid var(--color-success-border);
+ border-right: 1px solid var(--color-success-border);
+}
+
+.repository .ui.attached.isSigned.isVerified.top,
+.repository .ui.attached.isSigned.isVerified.message {
+ border-top: 1px solid var(--color-success-border);
+}
+
+.repository .ui.attached.isSigned.isVerified.message {
+ box-shadow: none;
+ background-color: var(--color-success-bg);
+ color: var(--color-success-text);
+}
+
+.repository .ui.attached.isSigned.isVerified.message .pull-right {
+ color: var(--color-text);
+}
+
+.repository .ui.attached.isSigned.isVerified.message .ui.text {
+ color: var(--color-success-text);
+}
+
+.repository .ui.attached.isSigned.isVerified:last-child,
+.repository .ui.attached.isSigned.isVerified.bottom {
+ border-bottom: 1px solid var(--color-success-border);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted,
+.repository .ui.attached.isSigned.isVerifiedUnmatched {
+ border-left: 1px solid var(--color-warning-border);
+ border-right: 1px solid var(--color-warning-border);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted.top,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.top,
+.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
+ border-top: 1px solid var(--color-warning-border);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
+ box-shadow: none;
+ background-color: var(--color-warning-bg);
+ color: var(--color-warning-text);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted.message .ui.text,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.message .ui.text {
+ color: var(--color-warning-text);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted:last-child,
+.repository .ui.attached.isSigned.isVerifiedUnmatched:last-child,
+.repository .ui.attached.isSigned.isVerifiedUntrusted.bottom,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.bottom {
+ border-bottom: 1px solid var(--color-warning-border);
+}
+
+.repository .release-tag-name .ui.label.isSigned,
+.repository .release-list-title .ui.label.isSigned {
+ padding: 0 0.5em;
+ box-shadow: none;
+}
+
+.repository .release-tag-name .ui.label.isSigned .avatar,
+.repository .release-list-title .ui.label.isSigned .avatar {
+ margin-left: .5rem;
+}
+
+.repository .release-tag-name .ui.label.isSigned.isVerified,
+.repository .release-list-title .ui.label.isSigned.isVerified {
+ border: 1px solid var(--color-success-border);
+ background-color: var(--color-success-bg);
+ color: var(--color-success-text);
+}
+
+.repository .release-tag-name .ui.label.isSigned.isWarning,
+.repository .release-list-title .ui.label.isSigned.isWarning {
+ border: 1px solid var(--color-warning-border);
+ background-color: var(--color-warning-bg);
+ color: var(--color-warning-text);
+}
+
+.repository .segment.reactions.dropdown .menu,
+.repository .select-reaction.dropdown .menu {
+ right: 0 !important;
+ left: auto !important;
+ min-width: 170px;
+}
+
+.repository .segment.reactions.dropdown .menu > .header,
+.repository .select-reaction.dropdown .menu > .header {
+ margin: 0.75rem 0 0.5rem;
+}
+
+.repository .segment.reactions.dropdown .menu > .item,
+.repository .select-reaction.dropdown .menu > .item {
+ float: left;
+ margin: 4px;
+ font-size: 20px;
+ width: 34px;
+ height: 34px;
+ min-height: 0 !important;
+ border-radius: var(--border-radius);
+ display: flex !important;
+ align-items: center;
+ justify-content: center;
+}
+
+.repository .segment.reactions {
+ padding: 0;
+ display: flex;
+ border: none !important;
+ border-top: 1px solid var(--color-secondary) !important;
+ width: 100% !important;
+ max-width: 100% !important;
+ margin: 0 !important;
+ border-radius: 0 0 var(--border-radius) var(--border-radius);
+}
+
+.repository .segment.reactions .ui.label {
+ max-height: 40px;
+ padding: 8px 16px !important;
+ display: flex !important;
+ align-items: center;
+ border: 0;
+ border-right: 1px solid;
+ border-radius: 0;
+ margin: 0;
+ font-size: 12px;
+ font-weight: var(--font-weight-normal);
+ border-color: var(--color-secondary) !important;
+ background: var(--color-reaction-bg);
+}
+
+.repository .segment.reactions .ui.label:first-of-type {
+ border-bottom-left-radius: 3px;
+}
+
+.repository .segment.reactions .ui.label.disabled {
+ cursor: default;
+ opacity: 1;
+}
+
+.repository .segment.reactions .ui.label.basic.primary {
+ color: var(--color-primary) !important;
+ background-color: var(--color-reaction-active-bg) !important;
+ border-color: var(--color-secondary-dark-1) !important;
+}
+
+.repository .segment.reactions .ui.label.basic:hover {
+ background-color: var(--color-reaction-hover-bg) !important;
+}
+
+.repository .segment.reactions .reaction-count {
+ margin-left: 0.5rem;
+}
+
+.repository .segment.reactions .select-reaction {
+ display: flex;
+ align-items: center;
+}
+
+.repository .segment.reactions .select-reaction a {
+ padding: 0 14px;
+}
+
+.repository .segment.reactions .select-reaction:not(.active) a {
+ display: none;
+}
+
+.repository .segment.reactions:hover .select-reaction a {
+ display: block;
+}
+
+.repository .ui.fluid.action.input .ui.search.action.input {
+ flex: auto;
+}
+
+.repository .repository-summary {
+ box-shadow: none;
+}
+
+.repository .repository-summary .segment.sub-menu {
+ border: none;
+ display: flex;
+ align-items: center;
+ padding: 0;
+ overflow: hidden;
+}
+
+.repository .repository-summary .sub-menu .item {
+ flex: 1;
+ height: 30px;
+ line-height: var(--line-height-default);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 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 {
+ background: var(--color-secondary);
+}
+
+.repository .repository-summary .segment.language-stats {
+ display: flex;
+ gap: 2px;
+ padding: 0;
+ height: 10px;
+ white-space: nowrap;
+ border-radius: 0 0 3px 3px !important;
+ overflow: hidden;
+}
+
+#cite-repo-modal #citation-panel {
+ display: flex;
+ width: 100%;
+}
+
+#cite-repo-modal #citation-panel input {
+ border-radius: 0;
+ padding: 5px 10px;
+ width: 50%;
+ line-height: 1.4;
+}
+
+#cite-repo-modal #citation-panel #citation-copy-content {
+ border-radius: 0;
+ padding: 5px 10px;
+ font-size: 1.2em;
+ line-height: 1.4;
+ flex: 1;
+}
+
+#cite-repo-modal #citation-panel #citation-copy-bibtex {
+ font-size: 13px;
+ padding: 7.5px 5px;
+ border-right: none;
+}
+
+#cite-repo-modal #citation-panel #goto-citation-btn {
+ border-left: none;
+}
+
+#cite-repo-modal #citation-panel > :first-child {
+ border-radius: var(--border-radius) 0 0 var(--border-radius) !important;
+}
+
+#cite-repo-modal #citation-panel > :last-child {
+ border-radius: 0 var(--border-radius) var(--border-radius) 0 !important;
+}
+
+#cite-repo-modal #citation-panel .icon.button {
+ padding: 0 10px;
+}
+
+.user-cards .list {
+ padding: 0;
+ display: flex;
+ flex-wrap: wrap;
+ margin: 10px 0;
+}
+
+.user-cards .list .item {
+ list-style: none;
+ width: 31%;
+ margin: 15px 15px 0 0;
+ padding: 14px;
+ float: left;
+}
+
+.user-cards .list .item .avatar {
+ width: 48px;
+ height: 48px;
+ float: left;
+ display: block;
+ margin-right: 10px;
+}
+
+.user-cards .list .item .name {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-weight: var(--font-weight-normal);
+}
+
+.user-cards .list .item .meta {
+ margin-top: 5px;
+}
+
+#search-user-box .results .result .image {
+ order: 0;
+ margin-right: 12px;
+ width: 2em;
+ height: 2em;
+ min-width: 2em;
+ min-height: 2em;
+}
+
+#search-user-box .results .result .content {
+ margin: 0; /* remove margin reserved for avatar because we move it to left via `order: 0` */
+}
+
+.ui.menu .item > img:not(.ui) {
+ width: auto;
+}
+
+.page.buttons {
+ padding-top: 15px;
+}
+
+.commit-header-row,
+.tag-signature-row {
+ min-height: 50px !important;
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+}
+
+.ui.attached.message.tag-signature-row {
+ border-radius: var(--border-radius);
+}
+
+.tag-signature-row div {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ display: inline-block !important;
+}
+
+.commit-header-buttons {
+ display: flex;
+ gap: 4px;
+ align-items: flex-start;
+ white-space: nowrap;
+}
+
+@media (max-width: 767.98px) {
+ .commit-header-buttons {
+ flex-direction: column;
+ align-items: stretch;
+ }
+}
+
+.settings.webhooks .list > .item:not(:first-child),
+.settings.githooks .list > .item:not(:first-child),
+.settings.actions .list > .item:not(:first-child) {
+ padding: 0.25rem 1rem;
+ margin: 12px -1rem -1rem;
+}
+
+.settings .list > .item:not(:first-child) {
+ border-top: 1px solid var(--color-secondary);
+ padding: 1rem;
+ margin: 16px -1rem -1rem;
+}
+
+.settings .list > .item > .svg {
+ display: table-cell;
+}
+
+.settings .list > .item > .svg + .content {
+ display: table-cell;
+ padding: 0 0 0 0.5em;
+ vertical-align: top;
+}
+
+.settings .list > .item .info {
+ margin-top: 10px;
+}
+
+.settings .list > .item .info .tab.segment {
+ border: 0;
+ padding: 10px 0 0;
+}
+
+.ui.vertical.menu .header.item {
+ font-size: 1.1em;
+ background: var(--color-box-header);
+}
+
+.comment:target .comment-container {
+ border-color: var(--color-primary) !important;
+ box-shadow: 0 0 0 3px var(--color-primary-alpha-30) !important;
+}
+
+.comment:target .header::before {
+ border-right-color: var(--color-primary) !important;
+ filter: drop-shadow(-3px 0 0 var(--color-primary-alpha-30)) !important;
+}
+
+.code-comment:target,
+.diff-file-box:target {
+ border-color: var(--color-primary) !important;
+ border-radius: var(--border-radius) !important;
+ box-shadow: 0 0 0 3px var(--color-primary-alpha-30) !important;
+}
+
+.code-comment:target .content {
+ box-shadow: none !important;
+}
+
+.comment-header {
+ border: none !important;
+ background: var(--color-box-header);
+ border-bottom: 1px solid var(--color-secondary) !important;
+ font-weight: var(--font-weight-normal) !important;
+ padding: 0.5rem 1rem;
+ margin: 0 !important;
+ position: relative;
+ color: var(--color-text);
+ min-height: var(--repo-header-issue-min-height);
+ background-color: var(--color-box-header);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.comment-header::before,
+.comment-header::after {
+ right: 100%;
+ top: 20px;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.comment-header::before {
+ border-right-color: var(--color-secondary);
+ border-width: 9px;
+ margin-top: -9px;
+}
+
+.comment-header::after {
+ border-right-color: var(--color-box-header);
+ border-width: 8px;
+ margin-top: -8px;
+}
+
+.comment-header.arrow-top::before,
+.comment-header.arrow-top::after {
+ transform: rotate(90deg);
+}
+
+.comment-header.arrow-top::before {
+ top: -9px;
+ left: 6px;
+}
+
+.comment-header.arrow-top::after {
+ top: -8px;
+ left: 7px;
+}
+
+.comment-header .actions a:not(.label) {
+ padding: 0.5rem !important;
+}
+
+.comment-header .actions .label {
+ margin: 0 !important;
+}
+
+.comment-header-left,
+.comment-header-right {
+ gap: 4px;
+}
+
+.comment-body {
+ background: var(--color-box-body);
+ border: none !important;
+ width: 100% !important;
+ max-width: 100% !important;
+ margin: 0 !important;
+ padding: 1em;
+}
+
+.edit-label.modal .form .column,
+.new-label.modal .form .column {
+ padding-right: 0;
+}
+
+.edit-label.modal .form .buttons,
+.new-label.modal .form .buttons {
+ margin-left: auto;
+ padding-top: 15px;
+}
+
+.stats-table {
+ display: table;
+ width: 100%;
+ margin: 6px 0;
+ border-spacing: 2px;
+}
+
+.stats-table .table-cell {
+ display: table-cell;
+}
+
+.stats-table .table-cell.tiny {
+ height: 8px;
+}
+
+.stats-table .table-cell:first-child {
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+.stats-table .table-cell:last-child {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.labels-list {
+ display: inline-flex;
+ flex-wrap: wrap;
+ gap: 2.5px;
+ align-items: center;
+}
+
+.labels-list .label {
+ padding: 0 6px;
+ min-height: 20px;
+ line-height: 1.3; /* there is a `font-size: 1.25em` for inside emoji, so here the line-height needs to be larger slightly */
+}
+
+/* Scoped labels with different colors on left and right */
+.ui.label.scope-parent {
+ background: none !important;
+ padding: 0 !important;
+ gap: 0 !important;
+}
+
+.ui.label.scope-left {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+ margin-right: 0;
+}
+
+.ui.label.scope-right {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+ margin-left: 0;
+}
+
+.archived-label {
+ filter: grayscale(0.25) saturate(0.75);
+}
+
+.repo-button-row {
+ margin: 10px 0;
+ display: flex;
+ align-items: center;
+ gap: 0.5em;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.repo-button-row .button {
+ padding: 6px 10px !important;
+ height: 30px;
+}
+
+.repo-button-row .button.dropdown:not(.icon) {
+ padding-right: 22px !important; /* normal buttons have !important paddings, so we need to override it for dropdown (Add File) icons */
+}
+
+.repo-button-row input {
+ height: 30px;
+}
+
+tbody.commit-list {
+ vertical-align: baseline;
+}
+
+.message-wrapper,
+.author-wrapper {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 100%;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.author-wrapper {
+ max-width: 180px;
+ align-self: center;
+ white-space: nowrap;
+}
+
+/* in the commit list, messages can wrap so we can use inline */
+.commit-list .message-wrapper {
+ display: inline;
+ overflow-wrap: anywhere;
+}
+
+/* but in the repo-files-table we cannot */
+#repo-files-table .commit-list .message-wrapper {
+ display: inline-block;
+}
+
+@media (max-width: 767.98px) {
+ tr.commit-list {
+ width: 100%;
+ }
+ .author-wrapper {
+ max-width: 80px;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991.98px) {
+ tr.commit-list {
+ width: 723px;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1200px) {
+ tr.commit-list {
+ width: 933px;
+ }
+}
+
+@media (min-width: 1201px) {
+ tr.commit-list {
+ width: 1127px;
+ }
+}
+
+.commit-body {
+ margin: 0.25em 0;
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
+ line-height: initial;
+}
+
+.git-notes.top {
+ text-align: left;
+}
+
+.comment-diff-data {
+ background: var(--color-code-bg);
+ min-height: 12em;
+ max-height: calc(100vh - 10.5rem);
+ overflow-y: auto;
+ tab-size: 4;
+}
+
+.comment-diff-data pre {
+ line-height: 18px;
+ margin: 1em;
+ white-space: pre-wrap;
+ word-break: break-all;
+ overflow-wrap: break-word;
+}
+
+.content-history-detail-dialog .header .avatar {
+ position: relative;
+ top: -2px;
+}
+
+#repo-topics .repo-topic {
+ font-weight: var(--font-weight-normal);
+ cursor: pointer;
+ margin: 0;
+}
+
+#new-dependency-drop-list.ui.selection.dropdown {
+ min-width: 0;
+ width: 100%;
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
+ border-right: 0;
+ white-space: nowrap;
+}
+
+#new-dependency-drop-list .text {
+ width: 100%;
+ overflow: hidden;
+}
+
+.tag-code {
+ height: 28px;
+}
+
+.tag-code,
+.tag-code td,
+.tag-code .blob-excerpt {
+ background-color: var(--color-box-body-highlight);
+ vertical-align: middle;
+}
+
+.resolved-placeholder {
+ font-weight: var(--font-weight-normal) !important;
+ border: 1px solid var(--color-secondary) !important;
+ border-radius: var(--border-radius) !important;
+ margin: 4px !important;
+}
+
+.resolved-placeholder + .comment-code-cloud {
+ padding-top: 0 !important;
+}
+
+.blob-excerpt {
+ background-color: var(--color-secondary-alpha-30);
+}
+
+.issue-keyword {
+ border-bottom: 1px dotted var(--color-text-light-3) !important;
+}
+
+.issue-keyword:hover {
+ border-bottom: none !important;
+}
+
+.file-header {
+ align-items: center;
+ display: flex;
+ justify-content: space-between;
+ overflow-x: auto;
+ padding: 6px 12px !important;
+ font-size: 13px !important;
+}
+
+.file-info {
+ display: flex;
+ align-items: center;
+}
+
+.file-info-entry {
+ display: flex;
+ align-items: center;
+ width: max-content;
+}
+
+.file-info-entry + .file-info-entry {
+ border-left: 1px solid currentcolor;
+ margin-left: 8px;
+ padding-left: 8px;
+}
+
+#diff-container {
+ display: flex;
+}
+
+#diff-file-boxes {
+ flex: 1;
+ max-width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+#diff-file-tree {
+ flex: 0 0 20%;
+ max-width: 380px;
+ line-height: inherit;
+ position: sticky;
+ padding-top: 0;
+ top: 47px;
+ max-height: calc(100vh - 47px);
+ height: 100%;
+ overflow-y: auto;
+}
+
+.ui.message.unicode-escape-prompt {
+ margin-bottom: 0;
+ border-radius: 0;
+ display: flex;
+ flex-direction: column;
+}
+
+/* fomantic's last-child selector does not work with hidden last child */
+.ui.buttons .unescape-button {
+ border-top-right-radius: 0.28571429rem;
+ border-bottom-right-radius: 0.28571429rem;
+}
+
+.webhook-info {
+ padding: 7px 12px;
+ margin: 10px 0;
+ background-color: var(--color-markup-code-block);
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ font-size: 13px;
+ line-height: 1.5;
+ overflow: auto;
+}
+
+.title_wip_desc {
+ margin-top: 1em;
+}
+
+.sidebar-item-link {
+ display: inline-flex;
+ align-items: center;
+ word-break: break-all;
+}
+
+.diff-file-header {
+ padding: 5px 8px !important;
+}
+
+.diff-file-box[data-folded="true"] .diff-file-body {
+ display: none;
+}
+
+.diff-file-box[data-folded="true"] .diff-file-header {
+ border-radius: var(--border-radius) !important;
+}
+
+.ui.attached.header.diff-file-header.sticky-2nd-row {
+ position: sticky;
+ top: 44px; /* match .repository .diff-detail-box */
+ z-index: 7;
+}
+
+.diff-file-name {
+ flex: auto;
+ min-width: 100px;
+}
+
+.diff-file-name .ui.label {
+ margin-left: 0 !important;
+}
+
+.diff-stats-bar {
+ display: inline-block;
+ background-color: var(--color-red);
+ height: 12px;
+ width: 44px;
+}
+
+.diff-stats-bar .diff-stats-add-bar {
+ background-color: var(--color-green);
+ height: 100%;
+}
+
+.ui.form .right .ui.button {
+ margin-left: 0.25em;
+ margin-right: 0;
+}
+
+.removed-code {
+ background: var(--color-diff-removed-word-bg);
+}
+
+.added-code {
+ background: var(--color-diff-added-word-bg);
+}
+
+.code-diff-unified .del-code,
+.code-diff-unified .del-code td,
+.code-diff-split .del-code .lines-num-old,
+.code-diff-split .del-code .lines-escape-old,
+.code-diff-split .del-code .lines-type-marker-old,
+.code-diff-split .del-code .lines-code-old {
+ background: var(--color-diff-removed-row-bg);
+ border-color: var(--color-diff-removed-row-border);
+}
+
+.code-diff-unified .add-code,
+.code-diff-unified .add-code td,
+.code-diff-split .add-code .lines-num-new,
+.code-diff-split .add-code .lines-type-marker-new,
+.code-diff-split .add-code .lines-escape-new,
+.code-diff-split .add-code .lines-code-new,
+.code-diff-split .del-code .add-code.lines-num-new,
+.code-diff-split .del-code .add-code.lines-type-marker-new,
+.code-diff-split .del-code .add-code.lines-escape-new,
+.code-diff-split .del-code .add-code.lines-code-new {
+ background: var(--color-diff-added-row-bg);
+ border-color: var(--color-diff-added-row-border);
+}
+
+.code-diff-split .del-code .lines-num-new,
+.code-diff-split .del-code .lines-type-marker-new,
+.code-diff-split .del-code .lines-code-new,
+.code-diff-split .del-code .lines-escape-new,
+.code-diff-split .add-code .lines-num-old,
+.code-diff-split .add-code .lines-escape-old,
+.code-diff-split .add-code .lines-type-marker-old,
+.code-diff-split .add-code .lines-code-old {
+ background: var(--color-diff-inactive);
+}
+
+.code-diff-split tbody tr td:nth-child(5),
+.code-diff-split tbody tr td.add-comment-right {
+ border-left: 1px solid var(--color-secondary);
+}
+
+.migrate-entries {
+ display: grid !important;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 25px;
+ margin: 0 !important;
+}
+
+@media (max-width: 767.98px) {
+ .migrate-entries {
+ grid-template-columns: repeat(1, 1fr);
+ }
+}
+
+.migrate-entry {
+ transition: all 0.1s ease-in-out;
+ box-shadow: none !important;
+ border: 1px solid var(--color-secondary);
+ color: var(--color-text) !important;
+ width: auto !important;
+ margin: 0 !important;
+}
+
+.migrate-entry:hover {
+ transform: scale(105%);
+ box-shadow: 0 0.5rem 1rem var(--color-shadow) !important;
+}
+
+.migrate-entry .description {
+ text-wrap: balance;
+}
+
+.commits-table .commits-table-right form {
+ display: flex;
+ align-items: center;
+ gap: 0.75em;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+@media (max-width: 767.98px) {
+ .repository.file.list #repo-files-table .entry,
+ .repository.file.list #repo-files-table .commit-list {
+ align-items: center;
+ display: flex !important;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ }
+ .repository.file.list #repo-files-table .entry td.age,
+ .repository.file.list #repo-files-table .commit-list td.age,
+ .repository.file.list #repo-files-table .entry th.age,
+ .repository.file.list #repo-files-table .commit-list th.age {
+ margin-left: auto;
+ }
+ .repository.file.list #repo-files-table .entry td.message,
+ .repository.file.list #repo-files-table .commit-list td.message,
+ .repository.file.list #repo-files-table .entry span.commit-summary,
+ .repository.file.list #repo-files-table .commit-list tr span.commit-summary {
+ display: none !important;
+ }
+ .repository.view.issue .comment-list .timeline,
+ .repository.view.issue .comment-list .timeline-item {
+ margin-left: 0;
+ }
+ .repository.view.issue .comment-list .timeline::before {
+ left: 14px;
+ }
+ .repository.view.issue .comment-list .timeline .inline-timeline-avatar {
+ display: flex;
+ margin-bottom: auto;
+ margin-left: 6px;
+ margin-right: 2px;
+ }
+ .repository.view.issue .comment-list .timeline .comment-header {
+ padding-left: 4px;
+ }
+ .repository.view.issue .comment-list .timeline .comment-header::before,
+ .repository.view.issue .comment-list .timeline .comment-header::after {
+ content: unset;
+ }
+ /* Don't show the general avatar, we show the inline avatar on mobile.
+ * And don't show the role labels, there's no place for that. */
+ .repository.view.issue .comment-list .timeline .timeline-avatar,
+ .repository.view.issue .comment-list .timeline .comment-header-right .role-label {
+ display: none;
+ }
+ .commit-header-row .ui.horizontal.list {
+ width: 100%;
+ overflow-x: auto;
+ margin-top: 2px;
+ }
+ .commit-header-row .ui.horizontal.list .item {
+ align-items: center;
+ display: flex;
+ }
+ .commit-header-row .author {
+ padding: 3px 0;
+ }
+ .commit-header h3 {
+ flex-basis: auto !important;
+ margin-bottom: 0.5rem !important;
+ }
+ .commits-table {
+ flex-direction: column;
+ }
+ .commits-table .commits-table-left {
+ align-items: initial !important;
+ margin-bottom: 6px;
+ }
+ .commits-table .commits-table-right form > div:nth-child(1) {
+ order: 1; /* the "commit search" input */
+ }
+ .commits-table .commits-table-right form > div:nth-child(2) {
+ order: 3; /* the "search all" checkbox */
+ }
+ .commits-table .commits-table-right form > button:nth-child(3) {
+ order: 2; /* the "search" button */
+ }
+ .commit-table {
+ overflow-x: auto;
+ }
+ .commit-table td.sha,
+ .commit-table th.sha {
+ display: none !important;
+ }
+ .comment-header {
+ flex-wrap: wrap;
+ }
+ .comment-header .comment-header-left {
+ flex-wrap: wrap;
+ }
+ .comment-header .comment-header-right {
+ margin-left: auto;
+ }
+}
+
+.branch-dropdown-button {
+ max-width: 340px;
+ vertical-align: bottom !important;
+}
+
+@media (min-width: 768px) and (max-width: 991.98px) {
+ .branch-dropdown-button {
+ max-width: 185px;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .branch-dropdown-button {
+ max-width: 165px;
+ }
+}
+
+.commit-status-header {
+ /* reset the default ".ui.attached.header" styles, to use the outer border */
+ border: none !important;
+ /* add a bottom border to make sure the there is always a divider between the header and list when the list is scrolling */
+ border-bottom: 1px solid var(--color-secondary) !important;
+ /* use negative margin to avoid the newly added border conflict with the list's top border */
+ margin: 0 0 -1px !important;
+}
+
+.commit-status-list {
+ max-height: 240px; /* fit exactly 6 items, commit-status-item.height * 6 */
+ overflow-x: hidden;
+ transition: max-height .2s;
+}
+
+.commit-status-item {
+ height: 40px;
+ padding: 0 10px;
+ display: flex;
+ gap: 8px;
+ align-items: center;
+}
+
+.commit-status-item + .commit-status-item {
+ border-top: 1px solid var(--color-secondary);
+}
+
+.commit-status-item .commit-status {
+ flex-shrink: 0;
+}
+
+.commit-status-item .status-context {
+ color: var(--color-text);
+ flex: 1;
+}
+
+.commit-status-item .status-details {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 8px;
+}
+
+@media (max-width: 767.98px) {
+ .commit-status-item .status-details {
+ flex-direction: column;
+ align-items: flex-end;
+ justify-content: center;
+ }
+}
+
+.commit-status-item .status-details > span {
+ padding-right: 0.5em; /* To match the alignment with the "required" label */
+}
+
+.search-fullname {
+ color: var(--color-text-light-2);
+}
+
+#issue-pins {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 8px;
+ margin-bottom: 8px;
+}
+
+@media (max-width: 767.98px) {
+ #issue-pins {
+ grid-template-columns: repeat(1, 1fr);
+ }
+}
+
+#cherry-pick-modal .scrolling.menu {
+ max-height: 200px;
+}
+
+/* Branch tag selector - TODO: Merge this into the same selector on repo page */
+.repository .issue-content .issue-content-right .ui.grid .column.row {
+ padding: 10px;
+ padding-bottom: 0;
+}
+.repository .issue-content .issue-content-right .ui.grid .column.muted {
+ padding: 0;
+}
+.repository .issue-content .issue-content-right .ui.grid .column.muted .text {
+ display: inline-block;
+ padding: 10px;
+ width: 100%;
+ text-align: center;
+ border: 1px solid transparent;
+ border-bottom: none;
+}
+.repository .issue-content .issue-content-right .ui.grid .column.muted .text.black {
+ border-color: var(--color-secondary);
+ background: var(--color-menu);
+ border-top-left-radius: var(--border-radius);
+ border-top-right-radius: var(--border-radius);
+}
+.repository .issue-content .issue-content-right .ui.dropdown .scrolling.menu {
+ border-top: none;
+}
+.repository .issue-content .issue-content-right .branch-tag-divider {
+ margin-top: -1px;
+ border-top: 1px solid var(--color-secondary);
+}
+#issue-info-popup .emoji {
+ font-size: inherit;
+ line-height: inherit;
+}
+
+#repo-activity-top-authors-chart {
+ height: 150px; /* Pre-allocate the height that will be taken up by the chart, to avoid the container 'jumping'. */
+}
diff --git a/web_src/css/repo/header.css b/web_src/css/repo/header.css
new file mode 100644
index 00000000..9da5fe6a
--- /dev/null
+++ b/web_src/css/repo/header.css
@@ -0,0 +1,68 @@
+.repository .secondary-nav {
+ padding-top: 12px;
+}
+
+.repository .secondary-nav .fork-flag {
+ margin-top: 0.5rem;
+ font-size: 12px;
+}
+
+.repo-header {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: space-between;
+ gap: 0.5rem;
+ margin-bottom: 4px;
+}
+
+.repo-header .flex-item {
+ padding: 0;
+}
+
+.repo-header .flex-item-main {
+ flex: 0;
+ flex-basis: unset;
+}
+
+.repo-header .flex-item-trailing {
+ flex-wrap: nowrap;
+}
+
+.repo-buttons {
+ align-items: center;
+ display: flex;
+ flex-flow: row wrap;
+ word-break: keep-all;
+}
+
+.repo-buttons .ui.labeled.button > .label:hover {
+ color: var(--color-primary-light-2);
+ background: var(--color-light);
+}
+
+.repo-buttons button[disabled] ~ .label {
+ opacity: var(--opacity-disabled);
+ color: var(--color-text-dark);
+ background: var(--color-light-mimic-enabled) !important;
+}
+
+.repo-buttons button[disabled] ~ .label:hover {
+ color: var(--color-primary-dark-1);
+}
+
+.repo-buttons .ui.labeled.button.disabled {
+ pointer-events: inherit !important;
+}
+
+.repo-buttons .ui.labeled.button.disabled > .label {
+ color: var(--color-text-dark);
+ background: var(--color-light-mimic-enabled) !important;
+}
+
+.repo-buttons .ui.labeled.button.disabled > .label:hover {
+ color: var(--color-primary-dark-1);
+}
+
+.repo-buttons .ui.labeled.button.disabled > .button {
+ pointer-events: none !important;
+}
diff --git a/web_src/css/repo/issue-card.css b/web_src/css/repo/issue-card.css
new file mode 100644
index 00000000..fb832bd0
--- /dev/null
+++ b/web_src/css/repo/issue-card.css
@@ -0,0 +1,40 @@
+.issue-card {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ align-items: stretch;
+ border-radius: var(--border-radius);
+ padding: 8px 10px;
+ border: 1px solid var(--color-secondary);
+ background: var(--color-card);
+}
+
+.issue-card-icon,
+.issue-card-unpin {
+ margin-top: 1px;
+ flex-shrink: 0;
+}
+
+.issue-card-title {
+ flex: 1;
+ font-size: 14px;
+}
+
+.issue-card.sortable-chosen .issue-card-title {
+ cursor: inherit;
+}
+
+.issue-card-bottom {
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ gap: 0.25em;
+}
+
+.issue-card-assignees {
+ display: flex;
+ align-items: center;
+ gap: 0.25em;
+ justify-content: end;
+ flex-wrap: wrap;
+}
diff --git a/web_src/css/repo/issue-label.css b/web_src/css/repo/issue-label.css
new file mode 100644
index 00000000..9b4b144a
--- /dev/null
+++ b/web_src/css/repo/issue-label.css
@@ -0,0 +1,52 @@
+.issue-label-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.issue-label-list .item {
+ border-bottom: 1px solid var(--color-secondary);
+ display: flex;
+ padding: 1em 0;
+ margin: 0;
+}
+
+.issue-label-list .item:first-child {
+ padding-top: 0;
+}
+
+.issue-label-list .item:last-child {
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.issue-label-list .item .label-title {
+ width: 33%;
+}
+
+.issue-label-list .item .label-issues {
+ width: 33%;
+}
+
+.issue-label-list .item .label-operation {
+ width: 33%;
+}
+
+.issue-label-list .item a {
+ font-size: 12px;
+ padding-right: 10px;
+ color: var(--color-text-light);
+}
+
+.issue-label-list .item.org-label {
+ opacity: 0.7;
+}
+
+.label-operation .label {
+ height: fit-content;
+}
+
+.archived-label-hint {
+ float: right;
+ margin: -12px;
+}
diff --git a/web_src/css/repo/issue-list.css b/web_src/css/repo/issue-list.css
new file mode 100644
index 00000000..9143b013
--- /dev/null
+++ b/web_src/css/repo/issue-list.css
@@ -0,0 +1,112 @@
+.issue-list-toolbar {
+ display: flex;
+ flex-wrap: wrap-reverse;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 1rem;
+ margin-top: 1rem;
+}
+
+.issue-list-toolbar-left {
+ display: flex;
+ align-items: center;
+}
+
+.issue-list-toolbar-right .filter.menu {
+ flex-direction: row;
+ flex-wrap: wrap;
+}
+
+.issue-list-new.button {
+ margin-right: 0;
+}
+
+.list-header-issues {
+ min-height: var(--repo-header-issue-min-height);
+}
+
+@media (max-width: 767.98px) {
+ .issue-list-navbar {
+ order: 0;
+ }
+ .issue-list-new {
+ order: 1;
+ margin-left: auto !important;
+ }
+ .issue-list-search {
+ order: 2 !important;
+ }
+ /* Don't use flex wrap on mobile as it takes too much vertical space.
+ * Only set overflow properties on mobile screens, because while the
+ * CSS trick to pop out from overflowing works on desktop screen, it
+ * has a massive flaw that it cannot inherited any max width from it's 'real'
+ * parent and therefor ends up taking more vertical space than is desired.
+ **/
+ .issue-list-toolbar-right .filter.menu {
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ overflow-y: hidden;
+ }
+
+ /* The following few CSS was created with care and built with the information
+ * from CSS-Tricks: https://css-tricks.com/popping-hidden-overflow/
+ */
+
+ /* It's important that every element up to .issue-list-toolbar-right doesn't
+ * have a position set, such that element that wants to pop out will use
+ * .issue-list-toolbar-right as 'clip parent' and thereby avoids the
+ * overflow-y: hidden.
+ */
+ .issue-list-toolbar-right .filter.menu > .dropdown.item {
+ position: initial;
+ }
+ /* It's important that this element and not an child has `position` set.
+ * Set width so that overflow-x knows where to stop overflowing.
+ */
+ .issue-list-toolbar-right {
+ position: relative;
+ width: 100%;
+ }
+}
+
+#issue-list .flex-item-body .branches {
+ display: inline-flex;
+}
+
+#issue-list .flex-item-body .branches .branch {
+ background-color: var(--color-secondary-alpha-50);
+ border-radius: var(--border-radius);
+ padding: 0 4px;
+}
+
+#issue-list .flex-item-body .branches .truncated-name {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 200px;
+ display: inline-block;
+ vertical-align: top;
+}
+
+#issue-list .flex-item-body .checklist progress {
+ margin-left: 2px;
+ width: 80px;
+ height: 6px;
+ display: inline-block;
+}
+
+#issue-list .flex-item-body .checklist progress::-webkit-progress-value {
+ background-color: var(--color-secondary-dark-4);
+}
+
+#issue-list .flex-item-body .checklist progress::-moz-progress-bar {
+ background-color: var(--color-secondary-dark-4);
+}
+
+.archived-label-filter {
+ margin-left: 10px;
+ font-size: 12px;
+ display: flex !important;
+ margin-bottom: 8px;
+ min-width: fit-content;
+}
diff --git a/web_src/css/repo/linebutton.css b/web_src/css/repo/linebutton.css
new file mode 100644
index 00000000..d32899a0
--- /dev/null
+++ b/web_src/css/repo/linebutton.css
@@ -0,0 +1,19 @@
+.code-view .lines-num:hover,
+.file-preview .lines-num:hover {
+ color: var(--color-text-dark) !important;
+}
+
+.code-line-button {
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ padding: 1px 4px !important;
+ position: absolute;
+ font-family: var(--fonts-regular);
+ left: 0;
+ transform: translateX(calc(-50% + 6px));
+ cursor: pointer;
+}
+
+.code-line-button:hover {
+ background: var(--color-secondary) !important;
+}
diff --git a/web_src/css/repo/list-header.css b/web_src/css/repo/list-header.css
new file mode 100644
index 00000000..304cfbc1
--- /dev/null
+++ b/web_src/css/repo/list-header.css
@@ -0,0 +1,58 @@
+.list-header {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: .5rem;
+}
+
+.list-header-sort {
+ display: flex;
+ align-items: center;
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+.list-header-search {
+ display: flex;
+ flex: 1;
+ align-items: center;
+ flex-wrap: wrap;
+ justify-content: center;
+ min-width: 200px; /* to enable flexbox wrapping on mobile */
+}
+
+.list-header-search .input {
+ flex: 1;
+}
+
+.small-menu-items {
+ min-height: 35.4px !important; /* match .small.button in height */
+ background: none !important; /* fomantic sets a color here which does not play well with active transparent color on the item, so unset and set the colors on the item */
+}
+
+.small-menu-items .item {
+ background: var(--color-menu) !important;
+ padding-top: 6px !important;
+ padding-bottom: 6px !important;
+}
+
+.small-menu-items .item:hover {
+ background: var(--color-hover) !important;
+}
+
+.small-menu-items .item.active {
+ background: var(--color-active) !important;
+}
+
+@media (max-width: 767.98px) {
+ .list-header-search {
+ order: 0;
+ }
+ .list-header-toggle {
+ order: 1;
+ }
+ .list-header-sort {
+ order: 2;
+ margin-left: auto;
+ }
+}
diff --git a/web_src/css/repo/release-tag.css b/web_src/css/repo/release-tag.css
new file mode 100644
index 00000000..429a4690
--- /dev/null
+++ b/web_src/css/repo/release-tag.css
@@ -0,0 +1,125 @@
+.repository.releases #release-list {
+ margin-top: 12px;
+ padding-top: 12px;
+ padding-left: 0;
+}
+
+.repository.releases #release-list .release-list-title {
+ font-size: 2rem;
+ font-weight: var(--font-weight-normal);
+ display: flex;
+ align-items: center;
+ gap: 0.25em;
+ margin: 0;
+}
+
+.repository.releases #release-list > li .meta {
+ padding-top: 25px;
+ position: relative;
+ text-align: right;
+ display: flex;
+ flex-direction: column;
+ gap: 1em;
+}
+
+.repository.releases #release-list > li .detail {
+ padding-bottom: 20px;
+ border-left: 1px solid var(--color-secondary);
+}
+
+.repository.releases #release-list > li .detail .author img {
+ margin-bottom: 2px; /* the legacy trick to align the avatar vertically, no better solution at the moment */
+}
+
+.repository.releases #release-list > li .detail .download .list {
+ padding-left: 0;
+}
+
+.repository.releases #release-list > li .detail .download .list li {
+ background: var(--color-light);
+ border: 1px solid var(--color-secondary);
+ border-top: none;
+ display: flex;
+ justify-content: space-between;
+ padding: 8px;
+}
+
+.repository.releases #release-list > li .detail .download .list :is(li:first-child, .start-gap + hr + li) {
+ border-top: 1px solid var(--color-secondary);
+ border-top-left-radius: var(--border-radius);
+ border-top-right-radius: var(--border-radius);
+}
+
+.repository.releases #release-list > li .detail .download .list :is(li:last-child, .start-gap) {
+ border-bottom: 1px solid var(--color-secondary);
+ border-bottom-left-radius: var(--border-radius);
+ border-bottom-right-radius: var(--border-radius);
+}
+
+.repository.releases #release-list > li .detail .download .list hr {
+ height: 8px;
+ margin: 0;
+}
+
+.repository.releases #release-list > li .detail .dot {
+ width: 10px;
+ height: 10px;
+ background-color: var(--color-secondary-dark-3);
+ position: absolute;
+ left: -5.5px;
+ top: 30px;
+ border-radius: var(--border-radius-full);
+ border: 2.5px solid var(--color-body);
+}
+
+.repository.tags #tags-table .tag {
+ padding: 8px 12px;
+}
+
+.repository.tags #tags-table .release-tag-name {
+ font-size: 18px;
+ font-weight: var(--font-weight-normal);
+}
+
+.repository.new.release .target {
+ min-width: 500px;
+}
+
+.repository.new.release .target #tag-name {
+ margin-top: -4px;
+}
+
+.repository.new.release .target .at {
+ margin-left: -5px;
+ margin-right: 5px;
+}
+
+.repository.new.release .target .selection.dropdown {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.repository.new.release .prerelease.field {
+ margin-bottom: 0;
+}
+
+@media (max-width: 438px) {
+ .repository.new.release .field button,
+ .repository.new.release .field input {
+ width: 100%;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .repository.new.release .field button {
+ margin-bottom: 1em;
+ }
+}
+
+.repository.new.release .field .attachment_edit {
+ max-width: 48em;
+}
+
+.repository.new.release .markup {
+ min-height: 240px;
+}
diff --git a/web_src/css/repo/wiki.css b/web_src/css/repo/wiki.css
new file mode 100644
index 00000000..ba502d32
--- /dev/null
+++ b/web_src/css/repo/wiki.css
@@ -0,0 +1,72 @@
+.repository.wiki .wiki-pages-list tr:hover {
+ background-color: var(--color-hover);
+}
+
+.repository.wiki .wiki-pages-list .wiki-git-entry {
+ margin-left: 10px;
+ display: none;
+}
+
+.repository.wiki .wiki-pages-list tr:hover .wiki-git-entry {
+ display: inline-block;
+}
+
+.repository.wiki .markup {
+ overflow: visible;
+}
+
+.repository.wiki .markup[data-tab-panel="markdown-previewer"] {
+ min-height: 340px; /* This height matches the markdown editor's height */
+}
+
+.repository.wiki .wiki-content-parts .markup {
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+ padding: 1em;
+ margin-top: 1em;
+ font-size: 1em;
+}
+
+.repository.wiki .wiki-content-main.with-sidebar {
+ float: left;
+ width: 80%;
+ max-width: calc(100% - 150px - 1em); /* match the min-width of .wiki-content-sidebar */
+}
+
+.repository.wiki .wiki-content-sidebar {
+ float: right;
+ width: calc(20% - 1em);
+ min-width: 150px;
+}
+
+.repository.wiki .wiki-content-sidebar .ui.message.unicode-escape-prompt p {
+ display: none;
+}
+
+.repository.wiki .wiki-content-footer {
+ margin-top: 1em;
+}
+
+.repository.wiki .wiki-content-toc ul {
+ margin: 0;
+ list-style: none;
+ padding: 5px 0 5px 1em;
+}
+
+.repository.wiki .wiki-content-toc ul ul {
+ border-left: 1px var(--color-secondary);
+ border-left-style: dashed;
+}
+
+@media (max-width: 767.98px) {
+ .repository.wiki .clone-panel #repo-clone-url {
+ width: 160px;
+ }
+ .repository.wiki .wiki-content-main.with-sidebar,
+ .repository.wiki .wiki-content-sidebar {
+ float: none;
+ width: 100%;
+ min-width: unset;
+ max-width: unset;
+ }
+}
diff --git a/web_src/css/review.css b/web_src/css/review.css
new file mode 100644
index 00000000..a198edf6
--- /dev/null
+++ b/web_src/css/review.css
@@ -0,0 +1,297 @@
+.show-outdated,
+.hide-outdated {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ user-select: none;
+}
+
+.ui.button.add-code-comment {
+ padding: 2px;
+ position: absolute;
+ margin-left: -22px;
+ z-index: 5;
+ opacity: 0;
+ transition: transform 0.1s ease-in-out;
+ transform: scale(1);
+ box-shadow: none !important;
+ border: none !important;
+}
+
+.ui.button.add-code-comment:hover {
+ transform: scale(1.1);
+}
+
+.lines-escape .toggle-escape-button::before {
+ visibility: visible;
+ content: "⚠️";
+ font-family: var(--fonts-emoji);
+ color: var(--color-red);
+}
+
+.repository .diff-file-box .code-diff td.lines-escape {
+ padding-left: 0 !important;
+}
+
+.diff-file-box .lines-code:hover .ui.button.add-code-comment {
+ opacity: 1;
+}
+
+.ui.button.add-code-comment:focus {
+ opacity: 1;
+}
+
+.repository .diff-file-box .code-diff .add-comment-left,
+.repository .diff-file-box .code-diff .add-comment-right,
+.repository .diff-file-box .code-diff .add-code-comment .add-comment-left,
+.repository .diff-file-box .code-diff .add-code-comment .add-comment-right,
+.repository .diff-file-box .code-diff .add-code-comment .lines-type-marker {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+}
+
+.add-comment-left.add-comment-right .ui.attached.header {
+ border: 1px solid var(--color-secondary);
+}
+
+.add-comment-left.add-comment-right .ui.attached.header:not(.top) {
+ margin-bottom: 0.5em;
+}
+
+.show-outdated:hover,
+.hide-outdated:hover {
+ text-decoration: underline;
+}
+
+.comment-code-cloud {
+ padding: 0.5rem 1rem !important;
+ position: relative;
+}
+
+.code-diff .conversation-holder .comment-code-cloud {
+ max-width: 820px;
+}
+
+@media (max-width: 767.98px) {
+ .comment-code-cloud {
+ max-width: none;
+ padding: 0.75rem !important;
+ }
+ .comment-code-cloud .code-comment-buttons {
+ margin: 0.5rem 0 0.25rem !important;
+ }
+ .comment-code-cloud .code-comment-buttons .code-comment-buttons-buttons {
+ width: 100%;
+ }
+ .comment-code-cloud .ui.buttons {
+ width: 100%;
+ margin: 0 !important;
+ }
+ .comment-code-cloud .ui.buttons .button {
+ flex: 1;
+ }
+}
+
+.comment-code-cloud .comments .comment {
+ padding: 0;
+}
+
+@media (max-width: 767.98px) {
+ .comment-code-cloud .comments .comment .comment-header-right.actions .ui.basic.label {
+ display: none;
+ }
+ .comment-code-cloud .comments .comment .avatar {
+ width: auto;
+ float: none;
+ margin: 0 0.5rem 0 0;
+ flex-shrink: 0;
+ }
+ .comment-code-cloud .comments .comment .avatar ~ .content {
+ margin-left: 1em;
+ }
+ .comment-code-cloud .comments .comment img.avatar {
+ margin: 0 !important;
+ }
+ .comment-code-cloud .comments .comment .comment-content {
+ margin-left: 0 !important;
+ }
+ .comment-code-cloud .comments .comment .comment-container {
+ width: 100%;
+ }
+ .comment-code-cloud .comments .comment.code-comment {
+ padding: 0 0 0.5rem !important;
+ }
+}
+
+.comment-code-cloud .attached.tab {
+ border: 0;
+ padding: 0;
+ margin: 0;
+}
+
+.comment-code-cloud .attached.header {
+ padding: 1px 8px 1px 12px;
+}
+
+.comment-code-cloud .attached.header .text {
+ margin: 0;
+}
+
+.comment-code-cloud .right.menu.options .item {
+ padding: 0.85714286em 0.442857em;
+ cursor: pointer;
+}
+
+.comment-code-cloud .ui.active.tab {
+ padding: 0.5em;
+}
+
+.comment-code-cloud .ui.active.tab.markup {
+ padding: 1em;
+ min-height: 168px;
+}
+
+.comment-code-cloud .ui.tab.markup {
+ font-size: 14px;
+}
+
+.comment-code-cloud .ui.tabular.menu {
+ margin: 0.5em;
+}
+
+.comment-code-cloud .editor-statusbar {
+ display: none;
+}
+
+.comment-code-cloud .footer {
+ padding: 10px 0;
+}
+
+.comment-code-cloud .footer .markup-info {
+ display: inline-block;
+ margin: 5px 0;
+ font-size: 12px;
+ color: var(--color-text-light);
+}
+
+.comment-code-cloud .footer .ui.right.floated {
+ padding-top: 6px;
+}
+
+.comment-code-cloud .footer::after {
+ clear: both;
+ content: "";
+ display: block;
+}
+
+@media (max-width: 767.98px) {
+ .comment-code-cloud .button {
+ width: 100%;
+ margin: 0 !important;
+ margin-bottom: 0.75rem !important;
+ }
+}
+
+.diff-file-body .comment-form {
+ margin: 0 0 0 3em;
+}
+
+.diff-file-body.binary {
+ padding: 5px 10px;
+}
+
+.file-comment {
+ color: var(--color-text);
+}
+
+.code-expander-button {
+ border: none;
+ color: var(--color-text-light);
+ height: 28px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ background: var(--color-expand-button);
+ flex: 1;
+}
+
+.code-expander-button:hover {
+ background: var(--color-primary);
+ color: var(--color-primary-contrast);
+}
+
+.review-box-panel .ui.segment {
+ border: none;
+}
+
+/* See the comment of createCommentEasyMDE() for the review editor */
+/* EasyMDE's options can not handle minHeight & maxHeight together correctly, we have to set minHeight in JS code */
+.review-box-panel .CodeMirror-scroll {
+ min-height: 80px;
+ max-height: calc(100vh - 360px);
+}
+
+.review-box-panel .combo-markdown-editor {
+ width: 730px; /* this width matches current EasyMDE's toolbar's width */
+ max-width: calc(100vw - 70px); /* leave enough space on left, and align the page content */
+}
+
+#review-box {
+ position: relative;
+}
+
+#review-box .review-comments-counter {
+ background-color: var(--color-primary-light-4);
+ color: var(--color-primary-contrast);
+}
+
+#review-box:hover .review-comments-counter {
+ background-color: var(--color-primary-light-5);
+}
+
+#review-box .review-comments-counter[data-pending-comment-number="0"] {
+ display: none;
+}
+
+.pull.files.diff .comment {
+ scroll-margin-top: 99px;
+}
+
+@media (max-width: 991.98px) {
+ .pull.files.diff .comment {
+ scroll-margin-top: 130px;
+ }
+}
+
+.changed-since-last-review {
+ border: 1px var(--color-accent) solid;
+ background-color: var(--color-small-accent);
+ border-radius: var(--border-radius);
+ padding: 4px 8px;
+ margin: -8px 0; /* just like other buttons in the diff box header */
+ font-size: 0.857rem; /* just like .ui.tiny.button */
+}
+
+.viewed-file-form {
+ display: flex;
+ align-items: center;
+ border: 1px solid transparent;
+ padding: 4px 8px;
+ margin: -8px 0; /* just like other buttons in the diff box header */
+ border-radius: var(--border-radius);
+ font-size: 0.857rem; /* just like .ui.tiny.button */
+}
+
+.viewed-file-form input {
+ margin-right: 4px;
+}
+
+.viewed-file-checked-form {
+ background-color: var(--color-small-accent);
+ border-color: var(--color-accent);
+}
+
+#viewed-files-summary {
+ width: 100%;
+ height: 8px;
+}
diff --git a/web_src/css/shared/flex-list.css b/web_src/css/shared/flex-list.css
new file mode 100644
index 00000000..0f547792
--- /dev/null
+++ b/web_src/css/shared/flex-list.css
@@ -0,0 +1,108 @@
+.flex-list {
+ list-style: none;
+}
+
+.flex-item {
+ display: flex;
+ gap: 8px;
+ align-items: flex-start;
+ padding: 10px 0;
+}
+
+.flex-item .flex-item-leading {
+ display: flex;
+ align-items: flex-start;
+}
+
+.flex-item .flex-item-main {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ flex-basis: 60%; /* avoid wrapping the "flex-item-trailing" too aggressively */
+ min-width: 0; /* make the "text truncate" work, otherwise the flex axis is not limited and the text just overflows */
+}
+
+.flex-item-header {
+ display: flex;
+ gap: .25rem;
+ justify-content: space-between;
+ flex-wrap: wrap;
+}
+
+.flex-item a:not(.label, .button):hover {
+ color: var(--color-primary) !important;
+}
+
+.flex-item .flex-item-icon {
+ align-self: baseline; /* mainly used by the issue list, to align the leading icon with the title */
+}
+
+.flex-item .flex-item-icon + .flex-item-main {
+ align-self: baseline;
+}
+
+.flex-item .flex-item-trailing {
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+ flex-grow: 0;
+ flex-wrap: wrap;
+ justify-content: end;
+}
+
+.flex-item .flex-item-title {
+ display: inline-flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: .25rem;
+ max-width: 100%;
+ color: var(--color-text);
+ font-size: 16px;
+ font-weight: var(--font-weight-semibold);
+ overflow-wrap: anywhere;
+ min-width: 0;
+}
+
+.flex-item .flex-item-title a {
+ color: var(--color-text);
+ overflow-wrap: anywhere;
+}
+
+.flex-item .flex-item-body {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: .25rem;
+ color: var(--color-text-light-2);
+ overflow-wrap: anywhere;
+}
+
+.flex-item .flex-item-body a {
+ color: inherit;
+ overflow-wrap: anywhere;
+}
+
+.flex-list > .flex-item + .flex-item {
+ border-top: 1px solid var(--color-secondary);
+}
+
+/* Fomantic UI segment has default "padding: 1em", so here it removes the padding-top and padding-bottom accordingly (there might also be some `tw-hidden` siblings).
+Developers could also use "flex-space-fitted" class to remove the first item's padding-top and the last item's padding-bottom */
+.flex-list.flex-space-fitted > .flex-item:first-child,
+.ui.segment > .flex-list > .flex-item:first-child {
+ padding-top: 0;
+}
+
+.flex-list.flex-space-fitted > .flex-item:last-child,
+.ui.segment > .flex-list > .flex-item:last-child {
+ padding-bottom: 0;
+}
+
+/* If there is a divider besides the flex-list, some padding/margin are not needs */
+.divider + .flex-list > .flex-item:first-child {
+ padding-top: 0;
+}
+
+.flex-list + .divider {
+ margin-top: 0;
+}
diff --git a/web_src/css/shared/milestone.css b/web_src/css/shared/milestone.css
new file mode 100644
index 00000000..91e6b5e3
--- /dev/null
+++ b/web_src/css/shared/milestone.css
@@ -0,0 +1,62 @@
+.milestone-list {
+ list-style: none;
+}
+
+.milestone-card {
+ width: 100%;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.milestone-card + .milestone-card {
+ border-top: 1px solid var(--color-secondary);
+}
+
+.milestone-card .content {
+ padding-top: 10px;
+}
+
+.milestone-header progress {
+ width: 200px;
+ height: 16px;
+}
+
+.milestone-header {
+ display: flex;
+ align-items: center;
+ margin: 0;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.milestone-toolbar {
+ padding-top: 5px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ justify-content: space-between;
+}
+
+.milestone-toolbar .group {
+ color: var(--color-text-light-2);
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.milestone-toolbar .group > a {
+ font-size: 15px;
+ color: var(--color-text-light-2);
+}
+
+.milestone-toolbar .group > a:hover {
+ color: var(--color-text);
+}
+
+@media (max-width: 767.98px) {
+ .milestone-card {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+}
diff --git a/web_src/css/shared/repoorg.css b/web_src/css/shared/repoorg.css
new file mode 100644
index 00000000..5573ae47
--- /dev/null
+++ b/web_src/css/shared/repoorg.css
@@ -0,0 +1,18 @@
+.repository .head .ui.header .text,
+.organization .head .ui.header .text {
+ vertical-align: middle;
+ font-size: 1.6rem;
+ margin-left: 15px;
+}
+
+.repository .ui.tabs.container,
+.organization .ui.tabs.container {
+ margin-top: 14px;
+ margin-bottom: 0;
+}
+
+.repository .head .ui.header .org-visibility .label,
+.organization .head .ui.header .org-visibility .label {
+ margin-left: 5px;
+ margin-top: 5px;
+}
diff --git a/web_src/css/shared/settings.css b/web_src/css/shared/settings.css
new file mode 100644
index 00000000..33f88615
--- /dev/null
+++ b/web_src/css/shared/settings.css
@@ -0,0 +1,37 @@
+details.toggleable-item {
+ user-select: none !important;
+ padding: 0 !important;
+}
+
+details.toggleable-item .menu {
+ margin: 4px 0 10px !important;
+}
+
+details.toggleable-item summary {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.92857143em 1.14285714em;
+}
+
+details.toggleable-item summary::marker, /* Chrome, Edge, Firefox */
+details.toggleable-item summary::-webkit-details-marker /* Safari */ {
+ display: none;
+}
+
+details.toggleable-item summary::after {
+ transition: transform 0.25s ease;
+ content: "";
+ width: 14px;
+ height: 14px;
+ mask-size: cover;
+ -webkit-mask-size: cover;
+ mask-image: var(--octicon-chevron-right);
+ -webkit-mask-image: var(--octicon-chevron-right);
+ background: currentcolor;
+ border: 1px solid var(--color-body); /* workaround https://bugzilla.mozilla.org/show_bug.cgi?id=1671784 */
+}
+
+details.toggleable-item[open] summary::after {
+ transform: rotate(90deg);
+}
diff --git a/web_src/css/standalone/devtest.css b/web_src/css/standalone/devtest.css
new file mode 100644
index 00000000..a7b00e1e
--- /dev/null
+++ b/web_src/css/standalone/devtest.css
@@ -0,0 +1,16 @@
+.button-sample-groups {
+ margin: 0; padding: 0;
+}
+
+.button-sample-groups .sample-group {
+ list-style: none; margin: 0; padding: 0;
+}
+
+.button-sample-groups .sample-group .ui.button {
+ margin-bottom: 5px;
+}
+
+h1, h2 {
+ margin: 0;
+ padding: 10px 0;
+}
diff --git a/web_src/css/standalone/swagger.css b/web_src/css/standalone/swagger.css
new file mode 100644
index 00000000..c32e3920
--- /dev/null
+++ b/web_src/css/standalone/swagger.css
@@ -0,0 +1,42 @@
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ background: #fff;
+}
+
+.swagger-back-link {
+ color: #1f69c0;
+ text-decoration: none;
+ position: absolute;
+ top: 1rem;
+ right: 1.5rem;
+ display: flex;
+ align-items: center;
+}
+
+.swagger-back-link:hover {
+ text-decoration: underline;
+}
+
+.swagger-back-link svg {
+ color: inherit;
+ fill: currentcolor;
+ margin-right: 0.5rem;
+}
+
+@media (prefers-color-scheme: dark) {
+ body {
+ background: #1e1e1e;
+ }
+ .swagger-ui, .swagger-back-link {
+ filter: invert(88%) hue-rotate(180deg);
+ }
+ .swagger-ui .microlight {
+ filter: invert(100%) hue-rotate(180deg);
+ }
+}
diff --git a/web_src/css/themes/theme-forgejo-auto-deuteranopia-protanopia.css b/web_src/css/themes/theme-forgejo-auto-deuteranopia-protanopia.css
new file mode 100644
index 00000000..5f97fa37
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-auto-deuteranopia-protanopia.css
@@ -0,0 +1,2 @@
+@import "theme-forgejo-light-deuteranopia-protanopia.css";
+@import "theme-forgejo-dark-deuteranopia-protanopia.css" (prefers-color-scheme: dark);
diff --git a/web_src/css/themes/theme-forgejo-auto-tritanopia.css b/web_src/css/themes/theme-forgejo-auto-tritanopia.css
new file mode 100644
index 00000000..256a7038
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-auto-tritanopia.css
@@ -0,0 +1,2 @@
+@import "theme-forgejo-light-tritanopia.css";
+@import "theme-forgejo-dark-tritanopia.css" (prefers-color-scheme: dark);
diff --git a/web_src/css/themes/theme-forgejo-auto.css b/web_src/css/themes/theme-forgejo-auto.css
new file mode 100644
index 00000000..ebf59942
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-auto.css
@@ -0,0 +1,2 @@
+@import "theme-forgejo-light.css";
+@import "theme-forgejo-dark.css" (prefers-color-scheme: dark);
diff --git a/web_src/css/themes/theme-forgejo-dark-deuteranopia-protanopia.css b/web_src/css/themes/theme-forgejo-dark-deuteranopia-protanopia.css
new file mode 100644
index 00000000..b30cfd6b
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-dark-deuteranopia-protanopia.css
@@ -0,0 +1,11 @@
+@import "./theme-forgejo-dark.css";
+
+:root {
+ --color-diff-removed-word-bg: #693f17;
+ --color-diff-removed-row-border: #693f17;
+ --color-diff-removed-row-bg: #221b17;
+ --color-diff-added-word-bg: #214d88;
+ --color-diff-added-row-border: #214d88;
+ --color-diff-added-row-bg: #13233a;
+ --color-code-bg: #0d1117;
+}
diff --git a/web_src/css/themes/theme-forgejo-dark-tritanopia.css b/web_src/css/themes/theme-forgejo-dark-tritanopia.css
new file mode 100644
index 00000000..aefdaa1b
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-dark-tritanopia.css
@@ -0,0 +1,11 @@
+@import "./theme-forgejo-dark.css";
+
+:root {
+ --color-diff-removed-word-bg: #792e2e;
+ --color-diff-removed-row-border: #792e2e;
+ --color-diff-removed-row-bg: #25171c;
+ --color-diff-added-word-bg: #214d88;
+ --color-diff-added-row-border: #214d88;
+ --color-diff-added-row-bg: #13233a;
+ --color-code-bg: #0d1117;
+}
diff --git a/web_src/css/themes/theme-forgejo-dark.css b/web_src/css/themes/theme-forgejo-dark.css
new file mode 100644
index 00000000..9622add8
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-dark.css
@@ -0,0 +1,340 @@
+@import "../chroma/dark.css";
+@import "../codemirror/dark.css";
+@import "../markup/dark.css";
+
+:root {
+ --steel-900: #10161d;
+ --steel-850: #131a21;
+ --steel-800: #171e26;
+ --steel-750: #1d262f;
+ --steel-700: #242d38;
+ --steel-650: #2b3642;
+ --steel-600: #374351;
+ --steel-550: #445161;
+ --steel-500: #515f70;
+ --steel-450: #5f6e80;
+ --steel-400: #6d7d8f;
+ --steel-350: #7c8c9f;
+ --steel-300: #8c9caf;
+ --steel-250: #9dadc0;
+ --steel-200: #aebed0;
+ --steel-150: #c0cfe0;
+ --steel-100: #d2e0f0;
+ --is-dark-theme: true;
+ --color-primary: #fb923c;
+ --color-primary-contrast: #000;
+ --color-primary-dark-1: #fdba74;
+ --color-primary-dark-2: #fdba74;
+ --color-primary-dark-3: #fed7aa;
+ --color-primary-dark-4: #fed7aa;
+ --color-primary-dark-5: #ffedd5;
+ --color-primary-dark-6: #ffedd5;
+ --color-primary-dark-7: #fff7ed;
+ --color-primary-light-1: #f97316;
+ --color-primary-light-2: #ea580c;
+ --color-primary-light-3: #c2410c;
+ --color-primary-light-4: #9a3412;
+ --color-primary-light-5: #9a3412;
+ --color-primary-light-6: #7c2d12;
+ --color-primary-light-7: #7c2d12;
+ --color-primary-alpha-10: #ea580c19;
+ --color-primary-alpha-20: #ea580c33;
+ --color-primary-alpha-30: #ea580c4b;
+ --color-primary-alpha-40: #ea580c66;
+ --color-primary-alpha-50: #ea580c80;
+ --color-primary-alpha-60: #ea580c99;
+ --color-primary-alpha-70: #ea580cb3;
+ --color-primary-alpha-80: #ea580ccc;
+ --color-primary-alpha-90: #ea580ce1;
+ --color-primary-hover: var(--color-primary-light-1);
+ --color-primary-active: var(--color-primary-light-2);
+ --color-secondary: var(--steel-700);
+ --color-secondary-dark-1: var(--steel-550);
+ --color-secondary-dark-2: var(--steel-500);
+ --color-secondary-dark-3: var(--steel-450);
+ --color-secondary-dark-4: var(--steel-400);
+ --color-secondary-dark-5: var(--steel-350);
+ --color-secondary-dark-6: var(--steel-300);
+ --color-secondary-dark-7: var(--steel-250);
+ --color-secondary-dark-8: var(--steel-200);
+ --color-secondary-dark-9: var(--steel-150);
+ --color-secondary-dark-10: var(--steel-100);
+ --color-secondary-dark-11: var(--steel-100);
+ --color-secondary-dark-12: var(--steel-100);
+ --color-secondary-dark-13: var(--steel-100);
+ --color-secondary-light-1: var(--steel-650);
+ --color-secondary-light-2: var(--steel-700);
+ --color-secondary-light-3: var(--steel-750);
+ --color-secondary-light-4: var(--steel-800);
+ --color-secondary-alpha-10: #2b364219;
+ --color-secondary-alpha-20: #2b364233;
+ --color-secondary-alpha-30: #2b36424b;
+ --color-secondary-alpha-40: #2b364266;
+ --color-secondary-alpha-50: #2b364280;
+ --color-secondary-alpha-60: #2b364299;
+ --color-secondary-alpha-70: #2b3642b3;
+ --color-secondary-alpha-80: #2b3642cc;
+ --color-secondary-alpha-90: #2b3642e1;
+ --color-secondary-hover: var(--color-secondary-light-1);
+ --color-secondary-active: var(--color-secondary-light-2);
+ /* console colors - used for actions console and console files */
+ --color-console-fg: #eeeff2;
+ --color-console-fg-subtle: #959cab;
+ --color-console-bg: #1f212b;
+ --color-console-border: #383c47;
+ --color-console-hover-bg: #ffffff16;
+ --color-console-active-bg: #454a57;
+ --color-console-menu-bg: #383c47;
+ --color-console-menu-border: #5c6374;
+ /* colors */
+ --color-red: #b91c1c;
+ --color-orange: #ea580c;
+ --color-yellow: #ca8a04;
+ --color-olive: #91a313;
+ --color-green: #15803d;
+ --color-teal: #0d9488;
+ --color-blue: #2563eb;
+ --color-violet: #7c3aed;
+ --color-purple: #9333ea;
+ --color-pink: #db2777;
+ --color-brown: #a47252;
+ --color-grey: var(--steel-500);
+ --color-black: #111827;
+ /* light variants */
+ --color-red-light: #dc2626;
+ --color-orange-light: #f97316;
+ --color-yellow-light: #eab308;
+ --color-olive-light: #839311;
+ --color-green-light: #16a34a;
+ --color-teal-light: #14b8a6;
+ --color-blue-light: #3b82f6;
+ --color-violet-light: #8b5cf6;
+ --color-purple-light: #a855f7;
+ --color-pink-light: #ec4899;
+ --color-brown-light: #94674a;
+ --color-grey-light: var(--steel-300);
+ --color-black-light: #1f2937;
+ /* dark 1 variants produced via Sass scale-color(color, $lightness: -10%) */
+ --color-red-dark-1: #a71919;
+ --color-orange-dark-1: #d34f0b;
+ --color-yellow-dark-1: #b67c04;
+ --color-olive-dark-1: #839311;
+ --color-green-dark-1: #137337;
+ --color-teal-dark-1: #0c857a;
+ --color-blue-dark-1: #1554e0;
+ --color-violet-dark-1: #6a1feb;
+ --color-purple-dark-1: #8519e7;
+ --color-pink-dark-1: #c7216b;
+ --color-brown-dark-1: #94674a;
+ --color-black-dark-1: #0f1623;
+ /* dark 2 variants produced via Sass scale-color(color, $lightness: -20%) */
+ --color-red-dark-2: #941616;
+ --color-orange-dark-2: #bb460a;
+ --color-yellow-dark-2: #ca8a04;
+ --color-olive-dark-2: #91a313;
+ --color-green-dark-2: #15803d;
+ --color-teal-dark-2: #0a766d;
+ --color-blue-dark-2: #2563eb;
+ --color-violet-dark-2: #5c14d8;
+ --color-purple-dark-2: #7c3aed;
+ --color-pink-dark-2: #b11d5f;
+ --color-brown-dark-2: #a47252;
+ --color-black-dark-2: #111827;
+ /* other colors */
+ --color-gold: #b1983b;
+ --color-white: #ffffff;
+ --color-pure-black: #000000;
+ --color-diff-removed-word-bg: #783030;
+ --color-diff-added-word-bg: #255c39;
+ --color-diff-removed-row-bg: #432121;
+ --color-diff-moved-row-bg: #825718;
+ --color-diff-added-row-bg: #1b3625;
+ --color-diff-removed-row-border: #783030;
+ --color-diff-moved-row-border: #a67a1d;
+ --color-diff-added-row-border: #255c39;
+ --color-diff-inactive: var(--steel-650);
+ --color-error-border: #783030;
+ --color-error-bg: #5f2525;
+ --color-error-bg-active: #783030;
+ --color-error-bg-hover: #783030;
+ --color-error-text: #fef2f2;
+ --color-success-border: #1f6e3c;
+ --color-success-bg: #1d462c;
+ --color-success-text: #aef0c2;
+ --color-warning-border: #a67a1d;
+ --color-warning-bg: #644821;
+ --color-warning-text: #fff388;
+ --color-info-border: #2e50b0;
+ --color-info-bg: #2a396b;
+ --color-info-text: var(--steel-100);
+ --color-red-badge: #b91c1c;
+ --color-red-badge-bg: #b91c1c22;
+ --color-red-badge-hover-bg: #b91c1c44;
+ --color-green-badge: #16a34a;
+ --color-green-badge-bg: #16a34a22;
+ --color-green-badge-hover-bg: #16a34a44;
+ --color-yellow-badge: #ca8a04;
+ --color-yellow-badge-bg: #ca8a0422;
+ --color-yellow-badge-hover-bg: #ca8a0444;
+ --color-orange-badge: #ea580c;
+ --color-orange-badge-bg: #ea580c22;
+ --color-orange-badge-hover-bg: #ea580c44;
+ --color-git: #f05133;
+ /* Icon colors (PR/Issue/...) */
+ --color-icon-green: #3fb950;
+ --color-icon-red: #f85149;
+ --color-icon-purple: #aa76ff;
+ /* target-based colors */
+ --color-body: var(--steel-800);
+ --color-box-header: var(--steel-700);
+ --color-box-body: var(--steel-750);
+ --color-box-body-highlight: var(--steel-650);
+ --color-text-dark: #fff;
+ --color-text: var(--steel-100);
+ --color-text-light: var(--steel-150);
+ --color-text-light-1: var(--steel-150);
+ --color-text-light-2: var(--steel-200);
+ --color-text-light-3: var(--steel-200);
+ --color-footer: var(--steel-900);
+ --color-timeline: var(--steel-650);
+ --color-input-text: var(--steel-100);
+ --color-input-background: var(--steel-650);
+ --color-input-toggle-background: var(--steel-650);
+ --color-input-border: var(--steel-550);
+ --color-input-border-hover: var(--steel-450);
+ --color-header-wrapper: var(--steel-850);
+ --color-header-wrapper-transparent: #242d3800;
+ --color-light: #00000028;
+ --color-light-mimic-enabled: rgba(0, 0, 0, calc(40 / 255 * 222 / 255 / var(--opacity-disabled)));
+ --color-light-border: #ffffff28;
+ --color-hover: var(--steel-600);
+ --color-active: var(--steel-650);
+ --color-menu: var(--steel-700);
+ --color-card: var(--steel-700);
+ --color-markup-table-row: #ffffff06;
+ --color-markup-code-block: var(--steel-800);
+ --color-markup-code-inline: var(--steel-850);
+ --color-button: var(--steel-600);
+ --color-code-bg: var(--steel-750);
+ --color-shadow: #00000060;
+ --color-secondary-bg: var(--steel-700);
+ --color-text-focus: #fff;
+ --color-expand-button: #3c404d;
+ --color-placeholder-text: var(--color-text-light-3);
+ --color-editor-line-highlight: var(--steel-700);
+ --color-project-board-bg: var(--color-secondary-light-3);
+ --color-project-board-dark-label: var(--color-text-light-3);
+ --color-caret: var(--color-text);
+ /* should ideally be --color-text-dark, see #15651 */
+ --color-reaction-bg: #ffffff12;
+ --color-reaction-active-bg: var(--color-primary-alpha-30);
+ --color-reaction-hover-bg: var(--color-primary-alpha-40);
+ --color-tooltip-text: #ffffff;
+ --color-tooltip-bg: #000000f0;
+ --color-nav-bg: var(--steel-900);
+ --color-nav-hover-bg: var(--steel-600);
+ --color-nav-text: var(--color-text);
+ --color-secondary-nav-bg: var(--color-body);
+ --color-label-text: #fff;
+ --color-label-bg: var(--steel-600);
+ --color-label-hover-bg: var(--steel-550);
+ --color-label-active-bg: var(--steel-500);
+ --color-label-bg-alt: var(--steel-550);
+ --color-accent: var(--color-primary-light-1);
+ --color-small-accent: var(--color-primary-light-5);
+ --color-highlight-fg: var(--color-primary-light-4);
+ --color-highlight-bg: var(--color-primary-alpha-20);
+ --color-overlay-backdrop: #080808c0;
+ /* pattern colors for image diff */
+ --checkerboard-color-1: #474747;
+ --checkerboard-color-2: #313131;
+ accent-color: var(--color-accent);
+ color-scheme: dark;
+}
+/* invert emojis that are hard to read otherwise */
+.emoji[aria-label="check mark"],
+.emoji[aria-label="currency exchange"],
+.emoji[aria-label="TOP arrow"],
+.emoji[aria-label="END arrow"],
+.emoji[aria-label="ON! arrow"],
+.emoji[aria-label="SOON arrow"],
+.emoji[aria-label="heavy dollar sign"],
+.emoji[aria-label="copyright"],
+.emoji[aria-label="registered"],
+.emoji[aria-label="trade mark"],
+.emoji[aria-label="multiply"],
+.emoji[aria-label="plus"],
+.emoji[aria-label="minus"],
+.emoji[aria-label="divide"],
+.emoji[aria-label="curly loop"],
+.emoji[aria-label="double curly loop"],
+.emoji[aria-label="wavy dash"],
+.emoji[aria-label="paw prints"],
+.emoji[aria-label="musical note"],
+.emoji[aria-label="musical notes"] {
+ filter: invert(100%) hue-rotate(180deg);
+}
+i.grey.icon.icon.icon.icon {
+ color: var(--steel-350) !important;
+}
+.ui.secondary.vertical.menu {
+ border-radius: 0.28571429rem !important;
+ overflow: hidden;
+}
+.ui.basic.primary.button.item {
+ background-color: var(--color-active) !important;
+ color: var(--color-text) !important;
+ box-shadow: none !important;
+}
+.ui.red.label.notification_count,
+.ui.primary.label,
+.ui.primary.labels .label {
+ background-color: var(--color-primary-light-3) !important;
+}
+.repository.view.issue .comment-list .code-comment + .code-comment {
+ margin: 1.25rem 0 !important;
+ padding-top: 1.25rem !important;
+ border-top-color: var(--steel-650) !important;
+}
+.ui.labeled.icon.buttons > .button > .icon,
+.ui.labeled.icon.button > .icon {
+ background-color: var(--color-light) !important;
+}
+#review-box .review-comments-counter {
+ background-color: var(--color-shadow) !important;
+ color: var(--color-white) !important;
+ margin-left: 0.5em;
+}
+.ui.basic.labels .primary.label,
+.ui.ui.ui.basic.primary.label {
+ color: var(--color-text-dark) !important;
+}
+.ui.basic.yellow.label.pending-label {
+ background: var(--color-light) !important;
+}
+::selection {
+ background: var(--steel-100) !important;
+ color: var(--color-pure-black) !important;
+}
+strong.attention-important, svg.attention-important {
+ color: var(--color-violet-light);
+}
+strong.attention-note, svg.attention-note {
+ color: var(--color-blue-light);
+}
+strong.attention-caution, svg.attention-caution {
+ color: var(--color-red-light);
+}
+.ui.basic.red.button {
+ background-color: var(--color-red);
+ color: var(--color-white);
+}
+.ui.basic.red.button:hover,
+.ui.basic.red.button:focus {
+ background-color: var(--color-red-dark-1);
+ color: var(--color-white);
+}
+.ui.basic.red.button:active {
+ background-color: var(--color-red-dark-2);
+ color: var(--color-white);
+}
diff --git a/web_src/css/themes/theme-forgejo-light-deuteranopia-protanopia.css b/web_src/css/themes/theme-forgejo-light-deuteranopia-protanopia.css
new file mode 100644
index 00000000..eb48b759
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-light-deuteranopia-protanopia.css
@@ -0,0 +1,11 @@
+@import "./theme-forgejo-light.css";
+
+:root {
+ --color-diff-removed-word-bg: #ffdbb0;
+ --color-diff-removed-row-border: #ffdbb0;
+ --color-diff-removed-row-bg: #fffaf3;
+ --color-diff-added-word-bg: #b1dbff;
+ --color-diff-added-row-border: #b1dbff;
+ --color-diff-added-row-bg: #eef9ff;
+ --color-code-bg: #ffffff;
+}
diff --git a/web_src/css/themes/theme-forgejo-light-tritanopia.css b/web_src/css/themes/theme-forgejo-light-tritanopia.css
new file mode 100644
index 00000000..208da559
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-light-tritanopia.css
@@ -0,0 +1,11 @@
+@import "./theme-forgejo-light.css";
+
+:root {
+ --color-diff-removed-word-bg: #ffd0ce;
+ --color-diff-removed-row-border: #ffd0ce;
+ --color-diff-removed-row-bg: #fff5f4;
+ --color-diff-added-word-bg: #b1dbff;
+ --color-diff-added-row-border: #eef9ff;
+ --color-diff-added-row-bg: #eef9ff;
+ --color-code-bg: #ffffff;
+}
diff --git a/web_src/css/themes/theme-forgejo-light.css b/web_src/css/themes/theme-forgejo-light.css
new file mode 100644
index 00000000..20181896
--- /dev/null
+++ b/web_src/css/themes/theme-forgejo-light.css
@@ -0,0 +1,308 @@
+@import "../chroma/light.css";
+@import "../codemirror/light.css";
+@import "../markup/light.css";
+
+:root {
+ --steel-900: #10161d;
+ --steel-850: #131a21;
+ --steel-800: #171e26;
+ --steel-750: #1d262f;
+ --steel-700: #242d38;
+ --steel-650: #2b3642;
+ --steel-600: #374351;
+ --steel-550: #445161;
+ --steel-500: #515f70;
+ --steel-450: #5f6e80;
+ --steel-400: #6d7d8f;
+ --steel-350: #7c8c9f;
+ --steel-300: #8c9caf;
+ --steel-250: #9dadc0;
+ --steel-200: #aebed0;
+ --steel-150: #c0cfe0;
+ --steel-100: #d2e0f0;
+ --zinc-50: #fafafa;
+ --zinc-100: #f4f4f5;
+ --zinc-150: #ececee;
+ --zinc-200: #e4e4e7;
+ --zinc-250: #dcdce0;
+ --zinc-300: #d4d4d8;
+ --zinc-350: #babac1;
+ --zinc-400: #a1a1aa;
+ --zinc-450: #898992;
+ --zinc-500: #71717a;
+ --zinc-550: #61616a;
+ --zinc-600: #52525b;
+ --zinc-650: #484850;
+ --zinc-700: #3f3f46;
+ --zinc-750: #333338;
+ --zinc-800: #27272a;
+ --zinc-850: #1f1f23;
+ --zinc-900: #18181b;
+ --color-primary: #c2410c;
+ --color-primary-contrast: #ffffff;
+ --color-primary-dark-1: #c2410c;
+ --color-primary-dark-2: #9a3412;
+ --color-primary-dark-3: #9a3412;
+ --color-primary-dark-4: #7c2d12;
+ --color-primary-dark-5: #7c2d12;
+ --color-primary-dark-6: #7c2d12;
+ --color-primary-dark-7: #7c2d12;
+ --color-primary-light-1: #ea580c;
+ --color-primary-light-2: #f97316;
+ --color-primary-light-3: #fb923c;
+ --color-primary-light-4: #fdba74;
+ --color-primary-light-5: #fed7aa;
+ --color-primary-light-6: #ffedd5;
+ --color-primary-light-7: #fff7ed;
+ --color-primary-alpha-10: #c2410c19;
+ --color-primary-alpha-20: #c2410c33;
+ --color-primary-alpha-30: #c2410c4b;
+ --color-primary-alpha-40: #c2410c66;
+ --color-primary-alpha-50: #c2410c80;
+ --color-primary-alpha-60: #c2410c99;
+ --color-primary-alpha-70: #c2410cb3;
+ --color-primary-alpha-80: #c2410ccc;
+ --color-primary-alpha-90: #c2410ce1;
+ --color-primary-hover: var(--color-primary-dark-2);
+ --color-primary-active: var(--color-primary-dark-4);
+ --color-secondary: var(--zinc-200);
+ --color-secondary-dark-1: var(--zinc-200);
+ --color-secondary-dark-2: var(--zinc-300);
+ --color-secondary-dark-3: var(--zinc-300);
+ --color-secondary-dark-4: var(--zinc-400);
+ --color-secondary-dark-5: var(--zinc-400);
+ --color-secondary-dark-6: var(--zinc-500);
+ --color-secondary-dark-7: var(--zinc-500);
+ --color-secondary-dark-8: var(--zinc-600);
+ --color-secondary-dark-9: var(--zinc-600);
+ --color-secondary-dark-10: var(--zinc-700);
+ --color-secondary-dark-11: var(--zinc-700);
+ --color-secondary-dark-12: var(--zinc-800);
+ --color-secondary-dark-13: var(--zinc-800);
+ --color-secondary-light-1: var(--zinc-200);
+ --color-secondary-light-2: var(--zinc-100);
+ --color-secondary-light-3: var(--zinc-100);
+ --color-secondary-light-4: var(--zinc-50);
+ --color-secondary-alpha-10: #d4d4d819;
+ --color-secondary-alpha-20: #d4d4d833;
+ --color-secondary-alpha-30: #d4d4d84b;
+ --color-secondary-alpha-40: #d4d4d866;
+ --color-secondary-alpha-50: #d4d4d880;
+ --color-secondary-alpha-60: #d4d4d899;
+ --color-secondary-alpha-70: #d4d4d8b3;
+ --color-secondary-alpha-80: #d4d4d8cc;
+ --color-secondary-alpha-90: #d4d4d8e1;
+ --color-secondary-hover: var(--color-secondary-dark-2);
+ --color-secondary-active: var(--color-secondary-dark-4);
+ /* console colors - used for actions console and console files */
+ --color-console-fg: #eeeff2;
+ --color-console-fg-subtle: #959cab;
+ --color-console-bg: #1f212b;
+ --color-console-border: #383c47;
+ --color-console-hover-bg: #ffffff16;
+ --color-console-active-bg: #454a57;
+ --color-console-menu-bg: #383c47;
+ --color-console-menu-border: #5c6374;
+ /* colors */
+ --color-red: #dc2626;
+ --color-orange: #ea580c;
+ --color-yellow: #ca8a04;
+ --color-olive: #91a313;
+ --color-green: #15803d;
+ --color-teal: #0d9488;
+ --color-blue: #2563eb;
+ --color-violet: #7c3aed;
+ --color-purple: #9333ea;
+ --color-pink: #db2777;
+ --color-brown: #a47252;
+ --color-grey: #4b5563;
+ --color-black: #000000;
+ /* light variants */
+ --color-red-light: #ef4444;
+ --color-orange-light: #f97316;
+ --color-yellow-light: #eab308;
+ --color-olive-light: #839311;
+ --color-green-light: #16a34a;
+ --color-teal-light: #14b8a6;
+ --color-blue-light: #3b82f6;
+ --color-violet-light: #8b5cf6;
+ --color-purple-light: #a855f7;
+ --color-pink-light: #ec4899;
+ --color-brown-light: #94674a;
+ --color-grey-light: #6b7280;
+ --color-black-light: #181818;
+ /* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
+ --color-red-dark-1: #c82020;
+ --color-orange-dark-1: #d34f0b;
+ --color-yellow-dark-1: #b67c04;
+ --color-olive-dark-1: #839311;
+ --color-green-dark-1: #137337;
+ --color-teal-dark-1: #0c857a;
+ --color-blue-dark-1: #1554e0;
+ --color-violet-dark-1: #6a1feb;
+ --color-purple-dark-1: #8519e7;
+ --color-pink-dark-1: #c7216b;
+ --color-brown-dark-1: #94674a;
+ --color-black-dark-1: #000000;
+ /* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
+ --color-red-dark-2: #b21d1d;
+ --color-orange-dark-2: #bb460a;
+ --color-yellow-dark-2: #a26e03;
+ --color-olive-dark-2: #74820f;
+ --color-green-dark-2: #116631;
+ --color-teal-dark-2: #0a766d;
+ --color-blue-dark-2: #124bc7;
+ --color-violet-dark-2: #5c14d8;
+ --color-purple-dark-2: #7715cf;
+ --color-pink-dark-2: #b11d5f;
+ --color-brown-dark-2: #835b42;
+ --color-black-dark-2: #000000;
+ /* other colors */
+ --color-gold: #b1983b;
+ --color-white: #ffffff;
+ --color-diff-removed-word-bg: #fca5a5;
+ --color-diff-added-word-bg: #86efac;
+ --color-diff-removed-row-bg: #fee2e2;
+ --color-diff-moved-row-bg: #fef9c3;
+ --color-diff-added-row-bg: #dcfce7;
+ --color-diff-removed-row-border: #fca5a5;
+ --color-diff-moved-row-border: #fde047;
+ --color-diff-added-row-border: #86efac;
+ --color-diff-inactive: var(--zinc-100);
+ --color-error-border: #fecaca;
+ --color-error-bg: #fee2e2;
+ --color-error-bg-active: #fca5a5;
+ --color-error-bg-hover: #fecaca;
+ --color-error-text: #7f1d1d;
+ --color-success-border: #bbf7d0;
+ --color-success-bg: #dcfce7;
+ --color-success-text: #14532d;
+ --color-warning-border: #fde047;
+ --color-warning-bg: #fef3c7;
+ --color-warning-text: #78350f;
+ --color-info-border: #bae6fd;
+ --color-info-bg: #e0f2fe;
+ --color-info-text: #0c4a6e;
+ --color-red-badge: #b91c1c;
+ --color-red-badge-bg: #b91c1c22;
+ --color-red-badge-hover-bg: #b91c1c44;
+ --color-green-badge: #16a34a;
+ --color-green-badge-bg: #16a34a22;
+ --color-green-badge-hover-bg: #16a34a44;
+ --color-yellow-badge: #ca8a04;
+ --color-yellow-badge-bg: #ca8a0422;
+ --color-yellow-badge-hover-bg: #ca8a0444;
+ --color-orange-badge: #ea580c;
+ --color-orange-badge-bg: #ea580c22;
+ --color-orange-badge-hover-bg: #ea580c44;
+ --color-git: #f05133;
+ /* Icon colors (PR/Issue/...) */
+ --color-icon-green: var(--color-green-light);
+ --color-icon-red: var(--color-red-light);
+ --color-icon-purple: var(--color-purple-light);
+ /* target-based colors */
+ --color-body: #fff;
+ --color-box-header: var(--zinc-100);
+ --color-box-body: var(--zinc-50);
+ --color-box-body-highlight: var(--zinc-200);
+ --color-text-dark: #000;
+ --color-text: var(--zinc-900);
+ --color-text-light: var(--zinc-700);
+ --color-text-light-1: var(--zinc-650);
+ --color-text-light-2: var(--zinc-600);
+ --color-text-light-3: var(--zinc-550);
+ --color-footer: var(--zinc-100);
+ --color-timeline: var(--zinc-200);
+ --color-input-text: var(--zinc-800);
+ --color-input-background: #fff;
+ --color-input-toggle-background: #fff;
+ --color-input-border: var(--zinc-300);
+ --color-input-border-hover: var(--zinc-400);
+ --color-header-wrapper: var(--zinc-50);
+ --color-header-wrapper-transparent: #d2e0f000;
+ --color-light: #ffffffcc;
+ --color-light-mimic-enabled: rgba(0, 0, 0, calc(6 / 255 * 222 / 255 / var(--opacity-disabled)));
+ --color-light-border: #0000001d;
+ --color-hover: #e4e4e4aa;
+ --color-active: #d4d4d8aa;
+ --color-menu: var(--zinc-100);
+ --color-card: var(--zinc-50);
+ --color-markup-table-row: #ffffff06;
+ --color-markup-code-block: var(--zinc-150);
+ --color-markup-code-inline: var(--zinc-200);
+ --color-button: var(--zinc-150);
+ --color-code-bg: var(--zinc-50);
+ --color-shadow: #00000060;
+ --color-secondary-bg: var(--zinc-100);
+ --color-text-focus: #fff;
+ --color-expand-button: var(--zinc-200);
+ --color-placeholder-text: var(--color-text-light-3);
+ --color-editor-line-highlight: var(--zinc-100);
+ --color-project-board-bg: var(--color-secondary-light-2);
+ --color-project-board-dark-label: var(--color-text-light-3);
+ --color-caret: var(--color-text);
+ /* should ideally be --color-text-dark, see #15651 */
+ --color-reaction-bg: #0000000a;
+ --color-reaction-active-bg: var(--color-primary-alpha-20);
+ --color-reaction-hover-bg: var(--color-primary-alpha-30);
+ --color-tooltip-text: #ffffff;
+ --color-tooltip-bg: #000000f0;
+ --color-nav-bg: var(--zinc-100);
+ --color-nav-hover-bg: var(--zinc-300);
+ --color-nav-text: var(--color-text);
+ --color-secondary-nav-bg: var(--color-body);
+ --color-label-text: var(--color-text);
+ --color-label-bg: #cacaca5b;
+ --color-label-hover-bg: #cacacaa0;
+ --color-label-active-bg: #cacacaff;
+ --color-label-bg-alt: #cacacaff;
+ --color-accent: var(--color-primary-light-1);
+ --color-small-accent: var(--color-primary-light-5);
+ --color-highlight-fg: var(--color-primary-light-4);
+ --color-highlight-bg: var(--color-primary-light-6);
+ --color-overlay-backdrop: #080808c0;
+ /* pattern colors for gradient */
+ --checkerboard-color-1: #ffffff;
+ --checkerboard-color-2: #e5e5e5;
+ accent-color: var(--color-accent);
+ color-scheme: light;
+}
+.ui.secondary.vertical.menu {
+ border-radius: 0.28571429rem !important;
+ overflow: hidden;
+}
+.ui.basic.primary.button.item {
+ background-color: var(--color-active) !important;
+ color: var(--color-text) !important;
+ box-shadow: none !important;
+}
+.ui.red.label.notification_count,
+.ui.primary.labels .label {
+ background-color: var(--color-primary-dark-1) !important;
+}
+.repository.view.issue .comment-list .code-comment + .code-comment {
+ margin: 1.25rem 0 !important;
+ padding-top: 1.25rem !important;
+ border-top-color: var(--zinc-250) !important;
+}
+.ui.labeled.icon.buttons > .button > .icon,
+.ui.labeled.icon.button > .icon {
+ background-color: var(--color-shadow) !important;
+}
+#review-box .review-comments-counter {
+ background-color: var(--color-label-bg) !important;
+ margin-left: 0.5em;
+}
+.ui.basic.labels .primary.label,
+.ui.ui.ui.basic.primary.label {
+ color: var(--color-text-dark) !important;
+}
+.ui.basic.yellow.label.pending-label {
+ background: var(--color-warning-bg) !important;
+ color: var(--color-warning-text) !important;
+ border-color: var(--color-yellow-light) !important;
+}
+::selection {
+ background: var(--steel-450) !important;
+ color: var(--color-white) !important;
+}
diff --git a/web_src/css/themes/theme-gitea-auto.css b/web_src/css/themes/theme-gitea-auto.css
new file mode 100644
index 00000000..509889e8
--- /dev/null
+++ b/web_src/css/themes/theme-gitea-auto.css
@@ -0,0 +1,2 @@
+@import "./theme-gitea-light.css" (prefers-color-scheme: light);
+@import "./theme-gitea-dark.css" (prefers-color-scheme: dark);
diff --git a/web_src/css/themes/theme-gitea-dark.css b/web_src/css/themes/theme-gitea-dark.css
new file mode 100644
index 00000000..6ad6efe7
--- /dev/null
+++ b/web_src/css/themes/theme-gitea-dark.css
@@ -0,0 +1,271 @@
+@import "../chroma/dark.css";
+@import "../codemirror/dark.css";
+@import "../markup/dark.css";
+
+:root {
+ --is-dark-theme: true;
+ --color-primary: #4183c4;
+ --color-primary-contrast: #ffffff;
+ --color-primary-dark-1: #548fca;
+ --color-primary-dark-2: #679cd0;
+ --color-primary-dark-3: #7aa8d6;
+ --color-primary-dark-4: #8db5dc;
+ --color-primary-dark-5: #b3cde7;
+ --color-primary-dark-6: #d9e6f3;
+ --color-primary-dark-7: #f4f8fb;
+ --color-primary-light-1: #3876b3;
+ --color-primary-light-2: #31699f;
+ --color-primary-light-3: #2b5c8b;
+ --color-primary-light-4: #254f77;
+ --color-primary-light-5: #193450;
+ --color-primary-light-6: #0c1a28;
+ --color-primary-light-7: #04080c;
+ --color-primary-alpha-10: #4183c419;
+ --color-primary-alpha-20: #4183c433;
+ --color-primary-alpha-30: #4183c44b;
+ --color-primary-alpha-40: #4183c466;
+ --color-primary-alpha-50: #4183c480;
+ --color-primary-alpha-60: #4183c499;
+ --color-primary-alpha-70: #4183c4b3;
+ --color-primary-alpha-80: #4183c4cc;
+ --color-primary-alpha-90: #4183c4e1;
+ --color-primary-hover: var(--color-primary-light-1);
+ --color-primary-active: var(--color-primary-light-2);
+ --color-secondary: #3b444a;
+ --color-secondary-dark-1: #424b51;
+ --color-secondary-dark-2: #4a545b;
+ --color-secondary-dark-3: #59646c;
+ --color-secondary-dark-4: #6b7681;
+ --color-secondary-dark-5: #78858f;
+ --color-secondary-dark-6: #87929d;
+ --color-secondary-dark-7: #939ea9;
+ --color-secondary-dark-8: #a1acb4;
+ --color-secondary-dark-9: #aab3bc;
+ --color-secondary-dark-10: #b6bfc8;
+ --color-secondary-dark-11: #c2cbd3;
+ --color-secondary-dark-12: #ccd4dc;
+ --color-secondary-dark-13: #cfd7df;
+ --color-secondary-light-1: #2e353b;
+ --color-secondary-light-2: #2b353e;
+ --color-secondary-light-3: #1c2227;
+ --color-secondary-light-4: #161b1f;
+ --color-secondary-alpha-10: #3b444a19;
+ --color-secondary-alpha-20: #3b444a33;
+ --color-secondary-alpha-30: #3b444a4b;
+ --color-secondary-alpha-40: #3b444a66;
+ --color-secondary-alpha-50: #3b444a80;
+ --color-secondary-alpha-60: #3b444a99;
+ --color-secondary-alpha-70: #3b444ab3;
+ --color-secondary-alpha-80: #3b444acc;
+ --color-secondary-alpha-90: #3b444ae1;
+ --color-secondary-button: var(--color-secondary-dark-4);
+ --color-secondary-hover: var(--color-secondary-dark-3);
+ --color-secondary-active: var(--color-secondary-dark-2);
+ /* console colors - used for actions console and console files */
+ --color-console-fg: #f8f8f9;
+ --color-console-fg-subtle: #bec4c8;
+ --color-console-bg: #171b1e;
+ --color-console-border: #2e353b;
+ --color-console-hover-bg: #292d31;
+ --color-console-active-bg: #2e353b;
+ --color-console-menu-bg: #252b30;
+ --color-console-menu-border: #424b51;
+ /* named colors */
+ --color-red: #cc4848;
+ --color-orange: #cc580c;
+ --color-yellow: #cc9903;
+ --color-olive: #91a313;
+ --color-green: #87ab63;
+ --color-teal: #00918a;
+ --color-blue: #3a8ac6;
+ --color-violet: #906ae1;
+ --color-purple: #b259d0;
+ --color-pink: #d22e8b;
+ --color-brown: #a47252;
+ --color-black: #1d2328;
+ /* light variants - produced via Sass scale-color(color, $lightness: +10%) */
+ --color-red-light: #d15a5a;
+ --color-orange-light: #f6a066;
+ --color-yellow-light: #eaaf03;
+ --color-olive-light: #abc016;
+ --color-green-light: #93b373;
+ --color-teal-light: #00b6ad;
+ --color-blue-light: #4e96cc;
+ --color-violet-light: #9b79e4;
+ --color-purple-light: #ba6ad5;
+ --color-pink-light: #d74397;
+ --color-brown-light: #b08061;
+ --color-black-light: #424851;
+ /* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
+ --color-red-dark-1: #c23636;
+ --color-orange-dark-1: #f38236;
+ --color-yellow-dark-1: #b88a03;
+ --color-olive-dark-1: #839311;
+ --color-green-dark-1: #7a9e55;
+ --color-teal-dark-1: #00837c;
+ --color-blue-dark-1: #347cb3;
+ --color-violet-dark-1: #7b4edb;
+ --color-purple-dark-1: #a742c9;
+ --color-pink-dark-1: #be297d;
+ --color-brown-dark-1: #94674a;
+ --color-black-dark-1: #292e38;
+ /* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
+ --color-red-dark-2: #ad3030;
+ --color-orange-dark-2: #f16e17;
+ --color-yellow-dark-2: #a37a02;
+ --color-olive-dark-2: #74820f;
+ --color-green-dark-2: #6c8c4c;
+ --color-teal-dark-2: #00746e;
+ --color-blue-dark-2: #2e6e9f;
+ --color-violet-dark-2: #6733d6;
+ --color-purple-dark-2: #9834b9;
+ --color-pink-dark-2: #a9246f;
+ --color-brown-dark-2: #835b42;
+ --color-black-dark-2: #272930;
+ /* ansi colors used for actions console and console files */
+ --color-ansi-black: #1d2328;
+ --color-ansi-red: #cc4848;
+ --color-ansi-green: #87ab63;
+ --color-ansi-yellow: #cc9903;
+ --color-ansi-blue: #3a8ac6;
+ --color-ansi-magenta: #d22e8b;
+ --color-ansi-cyan: #00918a;
+ --color-ansi-white: var(--color-console-fg-subtle);
+ --color-ansi-bright-black: #424851;
+ --color-ansi-bright-red: #d15a5a;
+ --color-ansi-bright-green: #93b373;
+ --color-ansi-bright-yellow: #eaaf03;
+ --color-ansi-bright-blue: #4e96cc;
+ --color-ansi-bright-magenta: #d74397;
+ --color-ansi-bright-cyan: #00b6ad;
+ --color-ansi-bright-white: var(--color-console-fg);
+ /* other colors */
+ --color-grey: #384147;
+ --color-grey-light: #828f99;
+ --color-gold: #b1983b;
+ --color-white: #ffffff;
+ --color-diff-removed-word-bg: #6f3333;
+ --color-diff-added-word-bg: #3c653c;
+ --color-diff-removed-row-bg: #3c2626;
+ --color-diff-moved-row-bg: #818044;
+ --color-diff-added-row-bg: #283e2d;
+ --color-diff-removed-row-border: #634343;
+ --color-diff-moved-row-border: #bcca6f;
+ --color-diff-added-row-border: #314a37;
+ --color-diff-inactive: #22282d;
+ --color-error-border: #a04141;
+ --color-error-bg: #522;
+ --color-error-bg-active: #744;
+ --color-error-bg-hover: #633;
+ --color-error-text: #f9cbcb;
+ --color-success-border: #458a57;
+ --color-success-bg: #284034;
+ --color-success-text: #6cc664;
+ --color-warning-border: #bb9d00;
+ --color-warning-bg: #3a3a30;
+ --color-warning-text: #fbbd08;
+ --color-info-border: #306090;
+ --color-info-bg: #26354c;
+ --color-info-text: #38a8e8;
+ --color-red-badge: #db2828;
+ --color-red-badge-bg: #db28281a;
+ --color-red-badge-hover-bg: #db28284d;
+ --color-green-badge: #21ba45;
+ --color-green-badge-bg: #21ba451a;
+ --color-green-badge-hover-bg: #21ba454d;
+ --color-yellow-badge: #fbbd08;
+ --color-yellow-badge-bg: #fbbd081a;
+ --color-yellow-badge-hover-bg: #fbbd084d;
+ --color-orange-badge: #f2711c;
+ --color-orange-badge-bg: #f2711c1a;
+ --color-orange-badge-hover-bg: #f2711c4d;
+ --color-git: #f05133;
+ /* Icon colors (PR/Issue/...) */
+ --color-icon-green: var(--color-green);
+ --color-icon-red: var(--color-red);
+ --color-icon-purple: var(--color-purple);
+ /* target-based colors */
+ --color-body: #1c1f25;
+ --color-box-header: #1a1d1f;
+ --color-box-body: #14171a;
+ --color-box-body-highlight: #1c2227;
+ --color-text-dark: #f8f8f9;
+ --color-text: #d1d5d8;
+ --color-text-light: #bdc3c7;
+ --color-text-light-1: #a8afb5;
+ --color-text-light-2: #929ba2;
+ --color-text-light-3: #7c8790;
+ --color-footer: var(--color-nav-bg);
+ --color-timeline: #353c42;
+ --color-input-text: var(--color-text-dark);
+ --color-input-background: #151a1e;
+ --color-input-toggle-background: #2e353b;
+ --color-input-border: var(--color-secondary);
+ --color-input-border-hover: var(--color-secondary-dark-1);
+ --color-light: #00001728;
+ --color-light-mimic-enabled: rgba(0, 0, 0, calc(40 / 255 * 222 / 255 / var(--opacity-disabled)));
+ --color-light-border: #e8e8ff28;
+ --color-hover: #e8e8ff19;
+ --color-active: #e8e8ff24;
+ --color-menu: #151a1e;
+ --color-card: #151a1e;
+ --color-markup-table-row: #e8e8ff0f;
+ --color-markup-code-block: #e8e8ff12;
+ --color-markup-code-inline: #e8e8ff28;
+ --color-button: #151a1e;
+ --color-code-bg: #14171a;
+ --color-shadow: #00001758;
+ --color-secondary-bg: #2f3138;
+ --color-expand-button: #2b353e;
+ --color-placeholder-text: var(--color-text-light-3);
+ --color-editor-line-highlight: var(--color-primary-light-5);
+ --color-project-column-bg: var(--color-secondary-light-2);
+ --color-caret: var(--color-text); /* should ideally be --color-text-dark, see #15651 */
+ --color-reaction-bg: #e8e8ff12;
+ --color-reaction-hover-bg: var(--color-primary-light-4);
+ --color-reaction-active-bg: var(--color-primary-light-5);
+ --color-tooltip-text: #fafafb;
+ --color-tooltip-bg: #000017f0;
+ --color-nav-bg: #16191c;
+ --color-nav-hover-bg: var(--color-secondary-light-1);
+ --color-nav-text: var(--color-text);
+ --color-secondary-nav-bg: #181c20;
+ --color-label-text: var(--color-text);
+ --color-label-bg: #73828e4b;
+ --color-label-hover-bg: #73828ea0;
+ --color-label-active-bg: #73828eff;
+ --color-accent: var(--color-primary-light-1);
+ --color-small-accent: var(--color-primary-light-5);
+ --color-highlight-fg: #87651e;
+ --color-highlight-bg: #352c1c;
+ --color-overlay-backdrop: #080808c0;
+ /* pattern colors for image diff */
+ --checkerboard-color-1: #313131;
+ --checkerboard-color-2: #212121;
+ accent-color: var(--color-accent);
+ color-scheme: dark;
+}
+
+/* invert emojis that are hard to read otherwise */
+.emoji[aria-label="check mark"],
+.emoji[aria-label="currency exchange"],
+.emoji[aria-label="TOP arrow"],
+.emoji[aria-label="END arrow"],
+.emoji[aria-label="ON! arrow"],
+.emoji[aria-label="SOON arrow"],
+.emoji[aria-label="heavy dollar sign"],
+.emoji[aria-label="copyright"],
+.emoji[aria-label="registered"],
+.emoji[aria-label="trade mark"],
+.emoji[aria-label="multiply"],
+.emoji[aria-label="plus"],
+.emoji[aria-label="minus"],
+.emoji[aria-label="divide"],
+.emoji[aria-label="curly loop"],
+.emoji[aria-label="double curly loop"],
+.emoji[aria-label="wavy dash"],
+.emoji[aria-label="paw prints"],
+.emoji[aria-label="musical note"],
+.emoji[aria-label="musical notes"] {
+ filter: invert(100%) hue-rotate(180deg);
+}
diff --git a/web_src/css/themes/theme-gitea-light.css b/web_src/css/themes/theme-gitea-light.css
new file mode 100644
index 00000000..830b96fe
--- /dev/null
+++ b/web_src/css/themes/theme-gitea-light.css
@@ -0,0 +1,247 @@
+@import "../chroma/light.css";
+@import "../codemirror/light.css";
+@import "../markup/light.css";
+
+:root {
+ --is-dark-theme: false;
+ --color-primary: #4183c4;
+ --color-primary-contrast: #ffffff;
+ --color-primary-dark-1: #3876b3;
+ --color-primary-dark-2: #31699f;
+ --color-primary-dark-3: #2b5c8b;
+ --color-primary-dark-4: #254f77;
+ --color-primary-dark-5: #193450;
+ --color-primary-dark-6: #0c1a28;
+ --color-primary-dark-7: #04080c;
+ --color-primary-light-1: #548fca;
+ --color-primary-light-2: #679cd0;
+ --color-primary-light-3: #7aa8d6;
+ --color-primary-light-4: #8db5dc;
+ --color-primary-light-5: #b3cde7;
+ --color-primary-light-6: #d9e6f3;
+ --color-primary-light-7: #f4f8fb;
+ --color-primary-alpha-10: #4183c419;
+ --color-primary-alpha-20: #4183c433;
+ --color-primary-alpha-30: #4183c44b;
+ --color-primary-alpha-40: #4183c466;
+ --color-primary-alpha-50: #4183c480;
+ --color-primary-alpha-60: #4183c499;
+ --color-primary-alpha-70: #4183c4b3;
+ --color-primary-alpha-80: #4183c4cc;
+ --color-primary-alpha-90: #4183c4e1;
+ --color-primary-hover: var(--color-primary-dark-1);
+ --color-primary-active: var(--color-primary-dark-2);
+ --color-secondary: #d0d7de;
+ --color-secondary-dark-1: #c7ced5;
+ --color-secondary-dark-2: #b9c0c7;
+ --color-secondary-dark-3: #99a0a7;
+ --color-secondary-dark-4: #899097;
+ --color-secondary-dark-5: #7a8188;
+ --color-secondary-dark-6: #6a7178;
+ --color-secondary-dark-7: #5b6269;
+ --color-secondary-dark-8: #4b5259;
+ --color-secondary-dark-9: #3c434a;
+ --color-secondary-dark-10: #2c333a;
+ --color-secondary-dark-11: #1d242b;
+ --color-secondary-dark-12: #0d141b;
+ --color-secondary-dark-13: #00040b;
+ --color-secondary-light-1: #dee5ec;
+ --color-secondary-light-2: #e4ebf2;
+ --color-secondary-light-3: #ebf2f9;
+ --color-secondary-light-4: #f1f8ff;
+ --color-secondary-alpha-10: #d0d7de19;
+ --color-secondary-alpha-20: #d0d7de33;
+ --color-secondary-alpha-30: #d0d7de4b;
+ --color-secondary-alpha-40: #d0d7de66;
+ --color-secondary-alpha-50: #d0d7de80;
+ --color-secondary-alpha-60: #d0d7de99;
+ --color-secondary-alpha-70: #d0d7deb3;
+ --color-secondary-alpha-80: #d0d7decc;
+ --color-secondary-alpha-90: #d0d7dee1;
+ --color-secondary-button: var(--color-secondary-dark-4);
+ --color-secondary-hover: var(--color-secondary-dark-5);
+ --color-secondary-active: var(--color-secondary-dark-6);
+ /* console colors - used for actions console and console files */
+ --color-console-fg: #f8f8f9;
+ --color-console-fg-subtle: #bec4c8;
+ --color-console-bg: #171b1e;
+ --color-console-border: #2e353b;
+ --color-console-hover-bg: #292d31;
+ --color-console-active-bg: #2e353b;
+ --color-console-menu-bg: #252b30;
+ --color-console-menu-border: #424b51;
+ /* named colors */
+ --color-red: #db2828;
+ --color-orange: #f2711c;
+ --color-yellow: #fbbd08;
+ --color-olive: #b5cc18;
+ --color-green: #21ba45;
+ --color-teal: #00b5ad;
+ --color-blue: #2185d0;
+ --color-violet: #6435c9;
+ --color-purple: #a333c8;
+ --color-pink: #e03997;
+ --color-brown: #a5673f;
+ --color-black: #191c1d;
+ /* light variants - produced via Sass scale-color(color, $lightness: +25%) */
+ --color-red-light: #e45e5e;
+ --color-orange-light: #f59555;
+ --color-yellow-light: #fcce46;
+ --color-olive-light: #d3e942;
+ --color-green-light: #46de6a;
+ --color-teal-light: #08fff4;
+ --color-blue-light: #51a5e3;
+ --color-violet-light: #8b67d7;
+ --color-purple-light: #bb64d8;
+ --color-pink-light: #e86bb1;
+ --color-brown-light: #c58b66;
+ --color-black-light: #525558;
+ /* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
+ --color-red-dark-1: #c82121;
+ --color-orange-dark-1: #e6630d;
+ --color-yellow-dark-1: #e5ac04;
+ --color-olive-dark-1: #a3b816;
+ --color-green-dark-1: #1ea73e;
+ --color-teal-dark-1: #00a39c;
+ --color-blue-dark-1: #1e78bb;
+ --color-violet-dark-1: #5a30b5;
+ --color-purple-dark-1: #932eb4;
+ --color-pink-dark-1: #db228a;
+ --color-brown-dark-1: #955d39;
+ --color-black-dark-1: #16191c;
+ /* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
+ --color-red-dark-2: #b11e1e;
+ --color-orange-dark-2: #cc580c;
+ --color-yellow-dark-2: #cc9903;
+ --color-olive-dark-2: #91a313;
+ --color-green-dark-2: #1a9537;
+ --color-teal-dark-2: #00918a;
+ --color-blue-dark-2: #1a6aa6;
+ --color-violet-dark-2: #502aa1;
+ --color-purple-dark-2: #8229a0;
+ --color-pink-dark-2: #c21e7b;
+ --color-brown-dark-2: #845232;
+ --color-black-dark-2: #131619;
+ /* ansi colors used for actions console and console files */
+ --color-ansi-black: #1f2326;
+ --color-ansi-red: #cc4848;
+ --color-ansi-green: #87ab63;
+ --color-ansi-yellow: #cc9903;
+ --color-ansi-blue: #3a8ac6;
+ --color-ansi-magenta: #d22e8b;
+ --color-ansi-cyan: #00918a;
+ --color-ansi-white: var(--color-console-fg-subtle);
+ --color-ansi-bright-black: #46494d;
+ --color-ansi-bright-red: #d15a5a;
+ --color-ansi-bright-green: #93b373;
+ --color-ansi-bright-yellow: #eaaf03;
+ --color-ansi-bright-blue: #4e96cc;
+ --color-ansi-bright-magenta: #d74397;
+ --color-ansi-bright-cyan: #00b6ad;
+ --color-ansi-bright-white: var(--color-console-fg);
+ /* other colors */
+ --color-grey: #697077;
+ --color-grey-light: #7c838a;
+ --color-gold: #a1882b;
+ --color-white: #ffffff;
+ --color-diff-removed-word-bg: #fdb8c0;
+ --color-diff-added-word-bg: #acf2bd;
+ --color-diff-removed-row-bg: #ffeef0;
+ --color-diff-moved-row-bg: #f1f8d1;
+ --color-diff-added-row-bg: #e6ffed;
+ --color-diff-removed-row-border: #f1c0c0;
+ --color-diff-moved-row-border: #d0e27f;
+ --color-diff-added-row-border: #e6ffed;
+ --color-diff-inactive: #f0f2f4;
+ --color-error-border: #e0b4b4;
+ --color-error-bg: #fff6f6;
+ --color-error-bg-active: #fbb;
+ --color-error-bg-hover: #fdd;
+ --color-error-text: #9f3a38;
+ --color-success-border: #a3c293;
+ --color-success-bg: #fcfff5;
+ --color-success-text: #2c662d;
+ --color-warning-border: #c9ba9b;
+ --color-warning-bg: #fffaf3;
+ --color-warning-text: #573a08;
+ --color-info-border: #a9d5de;
+ --color-info-bg: #f8ffff;
+ --color-info-text: #276f86;
+ --color-red-badge: #db2828;
+ --color-red-badge-bg: #db28281a;
+ --color-red-badge-hover-bg: #db28284d;
+ --color-green-badge: #21ba45;
+ --color-green-badge-bg: #21ba451a;
+ --color-green-badge-hover-bg: #21ba454d;
+ --color-yellow-badge: #fbbd08;
+ --color-yellow-badge-bg: #fbbd081a;
+ --color-yellow-badge-hover-bg: #fbbd084d;
+ --color-orange-badge: #f2711c;
+ --color-orange-badge-bg: #f2711c1a;
+ --color-orange-badge-hover-bg: #f2711c4d;
+ --color-git: #f05133;
+ /* Icon colors (PR/Issue/...) */
+ --color-icon-green: var(--color-green);
+ --color-icon-red: var(--color-red);
+ --color-icon-purple: var(--color-purple);
+ /* target-based colors */
+ --color-body: #ffffff;
+ --color-box-header: #f1f3f5;
+ --color-box-body: #ffffff;
+ --color-box-body-highlight: #ecf5fd;
+ --color-text-dark: #01050a;
+ --color-text: #181c21;
+ --color-text-light: #30363b;
+ --color-text-light-1: #40474d;
+ --color-text-light-2: #5b6167;
+ --color-text-light-3: #747c84;
+ --color-footer: var(--color-nav-bg);
+ --color-timeline: #d0d7de;
+ --color-input-text: var(--color-text-dark);
+ --color-input-background: #fff;
+ --color-input-toggle-background: #d0d7de;
+ --color-input-border: var(--color-secondary);
+ --color-input-border-hover: var(--color-secondary-dark-1);
+ --color-light: #00001706;
+ --color-light-mimic-enabled: rgba(0, 0, 0, calc(6 / 255 * 222 / 255 / var(--opacity-disabled)));
+ --color-light-border: #0000171d;
+ --color-hover: #00001708;
+ --color-active: #00001714;
+ --color-menu: #f8f9fb;
+ --color-card: #f8f9fb;
+ --color-markup-table-row: #0030600a;
+ --color-markup-code-block: #00306010;
+ --color-markup-code-inline: #00306012;
+ --color-button: #f8f9fb;
+ --color-code-bg: #fafdff;
+ --color-shadow: #00001726;
+ --color-secondary-bg: #f2f5f8;
+ --color-expand-button: #cfe8fa;
+ --color-placeholder-text: var(--color-text-light-3);
+ --color-editor-line-highlight: var(--color-primary-light-6);
+ --color-project-column-bg: var(--color-secondary-light-4);
+ --color-caret: var(--color-text-dark);
+ --color-reaction-bg: #0000170a;
+ --color-reaction-hover-bg: var(--color-primary-light-5);
+ --color-reaction-active-bg: var(--color-primary-light-6);
+ --color-tooltip-text: #fbfdff;
+ --color-tooltip-bg: #000017f0;
+ --color-nav-bg: #f6f7fa;
+ --color-nav-hover-bg: var(--color-secondary-light-1);
+ --color-nav-text: var(--color-text);
+ --color-secondary-nav-bg: #f9fafb;
+ --color-label-text: var(--color-text);
+ --color-label-bg: #949da64b;
+ --color-label-hover-bg: #949da6a0;
+ --color-label-active-bg: #949da6ff;
+ --color-accent: var(--color-primary-light-1);
+ --color-small-accent: var(--color-primary-light-6);
+ --color-highlight-fg: #eed200;
+ --color-highlight-bg: #fffbdd;
+ --color-overlay-backdrop: #080808c0;
+ /* pattern colors for gradient */
+ --checkerboard-color-1: #ffffff;
+ --checkerboard-color-2: #e5e5e5;
+ accent-color: var(--color-accent);
+ color-scheme: light;
+}
diff --git a/web_src/css/user.css b/web_src/css/user.css
new file mode 100644
index 00000000..16d431e2
--- /dev/null
+++ b/web_src/css/user.css
@@ -0,0 +1,149 @@
+.user.profile .ui.card .header {
+ display: block;
+ font-weight: var(--font-weight-semibold);
+ font-size: 1.3rem;
+ margin-top: -0.2rem;
+ line-height: 1.3rem;
+}
+
+.user.profile .ui.card .profile-avatar-name {
+ border-top: none;
+ text-align: center;
+}
+
+.user.profile .ui.card .extra.content {
+ padding: 0;
+}
+
+.user.profile .ui.card .extra.content > ul {
+ margin: 0;
+ padding: 0;
+}
+
+.user.profile .ui.card .extra.content > ul > li {
+ padding: 10px;
+ display: flex;
+ list-style: none;
+ align-items: center;
+ gap: 0.25em;
+}
+
+.user.profile .ui.card .extra.content > ul > li:not(:last-child) {
+ border-bottom: 1px solid var(--color-secondary);
+}
+
+.user.profile .ui.card .extra.content > ul > li .svg {
+ margin-left: 1px;
+ margin-right: 5px;
+}
+
+.user.profile .ui.card .extra.content > ul > li.follow .ui.button,
+.user.profile .ui.card .extra.content > ul > li.block .ui.button {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ width: 100%;
+}
+
+.user.profile .ui.card #profile-avatar {
+ padding: 1rem 1rem 0.25rem;
+ justify-content: center;
+}
+
+.user.profile .ui.card #profile-avatar img {
+ max-width: 100%;
+ height: auto;
+}
+
+@media (max-width: 767.98px) {
+ .user.profile .ui.card #profile-avatar img {
+ width: 30vw;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .user.profile .ui.card {
+ width: 100%;
+ }
+}
+
+.user.profile .ui.secondary.stackable.pointing.menu {
+ flex-wrap: wrap;
+}
+
+.user.link-account:not(.icon) {
+ padding-top: 15px;
+ padding-bottom: 5px;
+}
+
+.user.settings .iconFloat {
+ float: left;
+}
+
+.user-orgs {
+ display: flex;
+ flex-flow: row wrap;
+ padding: 0;
+ margin: -3px !important;
+}
+
+.user-orgs > li {
+ display: flex;
+ border-bottom: 0 !important;
+ padding: 3px !important;
+ max-width: 60px;
+}
+
+.user-badges {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, 64px);
+ gap: 2px;
+}
+
+.user-badges img {
+ object-fit: contain;
+}
+
+#readme_profile {
+ padding: 1.5em;
+ background: var(--color-box-body);
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+}
+
+#profile-avatar-card {
+ background: var(--color-box-body);
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+}
+
+#notification_table {
+ background: var(--color-box-body);
+ border: 1px solid var(--color-secondary);
+ border-radius: var(--border-radius);
+}
+
+.notifications-item:hover {
+ background: var(--color-hover);
+}
+
+.notifications-buttons {
+ display: none;
+ min-width: 74px;
+}
+
+.notifications-updated {
+ display: flex;
+}
+
+.notifications-item:hover .notifications-buttons {
+ display: flex;
+}
+
+.notifications-item:hover .notifications-updated {
+ display: none;
+}
+
+#pronouns-dropdown, #pronouns-custom {
+ width: 140px;
+}