diff --git a/frontend/editor/src/portal/components/pipelines/PipelineTemplateCard.css b/frontend/editor/src/portal/components/pipelines/PipelineTemplateCard.css
index 167c409c7d..b8dd8bb13a 100644
--- a/frontend/editor/src/portal/components/pipelines/PipelineTemplateCard.css
+++ b/frontend/editor/src/portal/components/pipelines/PipelineTemplateCard.css
@@ -3,7 +3,7 @@
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
- height: 100%;
+ height: 12rem;
}
.portal-pipelines__template-card--locked {
@@ -36,12 +36,22 @@
}
.portal-pipelines__template-blurb {
- /* Push the CTA to the card foot so cards in a row line their footers up. */
- flex: 1;
margin: 0;
font-size: 0.8125rem;
line-height: 1.45;
color: var(--c-text-subtle);
+ /* Clamp long descriptions to three lines with a trailing ellipsis. Note: no flex-grow here -
+ stretching the box defeats -webkit-line-clamp and makes it hard-clip mid-word instead. */
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 3;
+}
+
+/* Pin whatever ends the card (the "Set up" link or a locked/coming-soon chip) to the card foot,
+ so footers line up across cards without flex-growing the clamped blurb above. */
+.portal-pipelines__template-card > :last-child {
+ margin-top: auto;
}
.portal-pipelines__template-cta {
diff --git a/frontend/editor/src/portal/views/Pipelines.css b/frontend/editor/src/portal/views/Pipelines.css
index 89c8bb269a..df407a8a8d 100644
--- a/frontend/editor/src/portal/views/Pipelines.css
+++ b/frontend/editor/src/portal/views/Pipelines.css
@@ -39,11 +39,20 @@
gap: 0.75rem;
}
-/* Template gallery: a responsive row of cards that wraps to fit. */
-.portal-pipelines__templates-grid {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+/* Template gallery: a single row of cards that scrolls sideways rather than wrapping. */
+.portal-pipelines__templates-scroll {
+ display: flex;
+ flex-wrap: nowrap;
gap: 0.75rem;
+ overflow-x: auto;
+ /* A real horizontal scroller: keep the bounce, but don't chain to the browser's back gesture. */
+ overscroll-behavior-x: contain;
+ /* Room for the scrollbar so it doesn't sit under the last row of card text. */
+ padding-bottom: 0.25rem;
+}
+
+.portal-pipelines__templates-scroll > * {
+ flex: 0 0 16rem;
}
.portal-pipelines__section-title {
diff --git a/frontend/editor/src/portal/views/Pipelines.tsx b/frontend/editor/src/portal/views/Pipelines.tsx
index 76d049ee0f..51d77180c4 100644
--- a/frontend/editor/src/portal/views/Pipelines.tsx
+++ b/frontend/editor/src/portal/views/Pipelines.tsx
@@ -258,28 +258,6 @@ export function Pipelines() {
{pageError && }
- {galleryEntries.length > 0 && (
-
-
- {t("portal.pipelines.templates.title")}
-
-
- {t("portal.pipelines.templates.subtitle")}
-
-
- {galleryEntries.map((entry) => (
-
- ))}
-
-
- )}
-
{t("portal.pipelines.all.title")}
@@ -323,6 +301,28 @@ export function Pipelines() {
)}