diff --git a/libs/design-system/.storybook/assets/logo/antibody-validation-reports.svg b/libs/design-system/.storybook/assets/logo/antibody-validation-reports.svg
new file mode 100644
index 000000000..b2133b0a7
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/antibody-validation-reports.svg
@@ -0,0 +1,9 @@
+
diff --git a/libs/design-system/.storybook/assets/logo/asctb-reporter.svg b/libs/design-system/.storybook/assets/logo/asctb-reporter.svg
new file mode 100644
index 000000000..e9b5b2eb9
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/asctb-reporter.svg
@@ -0,0 +1,21 @@
+
diff --git a/libs/design-system/.storybook/assets/logo/azimuth.svg b/libs/design-system/.storybook/assets/logo/azimuth.svg
new file mode 100644
index 000000000..b6d96a9b6
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/azimuth.svg
@@ -0,0 +1,9 @@
+
diff --git a/libs/design-system/.storybook/assets/logo/data_portal.svg b/libs/design-system/.storybook/assets/logo/data_portal.svg
new file mode 100644
index 000000000..82c37ba96
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/data_portal.svg
@@ -0,0 +1,9 @@
+
diff --git a/libs/design-system/.storybook/assets/logo/eui.svg b/libs/design-system/.storybook/assets/logo/eui.svg
new file mode 100644
index 000000000..e7ecb2aec
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/eui.svg
@@ -0,0 +1,16 @@
+
diff --git a/libs/design-system/.storybook/assets/logo/fusion.svg b/libs/design-system/.storybook/assets/logo/fusion.svg
new file mode 100644
index 000000000..d417eabb2
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/fusion.svg
@@ -0,0 +1,9 @@
+
diff --git a/libs/design-system/.storybook/assets/logo/hubmap.svg b/libs/design-system/.storybook/assets/logo/hubmap.svg
new file mode 100644
index 000000000..95aa95d2f
--- /dev/null
+++ b/libs/design-system/.storybook/assets/logo/hubmap.svg
@@ -0,0 +1,9 @@
+
diff --git a/libs/design-system/apps-card/ng-package.json b/libs/design-system/apps-card/ng-package.json
new file mode 100644
index 000000000..c781f0df4
--- /dev/null
+++ b/libs/design-system/apps-card/ng-package.json
@@ -0,0 +1,5 @@
+{
+ "lib": {
+ "entryFile": "src/index.ts"
+ }
+}
diff --git a/libs/design-system/apps-card/src/index.ts b/libs/design-system/apps-card/src/index.ts
new file mode 100644
index 000000000..04b8aae5b
--- /dev/null
+++ b/libs/design-system/apps-card/src/index.ts
@@ -0,0 +1 @@
+export * from './lib/apps-card.component';
diff --git a/libs/design-system/apps-card/src/lib/apps-card.component.html b/libs/design-system/apps-card/src/lib/apps-card.component.html
new file mode 100644
index 000000000..471353b33
--- /dev/null
+++ b/libs/design-system/apps-card/src/lib/apps-card.component.html
@@ -0,0 +1,5 @@
+
+
+ {{ title() }}
+ {{ description() }}
+
diff --git a/libs/design-system/apps-card/src/lib/apps-card.component.scss b/libs/design-system/apps-card/src/lib/apps-card.component.scss
new file mode 100644
index 000000000..d8dffbcf9
--- /dev/null
+++ b/libs/design-system/apps-card/src/lib/apps-card.component.scss
@@ -0,0 +1,41 @@
+:host {
+ a {
+ display: grid;
+ grid-template-areas: 'icon title' 'icon description';
+ grid-template-columns: min-content auto;
+ column-gap: 1rem;
+ border-radius: 0.5rem;
+ max-width: 38rem;
+ align-items: center;
+ padding: 0.5rem;
+
+ &:hover {
+ background: rgb(from var(--sys-secondary) r g b / 0.04);
+ }
+
+ &:active {
+ background: rgb(from var(--sys-secondary) r g b / 0.08);
+ }
+
+ &:focus-visible {
+ outline: solid var(--sys-tertiary) 2px;
+ }
+
+ .icon {
+ grid-area: icon;
+ height: 3.5rem;
+ width: 3.5rem;
+ }
+
+ .title {
+ font: var(--sys-label-large);
+ color: var(--sys-secondary);
+ }
+
+ .description {
+ grid-area: description;
+ font: var(--sys-label-medium);
+ color: var(--sys-inverse-surface);
+ }
+ }
+}
diff --git a/libs/design-system/apps-card/src/lib/apps-card.component.spec.ts b/libs/design-system/apps-card/src/lib/apps-card.component.spec.ts
new file mode 100644
index 000000000..89f83418a
--- /dev/null
+++ b/libs/design-system/apps-card/src/lib/apps-card.component.spec.ts
@@ -0,0 +1,25 @@
+import { render, screen } from '@testing-library/angular';
+import { AppsCardComponent } from './apps-card.component';
+
+describe('AppsCardComponent', () => {
+ beforeEach(async () => {
+ await render(AppsCardComponent, {
+ componentInputs: {
+ icon: 'test.svg',
+ title: 'Test Title',
+ description: 'Test Description',
+ link: 'https://www.example.com',
+ },
+ });
+ });
+
+ it('should create and render the card', async () => {
+ const cardLink = screen.getByRole('link');
+ const cardImage = screen.getByRole('img');
+ expect(cardImage.getAttribute('alt')).toBe('Test Title Icon');
+ expect(cardImage.getAttribute('src')).toBe('test.svg');
+ expect(screen.getByText('Test Title')).toBeInTheDocument();
+ expect(screen.getByText('Test Description')).toBeInTheDocument();
+ expect(cardLink.getAttribute('href')).toBe('https://www.example.com');
+ });
+});
diff --git a/libs/design-system/apps-card/src/lib/apps-card.component.stories.ts b/libs/design-system/apps-card/src/lib/apps-card.component.stories.ts
new file mode 100644
index 000000000..9a4212d9d
--- /dev/null
+++ b/libs/design-system/apps-card/src/lib/apps-card.component.stories.ts
@@ -0,0 +1,94 @@
+import type { Meta, StoryObj } from '@storybook/angular';
+import { AppsCardComponent } from './apps-card.component';
+
+const apps: Record = {
+ 'HuBMAP Consortium': {
+ icon: 'assets/logo/hubmap.svg',
+ title: 'HuBMAP Consortium',
+ description:
+ 'HuBMAP all access: Learn about us, our policies, data, and tools. Explore our publications and how to work with us.',
+ link: 'https://hubmapconsortium.org/',
+ },
+ 'HubMAP Data Portal': {
+ icon: 'assets/logo/data_portal.svg',
+ title: 'HuBMAP Data Portal',
+ description:
+ 'Explore, visualize and download consortium-generated spatial and single cell data for the human body.',
+ link: 'https://portal.hubmapconsortium.org/',
+ },
+ 'Data Portal Workspaces': {
+ icon: 'assets/logo/data_portal.svg',
+ title: 'Data Portal Workspaces',
+ description:
+ 'Access HuBMAP data in a lightweight exploration platform and perform analyses directly within the portal.',
+ link: 'https://portal.hubmapconsortium.org/workspaces',
+ },
+ 'Human Reference Atlas': {
+ icon: 'assets/logo/hra_small.svg',
+ title: 'Human Reference Atlas',
+ description:
+ 'Use the HRA Portal to access atlas data, explore atlas functionality, and contribute to the Human Reference Atlas.',
+ link: 'https://humanatlas.io/',
+ },
+ 'Exploration User Interface': {
+ icon: 'assets/logo/eui.svg',
+ title: 'Exploration User Interface',
+ description: 'Explore and validate spatially registered single-cell datasets in three-dimensions across organs.',
+ link: 'https://apps.humanatlas.io/eui/',
+ },
+ 'ASCT+B Reporter': {
+ icon: 'assets/logo/asctb-reporter.svg',
+ title: 'ASCT+B Reporter',
+ description:
+ 'Explore and compare ASCT+B tables and construct validated panels for multiplexed antibody-based imaging (OMAPs) tables.',
+ link: 'https://hubmapconsortium.github.io/ccf-asct-reporter/',
+ },
+ Azimuth: {
+ icon: 'assets/logo/azimuth.svg',
+ title: 'Azimuth',
+ description:
+ 'Azimuth uses a reference dataset to process, analyze, and interpret single-cell RNA-seq or ATAC-seq experiments.',
+ link: 'https://azimuth.hubmapconsortium.org/',
+ },
+ FUSION: {
+ icon: 'assets/logo/fusion.svg',
+ title: 'FUSION',
+ description: 'Functional Unit State Identification and Navigation with WSI.',
+ link: 'http://fusion.hubmapconsortium.org/?utm_source=hubmap',
+ },
+ 'Antibody Validation Reports': {
+ icon: 'assets/logo/antibody-validation-reports.svg',
+ title: 'Antibody Validation Reports',
+ description:
+ 'Provide antibody details for multiplex imaging assays and capture data requested by journals for manuscript submission.',
+ link: 'https://avr.hubmapconsortium.org/',
+ },
+};
+
+const meta: Meta = {
+ component: AppsCardComponent,
+ title: 'AppsCardComponent',
+ parameters: {
+ design: {
+ type: 'figma',
+ url: 'https://www.figma.com/design/BCEJn9KCIbBJ5MzqnojKQp/Design-System-Components?node-id=78-355',
+ },
+ },
+ argTypes: {
+ app: {
+ control: 'select',
+ options: Object.keys(apps),
+ mapping: apps,
+ },
+ },
+ args: {
+ app: apps['HuBMAP Consortium'],
+ },
+ render: (args) => ({
+ props: args['app'],
+ }),
+};
+export default meta;
+type Story = StoryObj;
+
+export const Primary: Story = {};
diff --git a/libs/design-system/apps-card/src/lib/apps-card.component.ts b/libs/design-system/apps-card/src/lib/apps-card.component.ts
new file mode 100644
index 000000000..db9c129df
--- /dev/null
+++ b/libs/design-system/apps-card/src/lib/apps-card.component.ts
@@ -0,0 +1,22 @@
+import { ChangeDetectionStrategy, Component, input } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+/** Apps Card Component */
+@Component({
+ selector: 'hra-apps-card',
+ standalone: true,
+ imports: [CommonModule],
+ templateUrl: './apps-card.component.html',
+ styleUrl: './apps-card.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class AppsCardComponent {
+ /** URL for the icon */
+ readonly icon = input.required();
+ /** Title of the card */
+ readonly title = input.required();
+ /** Description of the card */
+ readonly description = input.required();
+ /** Link of the card */
+ readonly link = input.required();
+}
diff --git a/libs/design-system/styles/_light-theme.scss b/libs/design-system/styles/_light-theme.scss
index a422581ce..58a6cc137 100644
--- a/libs/design-system/styles/_light-theme.scss
+++ b/libs/design-system/styles/_light-theme.scss
@@ -60,7 +60,7 @@ $_palettes: (
neutral: (
0: #201e3d,
10: #201e3d,
- 20: #4c4c58,
+ 20: #4b4b5e,
25: #3c3b3b,
30: #484646,
35: #535252,