From c05f9e3d42a4498ba3f39ba27a44a6af9512ad7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriele=20Vigan=C3=B2?= Date: Tue, 27 Oct 2026 16:32:45 +0000 Subject: [PATCH 1/2] feat(join): restore Figma's rhythm and drop the extra path cards on /join - Same container, section titles and copy style as the other refined pages; copy is left-aligned at every width instead of centred on mobile. - The three "ways in" cards (not in Figma) are gone: the intro paragraph that already lists them now links to their sections. - Section spacing grows on large screens (224px from xl, 288px from 2xl), so the 1728px title positions sit within ~6% of Figma instead of -18%. - Team cards link to their team on /team and are the only cards that react to hover; InfoCard gains an optional href for this. - The members photo uses object-cover anchored to the bottom instead of Figma's percentage offsets, so the crop survives a different photo or box. - Mobile: the admin-task carousel runs to the screen edges so the next card peeks in; membership step titles are 20px and their notes 14px. Co-Authored-By: Claude Opus 5.5 --- src/app/join/page.tsx | 5 +-- src/components/collabora/info-card.tsx | 24 ++++++++++--- src/components/join/admin.tsx | 14 ++++---- src/components/join/cards.tsx | 5 +-- src/components/join/constants.ts | 4 +++ src/components/join/introduction.tsx | 48 ++++++++++++-------------- src/components/join/membership.tsx | 27 +++++++-------- src/components/join/teams.tsx | 15 ++++---- 8 files changed, 78 insertions(+), 64 deletions(-) diff --git a/src/app/join/page.tsx b/src/app/join/page.tsx index c22fc5c4..04c84c41 100644 --- a/src/app/join/page.tsx +++ b/src/app/join/page.tsx @@ -3,6 +3,7 @@ import { AdminSection } from "@/components/join/admin" import { Introduction } from "@/components/join/introduction" import { MembershipSection } from "@/components/join/membership" import { TeamsSection } from "@/components/join/teams" +import { CONTAINER } from "@/components/layout/page" import { Hero } from "@/components/ui/hero" export const metadata: Metadata = { @@ -13,8 +14,8 @@ export const metadata: Metadata = { export default function JoinPage() { return ( -
-
+
+
-
+ a:focus-visible]:ring-2 has-[>a:focus-visible]:ring-blue-secondary", + className + )} + > + {href && } + {href && } + {/* Positioned so the text stays above the hover background */} +
@@ -44,11 +58,11 @@ export function InfoCard({
{mobileDescription !== undefined && ( -

{mobileDescription}

+

{mobileDescription}

)}

+

-
- Diventa Admin -
+
+

Diventa Admin

+

Un admin è la presenza di PoliNetwork nei gruppi ogni giorno.

Non servono competenze specifiche ma solamente{" "} @@ -33,7 +33,7 @@ export function AdminSection() {

-

+

Ti interessano questi compiti?

    diff --git a/src/components/join/cards.tsx b/src/components/join/cards.tsx index 59c2a953..3e89da3c 100644 --- a/src/components/join/cards.tsx +++ b/src/components/join/cards.tsx @@ -17,9 +17,10 @@ export function JoinCards({ cards, carousel = false }: { cards: InfoCardData[]; return ( - + {cards.map((card) => ( diff --git a/src/components/join/constants.ts b/src/components/join/constants.ts index 469ccd83..c5f262fb 100644 --- a/src/components/join/constants.ts +++ b/src/components/join/constants.ts @@ -60,24 +60,28 @@ export const adminSteps: InfoCardData[] = [ export const teamCards: InfoCardData[] = [ { title: "Sviluppo Tecnico", + href: "/team#it", description: "Realizza prodotti digitali in produzione, usati da migliaia di persone", icon: code, iconClassName, }, { title: "Comunicazione", + href: "/team#design-marketing", description: "Gestisce la comunicazione e l’identità visiva dell’associazione: Instagram, grafiche di eventi…", icon: palette, iconClassName, }, { title: "Gestione HR", + href: "/team#hr", description: "Struttura i processi di recruiting e onboarding e gestisce i volontari del network", icon: hr, iconClassName, }, { title: "Eventi/Partnership", + href: "/team#events-partnership", description: "Organizza eventi e costruisce collaborazioni con aziende e associazioni esterne", icon: events, iconClassName, diff --git a/src/components/join/introduction.tsx b/src/components/join/introduction.tsx index e49057a4..b2d7ad75 100644 --- a/src/components/join/introduction.tsx +++ b/src/components/join/introduction.tsx @@ -1,23 +1,29 @@ import Image from "next/image" -import { FiMessageCircle, FiUserCheck, FiUsers } from "react-icons/fi" +import type { ReactNode } from "react" import networkLogo from "@/assets/images/join/network-logo.png" -import { CardIcon } from "@/components/card-icon" -import { Highlight, SectionTitle } from "@/components/collabora/section" -import { SECTION_LEAD } from "@/components/layout/page" +import { Highlight } from "@/components/collabora/section" +import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page" import { cn } from "@/lib/utils" -const paths = [ - { title: "Diventa Admin", icon: FiMessageCircle, href: "#admin" }, - { title: "Entra in un Team", icon: FiUsers, href: "#team" }, - { title: "Diventa Socio", icon: FiUserCheck, href: "#socio" }, -] +function SectionLink({ href, children }: { href: string; children: ReactNode }) { + return ( + + {children} + + ) +} export function Introduction() { return ( -
    -
    - Cosa significa far parte di PoliNetwork -
    +
    +
    +

    Cosa significa far parte di PoliNetwork

    +

    PoliNetwork è gestita interamente da studenti del Politecnico di Milano.

    @@ -33,23 +39,15 @@ export function Introduction() { tipo di esperienza che spesso si cerca dopo la laurea, ma che qui è disponibile durante.

    + {/* The three ways are already listed here: they jump to their sections, instead of a row of extra cards */}

    - Ci sono tre modi per fare parte di PoliNetwork: diventare admin, entrare in uno dei team operativi o - diventare socio. + Ci sono tre modi per fare parte di PoliNetwork: diventare admin,{" "} + entrare in uno dei team operativi o{" "} + diventare socio.

    -
      - {paths.map((path) => ( -
    • - -
    • - ))} -
    ) } diff --git a/src/components/join/membership.tsx b/src/components/join/membership.tsx index ecec0b21..bcfc5ac7 100644 --- a/src/components/join/membership.tsx +++ b/src/components/join/membership.tsx @@ -1,24 +1,21 @@ import Image from "next/image" import externalLink from "@/assets/icons/join/external-link.svg" import membersPhoto from "@/assets/images/join/members.webp" -import { Highlight, SectionTitle } from "@/components/collabora/section" -import { SECTION_LEAD } from "@/components/layout/page" +import { Highlight } from "@/components/collabora/section" +import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page" import { PhotoShapes } from "@/components/shapes" import { cn } from "@/lib/utils" import { membershipSteps } from "./constants" export function MembershipSection() { return ( -
    -
    - +
    +
    +

    Diventa Socio Diventa Socio di PoliNetwork - -
    +

    +

    Il tesseramento è il modo per fare parte di PoliNetwork in modo formale, con{" "} diritto di voto nelle Assemblee dei Soci, di candidarsi alle elezioni del direttivo e{" "} @@ -44,7 +41,7 @@ export function MembershipSection() {

    -
    - Entra in un Team -
    +
    +
    +

    Entra in un Team

    +

    Entrare in un team significa avere un ruolo operativo con deliverable reali, non essere osservatori di un progetto altrui. From c998509c352112a60b13d80aee9499fc13636c75 Mon Sep 17 00:00:00 2001 From: Bianca Roberta Ianosel Date: Mon, 2 Nov 2026 09:24:51 +0000 Subject: [PATCH 2/2] refactor(join): one inline-link style with a visible focus ring INLINE_LINK replaces the SectionLink component, whose focus state was only a thicker underline. The membership step links get the same ring. --- src/components/join/introduction.tsx | 31 +++++++++++++--------------- src/components/join/membership.tsx | 2 +- src/components/layout/page.ts | 4 ++++ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/components/join/introduction.tsx b/src/components/join/introduction.tsx index b2d7ad75..71aa648c 100644 --- a/src/components/join/introduction.tsx +++ b/src/components/join/introduction.tsx @@ -1,21 +1,9 @@ import Image from "next/image" -import type { ReactNode } from "react" import networkLogo from "@/assets/images/join/network-logo.png" import { Highlight } from "@/components/collabora/section" -import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page" +import { CONTAINER, INLINE_LINK, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page" import { cn } from "@/lib/utils" -function SectionLink({ href, children }: { href: string; children: ReactNode }) { - return ( - - {children} - - ) -} - export function Introduction() { return (

    - {/* The three ways are already listed here: they jump to their sections, instead of a row of extra cards */}

    - Ci sono tre modi per fare parte di PoliNetwork: diventare admin,{" "} - entrare in uno dei team operativi o{" "} - diventare socio. + Ci sono tre modi per fare parte di PoliNetwork:{" "} + + diventare admin + + ,{" "} + + entrare in uno dei team operativi + {" "} + o{" "} + + diventare socio + + .

    diff --git a/src/components/join/membership.tsx b/src/components/join/membership.tsx index bcfc5ac7..0e1a8f25 100644 --- a/src/components/join/membership.tsx +++ b/src/components/join/membership.tsx @@ -47,7 +47,7 @@ export function MembershipSection() { href={step.href} target={step.href.startsWith("https:") ? "_blank" : undefined} rel={step.href.startsWith("https:") ? "noopener noreferrer" : undefined} - className="decoration-1 underline-offset-4 hover:underline focus-visible:underline" + className="rounded-sm decoration-1 underline-offset-4 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-blue-secondary" > {step.title} {step.href.startsWith("https:") && ( diff --git a/src/components/layout/page.ts b/src/components/layout/page.ts index 1070c10c..a725375a 100644 --- a/src/components/layout/page.ts +++ b/src/components/layout/page.ts @@ -6,3 +6,7 @@ export const SECTION_TITLE = "typo-headline-medium sm:typo-display-medium text-balance bg-linear-to-b from-text-primary to-text-secondary bg-clip-text text-transparent" export const SECTION_LEAD = "typo-body-large sm:typo-headline-extrasmall text-pretty" + +/** A link inside running text: always underlined, so it reads as a link without relying on colour. */ +export const INLINE_LINK = + "rounded-sm text-blue-secondary underline decoration-1 decoration-blue-secondary/40 underline-offset-4 outline-none transition-colors hover:decoration-blue-secondary focus-visible:ring-2 focus-visible:ring-blue-secondary"