feat(web): restyle partner sections

This commit is contained in:
2026-10-07 11:33:10 +02:00
parent 847a7d733d
commit 2b3ffcf19e
2 changed files with 52 additions and 40 deletions
+31 -28
View File
@@ -10,8 +10,8 @@
Facts a four-cell seam grid: the run, the coverage, the lead Facts a four-cell seam grid: the run, the coverage, the lead
partner and the funder. partner and the funder.
Nationwide the approved body prose beside the three focus areas. Nationwide the approved body prose beside the three focus areas.
Consortium the three members as role / name / deliverable panels, under Consortium unboxed rows for the three members.
a header row that carries the EU funding line. The header carries the EU funding line.
Legacy the SHARP I and II panel with the accent start-edge, and the Legacy the SHARP I and II panel with the accent start-edge, and the
call to action into What We Do. call to action into What We Do.
@@ -157,7 +157,7 @@ const ACCENT_EDGE =
interface ConsortiumMember { interface ConsortiumMember {
id: string; id: string;
name: string; name: string;
/** The role chip - `consortium.role` in the CMS, or the bundled copy's. */ /** The role label - `consortium.role` in the CMS, or the bundled copy's. */
role: string | null; role: string | null;
description: string; description: string;
website: string | null; website: string | null;
@@ -301,33 +301,36 @@ export default function About({ loaderData }: Route.ComponentProps) {
</p> </p>
</div> </div>
<ul className="grid list-none grid-cols-1 gap-lg md:grid-cols-3"> <ul className="list-none divide-y divide-[var(--border-subtle)] border-y border-[var(--border-subtle)]">
{consortium.map((member) => ( {consortium.map((member) => (
<li key={member.id}> <li
<InfoPanel key={member.id}
/* On the sunken band the draft lifts these cards to the className="sh-reveal sh-reveal--in grid grid-cols-1 gap-md py-lg md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)] md:gap-xl"
raised dark it uses for a page band (#1d1d1b), one step >
lighter than the panel shade InfoPanel defaults to. The <div className="flex flex-col gap-xs">
`!` is what makes the override beat the component's own {member.role ? (
`bg-*` utility, which sorts after this one. */ <p className="label-md uppercase text-[var(--text-accent)]">
className="sh-lift sh-reveal sh-reveal--in hover:border-[var(--border-accent)]" {member.role}
title={member.name} </p>
{...(member.role
? { eyebrow: member.role, eyebrowVariant: "chip" as const }
: {})}
>
<span className="block">{member.description}</span>
{member.website ? (
<a
href={member.website}
target="_blank"
rel="noopener noreferrer"
className="mt-xs inline-block body-sm-bold text-[var(--text-link)] underline underline-offset-2 hover:text-[var(--text-link-hover)]"
>
{member.name}
</a>
) : null} ) : null}
</InfoPanel> <h3 className="heading-h3 text-[var(--text-primary)]">
{member.website ? (
<a
href={member.website}
target="_blank"
rel="noopener noreferrer"
className="text-[var(--text-link)] underline underline-offset-2 hover:text-[var(--text-link-hover)]"
>
{member.name}
</a>
) : (
member.name
)}
</h3>
</div>
<p className="body-md text-[var(--text-secondary)]">
{member.description}
</p>
</li> </li>
))} ))}
</ul> </ul>
+21 -12
View File
@@ -17,7 +17,7 @@
a link through to What We Do. a link through to What We Do.
Newsroom three cards from the newsroom, newest first. Newsroom three cards from the newsroom, newest first.
FAQs a sticky heading column beside the accordion. FAQs a sticky heading column beside the accordion.
Consortium the three members, then the civil society network logos. Consortium the three members, then the civil society network logos.
WHAT THE DRAFT SHIPS THAT THIS PAGE DOES NOT WHAT THE DRAFT SHIPS THAT THIS PAGE DOES NOT
-------------------------------------------- --------------------------------------------
@@ -141,10 +141,9 @@ const PARTNER_PAGE_SIZE = 36;
/** /**
* Below this many partners the wall stays a grid. * Below this many partners the wall stays a grid.
* *
* The marquee loops by carrying the tiles twice and sliding exactly half the * The loop slides exactly half the track; fewer than eight wider tiles would
* track, which only reads as a loop while the half is wider than the frame it * leave a short drift instead of filling a desktop frame, so the grid keeps
* slides through. Eight 178px tiles clear a desktop container; fewer would * them still.
* drift a short row across an empty band, so the grid keeps them still.
*/ */
const PARTNER_MARQUEE_MIN = 8; const PARTNER_MARQUEE_MIN = 8;
/** The draft's newsroom band is a straight three-up row. */ /** The draft's newsroom band is a straight three-up row. */
@@ -487,10 +486,21 @@ function PartnerTile({
src={partner.logo.src} src={partner.logo.src}
alt={decorative ? "" : partner.name} alt={decorative ? "" : partner.name}
loading="lazy" loading="lazy"
className="max-h-[3.5rem] w-auto max-w-full object-contain" className={cx(
"w-auto max-w-full object-contain",
fixedWidth
? "h-[6.75rem] transition-transform duration-[var(--motion-duration-base)] group-hover:scale-105"
: "max-h-[3.5rem]",
)}
/> />
) : ( ) : (
<span className="body-sm-bold text-center text-[var(--text-secondary)]"> <span
className={cx(
"body-sm-bold text-center text-[var(--text-secondary)]",
fixedWidth &&
"transition-colors duration-[var(--motion-duration-base)] group-hover:text-[var(--text-accent)]",
)}
>
{partner.name} {partner.name}
</span> </span>
); );
@@ -499,17 +509,16 @@ function PartnerTile({
<li <li
{...(decorative ? { "aria-hidden": true } : {})} {...(decorative ? { "aria-hidden": true } : {})}
className={cx( className={cx(
"flex h-[5.5rem] items-center justify-center", "flex items-center justify-center",
"rounded-control border border-[var(--border-subtle)] bg-[var(--surface-card)] p-md", fixedWidth
"transition-colors duration-[var(--motion-duration-base)]", ? "group me-lg h-[7.5rem] w-[12.5rem] shrink-0 ps-lg pe-lg"
"hover:border-[var(--border-accent)]", : "h-[5.5rem] rounded-control border border-[var(--border-subtle)] bg-[var(--surface-card)] p-md transition-colors duration-[var(--motion-duration-base)] hover:border-[var(--border-accent)] sh-reveal sh-reveal--in",
/* A still grid reveals tile by tile; a travelling track must not, or /* A still grid reveals tile by tile; a travelling track must not, or
each tile would ramp its own opacity while it moves. each tile would ramp its own opacity while it moves.
The track's spacing is a margin on the tile rather than a `gap` on The track's spacing is a margin on the tile rather than a `gap` on
the row: the loop slides exactly half the track, so each half has to the row: the loop slides exactly half the track, so each half has to
carry its own trailing space or the seam lands half a gap short. */ carry its own trailing space or the seam lands half a gap short. */
fixedWidth ? "me-md w-[11.125rem] shrink-0" : "sh-reveal sh-reveal--in",
decorative && "sh-marquee__clone", decorative && "sh-marquee__clone",
)} )}
> >