From 0c988da6b9ba48b2af12e850549fc43c8662b998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriele=20Vigan=C3=B2?= Date: Tue, 27 Oct 2026 15:44:26 +0000 Subject: [PATCH 1/2] feat(storia): de-cardify the history page and align it with Figma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Hero: Figma's centred XL title (fluid) with the two anchor actions; the rotated portrait collage and floating "200+" chip are gone (the board portraits already appear under "I nostri direttivi"). - "Come è nato tutto": the two 2016/2022 cards that repeated the timeline right below are removed; the text stands alone until the archive photo Figma reserves exists. - Timeline: nodes on a line (vertical below lg, horizontal from lg) instead of four hoverable glass cards; the year is the link to its chapter. - Chapters: numeral in the margin and one continuous vertical rule across all six; diagrams drawn without containers (icon chains, 5 → ~25 → 4, before → after columns, status list) instead of stacks of glass cards. - No hover on things that are not links (board portraits, the closing statement); "L'obiettivo è raggiunto" is a statement, not a card. - Projects note, thanks list, board summary and "La storia continua" lose their glass panels; the closing gradient panel and the filled "?" pill (which read as a button) become years on a line with an open slot. - One container for every section (Figma's 1272px column, 24/40/64px gutters) and left alignment at every width for this long reading page. Co-Authored-By: Claude Opus 5.5 --- src/app/storia/page.tsx | 75 +++---- src/components/storia/boards.tsx | 11 +- src/components/storia/constants.ts | 3 + src/components/storia/continuation.tsx | 93 ++++---- src/components/storia/hero.tsx | 88 ++------ src/components/storia/organization.tsx | 3 +- src/components/storia/projects.tsx | 35 ++-- src/components/storia/thanks.tsx | 15 +- src/components/storia/timeline.tsx | 280 ++++++++++++++----------- 9 files changed, 287 insertions(+), 316 deletions(-) diff --git a/src/app/storia/page.tsx b/src/app/storia/page.tsx index dc4fc1cf..a5b8d544 100644 --- a/src/app/storia/page.tsx +++ b/src/app/storia/page.tsx @@ -1,10 +1,9 @@ import type { Metadata } from "next" -import { FiMessageCircle, FiUserCheck } from "react-icons/fi" -import telegram from "@/assets/icons/telegram-gradient.svg" -import { CardCaption } from "@/components/card-caption" -import { CardIcon } from "@/components/card-icon" +import { FiMessageCircle } from "react-icons/fi" +import { GradientIcon } from "@/components/gradient-icon" import TextOnlyLayout from "@/components/layout/TextOnlySection" import { Boards } from "@/components/storia/boards" +import { CONTAINER } from "@/components/storia/constants" import { Continuation } from "@/components/storia/continuation" import { HistoryHero } from "@/components/storia/hero" import { Organization } from "@/components/storia/organization" @@ -20,10 +19,12 @@ export const metadata: Metadata = { export default function HistoryPage() { return ( -
+
-
+
+ {/* Figma reserves the right column for an archive photo that doesn't exist yet: until then the text stands alone. + The two milestone cards that filled it repeated the timeline right below. */} } classNames={{ - section: "mx-auto max-w-330 gap-12 px-6 md:px-6 xl:flex-row xl:items-center [&>div>h2]:typo-title-large", - textDiv: "min-w-0 xl:w-1/2 xl:items-start", - title: "text-balance text-blue-secondary xl:text-start", - descriptionDiv: "xl:text-start", - contentDiv: "min-w-0 xl:w-1/2", + section: `${CONTAINER} items-start [&>div>h2]:typo-title-large`, + textDiv: "max-w-180 items-start", + title: "text-balance text-start text-blue-secondary", + descriptionDiv: "text-start", + contentDiv: "hidden", }} - > -
- - -
-
+ /> @@ -92,25 +74,24 @@ export default function HistoryPage() { } classNames={{ - section: "mx-auto max-w-330 gap-12 px-6 md:px-6 xl:flex-row xl:items-center [&>div>h2]:typo-title-large", - title: "text-balance text-blue-secondary xl:text-start", - textDiv: "min-w-0 xl:w-1/2 xl:items-start", - descriptionDiv: "xl:text-start", + section: `${CONTAINER} gap-12 xl:flex-row xl:items-center xl:gap-16 [&>div>h2]:typo-title-large`, + title: "text-balance text-start text-blue-secondary", + textDiv: "min-w-0 items-start xl:w-1/2", + descriptionDiv: "text-start", contentDiv: "min-w-0 xl:w-1/2", }} > - - Se anche un solo studente ha trovato casa grazie a un nostro gruppo, o si è laureato in tempo perché - qualcuno gli ha risposto. -

- } - className="h-auto w-full gap-6 p-6 sm:p-10" - /> + {/* A closing statement, not a card: nothing here is clickable */} +
+ +

+ L’obiettivo è raggiunto. +

+

+ Se anche un solo studente ha trovato casa grazie a un nostro gruppo, o si è laureato in tempo perché + qualcuno gli ha risposto. +

+
diff --git a/src/components/storia/boards.tsx b/src/components/storia/boards.tsx index 1beca4d5..14e87ccf 100644 --- a/src/components/storia/boards.tsx +++ b/src/components/storia/boards.tsx @@ -1,17 +1,16 @@ "use client" import Image from "next/image" -import { Glass } from "@/components/glass" import TabsNavigation from "@/components/tabs" import { Tabs } from "@/components/tabs/tabs" import { TabsContent } from "@/components/tabs/tabs-content" import { Card, CardContent } from "@/components/ui/card" import { cn } from "@/lib/utils" -import { boardMembers, boardTerms } from "./constants" +import { boardMembers, boardTerms, CONTAINER } from "./constants" export function Boards() { return ( -
+

I nostri direttivi

Ogni mandato, un nuovo capitolo @@ -27,7 +26,7 @@ export function Boards() { {boardMembers.map((member) => (

- +

{term}

Il Direttivo

Si concentra sul rafforzamento della struttura, sull’evoluzione dei servizi e sullo sviluppo di nuovi progetti per la community.

- +
) : (
diff --git a/src/components/storia/constants.ts b/src/components/storia/constants.ts index 78b1325d..dd5eb8c1 100644 --- a/src/components/storia/constants.ts +++ b/src/components/storia/constants.ts @@ -6,6 +6,9 @@ import gabriele from "@/assets/images/storia/gabriele-vigano.jpg" import lorenzo from "@/assets/images/storia/lorenzo-corallo.jpg" import tommaso from "@/assets/images/storia/tommaso-morganti.jpg" +/** Shared section container: Figma's 1272px content column, with the homepage's 24/40/64px gutters (md:px-10 overrides TextOnlyLayout's md:px-36). */ +export const CONTAINER = "mx-auto w-full max-w-350 px-6 sm:px-10 md:px-10 lg:px-16" + // Contenuti del design Figma “La nostra storia”, nodo 5368:5885. export const milestones = [ { diff --git a/src/components/storia/continuation.tsx b/src/components/storia/continuation.tsx index 1b417174..9ce9b04c 100644 --- a/src/components/storia/continuation.tsx +++ b/src/components/storia/continuation.tsx @@ -1,53 +1,60 @@ import Link from "next/link" import { FiArrowUpRight } from "react-icons/fi" -import { Glass } from "@/components/glass" import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" +import { CONTAINER } from "./constants" +const years = ["2016", "2022", "2026", "?"] + +// Figma: text on the left, the years on a line on the right. No panel or gradient behind it, and the "?" is a +// quiet open slot rather than a filled pill that looks like a button. export function Continuation() { return ( -
- -
-

- La storia continua. -

-

- Ogni anno qualcuno arriva, qualcuno si laurea e qualcun altro raccoglie il testimone. La missione rimane la - stessa: rendere la vita universitaria più semplice, accessibile e umana. -

- -
-
-
    - {["2016", "2022", "2026", "?"].map((year) => ( -
  1. - - {year} - -
  2. - ))} -
-

Nuove persone, nuove idee, nuovi progetti.

-

- Il prossimo capitolo lo scriviamo insieme. -

-
-
+
+
+

+ La storia continua. +

+

+ Ogni anno qualcuno arriva, qualcuno si laurea e qualcun altro raccoglie il testimone. Nuove persone, nuove + idee, nuovi progetti. La missione rimane la stessa: rendere la vita universitaria più semplice, accessibile e + umana. +

+
+ +
+
    + {years.map((year, index) => ( +
  1. 0 && "flex-1")}> + {index > 0 && } + + {year} + +
  2. + ))} +
+

+ Il prossimo capitolo lo scriviamo insieme. +

+ +
) } diff --git a/src/components/storia/hero.tsx b/src/components/storia/hero.tsx index 6c260137..d35e2681 100644 --- a/src/components/storia/hero.tsx +++ b/src/components/storia/hero.tsx @@ -1,76 +1,30 @@ -import Image from "next/image" import Link from "next/link" -import { FiArrowDown, FiUsers } from "react-icons/fi" -import { Glass } from "@/components/glass" -import { GradientIcon } from "@/components/gradient-icon" +import { FiArrowDown } from "react-icons/fi" import { Button } from "@/components/ui/button" -import { Card, CardContent } from "@/components/ui/card" import { Hero } from "@/components/ui/hero" -import { cn } from "@/lib/utils" -import { boardMembers } from "./constants" - -const portraits = [ - { member: boardMembers[1], position: "top-12 left-0 -rotate-6" }, - { - member: boardMembers[0], - position: "-translate-x-1/2 top-0 left-1/2 z-10", - }, - { member: boardMembers[3], position: "top-12 right-0 rotate-6 sm:top-16" }, -] +import { CONTAINER } from "./constants" +// Figma: a centred XL title and nothing else. The board portraits appear further down, under "I nostri direttivi". export function HistoryHero() { return ( -
-
- -
- - -
-
-
-
- {portraits.map(({ member, position }) => ( - - {member.name} -
- - {member.role} - - - ))} -
- - -
-

200+

-

admin volontari, oggi

-
-
+
+ +
+ +
) diff --git a/src/components/storia/organization.tsx b/src/components/storia/organization.tsx index 7780ee4c..639068a1 100644 --- a/src/components/storia/organization.tsx +++ b/src/components/storia/organization.tsx @@ -17,6 +17,7 @@ import { GradientIcon } from "@/components/gradient-icon" import { Button } from "@/components/ui/button" import { Card, CardTitle } from "@/components/ui/card" import { cn } from "@/lib/utils" +import { CONTAINER } from "./constants" const teamLeads = [ { title: "Team lead HR", icon: LuBookUser }, @@ -176,7 +177,7 @@ function MobileChart() { export function Organization() { return ( -
+

Come è organizzata PoliNetwork diff --git a/src/components/storia/projects.tsx b/src/components/storia/projects.tsx index ee42bc09..0a5a4019 100644 --- a/src/components/storia/projects.tsx +++ b/src/components/storia/projects.tsx @@ -4,9 +4,9 @@ import { FiAirplay, FiArrowUpRight, FiBarChart, FiBook, FiCheck, FiHeadphones } import telegram from "@/assets/icons/telegram-gradient.svg" import projectsImage from "@/assets/images/storia/progetti.png" import { CardIcon } from "@/components/card-icon" -import { Glass } from "@/components/glass" import TextOnlyLayout from "@/components/layout/TextOnlySection" import { Button } from "@/components/ui/button" +import { CONTAINER } from "./constants" const projects = [ { @@ -35,7 +35,7 @@ const projects = [ export function HistoryProjects() { return ( -
+
div>h2]:typo-title-large", - textDiv: "min-w-0 xl:w-1/2 xl:items-start", - title: "text-blue-secondary xl:text-start", - descriptionDiv: "xl:text-start", + textDiv: "min-w-0 items-start xl:w-1/2", + title: "text-start text-blue-secondary", + descriptionDiv: "text-start", contentDiv: "min-w-0 xl:w-1/2", }} > Il sito PoliNetwork su computer e smartphone -
-
+ {/* Figma: the six tools on the left, the note about where they come from beside them, without a panel */} +
+
{projects.map((project) => ( ))}
- -
-

- Molti dei progetti di PoliNetwork sono nati da idee individuali: studenti che hanno - creato autonomamente uno strumento utile e che, nel tempo, sono entrati a far parte del network. -

-

Da un’idea di uno studente a uno strumento per migliaia di studenti.

-
- -
+
) diff --git a/src/components/storia/thanks.tsx b/src/components/storia/thanks.tsx index faf9b32e..73c6dbdd 100644 --- a/src/components/storia/thanks.tsx +++ b/src/components/storia/thanks.tsx @@ -2,13 +2,12 @@ import { useState } from "react" import { FiSearch } from "react-icons/fi" -import { Glass } from "@/components/glass" import TextOnlyLayout from "@/components/layout/TextOnlySection" import TabsNavigation from "@/components/tabs" import { Tabs } from "@/components/tabs/tabs" import { TabsContent } from "@/components/tabs/tabs-content" import { Input } from "@/components/ui/input" -import { contributors } from "./constants" +import { CONTAINER, contributors } from "./constants" const categories = ["Tutti", "Direttivi", "Admin", "Collaboratori"] @@ -35,14 +34,14 @@ export function Thanks() { } classNames={{ - section: "mx-auto max-w-330 gap-12 px-6 md:px-6 xl:flex-row [&>div>h2]:typo-title-large", - textDiv: "xl:w-1/2 xl:items-start xl:text-start", - title: "text-blue-secondary xl:text-start", - descriptionDiv: "xl:text-start", + section: `${CONTAINER} gap-12 xl:flex-row xl:gap-16 [&>div>h2]:typo-title-large`, + textDiv: "items-start text-start xl:w-1/2", + title: "text-start text-blue-secondary", + descriptionDiv: "text-start", contentDiv: "min-w-0 xl:w-1/2", }} > - +
} @@ -80,7 +79,7 @@ export function Thanks() { ) })} - +
) } diff --git a/src/components/storia/timeline.tsx b/src/components/storia/timeline.tsx index 63b93047..020d3974 100644 --- a/src/components/storia/timeline.tsx +++ b/src/components/storia/timeline.tsx @@ -1,48 +1,70 @@ +import Image from "next/image" import Link from "next/link" -import { - FiArrowDown, - FiCheckCircle, - FiClipboard, - FiClock, - FiLayers, - FiUser, - FiUserCheck, - FiUsers, -} from "react-icons/fi" +import type { ReactNode } from "react" +import { FiArrowDown, FiArrowRight, FiCheck, FiClipboard, FiClock, FiUser, FiUserCheck, FiUsers } from "react-icons/fi" import telegram from "@/assets/icons/telegram-gradient.svg" -import { CardCaption } from "@/components/card-caption" -import { CardIcon } from "@/components/card-icon" -import { Glass } from "@/components/glass" +import { GradientIcon, type GradientIconType } from "@/components/gradient-icon" import { Button } from "@/components/ui/button" -import { chapters, milestones } from "./constants" +import { cn } from "@/lib/utils" +import { CONTAINER, chapters, milestones } from "./constants" const milestoneLinks = ["#capitolo-1", "#capitolo-1", "#capitolo-5", "#direttivi"] const milestoneIcons = [FiUser, telegram.src, FiUserCheck, FiUsers] +/** The small icon tile Figma uses for timeline nodes and diagram steps. */ +function IconTile({ icon, className }: { icon: GradientIconType | string; className?: string }) { + return ( + + {typeof icon === "string" ? ( + + ) : ( + + )} + + ) +} + export function Timeline() { return ( -
+

Da un semplice gruppo a una rete costruita dagli studenti,{" "} per gli studenti.

-
    + + {/* Nodes on a line: vertical below lg, horizontal from lg (Figma) */} +
      {milestones.map((milestone, index) => ( -
    1. - +
    2. + + + {milestone.year} + +

      + {milestone.description} +

    3. ))}
    +

    Dieci anni di crescita, persone e progetti. La nostra storia{" "} @@ -58,122 +80,128 @@ export function Timeline() { ) } -const chapterVisuals = [ -

    - {[ - { icon: telegram.src, title: "Il primo gruppo" }, - { icon: FiUser, title: "I primi admin e volontari" }, - { icon: FiUserCheck, title: "Test su Informatica" }, - { icon: FiUsers, title: "Tutti i corsi" }, - ].map((item) => ( - - ))} -
    , -
    - {[ - { icon: FiClipboard, title: "Regole interne" }, - { icon: FiUserCheck, title: "Comunicazioni selezionate" }, - { icon: FiUsers, title: "Una community indipendente" }, - ].map((item) => ( - - ))} -
    , -
    +function Arrow({ className }: { className?: string }) { + return +} + +/** A left-to-right sequence of steps, joined by arrows. */ +function Steps({ items }: { items: { label: string; icon?: GradientIconType | string; value?: string }[] }) { + return ( +
      + {items.map((item, index) => ( +
    1. + {index > 0 && } +
      + {item.icon && } + {item.value && {item.value}} + {item.label} +
      +
    2. + ))} +
    + ) +} + +/** Two columns read as "before → after". */ +function BeforeAfter({ before, after }: { before: { title: string; items: string[] }; after: typeof before }) { + return ( +
    + {[before, after].map((column, index) => ( +
    +

    {column.title}

    +
      + {column.items.map((item) => ( +
    • {item}
    • + ))} +
    +
    + ))} + +
    + ) +} + +const chapterVisuals: ReactNode[] = [ + , + , + , + , + , +
      {[ - { title: "5", caption: "persone", icon: FiUser }, - { title: "~25", caption: "rappresentanti", icon: FiUsers }, - { title: "4", caption: "composizioni", icon: FiLayers }, + { title: "APS-ETS", status: "Riconosciuto dallo Stato", done: true }, + { title: "RUNTS", status: "Iscritta come ETS", done: true }, + { title: "Albo PoliMi", status: "Ancora da raggiungere", done: false }, ].map((item) => ( - +
    • + {item.done ? ( + + ) : ( + + )} + {item.title} + {item.status} +
    • ))} -
    , -
    - - -
    , -
    - - -
    , -
    - - - -
    , + , ] export function Chapters() { return ( -
    -
      +
      +
        {chapters.map((chapter, index) => (
      1. -
        - - {String(index + 1).padStart(2, "0")} - -

        - {chapter.title} -

        -

        + + {String(index + 1).padStart(2, "0")} + +

        +

        {chapter.title}

        +

        {chapter.subtitle}

        -

        +

        {chapter.description}

        -
        {chapterVisuals[index]}
        +
        + {chapterVisuals[index]} +
      2. ))}
      From 1e8fe67075571c87caf7e1130649c684a6b9f465 Mon Sep 17 00:00:00 2001 From: Bianca Roberta Ianosel Date: Mon, 2 Nov 2026 09:18:14 +0000 Subject: [PATCH 2/2] refactor(storia): keep milestone links and icons with their data Each milestone carries its own anchor and icon instead of two arrays kept in step by position. The chapter numeral column is 3rem, wide enough for "02" at 36px. The closing statement is a div: a figure without a caption has no meaning here. --- src/app/storia/page.tsx | 5 ++--- src/components/storia/constants.ts | 10 ++++++++++ src/components/storia/timeline.tsx | 12 ++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/app/storia/page.tsx b/src/app/storia/page.tsx index a5b8d544..7846e788 100644 --- a/src/app/storia/page.tsx +++ b/src/app/storia/page.tsx @@ -81,8 +81,7 @@ export default function HistoryPage() { contentDiv: "min-w-0 xl:w-1/2", }} > - {/* A closing statement, not a card: nothing here is clickable */} -
      +

      L’obiettivo è raggiunto. @@ -91,7 +90,7 @@ export default function HistoryPage() { Se anche un solo studente ha trovato casa grazie a un nostro gruppo, o si è laureato in tempo perché qualcuno gli ha risposto.

      -
      +
    diff --git a/src/components/storia/constants.ts b/src/components/storia/constants.ts index dd5eb8c1..59dc9ab5 100644 --- a/src/components/storia/constants.ts +++ b/src/components/storia/constants.ts @@ -1,3 +1,5 @@ +import { FiUser, FiUserCheck, FiUsers } from "react-icons/fi" +import telegram from "@/assets/icons/telegram-gradient.svg" import ale from "@/assets/images/storia/ale-he.jpg" import alessandro from "@/assets/images/storia/alessandro-gabbini.jpg" import elia from "@/assets/images/storia/elia-falzoni.jpg" @@ -13,19 +15,27 @@ export const CONTAINER = "mx-auto w-full max-w-350 px-6 sm:px-10 md:px-10 lg:px- export const milestones = [ { year: "2016", + href: "#capitolo-1", + icon: FiUser, description: "Nasce il primo gruppo per rispondere a una necessità semplice: trovare informazioni e parlare con i compagni di corso.", }, { year: "2017", + href: "#capitolo-1", + icon: telegram.src, description: "I gruppi si moltiplicano su Telegram e WhatsApp e iniziamo a coprire tutti i corsi di laurea.", }, { year: "2022", + href: "#capitolo-5", + icon: FiUserCheck, description: "PoliNetwork diventa un’APS-ETS, con un direttivo eletto e una struttura ancora più democratica.", }, { year: "OGGI", + href: "#direttivi", + icon: FiUsers, description: "Oltre 200 admin volontari e una community che accompagna ogni giorno migliaia di studenti del Politecnico di Milano.", }, diff --git a/src/components/storia/timeline.tsx b/src/components/storia/timeline.tsx index 020d3974..0b56fc9e 100644 --- a/src/components/storia/timeline.tsx +++ b/src/components/storia/timeline.tsx @@ -8,10 +8,6 @@ import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" import { CONTAINER, chapters, milestones } from "./constants" -const milestoneLinks = ["#capitolo-1", "#capitolo-1", "#capitolo-5", "#direttivi"] - -const milestoneIcons = [FiUser, telegram.src, FiUserCheck, FiUsers] - /** The small icon tile Figma uses for timeline nodes and diagram steps. */ function IconTile({ icon, className }: { icon: GradientIconType | string; className?: string }) { return ( @@ -41,7 +37,7 @@ export function Timeline() { {/* Nodes on a line: vertical below lg, horizontal from lg (Figma) */}
      - {milestones.map((milestone, index) => ( + {milestones.map((milestone) => (
    1. - + {milestone.year} @@ -185,7 +181,7 @@ export function Chapters() { id={`capitolo-${index + 1}`} key={chapter.title} // A single vertical rule runs between the numerals and the text, across every chapter (Figma) - className="relative grid scroll-mt-36 grid-cols-[2.5rem_minmax(0,1fr)] gap-x-6 pb-16 before:absolute before:inset-y-0 before:left-[calc(2.5rem+0.75rem)] before:w-px before:bg-blue-primary/30 last:pb-0 sm:grid-cols-[3.5rem_minmax(0,1fr)] sm:gap-x-10 sm:pb-24 sm:before:left-[calc(3.5rem+1.25rem)] xl:grid-cols-[3.5rem_minmax(0,7fr)_minmax(0,5fr)] xl:gap-x-16 xl:before:left-[calc(3.5rem+2rem)]" + className="relative grid scroll-mt-36 grid-cols-[3rem_minmax(0,1fr)] gap-x-6 pb-16 before:absolute before:inset-y-0 before:left-[calc(3rem+0.75rem)] before:w-px before:bg-blue-primary/30 last:pb-0 sm:grid-cols-[3.5rem_minmax(0,1fr)] sm:gap-x-10 sm:pb-24 sm:before:left-[calc(3.5rem+1.25rem)] xl:grid-cols-[3.5rem_minmax(0,7fr)_minmax(0,5fr)] xl:gap-x-16 xl:before:left-[calc(3.5rem+2rem)]" > {String(index + 1).padStart(2, "0")}