Styling improvements

This commit is contained in:
James Brunton
2026-08-27 11:38:50 +01:00
parent a3857a77bc
commit a4434284d8
3 changed files with 48 additions and 29 deletions
@@ -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 {
+13 -4
View File
@@ -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 {
+22 -22
View File
@@ -258,28 +258,6 @@ export function Pipelines() {
{pageError && <Banner tone="danger" description={pageError} />}
{galleryEntries.length > 0 && (
<section className="portal-pipelines__templates">
<h2 className="portal-pipelines__section-title">
{t("portal.pipelines.templates.title")}
</h2>
<p className="portal-pipelines__section-sub">
{t("portal.pipelines.templates.subtitle")}
</p>
<div className="portal-pipelines__templates-grid">
{galleryEntries.map((entry) => (
<PipelineTemplateCard
key={entry.category.id}
entry={entry}
onOpen={openTemplate}
locked={isLocked(entry)}
lockedLabel={t("portal.policies.card.requiresAiEngine")}
/>
))}
</div>
</section>
)}
<section className="portal-pipelines__all">
<h2 className="portal-pipelines__section-title">
{t("portal.pipelines.all.title")}
@@ -323,6 +301,28 @@ export function Pipelines() {
)}
</section>
{galleryEntries.length > 0 && (
<section className="portal-pipelines__templates">
<h2 className="portal-pipelines__section-title">
{t("portal.pipelines.templates.title")}
</h2>
<p className="portal-pipelines__section-sub">
{t("portal.pipelines.templates.subtitle")}
</p>
<div className="portal-pipelines__templates-scroll">
{galleryEntries.map((entry) => (
<PipelineTemplateCard
key={entry.category.id}
entry={entry}
onOpen={openTemplate}
locked={isLocked(entry)}
lockedLabel={t("portal.policies.card.requiresAiEngine")}
/>
))}
</div>
</section>
)}
<PolicyDetailPanel
policy={detail?.policy ?? null}
busy={busy}