diff --git a/landing/competitor-comparison.css b/landing/competitor-comparison.css
--- a/landing/competitor-comparison.css
+++ b/landing/competitor-comparison.css
@@ -53,3 +53,24 @@
   position: absolute;
   bottom: -16px;
 }
+
+.featureCardsContainer {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 40px;
+  margin-top: 48px;
+}
+
+/* 2*16(padding) + 3*432(cards) + 2*40(gap) */
+@media screen and (max-width: 1408px) {
+  .featureCardsContainer {
+    grid-template-columns: repeat(2, 1fr);
+  }
+}
+
+/* 2*16(padding) + 2*432(cards) + 40(gap) */
+@media screen and (max-width: 936px) {
+  .featureCardsContainer {
+    grid-template-columns: repeat(1, 1fr);
+  }
+}
diff --git a/landing/competitor-comparison.react.js b/landing/competitor-comparison.react.js
--- a/landing/competitor-comparison.react.js
+++ b/landing/competitor-comparison.react.js
@@ -3,8 +3,17 @@
 import classNames from 'classnames';
 import * as React from 'react';
 
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+
 import css from './competitor-comparison.css';
+import {
+  competitorData,
+  type Competitor,
+  type FeatureComparison,
+} from './competitor-data.js';
+import CompetitorFeatureCard from './competitor-feature-card.react.js';
 import CompetitorLogo from './competitor-logo.react.js';
+import FeatureModal from './feature-modal.react.js';
 import typography from './typography.css';
 
 const competitors = [
@@ -17,9 +26,18 @@
 ];
 
 function CompetitorComparison(): React.Node {
+  const { pushModal } = useModalContext();
+
   const [selectedCompetitorID, setSelectedCompetitorID] =
     React.useState<string>('signal');
 
+  const onFeatureCardClick = React.useCallback(
+    (competitor: Competitor, feature: FeatureComparison) => {
+      pushModal(<FeatureModal competitor={competitor} feature={feature} />);
+    },
+    [pushModal],
+  );
+
   const competitorSelector = React.useMemo(
     () =>
       competitors.map(competitor => {
@@ -46,12 +64,29 @@
     [selectedCompetitorID],
   );
 
+  const featureCards = React.useMemo(() => {
+    const selectedCompetitor = competitorData[selectedCompetitorID];
+
+    return selectedCompetitor.featureComparison.map(feature => (
+      <CompetitorFeatureCard
+        key={`${selectedCompetitor.id}_${feature.title}`}
+        competitorID={selectedCompetitor.id}
+        title={feature.title}
+        comingSoon={feature.comingSoon}
+        competitorDescription={feature.competitorDescriptionShort}
+        commDescription={feature.commDescriptionShort}
+        onClick={() => onFeatureCardClick(selectedCompetitor, feature)}
+      />
+    ));
+  }, [onFeatureCardClick, selectedCompetitorID]);
+
   const headerClassName = classNames([typography.heading1, css.headerText]);
 
   return (
     <section className={css.competitorComparisonSection}>
       <h1 className={headerClassName}>See how Comm is different</h1>
       <div className={css.competitorsContainer}>{competitorSelector}</div>
+      <div className={css.featureCardsContainer}>{featureCards}</div>
     </section>
   );
 }