From 0c3aee67b064fb148ca11c2169d2dee1be98dd7e Mon Sep 17 00:00:00 2001 From: Tommaso Morganti Date: Thu, 15 Oct 2026 13:23:46 +0200 Subject: [PATCH 1/2] fix(layout): make page spacing consistent and fluid across pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce fluid spacing tokens in globals.css that scale linearly between the 402px and 1728px Figma frames: - gutter (24 → 64px): page side margins, header and footer insets - page-top (168 → 208px): top offset below the fixed header - section (96 → 176px): gap between page sections and before the footer - block (40 → 72px): gap between a section heading and its content Add `page-layout` / `page-container` utilities that cap content at 1440px through padding instead of max-width, so section backgrounds and ShapeLayers keep spanning the full viewport. Apply them to every existing page, replacing the per-page values (py-49/50/52/64, px-2/4/6/36, gap-20/24/38/60/75...). Drop `min-h-screen` + vertical centering from content sections so spacing no longer depends on the viewport height, use the shared Hero on Matricole, and align the hero title padding across Hero, Groups and Guides. --- src/app/associations/page.tsx | 2 +- src/app/collabora/page.tsx | 3 +- src/app/contact/page.tsx | 2 +- src/app/faqs/page.tsx | 2 +- src/app/groups/page.tsx | 44 ++++--- src/app/guides/page.tsx | 42 +++---- src/app/matricole/guida/page.tsx | 4 +- src/app/matricole/page.tsx | 2 +- src/app/not-found.tsx | 2 +- src/app/page.tsx | 2 +- src/app/projects/page.tsx | 2 +- src/app/projects/shapes.tsx | 6 +- src/components/collabora/about-section.tsx | 2 +- .../collabora/association-section.tsx | 2 +- .../collabora/collaboration-section.tsx | 2 +- src/components/collabora/company-section.tsx | 2 +- src/components/collabora/contact-section.tsx | 2 +- src/components/contact/collabora-section.tsx | 2 +- src/components/contact/email-section.tsx | 28 +++-- src/components/contact/groups-section.tsx | 2 +- src/components/faqs/faqs-tabs.tsx | 7 +- src/components/footer/index.tsx | 8 +- src/components/groups/extra-groups.tsx | 64 +++++----- src/components/groups/groups-result.tsx | 116 +++++++++--------- src/components/guides/general-guides.tsx | 56 ++++----- src/components/guides/guides-result.tsx | 64 +++++----- src/components/header/desktop-layout.tsx | 2 +- src/components/header/mobile-layout.tsx | 2 +- src/components/home/about-us.tsx | 4 +- src/components/home/hero.tsx | 4 +- src/components/home/materials.tsx | 2 +- src/components/home/projects.tsx | 2 +- src/components/home/shapes.tsx | 4 +- src/components/layout/TextChildrenSection.tsx | 9 +- src/components/layout/TextImageSection.tsx | 2 +- src/components/layout/TextOnlySection.tsx | 2 +- src/components/matricole/faqs.tsx | 2 +- src/components/matricole/guides.tsx | 4 +- src/components/matricole/intro.tsx | 25 ++-- src/components/projects/collection.tsx | 2 +- src/components/projects/community-news.tsx | 4 +- src/components/projects/deprecated.tsx | 4 +- src/components/projects/upload.tsx | 2 +- src/components/ui/hero.tsx | 2 +- src/components/wizard/wizard-shell.tsx | 4 +- src/styles/globals.css | 31 +++++ 46 files changed, 304 insertions(+), 279 deletions(-) diff --git a/src/app/associations/page.tsx b/src/app/associations/page.tsx index 58304b1..8731abf 100644 --- a/src/app/associations/page.tsx +++ b/src/app/associations/page.tsx @@ -15,7 +15,7 @@ export default async function AssociationsPage() { const associations = await getAllAssociations() return ( -
+
diff --git a/src/app/collabora/page.tsx b/src/app/collabora/page.tsx index f680bbd..402ba65 100644 --- a/src/app/collabora/page.tsx +++ b/src/app/collabora/page.tsx @@ -22,8 +22,7 @@ export const metadata: Metadata = { export default function CollaboraPage() { return ( -
- {/* This page is broken on mobile */} +
+
+
diff --git a/src/app/groups/page.tsx b/src/app/groups/page.tsx index 1b6a4e1..b3c35c1 100644 --- a/src/app/groups/page.tsx +++ b/src/app/groups/page.tsx @@ -27,30 +27,28 @@ export const metadata: Metadata = { export default function Home() { return ( -
-
-
-

- Groups -

- -
+
+
+

+ Groups +

+ +
-
- {groups.map((group) => ( - - ))} -
+
+ {groups.map((group) => ( + + ))}
) diff --git a/src/app/guides/page.tsx b/src/app/guides/page.tsx index e9d039f..36326e2 100644 --- a/src/app/guides/page.tsx +++ b/src/app/guides/page.tsx @@ -26,29 +26,27 @@ export const metadata: Metadata = { export default function GuidesHome() { return ( -
-
-
-

- Guide -

-
+
+
+

+ Guide +

+
-
- {guides.map((guide) => ( - - ))} -
+
+ {guides.map((guide) => ( + + ))}
) diff --git a/src/app/matricole/guida/page.tsx b/src/app/matricole/guida/page.tsx index 729e925..eb24dd1 100644 --- a/src/app/matricole/guida/page.tsx +++ b/src/app/matricole/guida/page.tsx @@ -23,9 +23,9 @@ export default async function GuidaMatricolaPage() { const formattedDate = new Intl.DateTimeFormat("it-IT", { dateStyle: "long" }).format(new Date(guida.date)) return ( -
+
-
+

Guida della Matricola

diff --git a/src/app/matricole/page.tsx b/src/app/matricole/page.tsx index 7b7575a..1c349a6 100644 --- a/src/app/matricole/page.tsx +++ b/src/app/matricole/page.tsx @@ -12,7 +12,7 @@ export const metadata: Metadata = { export default function MatricolePage() { return ( -
+
diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 532b729..390f82b 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button" export default function NotFound() { return ( -
+
diff --git a/src/app/page.tsx b/src/app/page.tsx index 66b8b37..7240294 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -6,7 +6,7 @@ import { HomeMaterialsShapes, HomeProjectsShapes } from "@/components/home/shape export default function Home() { return ( -
+
diff --git a/src/app/projects/page.tsx b/src/app/projects/page.tsx index a431936..0f00761 100644 --- a/src/app/projects/page.tsx +++ b/src/app/projects/page.tsx @@ -20,7 +20,7 @@ export default async function Home() { const deprecated = projects.filter((project) => project.category === "deprecated") return ( -
+
diff --git a/src/app/projects/shapes.tsx b/src/app/projects/shapes.tsx index 90ec5bb..b2f62f2 100644 --- a/src/app/projects/shapes.tsx +++ b/src/app/projects/shapes.tsx @@ -8,9 +8,9 @@ import { Shape, ShapeLayer } from "@/components/shapes" * narrower than the 1728px/402px Figma reference frames. * * `top` is relative to the top of the section each component is mounted in - * (CommunityNews, Collection, Upload, Deprecated), not to the page. Every - * section on this page uses `min-h-screen` (fluid height, depends on the viewport) - * — each shape below is therefore scoped and `top`-anchored to the section it + * (CommunityNews, Collection, Upload, Deprecated), not to the page. Section + * heights and the gaps between them are fluid (data-dependent grids, viewport-based + * spacing tokens) — each shape below is therefore scoped and `top`-anchored to the section it * visually belongs to, rather than using cumulative page offsets. */ diff --git a/src/components/collabora/about-section.tsx b/src/components/collabora/about-section.tsx index 0b7b119..92a42c4 100644 --- a/src/components/collabora/about-section.tsx +++ b/src/components/collabora/about-section.tsx @@ -46,7 +46,7 @@ const cards = [ export function AboutSection() { return ( -
+

Chi siamo?

diff --git a/src/components/collabora/association-section.tsx b/src/components/collabora/association-section.tsx index c5b8144..9f8167e 100644 --- a/src/components/collabora/association-section.tsx +++ b/src/components/collabora/association-section.tsx @@ -3,7 +3,7 @@ import associationsImage from "@/assets/images/collabora_associations.jpg" export function AssociationSection() { return ( -
+

Sei un’associazione studentesca? diff --git a/src/components/collabora/collaboration-section.tsx b/src/components/collabora/collaboration-section.tsx index 13973fd..7504f62 100644 --- a/src/components/collabora/collaboration-section.tsx +++ b/src/components/collabora/collaboration-section.tsx @@ -1,6 +1,6 @@ export function CollaborationSection() { return ( -
+

Cosa possiamo fare insieme? diff --git a/src/components/collabora/company-section.tsx b/src/components/collabora/company-section.tsx index 5c56bda..9f1a767 100644 --- a/src/components/collabora/company-section.tsx +++ b/src/components/collabora/company-section.tsx @@ -3,7 +3,7 @@ import companyImage from "@/assets/images/collabora_company.png" export function CompanySection() { return ( -
+
+

Come contattarci

diff --git a/src/components/contact/collabora-section.tsx b/src/components/contact/collabora-section.tsx index ac68fdc..f4b9e5e 100644 --- a/src/components/contact/collabora-section.tsx +++ b/src/components/contact/collabora-section.tsx @@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button" export function CollaboraSection() { return ( -
+

Vuoi sviluppare un progetto insieme a noi? diff --git a/src/components/contact/email-section.tsx b/src/components/contact/email-section.tsx index e39276c..8d2c174 100644 --- a/src/components/contact/email-section.tsx +++ b/src/components/contact/email-section.tsx @@ -43,19 +43,21 @@ const contactCards: ContactCardData[] = [ export function EmailSection() { return ( -
-

- Hai una richiesta specifica? -

-

- Per tutto il resto,{" "} - - puoi scriverci direttamente - - . -
- Qui sotto trovi i contatti in base al tipo di richiesta. -

+
+
+

+ Hai una richiesta specifica? +

+

+ Per tutto il resto,{" "} + + puoi scriverci direttamente + + . +
+ Qui sotto trovi i contatti in base al tipo di richiesta. +

+
{contactCards.map((card) => ( diff --git a/src/components/contact/groups-section.tsx b/src/components/contact/groups-section.tsx index 37440fc..a0666a7 100644 --- a/src/components/contact/groups-section.tsx +++ b/src/components/contact/groups-section.tsx @@ -5,7 +5,7 @@ import { Button } from "@/components/ui/button" export function GroupsSection() { return ( -
+

Hai mille dubbi sul Poli? diff --git a/src/components/faqs/faqs-tabs.tsx b/src/components/faqs/faqs-tabs.tsx index ea36a7e..0b82f28 100644 --- a/src/components/faqs/faqs-tabs.tsx +++ b/src/components/faqs/faqs-tabs.tsx @@ -32,12 +32,15 @@ export function FaqsTabs({ categories }: { categories: FaqCategory[] }) { })) return ( -
+
{tabs.length === 0 ? (

Nessuna FAQ disponibile al momento.

) : ( - + {tabs.map((tab) => ( diff --git a/src/components/footer/index.tsx b/src/components/footer/index.tsx index 8fa811e..cfb61d5 100644 --- a/src/components/footer/index.tsx +++ b/src/components/footer/index.tsx @@ -8,9 +8,9 @@ import { FooterShapes } from "./shapes" export function Footer() { return ( -
+
-

+

Keep in touch!

@@ -27,7 +27,7 @@ export function Footer() { />
-
+
Unisciti a noi! Contattaci @@ -42,7 +42,7 @@ export function Footer() {
-
+
diff --git a/src/components/groups/extra-groups.tsx b/src/components/groups/extra-groups.tsx index 6140f2f..53ac1ab 100644 --- a/src/components/groups/extra-groups.tsx +++ b/src/components/groups/extra-groups.tsx @@ -12,38 +12,40 @@ export async function ExtraGroups() { ) return ( -
-
- - - -
-

Gruppi Extra

-
-
+
+
+
+ + + +
+

Gruppi Extra

+
+
- {extraGroups.length > 0 ? ( -
- {extraGroups.map((g) => ( - - ))} -
- ) : ( -

- Nessun gruppo extra disponibile al momento. -

- )} + {extraGroups.length > 0 ? ( +
+ {extraGroups.map((g) => ( + + ))} +
+ ) : ( +

+ Nessun gruppo extra disponibile al momento. +

+ )} +
) } diff --git a/src/components/groups/groups-result.tsx b/src/components/groups/groups-result.tsx index c1b3ba6..2f3063b 100644 --- a/src/components/groups/groups-result.tsx +++ b/src/components/groups/groups-result.tsx @@ -41,14 +41,14 @@ function GroupSection({ title, groups }: { title: string; groups: VisibleGroup[] if (merged.length === 0) return null return ( -
+

{title}

{merged.length} Gruppi

-
+
{merged.map((g) => ( ))} @@ -102,64 +102,66 @@ export async function GroupsResult({ courseGroups.length > 0 return ( -
-
- - - -
-

{courseName}

-

- Laurea {currentLevel.name} -

-
- - - -
+
+
+
+ + + +
+

{courseName}

+

+ Laurea {currentLevel.name} +

+
+ + + +
- {(mergedSiteGroups.length > 0 || - mergedSchoolGroups.length > 0 || - mergedLevelGroups.length > 0 || - mergedGeneralCourseGroups.length > 0) && ( -
- {mergedSiteGroups.map((g) => ( - - ))} - {mergedSchoolGroups.map((g) => ( - - ))} - {mergedLevelGroups.map((g) => ( - - ))} - {mergedGeneralCourseGroups.map((g) => ( - - ))} -
- )} + {(mergedSiteGroups.length > 0 || + mergedSchoolGroups.length > 0 || + mergedLevelGroups.length > 0 || + mergedGeneralCourseGroups.length > 0) && ( +
+ {mergedSiteGroups.map((g) => ( + + ))} + {mergedSchoolGroups.map((g) => ( + + ))} + {mergedLevelGroups.map((g) => ( + + ))} + {mergedGeneralCourseGroups.map((g) => ( + + ))} +
+ )} - {cohorts.map((cohort) => ( - - ))} + {cohorts.map((cohort) => ( + + ))} - {!hasAnyGroup && ( -

- Nessun gruppo disponibile al momento per questo corso. -

- )} + {!hasAnyGroup && ( +

+ Nessun gruppo disponibile al momento per questo corso. +

+ )} +
) } diff --git a/src/components/guides/general-guides.tsx b/src/components/guides/general-guides.tsx index 48b6290..9a15127 100644 --- a/src/components/guides/general-guides.tsx +++ b/src/components/guides/general-guides.tsx @@ -5,35 +5,35 @@ import { LOREM_GUIDES } from "@/components/guides/constants" export function GeneralGuides() { return ( -
-
- - - -
-

Guide Generali

-
- - - -
+
+
+
+ + + +
+

Guide Generali

+
+ + + +
- {LOREM_GUIDES.length > 0 ? ( - - ) : ( -

- Nessuna guida disponibile al momento. -

- )} + {LOREM_GUIDES.length > 0 ? ( + + ) : ( +

Nessuna guida disponibile al momento.

+ )} +
) } diff --git a/src/components/guides/guides-result.tsx b/src/components/guides/guides-result.tsx index bf98f20..f1c57f2 100644 --- a/src/components/guides/guides-result.tsx +++ b/src/components/guides/guides-result.tsx @@ -29,38 +29,40 @@ export async function GuidesResult({ const courseName = humanizeSlug(course) return ( -
-
- - - -
-

{courseName}

-

- Laurea {currentLevel.name} -

-
- - - -
+
+
+
+ + + +
+

{courseName}

+

+ Laurea {currentLevel.name} +

+
+ + + +
- {LOREM_GUIDES.length > 0 ? ( - - ) : ( -

- Nessuna guida disponibile al momento per questo corso. -

- )} + {LOREM_GUIDES.length > 0 ? ( + + ) : ( +

+ Nessuna guida disponibile al momento per questo corso. +

+ )} +
) } diff --git a/src/components/header/desktop-layout.tsx b/src/components/header/desktop-layout.tsx index f4a8007..c08c2de 100644 --- a/src/components/header/desktop-layout.tsx +++ b/src/components/header/desktop-layout.tsx @@ -21,7 +21,7 @@ export const DesktopLayout = ({ logoOnly = false }: { logoOnly?: boolean }) => { const customHoverEffectClass = "hover:underline focus-visible:underline decoration-1 decoration-blue-secondary " return ( -
+
{ }, [logoOnly]) return ( - +
{!logoOnly && ( diff --git a/src/components/home/about-us.tsx b/src/components/home/about-us.tsx index f879f91..615309e 100644 --- a/src/components/home/about-us.tsx +++ b/src/components/home/about-us.tsx @@ -4,8 +4,8 @@ import { Button } from "@/components/ui/button" export function AboutUs() { return ( -
-

+
+

PoliNetwork unisce gli studenti del Poli: gruppi, risorse e supporto, tutti in un'unica community.

diff --git a/src/components/home/hero.tsx b/src/components/home/hero.tsx index 1e9ff50..219b88f 100644 --- a/src/components/home/hero.tsx +++ b/src/components/home/hero.tsx @@ -6,9 +6,9 @@ import { HomeHeroShapes } from "./shapes" export function Hero() { return ( -
+
-
+

Trova gruppi, risorse e supporto tra gli studenti del Polimi

diff --git a/src/components/home/materials.tsx b/src/components/home/materials.tsx index 1dec069..79ef8e3 100644 --- a/src/components/home/materials.tsx +++ b/src/components/home/materials.tsx @@ -31,7 +31,7 @@ const quickLinks = [ export function Materials() { return ( -
+
{/* Desktop Cards */}
diff --git a/src/components/home/projects.tsx b/src/components/home/projects.tsx index b66fafc..3ecaccb 100644 --- a/src/components/home/projects.tsx +++ b/src/components/home/projects.tsx @@ -31,7 +31,7 @@ const featuredCards = [ export function Projects() { return ( -
+

15+ Projects diff --git a/src/components/home/shapes.tsx b/src/components/home/shapes.tsx index 8307868..96f64ec 100644 --- a/src/components/home/shapes.tsx +++ b/src/components/home/shapes.tsx @@ -9,8 +9,8 @@ import { Shape, ShapeLayer } from "@/components/shapes" * * `top` is relative to the top of the section each component is mounted in * (Materials or Projects), not to the page. Materials and Projects/AboutUs - * used to share one absolute layer with cumulative offsets, but AboutUs uses - * `min-h-screen` (fluid height, depends on the viewport) — if a shape ever + * used to share one absolute layer with cumulative offsets, but section heights + * and the gaps between them are fluid (they depend on the viewport) — if a shape ever * needs to sit inside AboutUs, mount it scoped to that section too, the same * way this file already splits Materials from Projects. Otherwise any * mismatch between a fluid section's real height and Figma's fixed height diff --git a/src/components/layout/TextChildrenSection.tsx b/src/components/layout/TextChildrenSection.tsx index be1436c..e1c3352 100644 --- a/src/components/layout/TextChildrenSection.tsx +++ b/src/components/layout/TextChildrenSection.tsx @@ -73,14 +73,7 @@ export default function TextChildrenLayout({ : "min-[1616px]:flex-row" return ( -
+

diff --git a/src/components/matricole/faqs.tsx b/src/components/matricole/faqs.tsx index 9643cab..0e2653b 100644 --- a/src/components/matricole/faqs.tsx +++ b/src/components/matricole/faqs.tsx @@ -4,7 +4,7 @@ import { accordionItems } from "./constants" export function FAQsPage() { return ( -
+

Domande Frequenti tra le Matricole

diff --git a/src/components/matricole/guides.tsx b/src/components/matricole/guides.tsx index d952b32..582567a 100644 --- a/src/components/matricole/guides.tsx +++ b/src/components/matricole/guides.tsx @@ -4,8 +4,8 @@ import { guides, hub, materiali, techTools } from "./constants" export function MatricoleGuides() { return ( -
-
+
+

Guide e Utility

diff --git a/src/components/matricole/intro.tsx b/src/components/matricole/intro.tsx index a0c7363..1e58d7a 100644 --- a/src/components/matricole/intro.tsx +++ b/src/components/matricole/intro.tsx @@ -1,24 +1,19 @@ import { CardIcon } from "@/components/card-icon" +import { Hero } from "@/components/ui/hero" import { resources } from "./constants" export function MatricoleIntro() { return ( -
-
-
-

- Matricole -

-

- Ecco una raccolta curata di risorse utili, guide e strumenti per supportare il tuo percorso. -

-
+
+ -
- {resources.map((resource) => ( - - ))} -
+
+ {resources.map((resource) => ( + + ))}
) diff --git a/src/components/projects/collection.tsx b/src/components/projects/collection.tsx index 8eb420c..75fbf4b 100644 --- a/src/components/projects/collection.tsx +++ b/src/components/projects/collection.tsx @@ -18,7 +18,7 @@ export function Collection({ projects }: { projects: Project[] }) { const visibleProjects = expanded ? projects : projects.slice(0, INITIAL_PROJECT_COUNT) return ( -
+

Esplora la raccolta completa dei progetti diff --git a/src/components/projects/community-news.tsx b/src/components/projects/community-news.tsx index 7b65cb5..3021e23 100644 --- a/src/components/projects/community-news.tsx +++ b/src/components/projects/community-news.tsx @@ -8,10 +8,10 @@ type Project = ApiOutput["web"]["projects"]["getAllProjects"][number] export function CommunityNews({ projects }: { projects: Project[] }) { return ( -
+
-
+

Le novità della community diff --git a/src/components/projects/deprecated.tsx b/src/components/projects/deprecated.tsx index b8ce5bb..5297b49 100644 --- a/src/components/projects/deprecated.tsx +++ b/src/components/projects/deprecated.tsx @@ -17,8 +17,8 @@ export function Deprecated({ projects }: { projects: Project[] }) { const visibleProjects = expanded ? projects : projects.slice(0, INITIAL_PROJECT_COUNT) return ( -
-
+
+

Progetti deprecati

diff --git a/src/components/projects/upload.tsx b/src/components/projects/upload.tsx index 889f8b1..21a08af 100644 --- a/src/components/projects/upload.tsx +++ b/src/components/projects/upload.tsx @@ -32,7 +32,7 @@ const cards = [ export function Upload() { return ( -

+

Hai un'idea?

diff --git a/src/components/ui/hero.tsx b/src/components/ui/hero.tsx index c270c5c..1fef01c 100644 --- a/src/components/ui/hero.tsx +++ b/src/components/ui/hero.tsx @@ -9,7 +9,7 @@ export function Hero({ }) { return (
-

+

{title}

- +

+
s keep spanning the whole viewport. + */ +@utility page-container { + width: 100%; + padding-inline: max(var(--spacing-gutter), calc((100% - var(--container-page)) / 2)); +} + +/* `page-container` for a whole
: also clears the fixed header and leaves room before the footer. */ +@utility page-layout { + width: 100%; + padding-inline: max(var(--spacing-gutter), calc((100% - var(--container-page)) / 2)); + padding-top: var(--spacing-page-top); + padding-bottom: var(--spacing-section); } @layer base { From e9e2dcffb3141a02911d2cc942c989f2a3831800 Mon Sep 17 00:00:00 2001 From: Tommaso Morganti Date: Thu, 15 Oct 2026 15:04:30 +0200 Subject: [PATCH 2/2] feat(chi-siamo): add "Su di noi" page (#180) * feat(chi-siamo): add "Su di noi" page Implement the "Su di noi" Figma page at /chi-siamo, the route the header already links to. The page is composed of existing components only (CardIcon, Card primitives, Glass, GradientIcon, Button, Shape/ShapeLayer) and uses the shared fluid spacing tokens (page-container, page-top, gap-section, gap-block). Sections: vision, problem, our answer, student path timeline, numbers, history/structure links and 5x1000 support. Background shapes follow the desktop Figma frame and are anchored per section; there is no mobile frame yet, so mobile has no shapes. * fix(chi-siamo): narrow the content column to the Figma width Content spanned up to 1440px, leaving only the fluid gutter (~50-60px on laptop screens) between it and the page edges. Override --container-page on this page so page-container caps it at 1200px like in Figma (262px margins on the 1728px frame). Adapt the number cards to the narrower column: tighter padding, Figma's unequal column proportions from xl, and the large icon only from 1xl, so labels stay on two lines. * style(chi-siamo): refine hierarchy cards and responsive layout * style(chi-siamo): remove eyebrows and restore section hierarchy --------- Co-authored-by: Bianca Roberta Ianosel --- src/app/chi-siamo/page.tsx | 54 ++++++++++++ src/app/chi-siamo/shapes.tsx | 88 ++++++++++++++++++++ src/components/chi-siamo/answer-section.tsx | 49 +++++++++++ src/components/chi-siamo/history-section.tsx | 44 ++++++++++ src/components/chi-siamo/numbers-section.tsx | 50 +++++++++++ src/components/chi-siamo/path-section.tsx | 56 +++++++++++++ src/components/chi-siamo/problem-section.tsx | 31 +++++++ src/components/chi-siamo/support-section.tsx | 31 +++++++ src/components/chi-siamo/vision-section.tsx | 29 +++++++ 9 files changed, 432 insertions(+) create mode 100644 src/app/chi-siamo/page.tsx create mode 100644 src/app/chi-siamo/shapes.tsx create mode 100644 src/components/chi-siamo/answer-section.tsx create mode 100644 src/components/chi-siamo/history-section.tsx create mode 100644 src/components/chi-siamo/numbers-section.tsx create mode 100644 src/components/chi-siamo/path-section.tsx create mode 100644 src/components/chi-siamo/problem-section.tsx create mode 100644 src/components/chi-siamo/support-section.tsx create mode 100644 src/components/chi-siamo/vision-section.tsx diff --git a/src/app/chi-siamo/page.tsx b/src/app/chi-siamo/page.tsx new file mode 100644 index 0000000..5f60553 --- /dev/null +++ b/src/app/chi-siamo/page.tsx @@ -0,0 +1,54 @@ +import type { Metadata } from "next" +import { AnswerSection } from "@/components/chi-siamo/answer-section" +import { HistorySection } from "@/components/chi-siamo/history-section" +import { NumbersSection } from "@/components/chi-siamo/numbers-section" +import { PathSection } from "@/components/chi-siamo/path-section" +import { ProblemSection } from "@/components/chi-siamo/problem-section" +import { SupportSection } from "@/components/chi-siamo/support-section" +import { VisionSection } from "@/components/chi-siamo/vision-section" +import { + ChiSiamoAnswerShapes, + ChiSiamoHistoryShapes, + ChiSiamoNumbersShapes, + ChiSiamoPathShapes, + ChiSiamoProblemShapes, + ChiSiamoVisionShapes, +} from "./shapes" + +export const metadata: Metadata = { + title: "Su di noi", + description: "Rendiamo le informazioni sul PoliMi più accessibili, comprensibili e facili da trovare.", +} + +export default function ChiSiamoPage() { + return ( + // Narrower content column (1200px, as in Figma): `page-container` caps its padding on this variable +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ ) +} diff --git a/src/app/chi-siamo/shapes.tsx b/src/app/chi-siamo/shapes.tsx new file mode 100644 index 0000000..3c16ff8 --- /dev/null +++ b/src/app/chi-siamo/shapes.tsx @@ -0,0 +1,88 @@ +import { Shape, ShapeLayer } from "@/components/shapes" + +/** + * `left` offsets are `calc(50% + Npx)`, relative to the horizontal center of + * the 1728px (desktop) Figma frame — see src/components/home/shapes.tsx. + * + * Each section's shapes are `top`-anchored to that section's heading (the + * section's top edge): `top = figmaY - figmaHeadingY`. The vision shapes are + * instead anchored to the page top, since that section starts at the top of + * `
`, where page y = Figma y. + * + * The Figma file only has a desktop frame for this page, so there are no + * mobile shapes yet. + */ + +export function ChiSiamoVisionShapes() { + return ( + + {/* Desktop Shapes */} + + + + + + ) +} + +export function ChiSiamoProblemShapes() { + return ( + + {/* Desktop Shapes */} + + + + ) +} + +export function ChiSiamoAnswerShapes() { + return ( + + {/* Desktop Shapes */} + + + ) +} + +export function ChiSiamoPathShapes() { + return ( + + {/* Desktop Shapes */} + + + + + ) +} + +export function ChiSiamoNumbersShapes() { + return ( + + {/* Desktop Shapes */} + + + + + ) +} + +export function ChiSiamoHistoryShapes() { + return ( + + {/* Desktop Shapes */} + + + ) +} diff --git a/src/components/chi-siamo/answer-section.tsx b/src/components/chi-siamo/answer-section.tsx new file mode 100644 index 0000000..84fd5ef --- /dev/null +++ b/src/components/chi-siamo/answer-section.tsx @@ -0,0 +1,49 @@ +import { FiAward, FiBookOpen, FiUsers } from "react-icons/fi" +import { CardIcon } from "@/components/card-icon" + +const cards = [ + { + title: "Community", + description: + "Gruppi Telegram e WhatsApp per corsi, scaglioni, sedi e interessi. Una rete moderata ogni giorno da admin volontari.", + icon: FiUsers, + }, + { + title: "Strumenti", + description: + "Strumenti gratuiti e open source: graduatorie e simulazioni TOL, bot per trovare il tuo gruppo, appunti e temi d’esame.", + icon: FiBookOpen, + }, + { + title: "Eventi", + description: "Eventi per incontrarsi e fare community. Collaborazioni che portano valore concreto agli studenti.", + icon: FiAward, + }, +] as const + +export function AnswerSection() { + return ( +
+
+

+ La nostra risposta +

+

+ Costruiamo e manteniamo la rete di comunicazione studentesca del Politecnico di Milano. +

+
+ +
+ {cards.map((card) => ( + + ))} +
+
+ ) +} diff --git a/src/components/chi-siamo/history-section.tsx b/src/components/chi-siamo/history-section.tsx new file mode 100644 index 0000000..7212a28 --- /dev/null +++ b/src/components/chi-siamo/history-section.tsx @@ -0,0 +1,44 @@ +import Link from "next/link" +import { FiArrowUpRight, FiClock, FiUsers } from "react-icons/fi" +import { Glass } from "@/components/glass" +import { GradientIcon } from "@/components/gradient-icon" +import { Button } from "@/components/ui/button" + +const blocks = [ + { + title: "Da dove veniamo", + description: "Dal primo gruppo Telegram, nel 2016, a una rete costruita dagli studenti, per gli studenti.", + icon: FiClock, + cta: "La nostra storia", + href: "/storia", + }, + { + title: "Come siamo organizzati", + icon: FiUsers, + description: "Direttivo, team operativi, admin e soci. Guarda come funziona la macchina dall'interno.", + cta: "La nostra struttura", + href: "/about", + }, +] as const + +export function HistorySection() { + return ( +
+ {blocks.map((block) => ( + + +

+ {block.title} +

+

{block.description}

+ +
+ ))} +
+ ) +} diff --git a/src/components/chi-siamo/numbers-section.tsx b/src/components/chi-siamo/numbers-section.tsx new file mode 100644 index 0000000..a4e5412 --- /dev/null +++ b/src/components/chi-siamo/numbers-section.tsx @@ -0,0 +1,50 @@ +import { FiBook, FiBookOpen, FiHeadphones, FiSend, FiUser, FiUsers } from "react-icons/fi" +import { GradientIcon } from "@/components/gradient-icon" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" + +const stats = [ + { value: "500+", label: "gruppi Telegram e WhatsApp attivi", icon: FiSend }, + { value: "30+", label: "corsi di laurea coperti", icon: FiBook }, + { value: "45k+", label: "studenti raggiunti ogni anno", icon: FiUser }, + { value: "100+", label: "admin volontari su tutte le sedi", icon: FiUsers }, + { value: "5", label: "team operativi", icon: FiHeadphones }, + { value: "100%", label: "progetti tecnici rilasciati open source", icon: FiBookOpen }, +] as const + +export function NumbersSection() { + return ( +
+
+

+ I numeri +

+

+ Un network in continua crescita, costruito dagli studenti, per gli studenti. +

+
+ +
+
+ {stats.map((stat) => ( + + + + {stat.value} + + + + {stat.label} + + ))} +
+ +

+ Dal 2016 al fianco degli studenti del PoliMi +

+
+
+ ) +} diff --git a/src/components/chi-siamo/path-section.tsx b/src/components/chi-siamo/path-section.tsx new file mode 100644 index 0000000..3967c25 --- /dev/null +++ b/src/components/chi-siamo/path-section.tsx @@ -0,0 +1,56 @@ +import { FiBook, FiClipboard, FiFileText, FiGift, FiUser, FiUserCheck } from "react-icons/fi" +import { Glass } from "@/components/glass" +import { GradientIcon } from "@/components/gradient-icon" +import { cn } from "@/lib/utils" + +const steps = [ + { title: "TOL", description: "Simulazioni, guide e consigli per affrontarlo al meglio.", icon: FiBook }, + { title: "Ammissione", description: "Graduatorie, scadenze e tutto ciò che serve per iniziare.", icon: FiClipboard }, + { title: "Primo anno", description: "Orientamento, gruppi, risorse e supporto tra studenti.", icon: FiUser }, + { title: "Esami", description: "Appunti, temi, consigli e strumenti per prepararti meglio.", icon: FiFileText }, + { + title: "Scelta del percorso", + description: "Informazioni chiare per decidere il tuo futuro al PoliMi.", + icon: FiUserCheck, + }, + { title: "Laurea", description: "Fino al traguardo, insieme.", icon: FiGift }, +] as const + +export function PathSection() { + return ( +
+

+ Il tuo percorso, sempre al tuo fianco +

+ +
    + {steps.map((step, index) => ( +
  1. + + + +
    +

    + {step.title} +

    +

    {step.description}

    +
    +
  2. + ))} +
+ +

+ Dalla prima simulazione del TOL fino alla laurea, ogni studente ha sempre{" "} + una risposta a portata di mano e{" "} + qualcuno a cui chiederla. +

+
+ ) +} diff --git a/src/components/chi-siamo/problem-section.tsx b/src/components/chi-siamo/problem-section.tsx new file mode 100644 index 0000000..85daeee --- /dev/null +++ b/src/components/chi-siamo/problem-section.tsx @@ -0,0 +1,31 @@ +import { FiEdit, FiFileText, FiUsers } from "react-icons/fi" +import { Card, CardAction, CardContent } from "@/components/ui/card" + +const questions = [ + { text: "Dove trovo il gruppo del mio corso?", icon: FiUsers }, + { text: "Come funziona il piano degli studi?", icon: FiFileText }, + { text: "Cosa succede se non passo l’OFA di inglese?", icon: FiEdit }, +] as const + +export function ProblemSection() { + return ( +
+
+

+ Il problema +

+

+ Il PoliMi è complesso. Le informazioni non dovrebbero esserlo. +

+
+
+ {questions.map((question) => ( + + {question.text} + + + ))} +
+
+ ) +} diff --git a/src/components/chi-siamo/support-section.tsx b/src/components/chi-siamo/support-section.tsx new file mode 100644 index 0000000..3d099ef --- /dev/null +++ b/src/components/chi-siamo/support-section.tsx @@ -0,0 +1,31 @@ +import { FiHeart } from "react-icons/fi" +import { Glass } from "@/components/glass" +import { GradientIcon } from "@/components/gradient-icon" + +export function SupportSection() { + return ( +
+ +
+ +

Sostieni PoliNetwork

+

+ Se vuoi supportare PoliNetwork economicamente, puoi destinarci il 5x1000 nella dichiarazione dei redditi. Si + tratta di una quota IRPEF che verseresti comunque, e che puoi scegliere di indirizzare a noi senza alcun + costo aggiuntivo. +

+
+ +

5x1000

+

Il tuo sostegno può fare la differenza

+

+ Nella sezione dedicata agli Enti del Terzo Settore, indica il nostro codice fiscale: +

+

+ 97927490157 +

+
+
+
+ ) +} diff --git a/src/components/chi-siamo/vision-section.tsx b/src/components/chi-siamo/vision-section.tsx new file mode 100644 index 0000000..895b233 --- /dev/null +++ b/src/components/chi-siamo/vision-section.tsx @@ -0,0 +1,29 @@ +import Link from "next/link" +import { FiArrowDown, FiArrowUpRight } from "react-icons/fi" +import { Button } from "@/components/ui/button" + +export function VisionSection() { + return ( +
+

+ Un Politecnico in cui nessuno studente resti indietro per mancanza di{" "} + informazioni. +

+

+ Rendiamo le informazioni sul PoliMi più accessibili, comprensibili e facili da trovare. +

+
+ + +
+
+ ) +}