diff --git a/.editorconfig b/.editorconfig
index af8f0cf310a8..049d90619a70 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,6 +1,6 @@
 root = true
 
-[*.{js, scss, css, hbs}]
+[*.{js, scss, css, hbs, svg}]
 indent_style = space
 indent_size = 2
 trim_trailing_whitespace = true
diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index.jelly b/core/src/main/resources/hudson/model/AbstractBuild/index.jelly
index 8444984d49cd..aba425c3420b 100644
--- a/core/src/main/resources/hudson/model/AbstractBuild/index.jelly
+++ b/core/src/main/resources/hudson/model/AbstractBuild/index.jelly
@@ -76,7 +76,7 @@ THE SOFTWARE.
                       <j:choose>
                         <j:when test="${dep.from!=null}">
                           <a href="${rootURL}/${dep.from.url}" class="model-link inside">
-                            <l:icon class="${dep.from.buildStatusIconClassName} icon-sm" alt="${dep.from.iconColor.description}"/>${dep.from.displayName}</a>
+                            <l:icon src="symbol-status-${dep.from.iconColor.iconName}" class="icon-sm" alt="${dep.from.iconColor.description}"/>${dep.from.displayName}</a>
                         </j:when>
                         <j:otherwise>
                           ?
@@ -86,7 +86,7 @@ THE SOFTWARE.
                       &#x2192; <!-- right arrow -->
 
                       <a href="${rootURL}/${dep.to.url}" class="model-link inside">
-                        <l:icon class="${dep.to.buildStatusIconClassName} icon-sm" alt="${dep.to.iconColor.description}" />${dep.to.displayName}</a>
+                        <l:icon src="symbol-status-${dep.to.iconColor.iconName}" class="icon-sm" alt="${dep.to.iconColor.description}" />${dep.to.displayName}</a>
 
                       (<a href="${rootURL}/${dep.project.url}changes?from=${dep.fromId}&amp;to=${dep.toId}">${%detail}</a>)
                     </li>
diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly b/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly
index 4021ab4109a4..56201d48dab8 100644
--- a/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly
+++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly
@@ -31,6 +31,14 @@ THE SOFTWARE.
     <l:breadcrumb title="${%Build Time Trend}" />
     <st:adjunct includes="hudson.model.Job.buildTimeTrend_resources" />
     <l:main-panel>
+      <template id="jenkins-build-status-icons">
+        <l:icon src="symbol-status-blue" id="blue" />
+        <l:icon src="symbol-status-yellow" id="yellow" />
+        <l:icon src="symbol-status-red" id="red" />
+        <l:icon src="symbol-status-nobuilt" id="nobuilt" />
+        <l:icon src="symbol-status-aborted" id="aborted" />
+        <l:icon src="symbol-status-disabled" id="disabled" />
+      </template>
       <h1>${%Build Time Trend}</h1>
           <div align="center">
             <img class="build-time-graph" src="buildTimeGraph/png" width="500" height="400" lazymap="buildTimeGraph/map" alt="[${%Build time graph}]" />
diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js
index 105cdbc06ed2..eadcb5970622 100644
--- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js
+++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_resources.js
@@ -67,76 +67,11 @@ window.buildTimeTrend_displayBuilds = function (data) {
 /**
  * Generate SVG Icon
  */
-function generateSVGIcon(iconName, iconSizeClass) {
-  const imagesURL = document.head.getAttribute("data-imagesurl");
-
-  const isInProgress = iconName.endsWith("anime");
-  let buildStatus = "never-built";
-  switch (iconName) {
-    case "red":
-    case "red-anime":
-      buildStatus = "last-failed";
-      break;
-    case "yellow":
-    case "yellow-anime":
-      buildStatus = "last-unstable";
-      break;
-    case "blue":
-    case "blue-anime":
-      buildStatus = "last-successful";
-      break;
-    case "grey":
-    case "grey-anime":
-    case "disabled":
-    case "disabled-anime":
-      buildStatus = "last-disabled";
-      break;
-    case "aborted":
-    case "aborted-anime":
-      buildStatus = "last-aborted";
-      break;
-    case "nobuilt":
-    case "nobuilt-anime":
-      buildStatus = "never-built";
-      break;
-  }
+function generateSVGIcon(iconName) {
+  const icons = document.querySelector("#jenkins-build-status-icons");
+  iconName = iconName.replace("-anime", "");
 
-  const svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-  svg1.setAttribute("class", "svg-icon");
-  svg1.setAttribute("viewBox", "0 0 24 24");
-  const use1 = document.createElementNS("http://www.w3.org/2000/svg", "use");
-  use1.setAttribute(
-    "href",
-    imagesURL +
-      "/build-status/build-status-sprite.svg#build-status-" +
-      (isInProgress ? "in-progress" : "static"),
-  );
-  svg1.appendChild(use1);
-
-  const svg2 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-  svg2.setAttribute(
-    "class",
-    "svg-icon icon-" + iconName + " " + (iconSizeClass || "icon-sm"),
-  );
-  svg2.setAttribute("viewBox", "0 0 24 24");
-  const use2 = document.createElementNS("http://www.w3.org/2000/svg", "use");
-  use2.setAttribute(
-    "href",
-    imagesURL + "/build-status/build-status-sprite.svg#" + buildStatus,
-  );
-  svg2.appendChild(use2);
-
-  const span = document.createElement("span");
-  span.classList.add("build-status-icon__wrapper", "icon-" + iconName);
-
-  let span2 = document.createElement("span");
-  span2.classList.add("build-status-icon__outer");
-  span2.appendChild(svg1);
-
-  span.appendChild(span2);
-  span.appendChild(svg2);
-
-  return span;
+  return icons.content.querySelector(`#${iconName}`).cloneNode(true);
 }
 
 /**
@@ -155,7 +90,7 @@ window.displayBuilds = function (data) {
     td1.classList.add("jenkins-table__cell--tight", "jenkins-table__icon");
     var div1 = document.createElement("div");
     div1.classList.add("jenkins-table__cell__button-wrapper");
-    var svg = generateSVGIcon(e.iconName, p.dataset.iconSizeClass);
+    var svg = generateSVGIcon(e.iconName);
     div1.appendChild(svg);
     td1.appendChild(div1);
     tr.appendChild(td1);
diff --git a/core/src/main/resources/hudson/model/Job/index.jelly b/core/src/main/resources/hudson/model/Job/index.jelly
index 23a454b4d52e..0fb537e267d7 100644
--- a/core/src/main/resources/hudson/model/Job/index.jelly
+++ b/core/src/main/resources/hudson/model/Job/index.jelly
@@ -33,7 +33,7 @@ THE SOFTWARE.
           <j:set var="lastBuild" value="${it.lastBuild}" />
           <j:if test="${lastBuild != null}">
             <a href="${rootURL + '/' + lastBuild.url}" class="jenkins-!-display-contents" tabindex="-1">
-              <l:icon class="${lastBuild.buildStatusIconClassName}" tooltip="${lastBuild.iconColor.description}"/>
+              <l:icon src="symbol-status-${lastBuild.iconColor.iconName}" tooltip="${lastBuild.iconColor.description}"/>
             </a>
           </j:if>
           <h1 class="job-index-headline page-headline">
diff --git a/core/src/main/resources/hudson/model/Run/statusIcon.jelly b/core/src/main/resources/hudson/model/Run/statusIcon.jelly
index 6ef664c98efe..650605c7e025 100644
--- a/core/src/main/resources/hudson/model/Run/statusIcon.jelly
+++ b/core/src/main/resources/hudson/model/Run/statusIcon.jelly
@@ -31,6 +31,6 @@ THE SOFTWARE.
 <st:compress xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
 <st:setHeader name="X-Building" value="${it.building}" />
 <l:ajax>
-  <l:icon alt="${it.iconColor.description}" class="${it.buildStatusIconClassName} icon-xlg" tooltip="${it.iconColor.description}"/>
+  <l:icon alt="${it.iconColor.description}" src="symbol-status-${it.iconColor.iconName}" class="icon-xlg" tooltip="${it.iconColor.description}"/>
 </l:ajax>
 </st:compress>
diff --git a/core/src/main/resources/hudson/views/StatusColumn/column.jelly b/core/src/main/resources/hudson/views/StatusColumn/column.jelly
index 5297d99809a3..5ac989e40521 100644
--- a/core/src/main/resources/hudson/views/StatusColumn/column.jelly
+++ b/core/src/main/resources/hudson/views/StatusColumn/column.jelly
@@ -23,6 +23,18 @@ THE SOFTWARE.
 -->
 
 <?jelly escape-by-default='true'?>
-<j:jelly xmlns:j="jelly:core" xmlns:t="/lib/hudson">
-    <t:ballColorTd it="${job.iconColor}" />
-</j:jelly>
\ No newline at end of file
+<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout">
+  <td class="jenkins-table__cell--tight jenkins-table__icon" data="${job.iconColor.ordinal()}">
+    <div class="jenkins-table__cell__button-wrapper">
+      <j:choose>
+        <j:when test="${job.iconColor.iconName != null}">
+          <l:icon src="symbol-status-${job.iconColor.iconName}" tooltip="${job.iconColor.description}" />
+        </j:when>
+        <j:otherwise>
+          <!-- This is for special conditions, such as folders -->
+          <l:icon src="${job.iconColor.iconClassName}" />
+        </j:otherwise>
+      </j:choose>
+    </div>
+  </td>
+</j:jelly>
diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly
index 366071ebf7fa..d203b8a98344 100644
--- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly
+++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly
@@ -39,7 +39,7 @@ THE SOFTWARE.
       <div class="pane build-name">
         <div class="build-icon">
           <a class="build-status-link" href="${h.getConsoleUrl(build)}" tooltip="${build.iconColor.description} > ${%Console Output}">
-            <l:icon class="${build.buildStatusIconClassName} icon-sm" />
+            <l:icon src="symbol-status-${build.iconColor.iconName}" />
           </a>
         </div>
         <a class="model-link inside build-link display-name" update-parent-class=".build-row" href="${link}">${build.displayName}</a>
diff --git a/core/src/main/resources/jenkins/model/Jenkins/_legend.jelly b/core/src/main/resources/jenkins/model/Jenkins/_legend.jelly
index 9ae7a079e739..90d8e8b89a13 100644
--- a/core/src/main/resources/jenkins/model/Jenkins/_legend.jelly
+++ b/core/src/main/resources/jenkins/model/Jenkins/_legend.jelly
@@ -29,87 +29,87 @@ THE SOFTWARE.
 
   <dl class="app-icon-legend">
     <dt>
-      <l:icon class="icon-blue icon-lg"/>
+      <l:icon src="symbol-status-blue" />
     </dt>
     <dd>
       ${%blue}
     </dd>
 
     <dt>
-      <l:icon class="icon-blue-anime icon-lg"/>
+      <l:icon src="symbol-status-blue-anime" />
     </dt>
     <dd>
       ${%blue_anime}
     </dd>
 
     <dt>
-      <l:icon class="icon-yellow icon-lg"/>
+      <l:icon src="symbol-status-yellow" />
     </dt>
     <dd>
       ${%yellow}
     </dd>
 
     <dt>
-      <l:icon class="icon-yellow-anime icon-lg"/>
+      <l:icon src="symbol-status-yellow-anime" />
     </dt>
     <dd>
       ${%yellow_anime}
     </dd>
 
     <dt>
-      <l:icon class="icon-red icon-lg"/>
+      <l:icon src="symbol-status-red" />
     </dt>
     <dd>
       ${%red}
     </dd>
 
     <dt>
-      <l:icon class="icon-red-anime icon-lg"/>
+      <l:icon src="symbol-status-red-anime" />
     </dt>
     <dd>
       ${%red_anime}
     </dd>
 
     <dt>
-      <l:icon class="icon-nobuilt icon-lg"/>
+      <l:icon src="symbol-status-nobuilt" />
     </dt>
     <dd>
       ${%lightgrey}
     </dd>
 
     <dt>
-      <l:icon class="icon-nobuilt-anime icon-lg"/>
+      <l:icon src="symbol-status-nobuilt-anime" />
     </dt>
     <dd>
       ${%lightgrey_anime}
     </dd>
 
     <dt>
-      <l:icon class="icon-disabled icon-lg"/>
+      <l:icon src="symbol-status-aborted" />
     </dt>
     <dd>
-      ${%grey}
+      ${%darkgrey}
     </dd>
 
     <dt>
-      <l:icon class="icon-disabled-anime icon-lg"/>
+      <l:icon src="symbol-status-aborted-anime" />
     </dt>
     <dd>
-      ${%grey_anime}
+      ${%darkgrey_anime}
     </dd>
 
     <dt>
-      <l:icon class="icon-aborted icon-lg"/>
+      <l:icon src="symbol-status-disabled" />
     </dt>
     <dd>
-      ${%darkgrey}
+      ${%grey}
     </dd>
 
     <dt>
-      <l:icon class="icon-aborted-anime icon-lg"/>
+      <l:icon src="symbol-status-disabled-anime" />
     </dt>
     <dd>
-      ${%darkgrey_anime}
+      ${%grey_anime}
     </dd>
   </dl>
 
diff --git a/core/src/main/resources/lib/hudson/buildCaption.jelly b/core/src/main/resources/lib/hudson/buildCaption.jelly
index b8fab1554e31..2f29e2808f4b 100644
--- a/core/src/main/resources/lib/hudson/buildCaption.jelly
+++ b/core/src/main/resources/lib/hudson/buildCaption.jelly
@@ -29,7 +29,7 @@ THE SOFTWARE.
 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
   <div class="jenkins-app-bar">
     <div class="jenkins-app-bar__content jenkins-build-caption">
-      <l:icon alt="${it.iconColor.description}" class="${it.buildStatusIconClassName} icon-xlg"
+      <l:icon alt="${it.iconColor.description}" src="symbol-status-${it.iconColor.iconName}"
           tooltip="${it.iconColor.description}"/>
       <h1>
         <d:invokeBody trim="true"/>
diff --git a/core/src/main/resources/lib/hudson/buildLink.jelly b/core/src/main/resources/lib/hudson/buildLink.jelly
index 18ccfc1ec675..ad23bfbbd763 100644
--- a/core/src/main/resources/lib/hudson/buildLink.jelly
+++ b/core/src/main/resources/lib/hudson/buildLink.jelly
@@ -52,7 +52,7 @@ THE SOFTWARE.
         </j:when>
         <j:otherwise>
           <a href="${attrs.href ?: rootURL+'/'+r.url}" class="model-link">
-          <l:icon alt="${r.iconColor.description}" class="${r.buildStatusIconClassName} icon-sm" style="margin-left: 0; position: relative; top: -0.1rem;"/><span class="jenkins-icon-adjacent">${jobName_}#<!-- -->${number}</span></a>
+          <l:icon alt="${r.iconColor.description}" src="symbol-status-${r.iconColor.iconName}" class="icon-sm" style="margin-left: 0; position: relative; top: -0.1rem;"/><span class="jenkins-icon-adjacent">${jobName_}#<!-- -->${number}</span></a>
         </j:otherwise>
       </j:choose>
     </j:otherwise>
diff --git a/core/src/main/resources/lib/hudson/buildListTable.jelly b/core/src/main/resources/lib/hudson/buildListTable.jelly
index cd617715838e..608af80d421b 100644
--- a/core/src/main/resources/lib/hudson/buildListTable.jelly
+++ b/core/src/main/resources/lib/hudson/buildListTable.jelly
@@ -30,6 +30,15 @@ THE SOFTWARE.
       A collection of builds to be displayed.
     </st:attribute>
   </st:documentation>
+  <template id="jenkins-build-status-icons">
+    <l:icon src="symbol-status-blue" id="blue" />
+    <l:icon src="symbol-status-yellow" id="yellow" />
+    <l:icon src="symbol-status-red" id="red" />
+    <l:icon src="symbol-status-nobuilt" id="nobuilt" />
+    <l:icon src="symbol-status-aborted" id="aborted" />
+    <l:icon src="symbol-status-disabled" id="disabled" />
+    <l:icon src="symbol-terminal" id="console" />
+  </template>
 
   <t:setIconSize/>
   <st:adjunct includes="hudson.model.Job.buildTimeTrend_resources" />
diff --git a/core/src/main/resources/lib/hudson/jobLink.jelly b/core/src/main/resources/lib/hudson/jobLink.jelly
index 0aaa0dcc7d5a..af40d22b37ae 100644
--- a/core/src/main/resources/lib/hudson/jobLink.jelly
+++ b/core/src/main/resources/lib/hudson/jobLink.jelly
@@ -31,7 +31,7 @@ THE SOFTWARE.
     </st:attribute>
   </st:documentation>
 
-  <l:icon alt="${job.iconColor.description}" class="${job.buildStatusIconClassName} icon-sm"/>
+  <l:icon alt="${job.iconColor.description}" src="symbol-status-${job.iconColor.iconName}" class="icon-sm"/>
   <a href="${h.getRelativeLinkTo(job)}" class="model-link jenkins-icon-adjacent">
     <l:breakable value="${job.fullDisplayName}"/>
   </a>
diff --git a/core/src/main/resources/lib/hudson/projectView.jelly b/core/src/main/resources/lib/hudson/projectView.jelly
index e2bae523dfcf..27d5cf967c6d 100644
--- a/core/src/main/resources/lib/hudson/projectView.jelly
+++ b/core/src/main/resources/lib/hudson/projectView.jelly
@@ -93,7 +93,15 @@ THE SOFTWARE.
           <div class="jenkins-jobs-list__item">
             <a class="jenkins-jobs-list__item__details" href="${jobBaseUrl}${job.shortUrl}">
               <div class="jenkins-jobs-list__item__icons">
-                <t:ballColorTd it="${job.iconColor}" />
+                <j:choose>
+                  <j:when test="${job.iconColor.iconName != null}">
+                    <l:icon src="symbol-status-${job.iconColor.iconName}" tooltip="${job.iconColor.description}" />
+                  </j:when>
+                  <j:otherwise>
+                    <!-- This is for special conditions, such as folders -->
+                    <l:icon src="${job.iconColor.iconClassName}" />
+                  </j:otherwise>
+                </j:choose>
               </div>
               <div class="jenkins-jobs-list__item__details__text">
                 <p class="jenkins-jobs-list__item__label">${job.displayName}</p>
diff --git a/war/src/main/resources/images/symbols/status-aborted-anime.svg b/war/src/main/resources/images/symbols/status-aborted-anime.svg
new file mode 100644
index 000000000000..308e6d7578c7
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-aborted-anime.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse opacity="0.4" cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M256 46C140.02 46 46 140.02 46 256" fill="transparent" stroke="var(--text-color-secondary)" stroke-width="36" stroke-miterlimit="10" stroke-linecap="round" data-symbol-animation="spin" />
+    <path fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" d="M192 320l128-128"/>
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-aborted.svg b/war/src/main/resources/images/symbols/status-aborted.svg
new file mode 100644
index 000000000000..fee388a4f27b
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-aborted.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" d="M192 320l128-128" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-blue-anime.svg b/war/src/main/resources/images/symbols/status-blue-anime.svg
new file mode 100644
index 000000000000..b11da163e9f7
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-blue-anime.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse opacity="0.4" cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--success-color)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M256 46C140.02 46 46 140.02 46 256" fill="transparent" stroke="var(--success-color)" stroke-width="36" stroke-miterlimit="10" stroke-linecap="round" data-symbol-animation="spin" />
+    <path d="M336 189L224 323L176 269.4" fill="transparent" stroke="var(--success-color)" stroke-width="36" stroke-linecap="round" stroke-linejoin="round" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-blue.svg b/war/src/main/resources/images/symbols/status-blue.svg
new file mode 100644
index 000000000000..2427dd5286dc
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-blue.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--success-color)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M336 189L224 323L176 269.4" fill="transparent" stroke="var(--success-color)" stroke-width="36" stroke-linecap="round" stroke-linejoin="round" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-disabled-anime.svg b/war/src/main/resources/images/symbols/status-disabled-anime.svg
new file mode 100644
index 000000000000..138edc7a9ec3
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-disabled-anime.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse opacity="0.4" cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M256 46C140.02 46 46 140.02 46 256" fill="transparent" stroke="var(--text-color-secondary)" stroke-width="36" stroke-miterlimit="10" stroke-linecap="round" data-symbol-animation="spin" />
+    <ellipse cx="256" cy="256" rx="100" ry="100" fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" d="M192 320l128-128" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-disabled.svg b/war/src/main/resources/images/symbols/status-disabled.svg
new file mode 100644
index 000000000000..32aa7eaef687
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-disabled.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <ellipse cx="256" cy="256" rx="100" ry="100" fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path fill="none" stroke="var(--text-color-secondary)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" d="M192 320l128-128" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-nobuilt-anime.svg b/war/src/main/resources/images/symbols/status-nobuilt-anime.svg
new file mode 100644
index 000000000000..9a534d34d237
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-nobuilt-anime.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+  <ellipse opacity="0.4" cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--blue)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+  <path d="M256 46C140.02 46 46 140.02 46 256" fill="transparent" stroke="var(--blue)" stroke-width="36" stroke-miterlimit="10" stroke-linecap="round" data-symbol-animation="spin" />
+  <circle cx="256" cy="256" r="30" fill="var(--blue)" />
+  <circle cx="352" cy="256" r="30" fill="var(--blue)" />
+  <circle cx="160" cy="256" r="30" fill="var(--blue)" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-nobuilt.svg b/war/src/main/resources/images/symbols/status-nobuilt.svg
new file mode 100644
index 000000000000..a2ba0f13edbc
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-nobuilt.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+  <ellipse cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--blue)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+  <circle cx="256" cy="256" r="30" fill="var(--blue)" />
+  <circle cx="352" cy="256" r="30" fill="var(--blue)" />
+  <circle cx="160" cy="256" r="30" fill="var(--blue)" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-red-anime.svg b/war/src/main/resources/images/symbols/status-red-anime.svg
new file mode 100644
index 000000000000..76b3bca95af1
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-red-anime.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse opacity="0.4" cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--red)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M256 46C140.02 46 46 140.02 46 256" fill="transparent" stroke="var(--red)" stroke-width="36" stroke-miterlimit="10" stroke-linecap="round" data-symbol-animation="spin" />
+    <path fill="none" stroke="var(--red)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" d="M320 320L192 192M192 320l128-128"/>
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-red.svg b/war/src/main/resources/images/symbols/status-red.svg
new file mode 100644
index 000000000000..547dc4a13f2d
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-red.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+    <ellipse cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--red)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path fill="none" stroke="var(--red)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" d="M320 320L192 192M192 320l128-128"/>
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-yellow-anime.svg b/war/src/main/resources/images/symbols/status-yellow-anime.svg
new file mode 100644
index 000000000000..c241c3c88024
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-yellow-anime.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
+    <ellipse opacity="0.4" cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--orange)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M256 46C140.02 46 46 140.02 46 256" fill="transparent" stroke="var(--orange)" stroke-width="36" stroke-miterlimit="10" stroke-linecap="round" data-symbol-animation="spin" />
+    <path d="M250.26 166.05L256 288l5.73-121.95a5.74 5.74 0 00-5.79-6h0a5.74 5.74 0 00-5.68 6z" fill="none" stroke="var(--orange)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" />
+    <ellipse cx="256" cy="350" rx="26" ry="26" fill="var(--orange)" />
+</svg>
diff --git a/war/src/main/resources/images/symbols/status-yellow.svg b/war/src/main/resources/images/symbols/status-yellow.svg
new file mode 100644
index 000000000000..57aab84b73de
--- /dev/null
+++ b/war/src/main/resources/images/symbols/status-yellow.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
+    <ellipse cx="256" cy="256" rx="210" ry="210" fill="none" stroke="var(--orange)" stroke-linecap="round" stroke-miterlimit="10" stroke-width="36" />
+    <path d="M250.26 166.05L256 288l5.73-121.95a5.74 5.74 0 00-5.79-6h0a5.74 5.74 0 00-5.68 6z" fill="none" stroke="var(--orange)" stroke-linecap="round" stroke-linejoin="round" stroke-width="36" />
+    <ellipse cx="256" cy="350" rx="26" ry="26" fill="var(--orange)" />
+</svg>
diff --git a/war/src/main/scss/base/_style.scss b/war/src/main/scss/base/_style.scss
index ecda3df84a4e..2abd6d4ef10a 100644
--- a/war/src/main/scss/base/_style.scss
+++ b/war/src/main/scss/base/_style.scss
@@ -866,13 +866,22 @@ table.progress-bar.red td.progress-bar-done {
 
 /* Unknown */
 
+[data-symbol-animation] {
+  animation: spin 1s linear infinite;
+  transform-origin: center;
+
+  @media (prefers-reduced-motion) {
+    animation-duration: 3s;
+  }
+}
+
 @keyframes spin {
   from {
-    transform: rotate(0deg) translateZ(0);
+    transform: rotate(0deg);
   }
 
   to {
-    transform: rotate(360deg) translateZ(0);
+    transform: rotate(360deg);
   }
 }
 
diff --git a/war/src/main/scss/components/_app-bar.scss b/war/src/main/scss/components/_app-bar.scss
index 1e5af8727f88..0cff962e7967 100644
--- a/war/src/main/scss/components/_app-bar.scss
+++ b/war/src/main/scss/components/_app-bar.scss
@@ -81,8 +81,7 @@
   overflow: hidden;
   text-overflow: ellipsis;
 
-  .build-status-icon__wrapper,
-  .build-status-icon__wrapper svg {
+  svg {
     width: 2rem !important;
     height: 2rem !important;
   }
diff --git a/war/src/main/scss/components/_side-panel-widgets.scss b/war/src/main/scss/components/_side-panel-widgets.scss
index 9d6933953efb..037674f61b88 100644
--- a/war/src/main/scss/components/_side-panel-widgets.scss
+++ b/war/src/main/scss/components/_side-panel-widgets.scss
@@ -156,6 +156,7 @@
 
 .build-row-cell .pane.build-name .build-icon {
   position: absolute;
+  margin-top: 2px;
   z-index: 1;
 }
 
diff --git a/war/src/main/scss/pages/_dashboard.scss b/war/src/main/scss/pages/_dashboard.scss
index 732b7db61001..cb029a9861a9 100644
--- a/war/src/main/scss/pages/_dashboard.scss
+++ b/war/src/main/scss/pages/_dashboard.scss
@@ -169,3 +169,14 @@ $min-button-size: 36px;
     }
   }
 }
+
+.build-status-link {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+
+  svg {
+    width: 1rem;
+    height: 1rem;
+  }
+}