diff --git a/packages/experiments-realm/address.gts b/packages/experiments-realm/address.gts
index 0cee00fa53..d640b9c18b 100644
--- a/packages/experiments-realm/address.gts
+++ b/packages/experiments-realm/address.gts
@@ -7,7 +7,7 @@ import {
 import StringField from 'https://cardstack.com/base/string';
 import { CountryField } from './country';
 import MapPinIcon from '@cardstack/boxel-icons/map-pin';
-import { EntityDisplay } from './components/entity-display';
+import EntityDisplayWithIcon from './components/entity-icon-display';
 
 function getAddressRows(
   addressLine1: string | undefined,
@@ -39,14 +39,11 @@ class Atom extends Component<typeof Address> {
     );
   }
   <template>
-    <EntityDisplay>
-      <:title>
-        {{this.label}}
-      </:title>
-      <:thumbnail>
+    <EntityDisplayWithIcon @title={{this.label}}>
+      <:icon>
         <MapPinIcon />
-      </:thumbnail>
-    </EntityDisplay>
+      </:icon>
+    </EntityDisplayWithIcon>
   </template>
 }
 
diff --git a/packages/experiments-realm/components/activity-card.gts b/packages/experiments-realm/components/activity-card.gts
index 76222830ea..b5277ff520 100644
--- a/packages/experiments-realm/components/activity-card.gts
+++ b/packages/experiments-realm/components/activity-card.gts
@@ -1,5 +1,5 @@
 import GlimmerComponent from '@glimmer/component';
-import { EntityDisplay } from './entity-display';
+import EntityDisplayWithThumbnail from './entity-thumbnail-display';
 
 interface ActivityCardArgs {
   Blocks: {
@@ -17,7 +17,7 @@ export default class ActivityCard extends GlimmerComponent<ActivityCardArgs> {
     <article class='activity-card' ...attributes>
       <header class='activity-card-header'>
         <div class='activity-card-title-desc-group'>
-          <EntityDisplay>
+          <EntityDisplayWithThumbnail>
             <:title>
               <span class='activity-card-title'>
                 {{yield to='title'}}
@@ -28,7 +28,7 @@ export default class ActivityCard extends GlimmerComponent<ActivityCardArgs> {
                 {{yield to='thumbnail'}}
               </span>
             </:thumbnail>
-          </EntityDisplay>
+          </EntityDisplayWithThumbnail>
 
           {{#if (has-block 'description')}}
             <p class='activity-card-description'>
diff --git a/packages/experiments-realm/components/contact-row.gts b/packages/experiments-realm/components/contact-row.gts
index 92b8f3e4c2..db8545180b 100644
--- a/packages/experiments-realm/components/contact-row.gts
+++ b/packages/experiments-realm/components/contact-row.gts
@@ -1,5 +1,5 @@
 import { Avatar, Pill } from '@cardstack/boxel-ui/components';
-import { EntityDisplay } from './entity-display';
+import EntityDisplayWithThumbnail from './entity-thumbnail-display';
 import GlimmerComponent from '@glimmer/component';
 
 interface ContactRowArgs {
@@ -15,10 +15,7 @@ interface ContactRowArgs {
 
 export class ContactRow extends GlimmerComponent<ContactRowArgs> {
   <template>
-    <EntityDisplay>
-      <:title>
-        {{@name}}
-      </:title>
+    <EntityDisplayWithThumbnail @title={{@name}}>
       <:thumbnail>
         <Avatar
           @userID={{@userID}}
@@ -35,7 +32,7 @@ export class ContactRow extends GlimmerComponent<ContactRowArgs> {
           </Pill>
         {{/if}}
       </:tag>
-    </EntityDisplay>
+    </EntityDisplayWithThumbnail>
     <style scoped>
       .avatar {
         --profile-avatar-icon-size: 20px;
diff --git a/packages/experiments-realm/components/entity-display.gts b/packages/experiments-realm/components/entity-display.gts
deleted file mode 100644
index 24aea981d9..0000000000
--- a/packages/experiments-realm/components/entity-display.gts
+++ /dev/null
@@ -1,93 +0,0 @@
-import GlimmerComponent from '@glimmer/component';
-interface EntityDisplayArgs {
-  Args: {
-    center?: boolean;
-    underline?: boolean;
-  };
-  Blocks: {
-    title: [];
-    thumbnail: [];
-    tag: [];
-    content: [];
-  };
-  Element: HTMLElement;
-}
-
-export class EntityDisplay extends GlimmerComponent<EntityDisplayArgs> {
-  get shouldAlignCenter() {
-    return this.args.center;
-  }
-
-  get shouldUnderlineText() {
-    return this.args.underline;
-  }
-
-  <template>
-    <div
-      class='entity-display {{if this.shouldAlignCenter "center"}}'
-      ...attributes
-    >
-      <div class='entity-thumbnail'>{{yield to='thumbnail'}}</div>
-
-      <div class='entity-info'>
-        <div class='entity-name-tag'>
-          <span class='entity-name {{if this.shouldUnderlineText "underline"}}'>
-            {{yield to='title'}}
-          </span>
-
-          {{yield to='tag'}}
-        </div>
-
-        <div class='entity-content'>
-          {{yield to='content'}}
-        </div>
-      </div>
-    </div>
-    <style scoped>
-      .entity-display {
-        display: inline-flex;
-        align-items: start;
-        gap: var(--entity-display-gap, var(--boxel-sp-xs));
-      }
-      .entity-display.center {
-        align-items: center;
-      }
-      .entity-thumbnail {
-        width: var(--entity-display-thumbnail-size, var(--boxel-icon-sm));
-        height: calc(
-          var(--entity-display-thumbnail-size, var(--boxel-icon-sm)) - 2px
-        );
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        flex-shrink: 0;
-        color: var(--entity-display-thumbnail-color, var(--boxel-600));
-      }
-      .entity-info {
-        display: flex;
-        flex-direction: column;
-        gap: var(--entity-display-info-gap, var(--boxel-sp-xxxs));
-      }
-      .entity-name-tag {
-        display: flex;
-        flex-wrap: wrap;
-        align-items: center;
-        gap: var(--entity-display-name-tag-gap, var(--boxel-sp-xxxs));
-      }
-      .entity-name {
-        word-break: break-word;
-      }
-      .entity-name.underline {
-        text-decoration: underline;
-      }
-      .entity-content {
-        margin: 0;
-        font-size: var(
-          --entity-display-content-font-size,
-          var(--boxel-font-size-sm)
-        );
-        color: var(--entity-display-content-color, var(--boxel-400));
-      }
-    </style>
-  </template>
-}
diff --git a/packages/experiments-realm/components/entity-icon-display.gts b/packages/experiments-realm/components/entity-icon-display.gts
new file mode 100644
index 0000000000..73cc4142d1
--- /dev/null
+++ b/packages/experiments-realm/components/entity-icon-display.gts
@@ -0,0 +1,126 @@
+import GlimmerComponent from '@glimmer/component';
+import { concat } from '@ember/helper';
+
+interface EntityDisplayWithIconArgs {
+  Args: {
+    title?: string; //prefer using args.title if the title is just a string
+    center?: boolean;
+    underline?: boolean;
+  };
+  Blocks: {
+    title?: []; //we can choose use this to pass instead of using args.title if the title block HTML is complex
+    icon?: [];
+    tag?: [];
+    content?: [];
+  };
+  Element: HTMLElement;
+}
+
+export default class EntityDisplayWithIcon extends GlimmerComponent<EntityDisplayWithIconArgs> {
+  get shouldAlignCenter() {
+    return this.args.center;
+  }
+
+  get shouldUnderlineText() {
+    return this.args.underline;
+  }
+
+  <template>
+    <div
+      class={{concat
+        'entity-icon-display'
+        (if this.shouldAlignCenter ' center')
+      }}
+      ...attributes
+    >
+      {{#if (has-block 'icon')}}
+        <aside class='entity-icon'>
+          {{yield to='icon'}}
+        </aside>
+      {{/if}}
+
+      <div class='entity-info'>
+        {{! Title and tag }}
+        <div class='entity-title-tag-container'>
+          {{! this guard clause is already priotize yield to 'title' instead of using args.title if both are provided}}
+          {{#if (has-block 'title')}}
+            {{yield to='title'}}
+          {{else if @title}}
+            <span
+              class={{concat
+                'entity-title'
+                (if this.shouldUnderlineText ' underline')
+              }}
+            >
+              {{@title}}
+            </span>
+          {{/if}}
+
+          {{#if (has-block 'tag')}}
+            {{yield to='tag'}}
+          {{/if}}
+        </div>
+
+        {{! Extra Content }}
+        {{#if (has-block 'content')}}
+          <div class='entity-content'>
+            {{yield to='content'}}
+          </div>
+        {{/if}}
+      </div>
+
+    </div>
+    <style scoped>
+      .entity-icon-display {
+        --icon-size: var(--entity-display-icon-size, var(--boxel-icon-sm));
+        --title-font-size: var(
+          --entity-display-title-font-size,
+          var(--boxel-font-size-sm)
+        );
+        --content-font-size: var(
+          --entity-display-content-font-size,
+          var(--boxel-font-size-xs)
+        );
+        --content-color: var(--entity-display-content-color, var(--boxel-400));
+        --content-gap: var(--entity-display-content-gap, var(--boxel-sp-xxxs));
+        display: flex;
+        align-items: flex-start;
+        gap: var(--content-gap);
+      }
+      .entity-icon-display.center {
+        align-items: center;
+      }
+      .entity-icon {
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        flex-shrink: 0;
+        width: var(--icon-size);
+        height: var(--icon-size);
+      }
+      .entity-info {
+        display: flex;
+        flex-direction: column;
+        gap: var(--content-gap);
+      }
+      .entity-title-tag-container {
+        display: flex;
+        flex-wrap: wrap;
+        align-items: center;
+        gap: var(--content-gap);
+      }
+      .entity-title {
+        word-break: break-word;
+        font-size: var(--title-font-size);
+      }
+      .entity-title.underline {
+        text-decoration: underline;
+      }
+      .entity-content {
+        margin: 0;
+        font-size: var(--content-font-size);
+        color: var(--content-color);
+      }
+    </style>
+  </template>
+}
diff --git a/packages/experiments-realm/components/entity-thumbnail-display.gts b/packages/experiments-realm/components/entity-thumbnail-display.gts
new file mode 100644
index 0000000000..26aac840e9
--- /dev/null
+++ b/packages/experiments-realm/components/entity-thumbnail-display.gts
@@ -0,0 +1,130 @@
+import GlimmerComponent from '@glimmer/component';
+import { concat } from '@ember/helper';
+
+interface EntityDisplayWithThumbnailArgs {
+  Args: {
+    title?: string; //prefer using args.title if the title is just a string
+    center?: boolean;
+    underline?: boolean;
+  };
+  Blocks: {
+    title?: []; //we can choose use this to pass instead of using args.title if the title block HTML is complex
+    thumbnail?: [];
+    tag?: [];
+    content?: [];
+  };
+  Element: HTMLElement;
+}
+
+export default class EntityDisplayWithThumbnail extends GlimmerComponent<EntityDisplayWithThumbnailArgs> {
+  get shouldAlignCenter() {
+    return this.args.center;
+  }
+
+  get shouldUnderlineText() {
+    return this.args.underline;
+  }
+
+  <template>
+    <div
+      class={{concat
+        'entity-thumbnail-display'
+        (if this.shouldAlignCenter ' center')
+      }}
+      ...attributes
+    >
+      {{#if (has-block 'thumbnail')}}
+        <aside class='entity-thumbnail'>
+          {{yield to='thumbnail'}}
+        </aside>
+      {{/if}}
+
+      <div class='entity-info'>
+        {{! Title and tag }}
+        <div class='entity-title-tag-container'>
+          {{! this guard clause is already priotize yield to 'title' instead of using args.title if both are provided}}
+          {{#if (has-block 'title')}}
+            {{yield to='title'}}
+          {{else if @title}}
+            <span
+              class={{concat
+                'entity-title'
+                (if this.shouldUnderlineText ' underline')
+              }}
+            >
+              {{@title}}
+            </span>
+          {{/if}}
+
+          {{#if (has-block 'tag')}}
+            {{yield to='tag'}}
+          {{/if}}
+        </div>
+
+        {{! Extra Content }}
+        {{#if (has-block 'content')}}
+          <div class='entity-content'>
+            {{yield to='content'}}
+          </div>
+        {{/if}}
+      </div>
+
+    </div>
+    <style scoped>
+      .entity-thumbnail-display {
+        --thumbnail-size: var(
+          --entity-display-thumbnail-size,
+          var(--boxel-icon-sm)
+        );
+        --title-font-size: var(
+          --entity-display-title-font-size,
+          var(--boxel-font-size-sm)
+        );
+        --content-font-size: var(
+          --entity-display-content-font-size,
+          var(--boxel-font-size-xs)
+        );
+        --content-color: var(--entity-display-content-color, var(--boxel-400));
+        --content-gap: var(--entity-display-content-gap, var(--boxel-sp-xxxs));
+        display: flex;
+        align-items: flex-start;
+        gap: var(--content-gap);
+      }
+      .entity-thumbnail-display.center {
+        align-items: center;
+      }
+      .entity-thumbnail {
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        flex-shrink: 0;
+        width: var(--thumbnail-size);
+        height: var(--thumbnail-size);
+        overflow: hidden;
+      }
+      .entity-info {
+        display: flex;
+        flex-direction: column;
+        gap: var(--content-gap);
+      }
+      .entity-title-tag-container {
+        display: flex;
+        flex-wrap: wrap;
+        align-items: center;
+        gap: var(--content-gap);
+      }
+      .entity-title {
+        word-break: break-word;
+        font-size: var(--title-font-size);
+      }
+      .entity-title.underline {
+        text-decoration: underline;
+      }
+      .entity-content {
+        margin: 0;
+        font-size: var(--content-font-size);
+        color: var(--content-color);
+      }
+    </style>
+  </template>
+}
diff --git a/packages/experiments-realm/crm-app.gts b/packages/experiments-realm/crm-app.gts
index b3a00c7348..c1bb2eb310 100644
--- a/packages/experiments-realm/crm-app.gts
+++ b/packages/experiments-realm/crm-app.gts
@@ -23,12 +23,7 @@ import {
 } from '@cardstack/boxel-ui/components';
 import { IconPlus } from '@cardstack/boxel-ui/icons';
 import { AppCard, Tab } from './app-card';
-import {
-  Query,
-  CardError,
-  SupportedMimeType,
-  codeRefWithAbsoluteURL,
-} from '@cardstack/runtime-common';
+import { Query, CardError, SupportedMimeType } from '@cardstack/runtime-common';
 import ContactIcon from '@cardstack/boxel-icons/contact';
 import HeartHandshakeIcon from '@cardstack/boxel-icons/heart-handshake';
 import TargetArrowIcon from '@cardstack/boxel-icons/target-arrow';
@@ -181,15 +176,6 @@ class CrmAppTemplate extends Component<typeof AppCard> {
     return this.activeTab?.tabId ? this.activeTab.tabId.toLowerCase() : '';
   }
 
-  get activeTabRef() {
-    if (!this.activeTab?.ref?.name || !this.activeTab.ref.module) {
-      return;
-    }
-    if (!this.currentRealm) {
-      return;
-    }
-    return codeRefWithAbsoluteURL(this.activeTab.ref, this.currentRealm);
-  }
   setTabs(tabs: Tab[]) {
     this.args.model.tabs = tabs ?? [];
   }
@@ -489,7 +475,7 @@ class CrmAppTemplate extends Component<typeof AppCard> {
 }
 
 export class CrmApp extends AppCard {
-  static displayName = 'Crm App';
+  static displayName = 'CRM App';
   static prefersWideFormat = true;
   static headerColor = '#4D3FE8';
   static isolated = CrmAppTemplate;
diff --git a/packages/experiments-realm/crm/account.gts b/packages/experiments-realm/crm/account.gts
index 72dd7b5483..b467468a30 100644
--- a/packages/experiments-realm/crm/account.gts
+++ b/packages/experiments-realm/crm/account.gts
@@ -26,7 +26,8 @@ import CalendarExclamation from '@cardstack/boxel-icons/calendar-exclamation';
 import { LooseGooseyField } from '../loosey-goosey';
 import { StatusPill } from '../components/status-pill';
 import { Avatar, Pill, BoxelButton } from '@cardstack/boxel-ui/components';
-import { EntityDisplay } from '../components/entity-display';
+import EntityDisplayWithIcon from '../components/entity-icon-display';
+import EntityDisplayWithThumbnail from '../components/entity-thumbnail-display';
 import ActivityCard from '../components/activity-card';
 import PlusIcon from '@cardstack/boxel-icons/plus';
 import PhoneIcon from '@cardstack/boxel-icons/phone';
@@ -283,41 +284,36 @@ class IsolatedTemplate extends Component<typeof Account> {
               </:description>
               <:content>
                 <div class='activity-card-group'>
-                  <EntityDisplay>
-                    <:thumbnail>
+                  <EntityDisplayWithIcon @title='Technova'>
+                    <:icon>
                       <SquareUser />
-                    </:thumbnail>
-                    <:title>
-                      Dmitri Petrov
-                    </:title>
+                    </:icon>
                     <:content>
                       Technova
                     </:content>
-                  </EntityDisplay>
-                  <EntityDisplay>
+                  </EntityDisplayWithIcon>
+                  <EntityDisplayWithThumbnail @title='Rep: Janus Dios'>
                     <:thumbnail>
                       <Avatar
                         @thumbnailURL='https://images.pexels.com/photos/1624229/pexels-photo-1624229.jpeg?auto=compress&cs=tinysrgb&w=300&h=300&dpr=2'
+                        class='avatar'
                       />
                     </:thumbnail>
-                    <:title>
-                      Rep: Janus Dios
-                    </:title>
                     <:content>
                       Sales Associate
                     </:content>
-                  </EntityDisplay>
-                  <EntityDisplay class='activity-time'>
-                    <:thumbnail>
+                  </EntityDisplayWithThumbnail>
+                  <EntityDisplayWithIcon
+                    class='activity-time'
+                    @title='May 15, 2024'
+                  >
+                    <:icon>
                       <CalendarTime />
-                    </:thumbnail>
-                    <:title>
-                      May 15, 2024
-                    </:title>
+                    </:icon>
                     <:content>
                       3:15pm
                     </:content>
-                  </EntityDisplay>
+                  </EntityDisplayWithIcon>
                 </div>
               </:content>
             </ActivityCard>
@@ -407,6 +403,11 @@ class IsolatedTemplate extends Component<typeof Account> {
         color: var(--boxel-color-gray);
         margin-left: auto;
       }
+      .avatar {
+        --profile-avatar-icon-size: 20px;
+        --profile-avatar-icon-border: 0px;
+        flex-shrink: 0;
+      }
 
       @container activities-summary-card (max-width: 447px) {
         .activity-button-mobile {
diff --git a/packages/experiments-realm/crm/company.gts b/packages/experiments-realm/crm/company.gts
index fe64a3a1c5..70af9f19ff 100644
--- a/packages/experiments-realm/crm/company.gts
+++ b/packages/experiments-realm/crm/company.gts
@@ -2,7 +2,7 @@ import StringField from 'https://cardstack.com/base/string';
 import NumberField from 'https://cardstack.com/base/number';
 import { WebsiteField } from '../website';
 import { Address } from '../address';
-import { EntityDisplay } from '../components/entity-display';
+import EntityDisplayWithIcon from '../components/entity-icon-display';
 
 import {
   Component,
@@ -15,14 +15,11 @@ import BuildingIcon from '@cardstack/boxel-icons/building';
 class ViewCompanyTemplate extends Component<typeof Company> {
   <template>
     <div class='company-group'>
-      <EntityDisplay @underline={{true}}>
-        <:title>
-          {{@model.name}}
-        </:title>
-        <:thumbnail>
+      <EntityDisplayWithIcon @title={{@model.name}} @underline={{true}}>
+        <:icon>
           <BuildingIcon />
-        </:thumbnail>
-      </EntityDisplay>
+        </:icon>
+      </EntityDisplayWithIcon>
     </div>
   </template>
 }
diff --git a/packages/experiments-realm/crm/contact.gts b/packages/experiments-realm/crm/contact.gts
index e043c105f0..8d29b1c062 100644
--- a/packages/experiments-realm/crm/contact.gts
+++ b/packages/experiments-realm/crm/contact.gts
@@ -19,7 +19,7 @@ import Email from '@cardstack/boxel-icons/mail';
 import Linkedin from '@cardstack/boxel-icons/linkedin';
 import XIcon from '@cardstack/boxel-icons/brand-x';
 import { LooseGooseyField } from '../loosey-goosey';
-import { EntityDisplay } from '../components/entity-display';
+import EntityDisplayWithThumbnail from '../components/entity-thumbnail-display';
 
 export class SocialLinkField extends ContactLinkField {
   static displayName = 'social-link';
@@ -186,7 +186,7 @@ class FittedTemplate extends Component<typeof Contact> {
         grid-area: avatar-group-container;
       }
       .avatar-group-container
-        :where(.avatar-info .company-group .entity-name-tag) {
+        :where(.avatar-info .company-group .entity-title-tag-container) {
         overflow: hidden;
         text-overflow: ellipsis;
         display: -webkit-box;
@@ -610,10 +610,7 @@ class AtomTemplate extends Component<typeof Contact> {
   }
   <template>
     <div class='contact'>
-      <EntityDisplay @underline={{true}}>
-        <:title>
-          {{this.label}}
-        </:title>
+      <EntityDisplayWithThumbnail @title={{this.label}} @underline={{true}}>
         <:thumbnail>
           <Avatar
             @userID={{@model.id}}
@@ -623,7 +620,7 @@ class AtomTemplate extends Component<typeof Contact> {
             class='avatar'
           />
         </:thumbnail>
-      </EntityDisplay>
+      </EntityDisplayWithThumbnail>
     </div>
     <style scoped>
       .contact {
diff --git a/packages/experiments-realm/crm/deal.gts b/packages/experiments-realm/crm/deal.gts
index 89b0ec1c11..cc14183498 100644
--- a/packages/experiments-realm/crm/deal.gts
+++ b/packages/experiments-realm/crm/deal.gts
@@ -18,7 +18,7 @@ import { BoxelButton, Pill } from '@cardstack/boxel-ui/components';
 import Info from '@cardstack/boxel-icons/info';
 import AccountHeader from '../components/account-header';
 import CrmProgressBar from '../components/crm-progress-bar';
-import { EntityDisplay } from '../components/entity-display';
+import EntityDisplayWithIcon from '../components/entity-icon-display';
 import { htmlSafe } from '@ember/template';
 import { concat } from '@ember/helper';
 import { LooseGooseyField } from '../loosey-goosey';
@@ -55,7 +55,6 @@ class IsolatedTemplate extends Component<typeof Deal> {
     );
   }
   get primaryContactName() {
-    console.log(this.args.fields.account?.primaryContact);
     return this.args.model.account?.primaryContact?.name;
   }
 
@@ -84,10 +83,6 @@ class IsolatedTemplate extends Component<typeof Deal> {
     return this.args.model[realmURL]!;
   }
 
-  get realmHref() {
-    return this.realmURL.href;
-  }
-
   get realmHrefs() {
     return [this.realmURL?.href];
   }
@@ -96,7 +91,7 @@ class IsolatedTemplate extends Component<typeof Deal> {
     return {
       filter: {
         type: {
-          module: `${this.realmHref}crm/deal`,
+          module: new URL('./crm/deal', import.meta.url).href,
           name: 'Deal',
         },
       },
@@ -116,14 +111,11 @@ class IsolatedTemplate extends Component<typeof Deal> {
       (acc, deal: Deal) => acc + deal.computedValue.amount,
       0,
     );
-    nonZeroDeals.map((d) => console.log(d.computedValue.amount));
-    console.log('totalDealRevenue', totalDealRevenue);
     let avgDealSize = totalDealRevenue / nonZeroDeals.length;
-    console.log('avgDealSize', avgDealSize);
+
     if (this.args.model.computedValue?.amount) {
       let percentDiff =
         (this.args.model.computedValue?.amount - avgDealSize) / avgDealSize;
-      console.log('percentDiff', percentDiff);
       let positive = percentDiff >= 0 ? true : false;
       let summary = `${percentDiff.toFixed(2)}% ${
         positive ? 'above' : 'below'
@@ -294,14 +286,11 @@ class IsolatedTemplate extends Component<typeof Deal> {
 
             <footer class='next-steps'>
               <div class='next-steps-row'>
-                <EntityDisplay @center={{true}}>
-                  <:title>
-                    Notes
-                  </:title>
-                  <:thumbnail>
+                <EntityDisplayWithIcon @title='Notes' @center={{true}}>
+                  <:icon>
                     <Info class='info-icon' />
-                  </:thumbnail>
-                </EntityDisplay>
+                  </:icon>
+                </EntityDisplayWithIcon>
 
                 {{#if @model.document}}
                   <BoxelButton
@@ -524,7 +513,7 @@ class IsolatedTemplate extends Component<typeof Deal> {
       }
       .info-atom {
         width: fit-content;
-        display: inline-block;
+        display: inline-flex;
       }
       .header-icon {
         width: var(--boxel-icon-sm);
@@ -712,7 +701,7 @@ class FittedTemplate extends Component<typeof Deal> {
       }
       .info-atom {
         width: fit-content;
-        display: inline-block;
+        display: inline-flex;
       }
       /* deal details */
       .deal-details {
diff --git a/packages/experiments-realm/email.gts b/packages/experiments-realm/email.gts
index b4991a0671..3d01fb25a3 100644
--- a/packages/experiments-realm/email.gts
+++ b/packages/experiments-realm/email.gts
@@ -15,7 +15,7 @@ import MailIcon from '@cardstack/boxel-icons/mail';
 import { debounce } from 'lodash';
 import { tracked } from '@glimmer/tracking';
 import { action } from '@ember/object';
-import { EntityDisplay } from './components/entity-display';
+import EntityDisplayWithIcon from './components/entity-icon-display';
 
 // We use simple regex here to validate common email formats
 // This is definitely NOT a full email validation
@@ -68,14 +68,11 @@ export class EmailField extends StringField {
   static atom = class Atom extends Component<typeof EmailField> {
     <template>
       {{#if @model}}
-        <EntityDisplay @underline={{false}}>
-          <:title>
-            {{@model}}
-          </:title>
-          <:thumbnail>
+        <EntityDisplayWithIcon @title={{@model}} @underline={{false}}>
+          <:icon>
             <MailIcon class='icon' />
-          </:thumbnail>
-        </EntityDisplay>
+          </:icon>
+        </EntityDisplayWithIcon>
       {{/if}}
       <style scoped>
         .icon {
diff --git a/packages/experiments-realm/phone-number.gts b/packages/experiments-realm/phone-number.gts
index 099cb099b2..e186326d94 100644
--- a/packages/experiments-realm/phone-number.gts
+++ b/packages/experiments-realm/phone-number.gts
@@ -8,7 +8,7 @@ import {
 import { LooseGooseyField, LooseyGooseyData } from './loosey-goosey';
 import { PhoneInput, Pill } from '@cardstack/boxel-ui/components';
 import { RadioInput } from '@cardstack/boxel-ui/components';
-import { EntityDisplay } from './components/entity-display';
+import EntityDisplayWithIcon from './components/entity-icon-display';
 import { tracked } from '@glimmer/tracking';
 import { fn } from '@ember/helper';
 import { action } from '@ember/object';
@@ -94,7 +94,7 @@ export class PhoneField extends FieldDef {
 
   static atom = class Atom extends Component<typeof PhoneField> {
     <template>
-      <EntityDisplay @underline={{false}}>
+      <EntityDisplayWithIcon @underline={{false}}>
         <:title>
           {{#if @model.countryCode}}
             +{{@model.countryCode}}{{@model.number}}
@@ -102,10 +102,10 @@ export class PhoneField extends FieldDef {
             {{@model.number}}
           {{/if}}
         </:title>
-        <:thumbnail>
+        <:icon>
           <PhoneIcon class='icon' />
-        </:thumbnail>
-      </EntityDisplay>
+        </:icon>
+      </EntityDisplayWithIcon>
       <style scoped>
         .icon {
           color: var(--boxel-400);
@@ -131,7 +131,7 @@ export class ContactPhoneNumber extends FieldDef {
 
   static atom = class Atom extends Component<typeof ContactPhoneNumber> {
     <template>
-      <EntityDisplay @underline={{false}}>
+      <EntityDisplayWithIcon @underline={{false}}>
         <:title>
           {{#if @model.phoneNumber.countryCode}}
             +{{@model.phoneNumber.countryCode}}{{@model.phoneNumber.number}}
@@ -139,9 +139,9 @@ export class ContactPhoneNumber extends FieldDef {
             {{@model.phoneNumber.number}}
           {{/if}}
         </:title>
-        <:thumbnail>
+        <:icon>
           <PhoneIcon class='icon' />
-        </:thumbnail>
+        </:icon>
         <:tag>
           {{#if @model.type.label}}
             <Pill class='pill-gray'>
@@ -149,7 +149,7 @@ export class ContactPhoneNumber extends FieldDef {
             </Pill>
           {{/if}}
         </:tag>
-      </EntityDisplay>
+      </EntityDisplayWithIcon>
       <style scoped>
         .icon {
           color: var(--boxel-400);
diff --git a/packages/experiments-realm/website.gts b/packages/experiments-realm/website.gts
index 2f79e4af5e..06ad9a5ee6 100644
--- a/packages/experiments-realm/website.gts
+++ b/packages/experiments-realm/website.gts
@@ -1,7 +1,7 @@
 import WorldWwwIcon from '@cardstack/boxel-icons/world-www';
 import { UrlField } from './url';
 import { Component } from 'https://cardstack.com/base/card-api';
-import { EntityDisplay } from './components/entity-display';
+import EntityDisplayWithIcon from './components/entity-icon-display';
 
 const domainWithPath = (urlString: string | null) => {
   if (!urlString) {
@@ -18,14 +18,11 @@ export class WebsiteField extends UrlField {
 
   static atom = class Atom extends Component<typeof WebsiteField> {
     <template>
-      <EntityDisplay>
-        <:title>
-          {{domainWithPath @model}}
-        </:title>
-        <:thumbnail>
+      <EntityDisplayWithIcon @title={{domainWithPath @model}}>
+        <:icon>
           <WorldWwwIcon />
-        </:thumbnail>
-      </EntityDisplay>
+        </:icon>
+      </EntityDisplayWithIcon>
     </template>
   };
 
diff --git a/packages/host/app/lib/current-run.ts b/packages/host/app/lib/current-run.ts
index 5a8ab028ba..e3d2d6f8c3 100644
--- a/packages/host/app/lib/current-run.ts
+++ b/packages/host/app/lib/current-run.ts
@@ -228,7 +228,7 @@ export class CurrentRun {
 
   private async discoverInvalidations(
     url: URL,
-    mtimes: LastModifiedTimes,
+    indexMtimes: LastModifiedTimes,
   ): Promise<void> {
     log.debug(`discovering invalidations in dir ${url.href}`);
     let ignorePatterns = await this.#reader.readFile(
@@ -239,35 +239,23 @@ export class CurrentRun {
       this.#ignoreData[url.href] = ignorePatterns.content;
     }
 
-    let entries = await this.#reader.directoryListing(url);
-
-    for (let { url, kind, lastModified } of entries) {
-      let innerURL = new URL(url);
-      if (isIgnored(this.#realmURL, this.ignoreMap, innerURL)) {
+    let filesystemMtimes = await this.#reader.mtimes();
+    for (let [url, lastModified] of Object.entries(filesystemMtimes)) {
+      if (!url.endsWith('.json') && !hasExecutableExtension(url)) {
+        // Only allow json and executable files to be invalidated so that we
+        // don't end up with invalidated files that weren't meant to be indexed
+        // (images, etc)
         continue;
       }
-
-      if (kind === 'directory') {
-        await this.discoverInvalidations(innerURL, mtimes);
-      } else {
-        if (!url.endsWith('.json') && !hasExecutableExtension(url)) {
-          // Only allow json and executable files to be invalidated so that we don't end up with invalidated files that weren't meant to be indexed (images, etc)
-          continue;
-        }
-
-        let indexEntry = mtimes.get(innerURL.href);
-        if (
-          !indexEntry ||
-          indexEntry.type === 'error' ||
-          indexEntry.lastModified == null
-        ) {
-          await this.batch.invalidate(innerURL);
-          continue;
-        }
-
-        if (lastModified !== indexEntry.lastModified) {
-          await this.batch.invalidate(innerURL);
-        }
+      let indexEntry = indexMtimes.get(url);
+
+      if (
+        !indexEntry ||
+        indexEntry.type === 'error' ||
+        indexEntry.lastModified == null ||
+        lastModified !== indexEntry.lastModified
+      ) {
+        await this.batch.invalidate(new URL(url));
       }
     }
   }
diff --git a/packages/host/tests/integration/realm-indexing-and-querying-test.gts b/packages/host/tests/integration/realm-indexing-and-querying-test.gts
index 717db00fc0..7cba0ce45f 100644
--- a/packages/host/tests/integration/realm-indexing-and-querying-test.gts
+++ b/packages/host/tests/integration/realm-indexing-and-querying-test.gts
@@ -3401,6 +3401,12 @@ module(`Integration | realm indexing and querying`, function (hooks) {
                 { id: mangoID },
                 {
                   id: vanGoghID,
+                  firstName: 'Van Gogh',
+                  friends: [
+                    {
+                      id: hassanID,
+                    },
+                  ],
                 },
               ],
             },
diff --git a/packages/realm-server/tests/helpers/index.ts b/packages/realm-server/tests/helpers/index.ts
index 084dd8411d..ee57575503 100644
--- a/packages/realm-server/tests/helpers/index.ts
+++ b/packages/realm-server/tests/helpers/index.ts
@@ -1,4 +1,4 @@
-import { writeFileSync, writeJSONSync } from 'fs-extra';
+import { writeFileSync, writeJSONSync, readdirSync, statSync } from 'fs-extra';
 import { NodeAdapter } from '../../node-realm';
 import { resolve, join } from 'path';
 import {
@@ -14,14 +14,16 @@ import {
   maybeHandleScopedCSSRequest,
   insertPermissions,
   IndexWriter,
-  type MatrixConfig,
-  type QueuePublisher,
-  type QueueRunner,
-  type IndexRunner,
   asExpressions,
   query,
   insert,
   param,
+  unixTime,
+  RealmPaths,
+  type MatrixConfig,
+  type QueuePublisher,
+  type QueueRunner,
+  type IndexRunner,
 } from '@cardstack/runtime-common';
 import { dirSync } from 'tmp';
 import { getLocalConfig as getSynapseConfig } from '../../synapse';
@@ -401,6 +403,7 @@ export async function runTestRealmServer({
   let testRealmHttpServer = testRealmServer.listen(parseInt(realmURL.port));
   await testRealmServer.start();
   return {
+    testRealmDir,
     testRealm,
     testRealmServer,
     testRealmHttpServer,
@@ -494,3 +497,28 @@ export async function fetchSubscriptionsByUserId(
     stripeSubscriptionId: result.stripe_subscription_id,
   }));
 }
+
+export function mtimes(
+  path: string,
+  realmURL: URL,
+): { [path: string]: number } {
+  const mtimes: { [path: string]: number } = {};
+  let paths = new RealmPaths(realmURL);
+
+  function traverseDir(currentPath: string) {
+    const entries = readdirSync(currentPath, { withFileTypes: true });
+    for (const entry of entries) {
+      const fullPath = join(currentPath, entry.name);
+      if (entry.isDirectory()) {
+        traverseDir(fullPath);
+      } else if (entry.isFile()) {
+        const stats = statSync(fullPath);
+        mtimes[paths.fileURL(fullPath.substring(path.length)).href] = unixTime(
+          stats.mtime.getTime(),
+        );
+      }
+    }
+  }
+  traverseDir(path);
+  return mtimes;
+}
diff --git a/packages/realm-server/tests/realm-server-test.ts b/packages/realm-server/tests/realm-server-test.ts
index 400fdbd557..f892a1f5ca 100644
--- a/packages/realm-server/tests/realm-server-test.ts
+++ b/packages/realm-server/tests/realm-server-test.ts
@@ -54,6 +54,7 @@ import {
   testRealmInfo,
   insertUser,
   insertPlan,
+  mtimes,
   fetchSubscriptionsByUserId,
   cleanWhiteSpace,
 } from './helpers';
@@ -152,6 +153,7 @@ module('Realm Server', function (hooks) {
   }
 
   let testRealm: Realm;
+  let testRealmPath: string;
   let testRealmHttpServer: Server;
   let request: SuperTest<Test>;
   let dir: DirResult;
@@ -173,7 +175,11 @@ module('Realm Server', function (hooks) {
           copySync(join(__dirname, 'cards'), testRealmDir);
         }
         let virtualNetwork = createVirtualNetwork();
-        ({ testRealm, testRealmHttpServer } = await runTestRealmServer({
+        ({
+          testRealm,
+          testRealmHttpServer,
+          testRealmDir: testRealmPath,
+        } = await runTestRealmServer({
           virtualNetwork,
           testRealmDir,
           realmsRootPath: join(dir.name, 'realm_server_1'),
@@ -210,6 +216,50 @@ module('Realm Server', function (hooks) {
     resetCatalogRealms();
   });
 
+  module('mtimes requests', function (hooks) {
+    setupPermissionedRealm(hooks, {
+      mary: ['read'],
+    });
+
+    test('non read permission GET /_mtimes', async function (assert) {
+      let response = await request
+        .get('/_mtimes')
+        .set('Accept', 'application/vnd.api+json')
+        .set('Authorization', `Bearer ${createJWT(testRealm, 'not-mary')}`);
+
+      assert.strictEqual(response.status, 403, 'HTTP 403 status');
+    });
+
+    test('read permission GET /_mtimes', async function (assert) {
+      let expectedMtimes = mtimes(testRealmPath, testRealmURL);
+      delete expectedMtimes[`${testRealmURL}.realm.json`];
+
+      let response = await request
+        .get('/_mtimes')
+        .set('Accept', 'application/vnd.api+json')
+        .set(
+          'Authorization',
+          `Bearer ${createJWT(testRealm, 'mary', ['read'])}`,
+        );
+
+      assert.strictEqual(response.status, 200, 'HTTP 200 status');
+      let json = response.body;
+      assert.deepEqual(
+        json,
+        {
+          data: {
+            type: 'mtimes',
+            id: testRealmHref,
+            attributes: {
+              mtimes: expectedMtimes,
+            },
+          },
+        },
+        'mtimes response is correct',
+      );
+    });
+  });
+
   module('permissions requests', function (hooks) {
     setupPermissionedRealm(hooks, {
       mary: ['read', 'write', 'realm-owner'],
diff --git a/packages/runtime-common/realm.ts b/packages/runtime-common/realm.ts
index f93bf128f2..8d9c6768ad 100644
--- a/packages/runtime-common/realm.ts
+++ b/packages/runtime-common/realm.ts
@@ -349,6 +349,7 @@ export class Realm {
         this.patchCard.bind(this),
       )
       .get('/_info', SupportedMimeType.RealmInfo, this.realmInfo.bind(this))
+      .get('/_mtimes', SupportedMimeType.Mtimes, this.realmMtimes.bind(this))
       .get('/_search', SupportedMimeType.CardJson, this.search.bind(this))
       .get(
         '/_search-prerendered',
@@ -1654,6 +1655,57 @@ export class Realm {
     });
   }
 
+  private async realmMtimes(
+    _request: Request,
+    requestContext: RequestContext,
+  ): Promise<Response> {
+    let mtimes: { [path: string]: number } = {};
+    let traverse = async (currentPath = '') => {
+      const entries = this.#adapter.readdir(currentPath);
+
+      for await (const entry of entries) {
+        let innerPath = join(currentPath, entry.name);
+        let innerURL =
+          entry.kind === 'directory'
+            ? this.paths.directoryURL(innerPath)
+            : this.paths.fileURL(innerPath);
+        if (await this.isIgnored(innerURL)) {
+          continue;
+        }
+        if (entry.kind === 'directory') {
+          await traverse(innerPath);
+        } else if (entry.kind === 'file') {
+          let mtime = await this.#adapter.lastModified(innerPath);
+          if (mtime != null) {
+            mtimes[innerURL.href] = mtime;
+          }
+        }
+      }
+    };
+
+    await traverse();
+
+    return createResponse({
+      body: JSON.stringify(
+        {
+          data: {
+            id: this.url,
+            type: 'mtimes',
+            attributes: {
+              mtimes,
+            },
+          },
+        },
+        null,
+        2,
+      ),
+      init: {
+        headers: { 'content-type': SupportedMimeType.Mtimes },
+      },
+      requestContext,
+    });
+  }
+
   private async getRealmPermissions(
     _request: Request,
     requestContext: RequestContext,
diff --git a/packages/runtime-common/router.ts b/packages/runtime-common/router.ts
index dbc47276ab..68aa62aacd 100644
--- a/packages/runtime-common/router.ts
+++ b/packages/runtime-common/router.ts
@@ -21,6 +21,7 @@ export enum SupportedMimeType {
   CardSource = 'application/vnd.card+source',
   DirectoryListing = 'application/vnd.api+json',
   RealmInfo = 'application/vnd.api+json',
+  Mtimes = 'application/vnd.api+json',
   Permissions = 'application/vnd.api+json',
   Session = 'application/json',
   EventStream = 'text/event-stream',
diff --git a/packages/runtime-common/worker.ts b/packages/runtime-common/worker.ts
index c93445d571..767bacfbb1 100644
--- a/packages/runtime-common/worker.ts
+++ b/packages/runtime-common/worker.ts
@@ -15,7 +15,6 @@ import {
   type QueueRunner,
   type TextFileRef,
   type VirtualNetwork,
-  type Relationship,
   type ResponseWithNodeStream,
 } from '.';
 import { MatrixClient } from './matrix-client';
@@ -36,11 +35,7 @@ export interface IndexResults {
 
 export interface Reader {
   readFile: (url: URL) => Promise<TextFileRef | undefined>;
-  directoryListing: (
-    url: URL,
-  ) => Promise<
-    { kind: 'directory' | 'file'; url: string; lastModified: number | null }[]
-  >;
+  mtimes: () => Promise<{ [url: string]: number }>;
 }
 
 export type RunnerRegistration = (
@@ -342,29 +337,20 @@ export function getReader(
       };
     },
 
-    directoryListing: async (url: URL) => {
-      let response = await _fetch(url, {
+    mtimes: async () => {
+      let response = await _fetch(`${realmURL.href}_mtimes`, {
         headers: {
-          Accept: SupportedMimeType.DirectoryListing,
+          Accept: SupportedMimeType.Mtimes,
         },
       });
       let {
-        data: { relationships: _relationships },
-      } = await response.json();
-      let relationships = _relationships as Record<string, Relationship>;
-      return Object.values(relationships).map((entry) =>
-        entry.meta!.kind === 'file'
-          ? {
-              url: entry.links.related!,
-              kind: 'file',
-              lastModified: (entry.meta?.lastModified ?? null) as number | null,
-            }
-          : {
-              url: entry.links.related!,
-              kind: 'directory',
-              lastModified: null,
-            },
-      );
+        data: {
+          attributes: { mtimes },
+        },
+      } = (await response.json()) as {
+        data: { attributes: { mtimes: { [url: string]: number } } };
+      };
+      return mtimes;
     },
   };
 }