Migrate more icons to use gr-icon.

Google-Bug-Id: b/237255434
Release-Notes: skip
Change-Id: I501ba4443108eb5ab24cde71cb2d6fa6bd2d5bcc
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-reviewer-flow/gr-change-list-reviewer-flow.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-reviewer-flow/gr-change-list-reviewer-flow.ts
index a2a3d45..644c91b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-reviewer-flow/gr-change-list-reviewer-flow.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-reviewer-flow/gr-change-list-reviewer-flow.ts
@@ -44,7 +44,6 @@
 import {fireAlert, fireReload} from '../../../utils/event-util';
 import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
 import {Interaction} from '../../../constants/reporting';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-change-list-reviewer-flow')
 export class GrChangeListReviewerFlow extends LitElement {
@@ -108,7 +107,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
         gr-dialog {
           width: 60em;
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts
index de9c211..7505f03 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts
@@ -25,7 +25,6 @@
 import {LitElement, PropertyValues, html, css} from 'lit';
 import {customElement, property, state, query} from 'lit/decorators';
 import {ValueChangedEvent} from '../../../types/events';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const LOOKUP_QUERY_PATTERNS: RegExp[] = [
   /^\s*i?[0-9a-f]{7,40}\s*$/i, // CHANGE_ID
@@ -106,7 +105,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
index ef30a3e..2968472 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
@@ -7,6 +7,7 @@
 import '../../shared/gr-button/gr-button';
 import '../../shared/gr-dialog/gr-dialog';
 import '../../shared/gr-dropdown/gr-dropdown';
+import '../../shared/gr-icon/gr-icon';
 import '../../shared/gr-icons/gr-icons';
 import '../../shared/gr-overlay/gr-overlay';
 import '../gr-confirm-abandon-dialog/gr-confirm-abandon-dialog';
@@ -103,7 +104,6 @@
 import {customElement, property, query, state} from 'lit/decorators';
 import {ifDefined} from 'lit/directives/if-defined';
 import {assertIsDefined, queryAll} from '../../../utils/common-util';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const ERR_BRANCH_EMPTY = 'The destination branch can’t be empty.';
 const ERR_COMMIT_EMPTY = 'The commit message can’t be empty.';
@@ -557,7 +557,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -587,11 +586,11 @@
           text-align: center;
         }
         iron-icon,
-        .material-icon {
+        gr-icon {
           color: inherit;
           margin-right: var(--spacing-xs);
         }
-        #moreActions .material-icon {
+        #moreActions gr-icon {
           margin: 0;
         }
         #moreMessage,
@@ -662,9 +661,7 @@
           .disabledIds=${this.disabledMenuActions}
           .items=${this.menuActions}
         >
-          <span class="material-icon" aria-labelledby="moreMessage"
-            >more_vert</span
-          >
+          <gr-icon icon="more_vert" aria-labelledby="moreMessage"></gr-icon>
           <span id="moreMessage">More</span>
         </gr-dropdown>
       </div>
@@ -799,9 +796,7 @@
       return html`<iron-icon .icon=${action.icon}></iron-icon>`;
     } else {
       return html`
-        <span class="material-icon ${action.filled ? 'filled' : ''} "
-          >${action.icon}</span
-        >
+        <gr-icon icon=${action.icon} ?filled=${action.filled}></gr-icon>
       `;
     }
   }
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts
index b4cb05f..1d4fa06 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts
@@ -165,7 +165,7 @@
                 role="button"
                 tabindex="0"
               >
-                <span class="material-icon">done_all</span>
+                <gr-icon icon="done_all"></gr-icon>
                 Submit
               </gr-button>
             </gr-tooltip-content>
@@ -195,9 +195,7 @@
             Loading actions...
           </gr-button>
           <gr-dropdown id="moreActions" link="">
-            <span aria-labelledby="moreMessage" class="material-icon">
-              more_vert
-            </span>
+            <gr-icon icon="more_vert" aria-labelledby="moreMessage"></gr-icon>
             <span id="moreMessage"> More </span>
           </gr-dropdown>
         </div>
@@ -525,7 +523,7 @@
 
       queryAndAssert<GrButton>(
         element,
-        'gr-button[data-action-key="submit"] .material-icon'
+        'gr-button[data-action-key="submit"] gr-icon'
       ).click();
       await submitted;
     });
@@ -536,7 +534,7 @@
 
       queryAndAssert<GrButton>(
         element,
-        'gr-button[data-action-key="submit"] .material-icon'
+        'gr-button[data-action-key="submit"] gr-icon'
       );
       queryAndAssert<GrButton>(
         element,
@@ -544,7 +542,7 @@
       );
       queryAndAssert<GrButton>(
         element,
-        'gr-button[data-action-key="edit"] .material-icon.filled'
+        'gr-button[data-action-key="edit"] gr-icon[filled]'
       );
     });
 
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
index 2040872..cfb5602 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
@@ -13,6 +13,7 @@
 import '../../shared/gr-account-chip/gr-account-chip';
 import '../../shared/gr-date-formatter/gr-date-formatter';
 import '../../shared/gr-editable-label/gr-editable-label';
+import '../../shared/gr-icon/gr-icon';
 import '../../shared/gr-limited-text/gr-limited-text';
 import '../../shared/gr-linked-chip/gr-linked-chip';
 import '../../shared/gr-tooltip-content/gr-tooltip-content';
@@ -80,7 +81,6 @@
 import {changeMetadataStyles} from '../../../styles/gr-change-metadata-shared-styles';
 import {when} from 'lit/directives/when';
 import {ifDefined} from 'lit/directives/if-defined';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const HASHTAG_ADD_MESSAGE = 'Add Hashtag';
 
@@ -176,7 +176,6 @@
   static override styles = [
     sharedStyles,
     fontStyles,
-    iconStyles,
     changeMetadataStyles,
     css`
       :host {
@@ -262,7 +261,7 @@
          commit message box. Their top border should be on the same line. */
         margin-bottom: var(--spacing-s);
       }
-      .show-all-button .material-icon {
+      .show-all-button gr-icon {
         color: inherit;
         font-size: 18px;
       }
@@ -312,11 +311,8 @@
       class="show-all-button"
       @click=${this.onShowAllClick}
       >${this.showAllSections ? 'Show less' : 'Show all'}
-      <span class="material-icon" ?hidden=${this.showAllSections}
-        >expand_more</span
-      ><span class="material-icon" ?hidden=${!this.showAllSections}
-        >expand_less</span
-      >
+      <gr-icon icon="expand_more" ?hidden=${this.showAllSections}></gr-icon>
+      <gr-icon icon="expand_less" ?hidden=${!this.showAllSections}></gr-icon>
     </gr-button>`;
   }
 
@@ -386,11 +382,10 @@
             has-tooltip
             title=${this.pushCertificateValidation!.message}
           >
-            <span
-              class="icon material-icon ${this.pushCertificateValidation!
-                .class}"
-              >${this.pushCertificateValidation!.icon}</span
-            >
+            <gr-icon
+              icon=${this.pushCertificateValidation!.icon}
+              class="icon ${this.pushCertificateValidation!.class}"
+            ></gr-icon>
           </gr-tooltip-content>`
         )}
       </span>
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
index 1c94744..806a3b5 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
@@ -91,8 +91,8 @@
           tabindex="0"
           aria-disabled="false"
         >
-          Show all <span class="material-icon">expand_more</span>
-          <span hidden="" class="material-icon">expand_less</span>
+          Show all <gr-icon icon="expand_more"></gr-icon>
+          <gr-icon hidden="" icon="expand_less"></gr-icon>
         </gr-button>
       </div>
       <section class="hideDisplay">
diff --git a/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts b/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts
index 32ca697..0346675 100644
--- a/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts
@@ -6,6 +6,7 @@
 import './gr-checks-chip';
 import './gr-summary-chip';
 import '../../shared/gr-avatar/gr-avatar';
+import '../../shared/gr-icon/gr-icon';
 import '../../checks/gr-checks-action';
 import {LitElement, css, html} from 'lit';
 import {customElement, state} from 'lit/decorators';
@@ -55,7 +56,6 @@
 
 import {SummaryChipStyles} from './gr-summary-chip';
 import {when} from 'lit/directives/when';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 function handleSpaceOrEnter(e: KeyboardEvent, handler: () => void) {
   if (modifierPressed(e)) return;
@@ -172,7 +172,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       spinnerStyles,
       css`
@@ -203,17 +202,17 @@
         div.error {
           background-color: var(--error-background);
         }
-        div.info .material-icon,
-        div.error .material-icon {
+        div.info gr-icon,
+        div.error gr-icon {
           font-size: 16px;
           position: relative;
           top: 4px;
           margin-right: var(--spacing-s);
         }
-        div.info .material-icon {
+        div.info gr-icon {
           color: var(--info-foreground);
         }
-        div.error .material-icon {
+        div.error gr-icon {
           color: var(--error-foreground);
         }
         div.info .right,
@@ -230,7 +229,7 @@
           justify-content: space-between;
           background: var(--info-background);
         }
-        .login .material-icon {
+        .login gr-icon {
           color: var(--info-foreground);
         }
         .login gr-button {
@@ -330,9 +329,7 @@
         .items=${items}
         .disabledIds=${disabledIds}
       >
-        <span class="material-icon" aria-labelledby="moreMessage"
-          >more_vert</span
-        >
+        <gr-icon icon="more_vert" aria-labelledby="moreMessage"></gr-icon>
         <span id="moreMessage">More</span>
       </gr-dropdown>
     `;
@@ -343,7 +340,7 @@
       m => html`
         <div class="info">
           <div class="left">
-            <span class="material-icon filled">info</span>
+            <gr-icon icon="info" filled></gr-icon>
           </div>
           <div class="right">
             <div class="message" title=${m}>${m}</div>
@@ -359,7 +356,7 @@
         html`
           <div class="error zeroState">
             <div class="left">
-              <span class="material-icon filled">error</span>
+              <gr-icon icon="error" filled></gr-icon>
             </div>
             <div class="right">
               <div class="message" title=${message}>
@@ -376,7 +373,7 @@
     return html`
       <div class="login">
         <div class="left">
-          <span class="material-icon">info</span>
+          <gr-icon icon="info"></gr-icon>
           Not logged in
         </div>
         <div class="right">
diff --git a/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary_test.ts b/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary_test.ts
index 96a2971..694c8ff 100644
--- a/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary_test.ts
@@ -93,7 +93,7 @@
         <gr-checks-chip> </gr-checks-chip>
         <div class="info">
           <div class="left">
-            <span class="material-icon filled">info</span>
+            <gr-icon icon="info" filled></gr-icon>
           </div>
           <div class="right">
             <div class="message" title="a message">a message</div>
diff --git a/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip.ts b/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip.ts
index f906da1..ee62922 100644
--- a/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip.ts
@@ -16,7 +16,6 @@
 } from '../../../models/checks/checks-util';
 import {fontStyles} from '../../../styles/gr-font-styles';
 import {Interaction} from '../../../constants/reporting';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-checks-chip')
 export class GrChecksChip extends LitElement {
@@ -34,7 +33,6 @@
   static override get styles() {
     return [
       fontStyles,
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -75,10 +73,10 @@
           text-overflow: ellipsis;
           vertical-align: top;
         }
-        .material-icon {
+        gr-icon {
           font-size: var(--line-height-small);
         }
-        .checksChip a .material-icon.launch {
+        .checksChip a gr-icon.launch {
           color: var(--link-color);
         }
         .checksChip.error {
@@ -93,7 +91,7 @@
         .checksChip.error:focus-within {
           background: var(--error-background-focus);
         }
-        .checksChip.error .material-icon {
+        .checksChip.error gr-icon {
           color: var(--error-foreground);
         }
         .checksChip.warning {
@@ -107,7 +105,7 @@
         .checksChip.warning:focus-within {
           background: var(--warning-background-focus);
         }
-        .checksChip.warning .material-icon {
+        .checksChip.warning gr-icon {
           color: var(--warning-foreground);
         }
         .checksChip.info {
@@ -121,7 +119,7 @@
         .checksChip.info:focus-within {
           background: var(--info-background-focus);
         }
-        .checksChip.info .material--icon {
+        .checksChip.info gr-icon {
           color: var(--info-foreground);
         }
         .checksChip.check_circle {
@@ -135,7 +133,7 @@
         .checksChip.check_circle:focus-within {
           background: var(--success-background-focus);
         }
-        .checksChip.check_circle .material-icon {
+        .checksChip.check_circle gr-icon {
           color: var(--success-foreground);
         }
         .checksChip.timelapse,
@@ -152,8 +150,8 @@
         .checksChip.pending_actions:focus-within {
           background: var(--gray-background-focus);
         }
-        .checksChip.timelapse .material-icon,
-        .checksChip.pending_actions .material-icon {
+        .checksChip.timelapse gr-icon,
+        .checksChip.pending_actions gr-icon {
           color: var(--gray-foreground);
         }
       `,
@@ -186,9 +184,7 @@
   private renderChip(clazz: string, ariaLabel: string, icon: ChecksIcon) {
     return html`
       <div class=${clazz} role="link" tabindex="0" aria-label=${ariaLabel}>
-        <span class="material-icon ${icon.filled ? 'filled' : ''}"
-          >${icon.name}</span
-        >
+        <gr-icon icon=${icon.name} ?filled=${icon.filled}></gr-icon>
         ${this.renderLinks()}
         <div class="text">${this.text}</div>
       </div>
@@ -204,8 +200,8 @@
           @click=${this.onLinkClick}
           @keydown=${this.onLinkKeyDown}
           aria-label="Link to check details"
-          ><span class="material-icon launch">open_in_new</span></a
-        >
+          ><gr-icon icon="open_in_new" class="launch"></gr-icon
+        ></a>
       `
     );
   }
diff --git a/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip_test.ts b/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip_test.ts
index 1ace1f4..1fbbca6 100644
--- a/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-summary/gr-checks-chip_test.ts
@@ -29,7 +29,7 @@
       role="link"
       tabindex="0"
     >
-      <span class="material-icon">check_circle</span>
+      <gr-icon icon="check_circle"></gr-icon>
       <div class="text">0</div>
     </div>`);
   });
diff --git a/polygerrit-ui/app/elements/change/gr-change-summary/gr-summary-chip.ts b/polygerrit-ui/app/elements/change/gr-change-summary/gr-summary-chip.ts
index d39df3c..a87420c 100644
--- a/polygerrit-ui/app/elements/change/gr-change-summary/gr-summary-chip.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-summary/gr-summary-chip.ts
@@ -3,6 +3,7 @@
  * Copyright 2022 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../../shared/gr-icon/gr-icon';
 import {LitElement, css, html} from 'lit';
 import {customElement, property} from 'lit/decorators';
 import {sharedStyles} from '../../../styles/shared-styles';
@@ -11,7 +12,6 @@
 import {PrimaryTab} from '../../../constants/constants';
 import {CommentTabState} from '../../../types/events';
 import {fontStyles} from '../../../styles/gr-font-styles';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 export enum SummaryChipStyles {
   INFO = 'info',
@@ -36,7 +36,6 @@
   static override get styles() {
     return [
       sharedStyles,
-      iconStyles,
       fontStyles,
       css`
         .summaryChip {
@@ -54,7 +53,7 @@
           position: relative;
           top: 2px;
         }
-        .material-icon {
+        gr-icon {
           font-size: var(--line-height-small);
         }
         .summaryChip.warning {
@@ -68,7 +67,7 @@
         .summaryChip.warning:focus-within {
           background: var(--warning-background-focus);
         }
-        .summaryChip.warning .material-icon {
+        .summaryChip.warning gr-icon {
           color: var(--warning-foreground);
         }
         .summaryChip.check {
@@ -82,7 +81,7 @@
         .summaryChip.check:focus-within {
           background: var(--gray-background-focus);
         }
-        .summaryChip.check .material-icon {
+        .summaryChip.check gr-icon {
           color: var(--gray-foreground);
         }
       `,
@@ -92,7 +91,7 @@
   override render() {
     const chipClass = `summaryChip font-small ${this.styleType}`;
     return html`<button class=${chipClass} @click=${this.handleClick}>
-      ${this.icon && html`<span class="material-icon">${this.icon}</span>`}
+      ${this.icon && html`<gr-icon icon=${this.icon}></gr-icon>`}
       <slot></slot>
     </button>`;
   }
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts
index 6f27451..816855c 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../shared/gr-dialog/gr-dialog';
+import '../../shared/gr-icon/gr-icon';
 import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
 import '../../plugins/gr-endpoint-param/gr-endpoint-param';
 import '../gr-thread-list/gr-thread-list';
@@ -20,7 +21,6 @@
 import {commentsModelToken} from '../../../models/comments/comments-model';
 import {changeModelToken} from '../../../models/change/change-model';
 import {resolve} from '../../../models/dependency';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-confirm-submit-dialog')
 export class GrConfirmSubmitDialog extends LitElement {
@@ -59,7 +59,6 @@
     return [
       sharedStyles,
       fontStyles,
-      iconStyles,
       css`
         #dialog {
           min-width: 40em;
@@ -100,7 +99,7 @@
     if (!this.change?.is_private) return '';
     return html`
       <p>
-        <span class="material-icon filled warningBeforeSubmit">warning</span>
+        <gr-icon icon="warning" filled class="warningBeforeSubmit"></gr-icon>
         <strong>Heads Up!</strong>
         Submitting this private change will also make it public.
       </p>
@@ -111,7 +110,7 @@
     if (!this.unresolvedThreads?.length) return '';
     return html`
       <p>
-        <span class="material-icon filled warningBeforeSubmit">warning</span>
+        <gr-icon icon="warning" filled class="warningBeforeSubmit"></gr-icon>
         ${this.computeUnresolvedCommentsWarning()}
       </p>
       <gr-thread-list
@@ -126,7 +125,7 @@
   private renderChangeEdit() {
     if (!this.computeHasChangeEdit()) return '';
     return html`
-      <span class="material-icon filled warningBeforeSubmit">warning</span>
+      <gr-icon icon="warning" filled class="warningBeforeSubmit"></gr-icon>
       Your unpublished edit will not be submitted. Did you forget to click
       <b>PUBLISH</b>
     `;
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts
index 6936f83..d34a9a5 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts
@@ -8,6 +8,7 @@
 import '../../edit/gr-edit-controls/gr-edit-controls';
 import '../../shared/gr-select/gr-select';
 import '../../shared/gr-button/gr-button';
+import '../../shared/gr-icon/gr-icon';
 import '../gr-commit-info/gr-commit-info';
 import {FilesExpandedState} from '../gr-file-list-constants';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation';
@@ -40,7 +41,6 @@
 import {getAppContext} from '../../../services/app-context';
 import {subscribe} from '../../lit/subscription-controller';
 import {configModelToken} from '../../../models/config/config-model';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-file-list-header')
 export class GrFileListHeader extends LitElement {
@@ -144,7 +144,6 @@
   }
 
   static override styles = [
-    iconStyles,
     sharedStyles,
     css`
       .prefsButton {
@@ -327,8 +326,8 @@
                   link
                   class="prefsButton desktop"
                   @click=${this.handlePrefsTap}
-                  ><span class="material-icon filled">settings</span></gr-button
-                >
+                  ><gr-icon icon="settings" filled></gr-icon
+                ></gr-button>
               </gr-tooltip-content>
             </span>
             <span class="separator"></span>
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts
index 6edd13c..e7b4a87 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts
@@ -83,7 +83,7 @@
                   role="button"
                   tabindex="0"
                 >
-                  <span class="filled material-icon"> settings </span>
+                  <gr-icon filled icon="settings"></gr-icon>
                 </gr-button>
               </gr-tooltip-content>
             </span>
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
index 50c51c2..52fa289 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
@@ -11,6 +11,7 @@
 import '../../edit/gr-edit-file-controls/gr-edit-file-controls';
 import '../../shared/gr-button/gr-button';
 import '../../shared/gr-cursor-manager/gr-cursor-manager';
+import '../../shared/gr-icon/gr-icon';
 import '../../shared/gr-linked-text/gr-linked-text';
 import '../../shared/gr-select/gr-select';
 import '../../shared/gr-tooltip-content/gr-tooltip-content';
@@ -79,7 +80,6 @@
 import {incrementalRepeat} from '../../lit/incremental-repeat';
 import {ifDefined} from 'lit/directives/if-defined';
 import {KnownExperimentId} from '../../../services/flags/flags';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 export const DEFAULT_NUM_FILES_SHOWN = 200;
 
@@ -314,7 +314,6 @@
     return [
       a11yStyles,
       sharedStyles,
-      iconStyles,
       css`
         :host {
           display: block;
@@ -577,6 +576,7 @@
           font-size: 16px;
           position: relative;
           top: 2px;
+          display: block;
         }
 
         @media screen and (max-width: 1200px) {
@@ -1116,7 +1116,7 @@
     if (!path) {
       return html`
         ${this.renderDivWithTooltip(`${psNum}`, `Patchset ${psNum}`)}
-        <div class="material-icon file-status-arrow">arrow_right_alt</div>
+        <gr-icon icon="arrow_right_alt" class="file-status-arrow"></gr-icon>
       `;
     }
     if (isMagicPath(path)) return nothing;
@@ -1131,7 +1131,7 @@
         .status=${status}
         .labelPostfix=${postfix}
       ></gr-file-status>
-      <div class="material-icon file-status-arrow">arrow_right_alt</div>
+      <gr-icon icon="arrow_right_alt" class="file-status-arrow"></gr-icon>
     `;
   }
 
@@ -1360,9 +1360,12 @@
       >
         <!-- Trick with tabindex to avoid outline on mouse focus, but
           preserve focus outline for keyboard navigation -->
-        <span class="show-hide-icon material-icon" tabindex="-1" id="icon"
-          >${this.computeShowHideIcon(file.__path)}
-        </span>
+        <gr-icon
+          class="show-hide-icon"
+          tabindex="-1"
+          id="icon"
+          icon=${this.computeShowHideIcon(file.__path)}
+        ></gr-icon>
       </span>
     </div>`;
   }
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts
index 8262b09..07ed67d 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts
@@ -53,6 +53,7 @@
 import {normalize} from '../../../models/change/files-model';
 import {GrDiffHost} from '../../diff/gr-diff-host/gr-diff-host';
 import {GrEditFileControls} from '../../edit/gr-edit-file-controls/gr-edit-file-controls';
+import {GrIcon} from '../../shared/gr-icon/gr-icon';
 
 const basicFixture = fixtureFromElement('gr-file-list');
 
@@ -242,9 +243,12 @@
             role="switch"
             tabindex="0"
           >
-            <span class="show-hide-icon material-icon" id="icon" tabindex="-1"
-              >expand_more
-            </span>
+            <gr-icon
+              icon="expand_more"
+              class="show-hide-icon"
+              id="icon"
+              tabindex="-1"
+            ></gr-icon>
           </span>
         </div>
       </div>`);
@@ -260,7 +264,7 @@
       expect(statusCol).dom.equal(/* HTML */ `
         <div class="extended status" role="gridcell">
           <gr-file-status></gr-file-status>
-          <div class="material-icon file-status-arrow">arrow_right_alt</div>
+          <gr-icon class="file-status-arrow" icon="arrow_right_alt"></gr-icon>
           <gr-file-status></gr-file-status>
         </div>
       `);
@@ -279,7 +283,7 @@
           <gr-tooltip-content has-tooltip="" title="Patchset 1">
             <div class="content">1</div>
           </gr-tooltip-content>
-          <div class="material-icon file-status-arrow">arrow_right_alt</div>
+          <gr-icon class="file-status-arrow" icon="arrow_right_alt"></gr-icon>
           <gr-tooltip-content has-tooltip="" title="Patchset 2">
             <div class="content">2</div>
           </gr-tooltip-content>
@@ -1332,7 +1336,7 @@
       const collapseStub = sinon.stub(element, 'clearCollapsedDiffs');
 
       assert.equal(
-        queryAndAssert<HTMLSpanElement>(element, '.material-icon').innerText,
+        queryAndAssert<GrIcon>(element, 'gr-icon').icon,
         'expand_more'
       );
       assert.equal(element.expandedFiles.length, 0);
@@ -1343,7 +1347,7 @@
 
       assert.equal(collapseStub.lastCall.args[0].length, 0);
       assert.equal(
-        queryAndAssert<HTMLSpanElement>(element, '.material-icon').innerText,
+        queryAndAssert<GrIcon>(element, 'gr-icon').icon,
         'expand_less'
       );
 
@@ -1355,7 +1359,7 @@
       await flush();
 
       assert.equal(
-        queryAndAssert<HTMLSpanElement>(element, '.material-icon').innerText,
+        queryAndAssert<GrIcon>(element, 'gr-icon').icon,
         'expand_more'
       );
       assert.equal(renderSpy.callCount, 1);
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.ts b/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
index f35fc6f..b6d3328 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
@@ -6,6 +6,7 @@
 import '../../shared/gr-account-label/gr-account-label';
 import '../../shared/gr-account-chip/gr-account-chip';
 import '../../shared/gr-button/gr-button';
+import '../../shared/gr-icon/gr-icon';
 import '../../shared/gr-date-formatter/gr-date-formatter';
 import '../../shared/gr-formatted-text/gr-formatted-text';
 import '../gr-message-scores/gr-message-scores';
@@ -46,7 +47,6 @@
 import {assertIsDefined} from '../../../utils/common-util';
 import {when} from 'lit/directives/when';
 import {FormattedReviewerUpdateInfo} from '../../../types/types';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const UPLOADED_NEW_PATCHSET_PATTERN = /Uploaded patch set (\d+)./;
 const MERGED_PATCHSET_PATTERN = /(\d+) is the latest approved patch-set/;
@@ -149,7 +149,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
         :host {
           display: block;
@@ -256,7 +255,7 @@
           right: var(--spacing-l);
           top: var(--spacing-m);
         }
-        .dateContainer .material-icon {
+        .dateContainer gr-icon {
           margin-right: var(--spacing-m);
           color: var(--deemphasized-text-color);
         }
@@ -273,7 +272,7 @@
         span.date:hover {
           text-decoration: underline;
         }
-        .dateContainer .material-icon {
+        .dateContainer gr-icon {
           cursor: pointer;
           vertical-align: top;
         }
@@ -358,7 +357,7 @@
     const commentCountText = pluralize(this.commentThreads.length, 'comment');
     return html`
       <div class="commentsSummary">
-        <span class="commentsIcon material-icon filled">mode_comment</span>
+        <gr-icon icon="mode_comment" filled class="commentsIcon"></gr-icon>
         <span class="numberOfComments">${commentCountText}</span>
       </div>
     `;
@@ -483,13 +482,12 @@
           </span>
         `
       )}
-      <span
+      <gr-icon
         id="expandToggle"
         @click=${this.toggleExpanded}
         title="Toggle expanded state"
-        class="material-icon"
-        >${this.computeExpandToggleIcon()}</span
-      >
+        icon=${this.computeExpandToggleIcon()}
+      ></gr-icon>
     </span>`;
   }
 
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts
index 9cdf31d..cd44925 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts
@@ -158,12 +158,11 @@
               <gr-date-formatter showdateandtime="" withtooltip="">
               </gr-date-formatter>
             </span>
-            <span
-              class="material-icon"
+            <gr-icon
+              icon="expand_more"
               id="expandToggle"
               title="Toggle expanded state"
-              >expand_more</span
-            >
+            ></gr-icon>
           </span>
         </div>
       </div>`);
@@ -200,12 +199,11 @@
               <gr-date-formatter showdateandtime="" withtooltip="">
               </gr-date-formatter>
             </span>
-            <span
-              class="material-icon"
+            <gr-icon
+              icon="expand_more"
               id="expandToggle"
               title="Toggle expanded state"
-              >expand_more</span
-            >
+            ></gr-icon>
           </span>
         </div>
       </div>`);
@@ -244,12 +242,11 @@
               <gr-date-formatter showdateandtime="" withtooltip="">
               </gr-date-formatter>
             </span>
-            <span
-              class="material-icon"
+            <gr-icon
+              icon="expand_more"
               id="expandToggle"
               title="Toggle expanded state"
-              >expand_more</span
-            >
+            ></gr-icon>
           </span>
         </div>
       </div>`);
@@ -285,12 +282,11 @@
               <gr-date-formatter showdateandtime="" withtooltip="">
               </gr-date-formatter>
             </span>
-            <span
-              class="material-icon"
+            <gr-icon
+              icon="expand_more"
               id="expandToggle"
               title="Toggle expanded state"
-              >expand_more</span
-            >
+            ></gr-icon>
           </span>
         </div>
       </div>`;
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts
index 43f0754..b89232e 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts
@@ -8,6 +8,7 @@
 import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
 import '../../plugins/gr-endpoint-param/gr-endpoint-param';
 import '../../plugins/gr-endpoint-slot/gr-endpoint-slot';
+import '../../shared/gr-icon/gr-icon';
 import {classMap} from 'lit/directives/class-map';
 import {LitElement, css, html, TemplateResult} from 'lit';
 import {customElement, property, state} from 'lit/decorators';
@@ -32,7 +33,6 @@
   isChangeInfo,
 } from '../../../utils/change-util';
 import {DEFALT_NUM_CHANGES_WHEN_COLLAPSED} from './gr-related-collapse';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 export interface ChangeMarkersInList {
   showCurrentChangeArrow: boolean;
@@ -82,7 +82,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         .note {
@@ -551,16 +550,16 @@
         role="img"
         class="marker arrow"
         aria-label="Arrow marking change has collapsed ancestors"
-        ><span class="material-icon">arrow_drop_up</span></span
-      > `;
+        ><gr-icon icon="arrow_drop_up"></gr-icon
+      ></span> `;
     }
     if (changeMarkers.showBottomArrow) {
       return html`<span
         role="img"
         class="marker arrow"
         aria-label="Arrow marking change has collapsed descendants"
-        ><span class="material-icon">arrow_drop_down</span></span
-      > `;
+        ><gr-icon icon="arrow_drop_down"></gr-icon
+      ></span> `;
     }
     return html`<span class="marker space"></span>`;
   }
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-collapse.ts b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-collapse.ts
index 93a1f27..fa01a6a 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-collapse.ts
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-collapse.ts
@@ -4,12 +4,12 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import {LitElement, css, html, nothing, TemplateResult} from 'lit';
+import '../../shared/gr-icon/gr-icon';
 import {customElement, property} from 'lit/decorators';
 import {sharedStyles} from '../../../styles/shared-styles';
 import {getAppContext} from '../../../services/app-context';
 import {Interaction} from '../../../constants/reporting';
 import {fontStyles} from '../../../styles/gr-font-styles';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 /** What is the maximum number of shown changes in collapsed list? */
 export const DEFALT_NUM_CHANGES_WHEN_COLLAPSED = 3;
@@ -37,7 +37,6 @@
     return [
       sharedStyles,
       fontStyles,
-      iconStyles,
       css`
         .title {
           color: var(--deemphasized-text-color);
@@ -48,7 +47,7 @@
         gr-button {
           display: flex;
         }
-        gr-button .material-icon {
+        gr-button gr-icon {
           color: inherit;
           font-size: 18px;
         }
@@ -77,10 +76,8 @@
         : `Show all (${this.length})`;
       const buttonIcon = this.showAll ? 'expand_less' : 'expand_more';
       button = html`<gr-button link="" @click=${this.toggle}
-        >${buttonText}<span class="material-icon"
-          >${buttonIcon}</span
-        ></gr-button
-      >`;
+        >${buttonText}<gr-icon icon=${buttonIcon}></gr-icon
+      ></gr-button>`;
     }
 
     return html`<div class="container">${title}${button}</div>
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.ts b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.ts
index 24be183..61e16b0 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.ts
@@ -5,6 +5,7 @@
  */
 import '../../shared/gr-account-chip/gr-account-chip';
 import '../../shared/gr-button/gr-button';
+import '../../shared/gr-icon/gr-icon';
 import '../../shared/gr-vote-chip/gr-vote-chip';
 import {LitElement, html} from 'lit';
 import {customElement, property, state} from 'lit/decorators';
@@ -22,7 +23,6 @@
 import {sharedStyles} from '../../../styles/shared-styles';
 import {css} from 'lit';
 import {nothing} from 'lit';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-reviewer-list')
 export class GrReviewerList extends LitElement {
@@ -54,7 +54,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -72,7 +71,7 @@
           line-height: calc(var(--line-height-normal) + 2px + var(--spacing-s));
           margin-bottom: calc(0px - var(--spacing-s));
         }
-        .addReviewer .material-icon {
+        .addReviewer gr-icon {
           color: inherit;
           font-size: 18px;
         }
@@ -118,7 +117,7 @@
               class="addReviewer"
               @click=${this.handleAddTap}
               title=${this.ccsOnly ? 'Add CC' : 'Add reviewer'}
-              ><span class="material-icon filled">edit</span>
+              ><gr-icon icon="edit" filled></gr-icon>
             </gr-button>
           </div>
         </div>
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.ts b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.ts
index 7e17d1a..89bb2fd 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.ts
@@ -39,7 +39,7 @@
               tabindex="0"
               title="Add reviewer"
             >
-              <span class="filled material-icon"> edit </span>
+              <gr-icon icon="edit" filled></gr-icon>
             </gr-button>
           </div>
         </div>
diff --git a/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard.ts b/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard.ts
index c5f7fa8..382d763 100644
--- a/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard.ts
+++ b/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard.ts
@@ -3,12 +3,12 @@
  * Copyright 2021 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../../shared/gr-icon/gr-icon';
 import {customElement, property} from 'lit/decorators';
 import {css, html, LitElement} from 'lit';
 import {HovercardMixin} from '../../../mixins/hovercard-mixin/hovercard-mixin';
 import {fontStyles} from '../../../styles/gr-font-styles';
 import {LabelInfo} from '../../../api/rest-api';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 // This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
 const base = HovercardMixin(LitElement);
@@ -24,7 +24,6 @@
   static override get styles() {
     return [
       fontStyles,
-      iconStyles,
       base.styles || [],
       css`
         #container {
@@ -47,7 +46,7 @@
         div.sectionIcon {
           flex: 0 0 30px;
         }
-        div.sectionIcon .material-icon {
+        div.sectionIcon gr-icon {
           position: relative;
           font-size: 20px;
         }
@@ -66,7 +65,7 @@
       </div>
       <div class="section">
         <div class="sectionIcon">
-          <span class="small material-icon">info</span>
+          <gr-icon icon="info" class="small"></gr-icon></span>
         </div>
         <div class="sectionContent">
           <div class="row">
@@ -86,7 +85,7 @@
     if (!description) return;
     return html`<div class="section description">
       <div class="sectionIcon">
-        <span class="material-icon">description</span>
+        <gr-icon icon="description"></gr-icon>
       </div>
       <div class="sectionContent">
         <gr-formatted-text
diff --git a/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard_test.ts b/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard_test.ts
index 37ca1a7..8a67ea3 100644
--- a/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-trigger-vote-hovercard/gr-trigger-vote-hovercard_test.ts
@@ -33,7 +33,7 @@
         </div>
         <div class="section">
           <div class="sectionIcon">
-            <span class="material-icon small"> info </span>
+            <gr-icon icon="info" class=" small"></gr-icon>
           </div>
           <div class="sectionContent">
             <div class="row">
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-results.ts b/polygerrit-ui/app/elements/checks/gr-checks-results.ts
index 1608528..202c502 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-results.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-results.ts
@@ -3,6 +3,7 @@
  * Copyright 2020 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../shared/gr-icon/gr-icon';
 import {classMap} from 'lit/directives/class-map';
 import {repeat} from 'lit/directives/repeat';
 import {ifDefined} from 'lit/directives/if-defined';
@@ -62,7 +63,6 @@
 import {changeModelToken} from '../../models/change/change-model';
 import {getAppContext} from '../../services/app-context';
 import {when} from 'lit/directives/when';
-import {iconStyles} from '../../styles/gr-icon-styles';
 
 /**
  * Firing this event sets the regular expression of the results filter.
@@ -123,7 +123,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -141,7 +140,7 @@
         a.link {
           margin-right: var(--spacing-s);
         }
-        .material-icon.link {
+        gr-icon.link {
           color: var(--link-color);
         }
         td.nameCol div.flex {
@@ -260,7 +259,7 @@
           margin: -4px 0;
           vertical-align: top;
         }
-        #moreActions .material-icon {
+        #moreActions gr-icon {
           color: var(--link-color);
         }
         #moreMessage {
@@ -378,9 +377,9 @@
               : 'Expand result row'}
             @keydown=${this.toggleExpandedPress}
           >
-            <span class="material-icon"
-              >${this.isExpanded ? 'expand_less' : 'expand_more'}</span
-            >
+            <gr-icon
+              icon=${this.isExpanded ? 'expand_less' : 'expand_more'}
+            ></gr-icon>
           </div>
         </td>
       </tr>
@@ -495,11 +494,13 @@
     const tooltipText = link.tooltip ?? tooltipForLink(link.icon);
     const icon = iconForLink(link.icon);
     return html`<a href=${link.url} class="link" target="_blank"
-      ><span
+      ><gr-icon
+        icon=${icon.name}
+        ?filled=${icon.filled}
         aria-label="external link to details"
-        class="material-icon link ${icon.filled ? 'filled' : ''}"
-        >${icon.name}</span
-      ><paper-tooltip offset="5">${tooltipText}</paper-tooltip></a
+        class="link"
+      ></gr-icon>
+      <paper-tooltip offset="5">${tooltipText}</paper-tooltip></a
     >`;
   }
 
@@ -526,9 +527,7 @@
         .items=${overflowItems}
         .disabledIds=${disabledItems}
       >
-        <span class="material-icon" aria-labelledby="moreMessage"
-          >more_vert</span
-        >
+        <gr-icon icon="more_vert" aria-labelledby="moreMessage"></gr-icon>
         <span id="moreMessage">More</span>
       </gr-dropdown>
     </div>`;
@@ -599,7 +598,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         .links {
@@ -609,7 +607,7 @@
           display: inline-block;
           margin-right: var(--spacing-xl);
         }
-        .links a .material-icon {
+        .links a gr-icon {
           margin-right: var(--spacing-xs);
         }
         .message {
@@ -707,9 +705,8 @@
     const target = targetBlank ? '_blank' : undefined;
     const icon = iconForLink(link.icon);
     return html`<a href=${link.url} target=${ifDefined(target)}>
-      <span class="material-icon link ${icon.filled ? 'filled' : ''}"
-        >${icon.name}</span
-      ><span>${text}</span>
+      <gr-icon icon=${icon.name} class="link" ?filled=${icon.filled}></gr-icon>
+      <span>${text}</span>
     </a>`;
   }
 }
@@ -828,7 +825,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       spinnerStyles,
       fontStyles,
@@ -893,7 +889,7 @@
           margin-right: var(--spacing-m);
           --gr-button-padding: var(--spacing-s) var(--spacing-m);
         }
-        .headerBottomRow .material-icon {
+        .headerBottomRow gr-icon {
           color: var(--link-color);
         }
         .headerBottomRow .space {
@@ -904,7 +900,7 @@
         .headerBottomRow a {
           margin-right: var(--spacing-l);
         }
-        #moreActions .material-icon {
+        #moreActions gr-icon {
           color: var(--link-color);
         }
         #moreMessage {
@@ -959,7 +955,7 @@
         .categoryHeader .statusIcon.success {
           color: var(--success-foreground);
         }
-        .categoryHeader.empty .material-icon.statusIcon {
+        .categoryHeader.empty gr-icon.statusIcon {
           color: var(--deemphasized-text-color);
         }
         .categoryHeader .filtered {
@@ -1151,11 +1147,13 @@
     const tooltipText = link.tooltip ?? tooltipForLink(link.icon);
     const icon = iconForLink(link.icon);
     return html`<a href=${link.url} target="_blank"
-      ><span
+      ><gr-icon
+        icon=${icon.name}
         aria-label=${tooltipText}
-        class="material-icon link ${icon.filled ? 'filled' : ''}"
-        >${icon.name}</span
-      ><paper-tooltip offset="5">${tooltipText}</paper-tooltip></a
+        class="link"
+        ?filled=${icon.filled}
+      ></gr-icon>
+      <paper-tooltip offset="5">${tooltipText}</paper-tooltip></a
     >`;
   }
 
@@ -1171,9 +1169,7 @@
         .items=${items}
         .disabledIds=${disabledIds}
       >
-        <span class="material-icon" aria-labelledby="moreMessage"
-          >more_vert</span
-        >
+        <gr-icon icon="more_vert" aria-labelledby="moreMessage"></gr-icon>
         <span id="moreMessage">More</span>
       </gr-dropdown>
     `;
@@ -1309,16 +1305,16 @@
           class="categoryHeader ${catString} ${empty} heading-3"
           @click=${() => this.toggleExpanded(category)}
         >
-          <span class="expandIcon material-icon"
-            >${expanded ? 'expand_less' : 'expand_more'}</span
-          >
+          <gr-icon
+            class="expandIcon"
+            icon=${expanded ? 'expand_less' : 'expand_more'}
+          ></gr-icon>
           <div class="statusIconWrapper">
-            <span
-              class="material-icon statusIcon ${catString} ${icon.filled
-                ? 'filled'
-                : ''}"
-              >${icon.name}</span
-            >
+            <gr-icon
+              icon=${icon.name}
+              ?filled=${icon.filled}
+              class="statusIcon ${catString}"
+            ></gr-icon>
             <span class="title">${catString}</span>
             <span class="count">${this.renderCount(all, filtered)}</span>
             <paper-tooltip offset="5"
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-results_test.ts b/polygerrit-ui/app/elements/checks/gr-checks-results_test.ts
index d438a73..d47df32 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-results_test.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-results_test.ts
@@ -66,11 +66,11 @@
       </div>
         <div class="summary-cell">
           <a class="link" href="https://www.google.com" target="_blank">
-            <span
+            <gr-icon
+              icon="open_in_new"
               aria-label="external link to details"
-              class="material-icon link"
-            >open_in_new
-            </span>
+              class="link"
+            ></gr-icon>
             <paper-tooltip offset="5" role="tooltip" tabindex="-1">
               Link to details
             </paper-tooltip>
@@ -115,7 +115,7 @@
           role="switch"
           tabindex="0"
         >
-          <span class="material-icon">expand_more</span>
+          <gr-icon icon="expand_more"></gr-icon>
         </div>
       </div>
     `);
@@ -157,31 +157,34 @@
             <div class="left"></div>
             <div class="right">
               <a href="https://www.google.com" target="_blank">
-                <span
+                <gr-icon
+                  icon="bug_report"
+                  filled
                   aria-label="Fake Bug Report 1"
-                  class="material-icon filled link"
-                  >bug_report
-                </span>
+                  class="link"
+                ></gr-icon>
                 <paper-tooltip offset="5"> </paper-tooltip>
               </a>
               <a href="https://www.google.com" target="_blank">
-                <span aria-label="Fake Link 1" class="material-icon link"
-                  >open_in_new
-                </span>
+                <gr-icon
+                  icon="open_in_new"
+                  aria-label="Fake Link 1"
+                  class="link"
+                ></gr-icon>
                 <paper-tooltip offset="5"> </paper-tooltip>
               </a>
               <a href="https://www.google.com" target="_blank">
-                <span aria-label="Fake Code Link" class="material-icon link"
-                  >code
-                </span>
+                <gr-icon icon="code" aria-label="Fake Code Link" class="link">
+                </gr-icon>
                 <paper-tooltip offset="5"> </paper-tooltip>
               </a>
               <a href="https://www.google.com" target="_blank">
-                <span
+                <gr-icon
+                  icon="image"
+                  filled
                   aria-label="Fake Image Link"
-                  class="material-icon filled link"
-                  >image
-                </span>
+                  class="link"
+                ></gr-icon>
                 <paper-tooltip offset="5"> </paper-tooltip>
               </a>
               <div class="space"></div>
@@ -192,9 +195,10 @@
                 link=""
                 vertical-offset="32"
               >
-                <span aria-labelledby="moreMessage" class="material-icon"
-                  >more_vert
-                </span>
+                <gr-icon
+                  icon="more_vert"
+                  aria-labelledby="moreMessage"
+                ></gr-icon>
                 <span id="moreMessage"> More </span>
               </gr-dropdown>
             </div>
@@ -203,9 +207,9 @@
         <div class="body">
           <div class="collapsed">
             <h3 class="categoryHeader empty error heading-3">
-              <span class="expandIcon material-icon">expand_more</span>
+              <gr-icon icon="expand_more" class="expandIcon"></gr-icon>
               <div class="statusIconWrapper">
-                <span class="material-icon filled error statusIcon">error</span>
+                <gr-icon icon="error" filled class="error statusIcon"></gr-icon>
                 <span class="title"> error </span>
                 <span class="count"> (0) </span>
                 <paper-tooltip offset="5"> </paper-tooltip>
@@ -214,11 +218,10 @@
           </div>
           <div class="collapsed">
             <h3 class="categoryHeader empty heading-3 warning">
-              <span class="expandIcon material-icon">expand_more</span>
+              <gr-icon icon="expand_more" class="expandIcon"></gr-icon>
               <div class="statusIconWrapper">
-                <span class="material-icon filled warning statusIcon"
-                  >warning
-                </span>
+                <gr-icon icon="warning" filled class="warning statusIcon">
+                </gr-icon>
                 <span class="title"> warning </span>
                 <span class="count"> (0) </span>
                 <paper-tooltip offset="5"> </paper-tooltip>
@@ -227,9 +230,9 @@
           </div>
           <div class="collapsed">
             <h3 class="categoryHeader empty heading-3 info">
-              <span class="expandIcon material-icon">expand_more</span>
+              <gr-icon icon="expand_more" class="expandIcon"></gr-icon>
               <div class="statusIconWrapper">
-                <span class="material-icon info statusIcon">info</span>
+                <gr-icon icon="info" class="info statusIcon"></gr-icon>
                 <span class="title"> info </span>
                 <span class="count"> (0) </span>
                 <paper-tooltip offset="5"> </paper-tooltip>
@@ -238,11 +241,10 @@
           </div>
           <div class="collapsed">
             <h3 class="categoryHeader empty heading-3 success">
-              <span class="expandIcon material-icon">expand_more</span>
+              <gr-icon icon="expand_more" class="expandIcon"></gr-icon>
               <div class="statusIconWrapper">
-                <span class="material-icon statusIcon success"
-                  >check_circle
-                </span>
+                <gr-icon icon="check_circle" class="statusIcon success">
+                </gr-icon>
                 <span class="title"> success </span>
                 <span class="count"> (0) </span>
                 <paper-tooltip offset="5"> </paper-tooltip>
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-runs.ts b/polygerrit-ui/app/elements/checks/gr-checks-runs.ts
index e522479..f1fed97 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-runs.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-runs.ts
@@ -3,6 +3,7 @@
  * Copyright 2020 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../shared/gr-icon/gr-icon';
 import {classMap} from 'lit/directives/class-map';
 import './gr-hovercard-run';
 import {css, html, LitElement, nothing, PropertyValues} from 'lit';
@@ -55,13 +56,11 @@
 import {checksModelToken} from '../../models/checks/checks-model';
 import {Interaction} from '../../constants/reporting';
 import {Deduping} from '../../api/reporting';
-import {iconStyles} from '../../styles/gr-icon-styles';
 
 @customElement('gr-checks-run')
 export class GrChecksRun extends LitElement {
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -117,19 +116,19 @@
         .chip.placeholder {
           border-left: var(--thick-border) solid var(--border-color);
         }
-        .chip.placeholder .material-icon {
+        .chip.placeholder gr-icon {
           display: none;
         }
-        .material-icon.error {
+        gr-icon.error {
           color: var(--error-foreground);
         }
-        .material-icon.warning {
+        gr-icon.warning {
           color: var(--warning-foreground);
         }
-        .material-icon.info {
+        gr-icon.info {
           color: var(--info-foreground);
         }
-        .material-icon.check_circle {
+        gr-icon.check_circle {
           color: var(--success-foreground);
         }
         div.chip:hover {
@@ -145,7 +144,7 @@
           padding-left: calc(var(--spacing-m) + var(--thick-border) - 1px);
         }
         div.chip.selected .name,
-        div.chip.selected .material-icon.filter {
+        div.chip.selected gr-icon.filter {
           color: var(--selected-foreground);
         }
         gr-checks-action {
@@ -243,9 +242,7 @@
         <div class="left">
           <gr-hovercard-run .run=${this.run}></gr-hovercard-run>
           ${this.renderFilterIcon()}
-          <span class="material-icon ${icon.filled ? 'filled' : ''}"
-            >${icon.name}</span
-          >
+          <gr-icon icon=${icon.name} ?filled=${icon.filled}></gr-icon>
           ${this.renderAdditionalIcon()}
           <span class="name">${this.run.checkName}</span>
           ${this.renderETA()}
@@ -293,9 +290,11 @@
         ?disabled=${!this.isSelected(detail) && wasNotRun}
         @change=${() => this.handleAttemptChange(detail)}
       />
-      <span class="material-icon ${icon.name} ${icon.filled ? 'filled' : ''}"
-        >${icon.name}</span
-      >
+      <gr-icon
+        icon=${icon.name}
+        class=${icon.name}
+        ?filled=${icon.filled}
+      ></gr-icon>
       <label for=${id}>
         Attempt ${detail.attempt}${wasNotRun ? ' (not run)' : ''}
       </label>
@@ -322,11 +321,11 @@
     if (!link) return;
     return html`
       <a href=${link} target="_blank" @click=${this.onLinkClick}
-        ><span
-          class="material-icon statusLinkIcon"
+        ><gr-icon
+          icon="open_in_new"
+          class="statusLinkIcon"
           aria-label="external link to run status details"
-          >open_in_new</span
-        >
+        ></gr-icon>
         <paper-tooltip offset="5">Link to run status details</paper-tooltip>
       </a>
     `;
@@ -343,7 +342,7 @@
 
   renderFilterIcon() {
     if (!this.selected) return;
-    return html`<span class="filter material-icon filled">filter_alt</span>`;
+    return html`<gr-icon icon="filter_alt" filled class="filter"></gr-icon>`;
   }
 
   /**
@@ -356,9 +355,11 @@
     if (!category) return nothing;
     const icon = iconFor(category);
     return html`
-      <span class="material-icon ${icon.name} ${icon.filled ? 'filled' : ''}"
-        >${icon.name}</span
-      >
+      <gr-icon
+        icon=${icon.name}
+        class=${icon.name}
+        ?filled=${icon.filled}
+      ></gr-icon>
     `;
   }
 
@@ -444,7 +445,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       fontStyles,
       css`
@@ -528,14 +528,14 @@
           display: flex;
           background-color: var(--error-background);
         }
-        .error .material-icon {
+        .error gr-icon {
           color: var(--error-foreground);
           margin-right: var(--spacing-m);
         }
         .login {
           background: var(--info-background);
         }
-        .login .material-icon {
+        .login gr-icon {
           color: var(--info-foreground);
         }
         .login .buttonRow {
@@ -614,7 +614,7 @@
         html`
           <div class="error">
             <div class="left">
-              <span class="material-icon filled">error</span>s
+              <gr-icon icon="error" filled></gr-icon>
             </div>
             <div class="right">
               <div class="message">
@@ -631,7 +631,7 @@
     return html`
       <div class="login">
         <div>
-          <span class="material-icon">info</span>
+          <gr-icon icon="info"></gr-icon>
           Sign in to Checks Plugin to see runs and results
         </div>
         <div class="buttonRow">
@@ -705,9 +705,11 @@
             ? 'Expand runs panel'
             : 'Collapse runs panel'}
           @click=${this.toggleCollapsed}
-          ><span class="material-icon expandIcon">
-            ${this.collapsed ? 'chevron_right' : 'chevron_left'}</span
+          ><gr-icon
+            icon=${this.collapsed ? 'chevron_right' : 'chevron_left'}
+            class="expandIcon"
           >
+          </gr-icon>
         </gr-button>
       </gr-tooltip-content>
     `;
@@ -773,7 +775,7 @@
     return html`
       <div class="${status.toLowerCase()} ${expandedClass}">
         <div class="sectionHeader" @click=${() => this.toggleExpanded(status)}>
-          <span class="expandIcon material-icon">${icon}</span>
+          <gr-icon icon=${icon} class="expandIcon"></gr-icon>
           <h3 class="heading-3">${header} (${runs.length})</h3>
         </div>
         <div class="sectionRuns">${runs.map(run => this.renderRun(run))}</div>
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-runs_test.ts b/polygerrit-ui/app/elements/checks/gr-checks-runs_test.ts
index b25f3ff..da745a8 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-runs_test.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-runs_test.ts
@@ -45,7 +45,7 @@
               link=""
               role="switch"
             >
-              <span class="material-icon expandIcon">chevron_left</span>
+              <gr-icon icon="chevron_left" class="expandIcon"></gr-icon>
             </gr-button>
           </gr-tooltip-content>
         </h2>
@@ -56,7 +56,7 @@
         />
         <div class="expanded running">
           <div class="sectionHeader">
-            <span class="expandIcon material-icon">expand_less</span>
+            <gr-icon icon="expand_less" class="expandIcon"></gr-icon>
             <h3 class="heading-3">Running / Scheduled (2)</h3>
           </div>
           <div class="sectionRuns">
@@ -66,7 +66,7 @@
         </div>
         <div class="completed expanded">
           <div class="sectionHeader">
-            <span class="expandIcon material-icon">expand_less</span>
+            <gr-icon icon="expand_less" class="expandIcon"></gr-icon>
             <h3 class="heading-3">Completed (3)</h3>
           </div>
           <div class="sectionRuns">
@@ -77,7 +77,7 @@
         </div>
         <div class="expanded runnable">
           <div class="sectionHeader">
-            <span class="expandIcon material-icon">expand_less</span>
+            <gr-icon icon="expand_less" class="expandIcon"></gr-icon>
             <h3 class="heading-3">Not run (1)</h3>
           </div>
           <div class="sectionRuns">
@@ -103,7 +103,7 @@
             link=""
             role="switch"
           >
-            <span class="material-icon expandIcon">chevron_right</span>
+            <gr-icon icon="chevron_right" class="expandIcon"></gr-icon>
           </gr-button>
         </gr-tooltip-content>
       `,
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-styles.ts b/polygerrit-ui/app/elements/checks/gr-checks-styles.ts
index f1d33b9..6284892 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-styles.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-styles.ts
@@ -8,16 +8,16 @@
 const $_documentContainer = document.createElement('template');
 
 export const checksStyles = css`
-  .material-icon.error {
+  gr-icon.error {
     color: var(--error-foreground);
   }
-  .material-icon.warning {
+  gr-icon.warning {
     color: var(--warning-foreground);
   }
-  .material-icon.info {
+  gr-icon.info {
     color: var(--info-foreground);
   }
-  .material-icon.check_circle {
+  gr-icon.check_circle {
     color: var(--success-foreground);
   }
 `;
diff --git a/polygerrit-ui/app/elements/checks/gr-diff-check-result.ts b/polygerrit-ui/app/elements/checks/gr-diff-check-result.ts
index 3eb5927..2929f93 100644
--- a/polygerrit-ui/app/elements/checks/gr-diff-check-result.ts
+++ b/polygerrit-ui/app/elements/checks/gr-diff-check-result.ts
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '@polymer/paper-tooltip/paper-tooltip';
+import '../shared/gr-icon/gr-icon';
 import {LitElement, css, html, PropertyValues, nothing} from 'lit';
 import {customElement, property, state} from 'lit/decorators';
 import {RunResult} from '../../models/checks/checks-model';
@@ -12,7 +13,6 @@
 import './gr-checks-results';
 import './gr-hovercard-run';
 import {fontStyles} from '../../styles/gr-font-styles';
-import {iconStyles} from '../../styles/gr-icon-styles';
 
 @customElement('gr-diff-check-result')
 export class GrDiffCheckResult extends LitElement {
@@ -35,7 +35,6 @@
   static override get styles() {
     return [
       fontStyles,
-      iconStyles,
       css`
         .container {
           font-family: var(--font-family);
@@ -99,10 +98,10 @@
           display: block;
           margin-top: var(--spacing-m);
         }
-        .material-icon {
+        gr-icon {
           font-size: var(--line-height-normal);
         }
-        .icon .material-icon {
+        .icon gr-icon {
           font-size: calc(var(--line-height-normal) - 4px);
           position: relative;
           top: 2px;
@@ -119,9 +118,7 @@
       <div class="${cat} container font-normal">
         <div class="header" @click=${this.toggleExpandedClick}>
           <div class="icon">
-            <span class="material-icon ${icon.filled ? 'filled' : ''}"
-              >${icon.name}</span
-            >
+            <gr-icon icon=${icon.name} ?filled=${icon.filled}></gr-icon>
           </div>
           <div class="name">
             <gr-hovercard-run .run=${this.result}></gr-hovercard-run>
@@ -160,9 +157,9 @@
           : 'Expand result row'}
         @keydown=${this.toggleExpandedPress}
       >
-        <span class="material-icon"
-          >${this.isExpanded ? 'expand_less' : 'expand_more'}</span
-        >
+        <gr-icon
+          icon=${this.isExpanded ? 'expand_less' : 'expand_more'}
+        ></gr-icon>
       </div>
     `;
   }
diff --git a/polygerrit-ui/app/elements/checks/gr-diff-check-result_test.ts b/polygerrit-ui/app/elements/checks/gr-diff-check-result_test.ts
index a40bdb5..e863f14 100644
--- a/polygerrit-ui/app/elements/checks/gr-diff-check-result_test.ts
+++ b/polygerrit-ui/app/elements/checks/gr-diff-check-result_test.ts
@@ -30,7 +30,7 @@
       <div class="container font-normal warning">
         <div class="header">
           <div class="icon">
-            <span class="material-icon filled">warning</span>
+            <gr-icon icon="warning" filled></gr-icon>
           </div>
           <div class="name">
             <gr-hovercard-run> </gr-hovercard-run>
diff --git a/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts b/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts
index 0342183..209ae07 100644
--- a/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts
+++ b/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts
@@ -3,6 +3,7 @@
  * Copyright 2021 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../shared/gr-icon/gr-icon';
 import {fontStyles} from '../../styles/gr-font-styles';
 import {customElement, property} from 'lit/decorators';
 import './gr-checks-action';
@@ -20,7 +21,6 @@
 import {HovercardMixin} from '../../mixins/hovercard-mixin/hovercard-mixin';
 import {css, html, LitElement} from 'lit';
 import {checksStyles} from './gr-checks-styles';
-import {iconStyles} from '../../styles/gr-icon-styles';
 
 // This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
 const base = HovercardMixin(LitElement);
@@ -33,7 +33,6 @@
   static override get styles() {
     return [
       fontStyles,
-      iconStyles,
       checksStyles,
       base.styles || [],
       css`
@@ -71,34 +70,34 @@
         div.sectionIcon {
           flex: 0 0 30px;
         }
-        div.chip .material-icon {
+        div.chip gr-icon {
           font-size: 16px;
           /* Positioning of a 16px icon in the middle of a 20px line. */
           position: relative;
           top: 2px;
         }
-        div.sectionIcon .material-icon {
+        div.sectionIcon gr-icon {
           position: relative;
           top: 2px;
           font-size: 20px;
         }
-        div.sectionIcon .small.material-icon {
+        div.sectionIcon gr-icon.small {
           position: relative;
           top: 6px;
           font-size: 16px;
         }
-        div.sectionContent .material-icon.link {
+        div.sectionContent gr-icon.link {
           color: var(--link-color);
         }
-        div.sectionContent .attemptIcon .material-icon,
-        div.sectionContent .material-icon.small {
+        div.sectionContent .attemptIcon gr-icon,
+        div.sectionContent gr-icon.small {
           font-size: 16px;
           margin-right: var(--spacing-s);
           /* Positioning of a 16px icon in the middle of a 20px line. */
           position: relative;
           top: 2px;
         }
-        div.sectionContent .attemptIcon .material-icon {
+        div.sectionContent .attemptIcon gr-icon {
           margin-right: 0;
         }
         .attemptIcon,
@@ -130,19 +129,21 @@
             class="chipRow"
           >
             <div class="chip">
-              <span class="material-icon ${chipIcon.filled ? 'filled' : ''}"
-                >${chipIcon.name}</span
-              >
+              <gr-icon
+                icon=${chipIcon.name}
+                ?filled=${chipIcon.filled}
+              ></gr-icon>
               <span>${this.run.status}</span>
             </div>
           </div>
         </div>
         <div class="section">
           <div class="sectionIcon" ?hidden=${icon.name.length === 0}>
-            <span
-              class="material-icon ${icon.name} ${icon.filled ? 'filled' : ''}"
-              >${icon.name}</span
-            >
+            <gr-icon
+              icon=${icon.name}
+              class=${icon.name}
+              ?filled=${icon.filled}
+            ></gr-icon>
           </div>
           <div class="sectionContent">
             <h3 class="name heading-3">
@@ -164,7 +165,7 @@
     return html`
       <div class="section">
         <div class="sectionIcon">
-          <span class="small material-icon">info</span>
+          <gr-icon icon="info" class="small"></gr-icon>
         </div>
         <div class="sectionContent">
           ${this.run.statusLink
@@ -172,10 +173,11 @@
                 <div class="title">Status</div>
                 <div>
                   <a href=${this.run.statusLink} target="_blank"
-                    ><span
+                    ><gr-icon
+                      icon="open_in_new"
                       aria-label="external link to check status"
-                      class="material-icon small link"
-                      >open_in_new</span
+                      class="small link"
+                    ></gr-icon
                     >${this.computeHostName(this.run.statusLink)}
                   </a>
                 </div>
@@ -198,7 +200,7 @@
     return html`
       <div class="section">
         <div class="sectionIcon">
-          <span class="small material-icon">arrow_forward</span>
+          <gr-icon icon="arrow_forward" class="small"></gr-icon>
         </div>
         <div class="sectionContent">
           <div class="attempts row">
@@ -214,9 +216,8 @@
     return html`
       <div>
         <div class="attemptIcon">
-          <span class="material-icon ${attempt.icon.filled ? 'filled' : ''}"
-            >${attempt.icon.name}</span
-          >
+          <gr-icon icon=${attempt.icon.name} ?filled=${attempt.icon.filled}>
+          </gr-icon>
         </div>
         <div class="attemptNumber">${ordinal(attempt.attempt)}</div>
       </div>
@@ -284,7 +285,7 @@
     return html`
       <div class="section">
         <div class="sectionIcon">
-          <span class="small material-icon">schedule</span>
+          <gr-icon icon="schedule" class="small"></gr-icon>
         </div>
         <div class="sectionContent">
           ${scheduled} ${started} ${finished} ${completed} ${eta}
@@ -299,7 +300,7 @@
     return html`
       <div class="section">
         <div class="sectionIcon">
-          <span class="small material-icon">link</span>
+          <gr-icon icon="link" class="small"></gr-icon>
         </div>
         <div class="sectionContent">
           ${this.run.checkDescription
@@ -313,10 +314,11 @@
                 <div class="title">Documentation</div>
                 <div>
                   <a href=${this.run.checkLink} target="_blank"
-                    ><span
+                    ><gr-icon
+                      icon="open_in_new"
                       aria-label="external link to check documentation"
-                      class="material-icon small link"
-                      >open_in_new</span
+                      class="small link"
+                    ></gr-icon
                     >${this.computeHostName(this.run.checkLink)}
                   </a>
                 </div>
diff --git a/polygerrit-ui/app/elements/checks/gr-hovercard-run_test.ts b/polygerrit-ui/app/elements/checks/gr-hovercard-run_test.ts
index e237560..4a9f69d 100644
--- a/polygerrit-ui/app/elements/checks/gr-hovercard-run_test.ts
+++ b/polygerrit-ui/app/elements/checks/gr-hovercard-run_test.ts
@@ -28,14 +28,14 @@
         <div class="section">
           <div class="chipRow">
             <div class="chip">
-              <span class="material-icon">check</span>
+              <gr-icon icon="check"></gr-icon>
               <span> COMPLETED </span>
             </div>
           </div>
         </div>
         <div class="section">
           <div class="sectionIcon">
-            <span class="material-icon filled error">error</span>
+            <gr-icon icon="error" filled class="error"></gr-icon>
           </div>
           <div class="sectionContent">
             <h3 class="heading-3 name">
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts
index 8134101..cbfbcc6 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts
@@ -7,6 +7,7 @@
 import {map, distinctUntilChanged} from 'rxjs/operators';
 import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
 import '../../shared/gr-dropdown/gr-dropdown';
+import '../../shared/gr-icon/gr-icon';
 import '../gr-account-dropdown/gr-account-dropdown';
 import '../gr-smart-search/gr-smart-search';
 import {getBaseUrl, getDocsBaseUrl} from '../../../utils/url-util';
@@ -28,7 +29,6 @@
 import {fireEvent} from '../../../utils/event-util';
 import {resolve} from '../../../models/dependency';
 import {configModelToken} from '../../../models/config/config-model';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 type MainHeaderLink = RequireProperties<DropdownLink, 'url' | 'name'>;
 
@@ -185,7 +185,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -311,7 +310,7 @@
         .bigTitle,
         .loginButton,
         .registerButton,
-        .material-icon,
+        gr-icon,
         gr-account-dropdown {
           color: var(--header-text-color);
         }
@@ -414,7 +413,7 @@
         target="_blank"
         role="button"
       >
-        <span class="material-icon filled">bug_report</span>
+        <gr-icon icon="bug_report" filled></gr-icon>
       </a>
     `;
   }
@@ -422,9 +421,9 @@
   private renderAccount() {
     return html`
       <div class="accountContainer" id="accountContainer">
-        <span
+        <gr-icon
           id="mobileSearch"
-          class="material-icon"
+          icon="search"
           @click=${(e: Event) => {
             this.onMobileSearchTap(e);
           }}
@@ -432,8 +431,7 @@
           aria-label=${this.mobileSearchHidden
             ? 'Show Searchbar'
             : 'Hide Searchbar'}
-          >search</span
-        >
+        ></gr-icon>
         ${this.renderRegister()}
         <a class="loginButton" href=${this.loginUrl}>Sign in</a>
         <a
@@ -443,7 +441,7 @@
           aria-label="Settings"
           role="button"
         >
-          <span class="material-icon filled">settings</span>
+          <gr-icon icon="settings" filled></gr-icon>
         </a>
         ${this.renderAccountDropdown()}
       </div>
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.ts b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.ts
index 6da1c2c..4f47f7a 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.ts
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.ts
@@ -65,14 +65,13 @@
           </gr-endpoint-decorator>
         </div>
         <div class="accountContainer" id="accountContainer">
-          <span
+          <gr-icon
             aria-label="Hide Searchbar"
-            class="material-icon"
+            icon="search"
             id="mobileSearch"
             role="button"
           >
-            search
-          </span>
+          </gr-icon>
           <a class="loginButton" href="/login"> Sign in </a>
           <a
             aria-label="Settings"
@@ -81,7 +80,7 @@
             role="button"
             title="Settings"
           >
-            <span class="filled material-icon"> settings </span>
+            <gr-icon icon="settings" filled></gr-icon>
           </a>
         </div>
       </nav>
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
index 2833aeb..c488823 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../shared/gr-autocomplete/gr-autocomplete';
+import '../../shared/gr-icon/gr-icon';
 import {ServerInfo} from '../../../types/common';
 import {
   AutocompleteQuery,
@@ -25,7 +26,6 @@
 import {configModelToken} from '../../../models/config/config-model';
 import {resolve} from '../../../models/dependency';
 import {subscribe} from '../../lit/subscription-controller';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 // Possible static search options for auto complete, without negations.
 const SEARCH_OPERATORS: ReadonlyArray<string> = [
@@ -198,7 +198,6 @@
   static override get styles() {
     return [
       sharedStyles,
-      iconStyles,
       css`
         form {
           display: flex;
@@ -241,7 +240,7 @@
             target="_blank"
             tabindex="-1"
           >
-            <span class="material-icon" title="read documentation">help</span>
+            <gr-icon icon="help" title="read documentation"></gr-icon>
           </a>
         </gr-autocomplete>
       </form>
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts
index bde1ec7..cef4081 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts
@@ -45,7 +45,7 @@
             tabindex="-1"
             target="_blank"
           >
-            <span class="material-icon" title="read documentation"> help </span>
+            <gr-icon icon="help" title="read documentation"></gr-icon>
           </a>
         </gr-autocomplete>
       </form>
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts
index 3120c64..66aaf9d 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts
@@ -5,6 +5,7 @@
  */
 import '../gr-account-label/gr-account-label';
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import {
   AccountInfo,
   ApprovalInfo,
@@ -16,7 +17,6 @@
 import {customElement, property} from 'lit/decorators';
 import {ClassInfo, classMap} from 'lit/directives/class-map';
 import {getLabelStatus, hasVoted, LabelStatus} from '../../../utils/label-util';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-account-chip')
 export class GrAccountChip extends LitElement {
@@ -78,7 +78,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
         :host {
           display: block;
@@ -115,7 +114,7 @@
           opacity: 0.6;
           pointer-events: none;
         }
-        .material-icon {
+        gr-icon {
           font-size: 1.2rem;
         }
         .container gr-account-label::part(gr-account-label-text) {
@@ -183,7 +182,7 @@
         class="remove"
         @click=${this.handleRemoveTap}
       >
-        <span class="material-icon">close</span>
+        <gr-icon icon="close"></gr-icon>
       </gr-button>
     </div>`;
   }
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_test.ts b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_test.ts
index 7f4b8b6..408bb74 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_test.ts
@@ -41,7 +41,7 @@
           role="button"
           tabindex="0"
         >
-          <span class="material-icon">close</span>
+          <gr-icon icon="close"></gr-icon>
         </gr-button>
       </div>
     `);
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
index 543b8c2..5c0c6d6 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
@@ -5,6 +5,7 @@
  */
 import '../gr-avatar/gr-avatar';
 import '../gr-hovercard-account/gr-hovercard-account';
+import '../gr-icon/gr-icon';
 import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
 import '../../plugins/gr-endpoint-param/gr-endpoint-param';
 import {getAppContext} from '../../../services/app-context';
@@ -21,7 +22,6 @@
 import {getRemovedByIconClickReason} from '../../../utils/attention-set-util';
 import {ifDefined} from 'lit/directives/if-defined';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 @customElement('gr-account-label')
 export class GrAccountLabel extends LitElement {
@@ -99,7 +99,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
         :host {
           display: inline-block;
@@ -141,7 +140,7 @@
           border-radius: 8px;
           color: var(--chip-selected-text-color);
         }
-        :host([selected]) .material-icon.attention {
+        :host([selected]) gr-icon.attention {
           color: var(--chip-selected-text-color);
         }
         gr-avatar {
@@ -158,7 +157,7 @@
           margin: 0 -4px 0 -4px;
           vertical-align: top;
         }
-        .material-icon.attention {
+        gr-icon.attention {
           color: var(--deemphasized-text-color);
           font-size: 12px;
         }
@@ -236,9 +235,11 @@
                   this.selected,
                   this._selfAccount
                 )}
-                ><span class="attention material-icon filled"
-                  >label_important</span
-                >
+                ><gr-icon
+                  icon="label_important"
+                  filled
+                  class="attention"
+                ></gr-icon>
               </gr-button>
             </gr-tooltip-content>`
           : ''}
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
index deafa90..1934f705 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
@@ -6,6 +6,7 @@
 import '@polymer/paper-input/paper-input';
 import '../gr-autocomplete-dropdown/gr-autocomplete-dropdown';
 import '../gr-cursor-manager/gr-cursor-manager';
+import '../gr-icon/gr-icon';
 import '../../../styles/shared-styles';
 import {GrAutocompleteDropdown} from '../gr-autocomplete-dropdown/gr-autocomplete-dropdown';
 import {fire, fireEvent} from '../../../utils/event-util';
@@ -18,7 +19,6 @@
 import {ValueChangedEvent} from '../../../types/events';
 import {PaperInputElement} from '@polymer/paper-input/paper-input';
 import {IronInputElement} from '@polymer/iron-input';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
 const DEBOUNCE_WAIT_MS = 200;
@@ -188,7 +188,6 @@
   }
 
   static override styles = [
-    iconStyles,
     sharedStyles,
     css`
       .searchIcon {
@@ -197,7 +196,7 @@
       .searchIcon.showSearchIcon {
         display: inline-block;
       }
-      .material-icon {
+      gr-icon {
         margin: 0 var(--spacing-xs);
       }
       paper-input.borderless {
@@ -300,12 +299,12 @@
         .label=${this.label}
       >
         <div slot="prefix">
-          <span
-            class="material-icon searchIcon ${this.computeShowSearchIconClass(
+          <gr-icon
+            icon="search"
+            class="searchIcon ${this.computeShowSearchIconClass(
               this.showSearchIcon
             )}"
-            >search
-          </span>
+          ></gr-icon>
         </div>
 
         <div slot="suffix">
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts
index 73e472c..1d24838 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts
@@ -40,7 +40,7 @@
         tabindex="0"
       >
         <div slot="prefix">
-          <span class="material-icon searchIcon"> search </span>
+          <gr-icon icon="search" class="searchIcon"></gr-icon>
         </div>
         <div slot="suffix">
           <slot name="suffix"> </slot>
@@ -84,7 +84,7 @@
           tabindex="0"
         >
           <div slot="prefix">
-            <span class="material-icon searchIcon"> search </span>
+            <gr-icon icon="search" class="searchIcon"></gr-icon>
           </div>
           <div slot="suffix">
             <slot name="suffix"> </slot>
@@ -469,14 +469,14 @@
 
   test('search icon shows with showSearchIcon property', async () => {
     assert.equal(
-      getComputedStyle(queryAndAssert(element, '.material-icon')).display,
+      getComputedStyle(queryAndAssert(element, 'gr-icon')).display,
       'none'
     );
     element.showSearchIcon = true;
     await element.updateComplete;
 
     assert.notEqual(
-      getComputedStyle(queryAndAssert(element, '.material-icon')).display,
+      getComputedStyle(queryAndAssert(element, 'gr-icon')).display,
       'none'
     );
   });
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.ts b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.ts
index e9c70c2..555aa28 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.ts
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.ts
@@ -14,8 +14,6 @@
 import {customElement, property} from 'lit/decorators';
 import {resolve} from '../../../models/dependency';
 import {shortcutsServiceToken} from '../../../services/shortcuts/shortcuts-service';
-import {classMap} from 'lit/directives/class-map';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -43,7 +41,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         button {
@@ -59,11 +56,6 @@
   }
 
   override render() {
-    const classes = {
-      'material-icon': true,
-      filled: !!this.change?.starred,
-      active: !!this.change?.starred,
-    };
     return html`
       <button
         role="checkbox"
@@ -76,7 +68,11 @@
           : 'Star this change'}
         @click=${this.toggleStar}
       >
-        <span class=${classMap(classes)}>grade</span>
+        <gr-icon
+          icon="grade"
+          ?filled=${!!this.change?.starred}
+          class=${this.change?.starred ? 'active' : ''}
+        ></gr-icon>
       </button>
     `;
   }
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.ts b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.ts
index 73daa7e..cc8a471 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.ts
@@ -31,7 +31,7 @@
         role="checkbox"
         title="Star/unstar change (shortcut: s)"
       >
-        <span class="active filled material-icon"> grade </span>
+        <gr-icon icon="grade" filled class="active"></gr-icon>
       </button>
     `);
   });
@@ -47,7 +47,7 @@
         role="checkbox"
         title="Star/unstar change (shortcut: s)"
       >
-        <span class="material-icon"> grade </span>
+        <gr-icon icon="grade"></gr-icon>
       </button>
     `);
   });
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts
index 4e73b90..954a606 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts
@@ -3,6 +3,7 @@
  * Copyright 2017 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../gr-icon/gr-icon';
 import '../gr-tooltip-content/gr-tooltip-content';
 import '../../../styles/shared-styles';
 import {
@@ -14,7 +15,6 @@
 import {sharedStyles} from '../../../styles/shared-styles';
 import {LitElement, PropertyValues, html, css} from 'lit';
 import {customElement, property, state} from 'lit/decorators';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 export enum ChangeStates {
   ABANDONED = 'Abandoned',
@@ -65,7 +65,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         .chip {
@@ -125,7 +124,7 @@
         .icon {
           color: var(--status-text-color);
         }
-        .material-icon {
+        gr-icon {
           font-size: 18px;
         }
       `,
@@ -159,7 +158,7 @@
         <div class="chip" aria-label="Label: ${this.status}">
           ${this.computeStatusString()}
           ${this.showResolveIcon()
-            ? html`<span class="material-icon filled">edit</span>`
+            ? html`<gr-icon icon="edit" filled></gr-icon>`
             : ''}
         </div>
       </a>
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
index 09487fd..6374714 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
@@ -6,6 +6,7 @@
 import '../../../styles/gr-a11y-styles';
 import '../../../styles/shared-styles';
 import '../gr-comment/gr-comment';
+import '../gr-icon/gr-icon';
 import '../../../embed/diff/gr-diff/gr-diff';
 import '../gr-copy-clipboard/gr-copy-clipboard';
 import {css, html, nothing, LitElement, PropertyValues} from 'lit';
@@ -64,7 +65,6 @@
 import {changeModelToken} from '../../../models/change/change-model';
 import {whenRendered} from '../../../utils/dom-util';
 import {Interaction} from '../../../constants/reporting';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const NEWLINE_PATTERN = /\n/g;
 
@@ -317,7 +317,6 @@
   static override get styles() {
     return [
       a11yStyles,
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -572,14 +571,14 @@
                 `
               : ''
           }
-          <span
-            class="link-icon copy material-icon"
+          <gr-icon
+            icon="link"
+            class="link-icon copy"
             @click=${this.handleCopyLink}
             title="Copy link to this comment"
             role="button"
             tabindex="0"
-          >link</span
-          >
+          ></gr-icon>
         </div>
       </div>
     </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
index 67f7b1a..53ebf6a 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
@@ -176,13 +176,13 @@
               >
                 Quote
               </gr-button>
-              <span
-                class="copy link-icon material-icon"
+              <gr-icon
+                icon="link"
+                class="copy link-icon"
                 role="button"
                 tabindex="0"
                 title="Copy link to this comment"
-                >link</span
-              >
+              ></gr-icon>
             </div>
           </div>
         </div>
@@ -242,13 +242,13 @@
               >
                 Done
               </gr-button>
-              <span
-                class="copy link-icon material-icon"
+              <gr-icon
+                icon="link"
+                class="copy link-icon"
                 role="button"
                 tabindex="0"
                 title="Copy link to this comment"
-                >link</span
-              >
+              ></gr-icon>
             </div>
           </div>
         </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
index d3d548a..2d6c2b5 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -10,6 +10,7 @@
 import '../gr-button/gr-button';
 import '../gr-dialog/gr-dialog';
 import '../gr-formatted-text/gr-formatted-text';
+import '../gr-icon/gr-icon';
 import '../gr-overlay/gr-overlay';
 import '../gr-textarea/gr-textarea';
 import '../gr-tooltip-content/gr-tooltip-content';
@@ -57,7 +58,6 @@
 import {configModelToken} from '../../../models/config/config-model';
 import {changeModelToken} from '../../../models/change/change-model';
 import {Interaction} from '../../../constants/reporting';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const UNSAVED_MESSAGE = 'Unable to save draft';
 
@@ -287,7 +287,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -386,7 +385,7 @@
           cursor: pointer;
           display: block;
         }
-        label.show-hide .material-icon {
+        label.show-hide gr-icon {
           vertical-align: top;
         }
         :host([collapsed]) #container .body {
@@ -576,7 +575,7 @@
         class="action delete"
         @click=${this.openDeleteCommentOverlay}
       >
-        <span id="icon" class="material-icon filled">delete</span>
+        <gr-icon id="icon" icon="delete" filled></gr-icon>
       </gr-button>
     `;
   }
@@ -614,7 +613,7 @@
             ?checked=${this.collapsed}
             @change=${() => (this.collapsed = !this.collapsed)}
           />
-          <span id="icon" class="material-icon">${icon}</span>
+          <gr-icon icon=${icon} id="icon"></gr-icon>
         </label>
       </div>
     `;
@@ -666,14 +665,14 @@
     // Only show the icon when the thread contains a published comment.
     if (!this.comment?.in_reply_to && isDraftOrUnsaved(this.comment)) return;
     return html`
-      <span
-        class="copy link-icon material-icon"
+      <gr-icon
+        icon="link"
+        class="copy link-icon"
         @click=${this.handleCopyLink}
         title="Copy link to this comment"
         role="button"
         tabindex="0"
-        >link</span
-      >
+      ></gr-icon>
     `;
   }
 
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts
index 17df9c6..3b94706 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts
@@ -89,7 +89,7 @@
             <div class="show-hide" tabindex="0">
               <label aria-label="Expand" class="show-hide">
                 <input checked="" class="show-hide" type="checkbox" />
-                <span id="icon" class="material-icon">expand_more</span>
+                <gr-icon id="icon" icon="expand_more"></gr-icon>
               </label>
             </div>
           </div>
@@ -116,7 +116,7 @@
             <div class="show-hide" tabindex="0">
               <label aria-label="Collapse" class="show-hide">
                 <input class="show-hide" type="checkbox" />
-                <span id="icon" class="material-icon">expand_less</span>
+                <gr-icon id="icon" icon="expand_less"></gr-icon>
               </label>
             </div>
           </div>
@@ -149,7 +149,7 @@
             <div class="show-hide" tabindex="0">
               <label aria-label="Collapse" class="show-hide">
                 <input class="show-hide" type="checkbox" />
-                <span id="icon" class="material-icon">expand_less</span>
+                <gr-icon id="icon" icon="expand_less"></gr-icon>
               </label>
             </div>
           </div>
@@ -160,13 +160,13 @@
               notrailingmargin=""
             ></gr-formatted-text>
             <div class="robotActions">
-              <span
-                class="copy link-icon material-icon"
+              <gr-icon
+                icon="link"
+                class="copy link-icon"
                 role="button"
                 tabindex="0"
                 title="Copy link to this comment"
-                >link</span
-              >
+              ></gr-icon>
               <gr-endpoint-decorator name="robot-comment-controls">
                 <gr-endpoint-param name="comment"></gr-endpoint-param>
               </gr-endpoint-decorator>
@@ -210,7 +210,7 @@
           tabindex="0"
           title="Delete Comment"
         >
-          <span id="icon" class="material-icon filled">delete</span>
+          <gr-icon id="icon" icon="delete" filled></gr-icon>
         </gr-button>
       `);
     });
@@ -243,7 +243,7 @@
             <div class="show-hide" tabindex="0">
               <label aria-label="Collapse" class="show-hide">
                 <input class="show-hide" type="checkbox" />
-                <span id="icon" class="material-icon">expand_less</span>
+                <gr-icon id="icon" icon="expand_less"></gr-icon>
               </label>
             </div>
           </div>
@@ -311,7 +311,7 @@
             <div class="show-hide" tabindex="0">
               <label aria-label="Collapse" class="show-hide">
                 <input class="show-hide" type="checkbox" />
-                <span id="icon" class="material-icon">expand_less</span>
+                <gr-icon id="icon" icon="expand_less"></gr-icon>
               </label>
             </div>
           </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
index bb75283..2b62b34 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
@@ -5,13 +5,13 @@
  */
 import '@polymer/iron-input/iron-input';
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
 import {classMap} from 'lit/directives/class-map';
 import {ifDefined} from 'lit/directives/if-defined';
 import {LitElement, css, html} from 'lit';
 import {customElement, property} from 'lit/decorators';
 import {GrButton} from '../gr-button/gr-button';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const COPY_TIMEOUT_MS = 1000;
 
@@ -36,7 +36,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
         .text {
           align-items: center;
@@ -67,7 +66,7 @@
           height: 16px;
           width: 16px;
         }
-        .material-icon {
+        gr-icon {
           color: var(--deemphasized-text-color);
         }
         gr-button {
@@ -108,7 +107,7 @@
             @click=${this._copyToClipboard}
             aria-label="Click to copy to clipboard"
           >
-            <span id="icon" class="material-icon">content_copy</span>
+            <gr-icon id="icon" icon="content_copy"></gr-icon>
           </gr-button>
         </gr-tooltip-content>
       </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts
index 5d5912e..7b441d3 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts
@@ -43,7 +43,7 @@
             role="button"
             tabindex="0"
           >
-            <span class="material-icon" id="icon"> content_copy </span>
+            <gr-icon icon="content_copy" id="icon"></gr-icon>
           </gr-button>
         </gr-tooltip-content>
       </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
index 3dc1cc9..ac910ea 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
@@ -6,6 +6,7 @@
 import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
 import '../../../styles/shared-styles';
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
 import '../../plugins/gr-endpoint-param/gr-endpoint-param';
 import '../../plugins/gr-endpoint-slot/gr-endpoint-slot';
@@ -24,7 +25,6 @@
 import {nothing} from 'lit';
 import {classMap} from 'lit/directives/class-map';
 import {when} from 'lit/directives/when';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const RESTORED_MESSAGE = 'Content restored from a previous edit.';
 const STORAGE_DEBOUNCE_INTERVAL_MS = 400;
@@ -109,7 +109,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -165,7 +164,7 @@
         .flex-space {
           flex-grow: 1;
         }
-        .show-all-container .material-icon {
+        .show-all-container gr-icon {
           color: inherit;
           font-size: 18px;
         }
@@ -245,11 +244,11 @@
             >
               ${when(
                 !this.commitCollapsed,
-                () => html`<span class="material-icon">expand_less</span>`
+                () => html`<gr-icon icon="expand_less"></gr-icon>`
               )}
               ${when(
                 this.commitCollapsed,
-                () => html`<span class="material-icon">expand_more</span>`
+                () => html`<gr-icon icon="expand_more"></gr-icon>`
               )}
               ${this.commitCollapsed ? 'Show all' : 'Show less'}
             </gr-button>
@@ -264,7 +263,7 @@
               class="edit-commit-message"
               title="Edit commit message"
               @click=${this.handleEditCommitMessage}
-              ><span class="material-icon filled">edit</span> Edit</gr-button
+              ><gr-icon icon="edit" filled></gr-icon> Edit</gr-button
             >
           `
         )}
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts
index e890d3a..ed09c49 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts
@@ -35,7 +35,7 @@
           role="button"
           tabindex="0"
         >
-          <span class="material-icon">expand_more</span>
+          <gr-icon icon="expand_more"></gr-icon>
           Show all
         </gr-button>
         <div class="flex-space"></div>
@@ -47,7 +47,7 @@
           tabindex="0"
           title="Edit commit message"
         >
-          <span class="material-icon filled">edit</span>
+          <gr-icon icon="edit" filled></gr-icon>
           Edit
         </gr-button>
       </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts
index b1f61f6..231b6fd 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts
@@ -5,8 +5,8 @@
  */
 import '@polymer/iron-dropdown/iron-dropdown';
 import '@polymer/paper-input/paper-input';
-import '../../../styles/shared-styles';
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import '../../shared/gr-autocomplete/gr-autocomplete';
 import {IronDropdownElement} from '@polymer/iron-dropdown/iron-dropdown';
 import {
@@ -20,7 +20,6 @@
 import {sharedStyles} from '../../../styles/shared-styles';
 import {PaperInputElement} from '@polymer/paper-input/paper-input';
 import {IronInputElement} from '@polymer/iron-input';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const AWAIT_MAX_ITERS = 10;
 const AWAIT_STEP = 5;
@@ -91,7 +90,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -144,7 +142,7 @@
           };
           --paper-input-container-focus-color: var(--link-color);
         }
-        gr-button .material-icon {
+        gr-button gr-icon {
           color: inherit;
           font-size: 18px;
         }
@@ -190,8 +188,8 @@
         class="pencil ${this.computeLabelClass()}"
         @click=${this.showDropdown}
         title=${this.computeLabel()}
-        ><span class="material-icon filled">edit</span></gr-button
-      >`;
+        ><gr-icon icon="edit" filled></gr-icon
+      ></gr-button>`;
     } else {
       return html`<label
         class=${this.computeLabelClass()}
diff --git a/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status.ts b/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status.ts
index f9a3cba..e15ce56 100644
--- a/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status.ts
+++ b/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status.ts
@@ -7,8 +7,8 @@
 import {LitElement, css, html} from 'lit';
 import {customElement, property} from 'lit/decorators';
 import {assertNever} from '../../../utils/common-util';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 import '../gr-tooltip-content/gr-tooltip-content';
+import '../gr-icon/gr-icon';
 
 function statusString(status: FileInfoStatus) {
   if (!status) return '';
@@ -63,7 +63,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
         :host {
           display: inline-block;
@@ -125,9 +124,11 @@
   private renderNewlyChanged() {
     if (!this.newlyChanged) return;
     return html`<gr-tooltip-content title=${this.computeLabel()} has-tooltip>
-      <span class="material-icon size-16" aria-label=${this.computeLabel()}
-        >new_releases</span
-      >
+      <gr-icon
+        icon="new_releases"
+        class="size-16"
+        aria-label=${this.computeLabel()}
+      ></gr-icon>
     </gr-tooltip-content>`;
   }
 
diff --git a/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status_test.ts b/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status_test.ts
index cff1a41..928ec26 100644
--- a/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-file-status-chip/gr-file-status_test.ts
@@ -45,9 +45,11 @@
       await setStatus(FileInfoStatus.ADDED, true);
       expect(element).shadowDom.to.equal(/* HTML */ `
         <gr-tooltip-content has-tooltip="" title="Newly Added">
-          <span class="material-icon size-16" aria-label="Newly Added"
-            >new_releases</span
-          >
+          <gr-icon
+            icon="new_releases"
+            class="size-16"
+            aria-label="Newly Added"
+          ></gr-icon>
         </gr-tooltip-content>
         <gr-tooltip-content has-tooltip="" title="Newly Added">
           <div class="A status" aria-label="Newly Added" tabindex="0">A</div>
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts
index df8ffeb..d3b16c8 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts
@@ -5,6 +5,7 @@
  */
 import '../gr-avatar/gr-avatar';
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
 import '../../plugins/gr-endpoint-param/gr-endpoint-param';
 import {getAppContext} from '../../../services/app-context';
@@ -37,7 +38,6 @@
 import {ifDefined} from 'lit/directives/if-defined';
 import {HovercardMixin} from '../../../mixins/hovercard-mixin/hovercard-mixin';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 // This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
 const base = HovercardMixin(LitElement);
@@ -86,7 +86,6 @@
   static override get styles() {
     return [
       fontStyles,
-      iconStyles,
       base.styles || [],
       css`
         .top,
@@ -123,17 +122,17 @@
         .attention a {
           text-decoration: none;
         }
-        .status .material-icon {
+        .status gr-icon {
           font-size: 14px;
           position: relative;
           top: 2px;
         }
-        .material-icon.attentionIcon {
+        gr-icon.attentionIcon {
           font-size: 14px;
           position: relative;
           top: 3px;
         }
-        .material-icon.linkIcon {
+        gr-icon.linkIcon {
           font-size: var(--line-height-normal, 20px);
           color: var(--deemphasized-text-color);
           padding-right: 12px;
@@ -225,7 +224,7 @@
 
   private renderLinks() {
     return html` <div class="links">
-      <span class="material-icon linkIcon">link</span
+      <gr-icon icon="link" class="linkIcon"></gr-icon
       ><a
         href=${ifDefined(this.computeOwnerChangesLink())}
         @click=${() => {
@@ -268,15 +267,17 @@
     return html`
       <div class="attention">
         <div>
-          <span class="attentionIcon material-icon filled"
-            >label_important</span
-          >
+          <gr-icon
+            icon="label_important"
+            filled
+            class="attentionIcon"
+          ></gr-icon>
           <span> ${this.computePronoun()} turn to take action. </span>
           <a
             href="https://gerrit-review.googlesource.com/Documentation/user-attention-set.html"
             target="_blank"
           >
-            <span class="material-icon" title="read documentation">help</span>
+            <gr-icon icon="help" title="read documentation"></gr-icon>
           </a>
         </div>
         <div class="reason">
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts
index a1c94c3..0ef1e69 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts
@@ -84,7 +84,7 @@
           <span class="value">I am a frog</span>
         </div>
         <div class="links">
-          <span class="linkIcon material-icon">link</span>
+          <gr-icon icon="link" class="linkIcon"></gr-icon>
           <a href="">Changes</a>·<a href="">Dashboard</a>
         </div>
       </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.ts b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.ts
index 5bf4f4a..b3a52be 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.ts
@@ -23,6 +23,7 @@
 import {GrButton} from '../gr-button/gr-button';
 import {ChangeViewChangeInfo} from '../../../types/common';
 import {GrDropdown} from '../gr-dropdown/gr-dropdown';
+import {GrIcon} from '../gr-icon/gr-icon';
 
 suite('gr-change-actions-js-api-interface tests', () => {
   let element: GrChangeActions;
@@ -137,15 +138,12 @@
       changeActions.setLabel(key, 'Yo');
       changeActions.setTitle(key, 'Yo hint');
       changeActions.setEnabled(key, false);
-      changeActions.setIcon(key, 'pupper');
+      changeActions.setIcon(key, 'hive');
       await element.updateComplete;
       assert.equal(button.getAttribute('data-label'), 'Yo');
       assert.equal(button.parentElement!.getAttribute('title'), 'Yo hint');
       assert.isTrue(button.disabled);
-      assert.equal(
-        queryAndAssert<HTMLSpanElement>(button, '.material-icon').textContent,
-        'pupper'
-      );
+      assert.equal(queryAndAssert<GrIcon>(button, 'gr-icon').icon, 'hive');
     });
 
     test('hide action buttons', async () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts
index 8f6659f..6d40b7e 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts
@@ -6,6 +6,7 @@
 import '../../../styles/gr-font-styles';
 import '../../../styles/gr-voting-styles';
 import '../../../styles/shared-styles';
+import '../gr-icon/gr-icon';
 import '../gr-vote-chip/gr-vote-chip';
 import '../gr-account-chip/gr-account-chip';
 import '../gr-button/gr-button';
@@ -35,7 +36,6 @@
 import {ifDefined} from 'lit/directives/if-defined';
 import {fireReload} from '../../../utils/event-util';
 import {sortReviewers} from '../../../utils/attention-set-util';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -81,7 +81,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       fontStyles,
       votingStyles,
@@ -108,10 +107,10 @@
           width: var(--line-height-normal);
           padding: 0;
         }
-        gr-button[disabled] .material-icon {
+        gr-button[disabled] gr-icon {
           color: var(--border-color);
         }
-        .material-icon {
+        gr-icon {
           font-size: calc(var(--line-height-normal) - 2px);
         }
         .reviewer-row {
@@ -216,7 +215,7 @@
           this.change
         )}"
       >
-        <span class="material-icon filled">delete</span>
+        <gr-icon icon="delete" filled></gr-icon>
       </gr-button>
     </gr-tooltip-content>`;
   }
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts
index f9a9234..ea7d4a7 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts
@@ -67,7 +67,7 @@
             role="button"
             tabindex="0"
           >
-            <span class="material-icon filled">delete</span>
+            <gr-icon icon="delete" filled></gr-icon>
           </gr-button>
         </gr-tooltip-content>
       </div>
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.ts b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.ts
index 414d311..4cf42fd 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.ts
+++ b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.ts
@@ -4,12 +4,12 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import '../gr-limited-text/gr-limited-text';
 import {fireEvent} from '../../../utils/event-util';
 import {sharedStyles} from '../../../styles/shared-styles';
 import {LitElement, css, html} from 'lit';
 import {customElement, property} from 'lit/decorators';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -37,7 +37,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -58,7 +57,7 @@
         a {
           color: var(--linked-chip-text-color);
         }
-        .material-icon {
+        gr-icon {
           font-size: 1.2rem;
         }
         gr-button::part(paper-button),
@@ -95,7 +94,7 @@
         class="remove"
         @click=${this.handleRemoveTap}
       >
-        <span class="material-icon">close</span>
+        <gr-icon icon="close"></gr-icon>
       </gr-button>
     </div>`;
   }
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.ts b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.ts
index 5959c5f..4667703 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.ts
@@ -31,7 +31,7 @@
         role="button"
         tabindex="0"
       >
-        <span class="material-icon">close</span>
+        <gr-icon icon="close"></gr-icon>
       </gr-button>
     </div>`);
   });
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.ts b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.ts
index a670919..48beb3a 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.ts
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.ts
@@ -5,6 +5,7 @@
  */
 import '@polymer/iron-input/iron-input';
 import '../gr-button/gr-button';
+import '../gr-icon/gr-icon';
 import {encodeURL, getBaseUrl} from '../../../utils/url-util';
 import {page} from '../../../utils/page-wrapper-utils';
 import {fireEvent} from '../../../utils/event-util';
@@ -13,7 +14,6 @@
 import {LitElement, PropertyValues, css, html} from 'lit';
 import {customElement, property} from 'lit/decorators';
 import {BindValueChangeEvent} from '../../../types/events';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const REQUEST_DEBOUNCE_INTERVAL_MS = 200;
 
@@ -55,7 +55,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         #filter {
@@ -89,7 +88,7 @@
           margin-right: 20px;
           color: var(--deemphasized-text-color);
         }
-        .material-icon {
+        gr-icon {
           font-size: 1.85rem;
           margin-left: 16px;
         }
@@ -134,7 +133,7 @@
           )}
           ?hidden=${this.loading || this.offset === 0}
         >
-          <span class="material-icon">chevron_left</span>
+          <gr-icon icon="chevron_left"></gr-icon>
         </a>
         <a
           id="nextArrow"
@@ -147,7 +146,7 @@
           )}
           ?hidden=${this.hideNextArrow(this.loading, this.items)}
         >
-          <span class="material-icon">chevron_right</span>
+          <gr-icon icon="chevron_right"></gr-icon>
         </a>
       </nav>
     `;
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.ts b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.ts
index 2ceb5c9..887c181 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.ts
@@ -47,10 +47,10 @@
       <nav>
         Page 1
         <a hidden="" href="" id="prevArrow">
-          <span class="material-icon"> chevron_left </span>
+          <gr-icon icon="chevron_left"></gr-icon>
         </a>
         <a hidden="" href=",25" id="nextArrow">
-          <span class="material-icon"> chevron_right </span>
+          <gr-icon icon="chevron_right"></gr-icon>
         </a>
       </nav>
     `);
diff --git a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.ts b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.ts
index 43346f9..cabbfc8 100644
--- a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.ts
+++ b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.ts
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../gr-labeled-autocomplete/gr-labeled-autocomplete';
+import '../gr-icon/gr-icon';
 import {singleDecodeURL} from '../../../utils/url-util';
 import {AutocompleteQuery} from '../gr-autocomplete/gr-autocomplete';
 import {
@@ -20,7 +21,6 @@
 import {assertIsDefined} from '../../../utils/common-util';
 import {fire} from '../../../utils/event-util';
 import {BindValueChangeEvent} from '../../../types/events';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const SUGGESTIONS_LIMIT = 15;
 const REF_PREFIX = 'refs/heads/';
@@ -62,7 +62,6 @@
 
   static override get styles() {
     return [
-      iconStyles,
       sharedStyles,
       css`
         :host {
@@ -71,7 +70,7 @@
         gr-labeled-autocomplete {
           display: inline-block;
         }
-        .material-icon {
+        gr-icon {
           margin-bottom: var(--spacing-l);
         }
       `,
@@ -91,7 +90,7 @@
           }}
         >
         </gr-labeled-autocomplete>
-        <span class="material-icon">chevron_right</span>
+        <gr-icon icon="chevron_right"></gr-icon>
         <gr-labeled-autocomplete
           id="branchInput"
           label="Branch"
diff --git a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.ts b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.ts
index 0119aa0..f6d4f81 100644
--- a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.ts
@@ -28,7 +28,7 @@
           placeholder="Select repo"
         >
         </gr-labeled-autocomplete>
-        <span class="material-icon"> chevron_right </span>
+        <gr-icon icon="chevron_right"></gr-icon>
         <gr-labeled-autocomplete
           disabled=""
           id="branchInput"
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts
index aa39e00..5e680ae 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts
@@ -3,12 +3,12 @@
  * Copyright 2017 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import '../gr-icon/gr-icon';
 import '../gr-tooltip/gr-tooltip';
 import {getRootElement} from '../../../scripts/rootElement';
 import {GrTooltip} from '../gr-tooltip/gr-tooltip';
 import {css, html, LitElement, PropertyValues} from 'lit';
 import {customElement, property, state} from 'lit/decorators';
-import {iconStyles} from '../../../styles/gr-icon-styles';
 
 const BOTTOM_OFFSET = 7.2; // Height of the arrow in tooltip.
 
@@ -72,9 +72,8 @@
 
   static override get styles() {
     return [
-      iconStyles,
       css`
-        .material-icon {
+        gr-icon {
           font-size: var(--line-height-normal);
         }
       `,
@@ -90,7 +89,7 @@
 
   renderIcon() {
     if (!this.showIcon) return;
-    return html`<span class="material-icon filled">info</span>`;
+    return html`<gr-icon icon="info" filled></gr-icon>`;
   }
 
   override updated(changedProperties: PropertyValues) {
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.ts b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.ts
index e246be0..051fbd4 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.ts
@@ -42,18 +42,18 @@
 
     expect(element).shadowDom.to.equal(/* HTML */ `
       <slot> </slot>
-      <span class="filled material-icon"> info </span>
+      <gr-icon icon="info" filled></gr-icon>
     `);
   });
 
   test('icon is not visible by default', () => {
-    assert.isNotOk(query(element, '.material-icon'));
+    assert.isNotOk(query(element, 'gr-icon'));
   });
 
   test('icon is visible with showIcon property', async () => {
     element.showIcon = true;
     await element.updateComplete;
-    assert.isOk(query(element, '.material-icon'));
+    assert.isOk(query(element, 'gr-icon'));
   });
 
   test('position-below attribute is reflected', async () => {
diff --git a/polygerrit-ui/app/utils/label-util.ts b/polygerrit-ui/app/utils/label-util.ts
index 99f4215..32d8ceb 100644
--- a/polygerrit-ui/app/utils/label-util.ts
+++ b/polygerrit-ui/app/utils/label-util.ts
@@ -241,7 +241,7 @@
 export interface SubmitRequirementsIcon {
   // The material icon name.
   icon: string;
-  // Whether the material-icon need to be filled.
+  // Whether the gr-icon need to be filled.
   filled?: boolean;
 }