diff --git a/frontend/src/app/features/about/about-page.component.html b/frontend/src/app/features/about/about-page.component.html index 51321c3..9dd3f12 100644 --- a/frontend/src/app/features/about/about-page.component.html +++ b/frontend/src/app/features/about/about-page.component.html @@ -40,3 +40,5 @@ + + diff --git a/frontend/src/app/features/about/about-page.component.ts b/frontend/src/app/features/about/about-page.component.ts index edb3d90..dcb93f8 100644 --- a/frontend/src/app/features/about/about-page.component.ts +++ b/frontend/src/app/features/about/about-page.component.ts @@ -1,11 +1,11 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; - +import { AppLocationsComponent } from '../../shared/components/app-locations/app-locations.component'; @Component({ selector: 'app-about-page', standalone: true, - imports: [TranslateModule], + imports: [TranslateModule, AppLocationsComponent], templateUrl: './about-page.component.html', styleUrl: './about-page.component.scss' }) diff --git a/frontend/src/app/features/home/home.component.html b/frontend/src/app/features/home/home.component.html index 8380ff0..f1c0826 100644 --- a/frontend/src/app/features/home/home.component.html +++ b/frontend/src/app/features/home/home.component.html @@ -7,13 +7,17 @@ Prezzo e tempi in pochi secondi.
Dal file 3D al pezzo finito. +

+ Il calcolatore più avanzato per le tue stampe 3D: precisione assoluta e zero sorprese. +

- Lavoriamo con trasparenza su costi, qualità e tempi. Produciamo prototipi, pezzi personalizzati - e piccole serie con supporto tecnico reale. + Realizziamo pezzi unici e produzioni in serie. Se hai il file, il preventivo è istantaneo. + Se devi ancora crearlo, il nostro team di design lo progetterà per te.

- Parla con noi + Calcola Preventivo Vai allo shop + Parla con noi
@@ -22,13 +26,12 @@
-

Preventivo immediato

+

Preventivo immediato in pochi secondi

- Carica il file 3D e ottieni subito costo e tempo di stampa. Nessuna registrazione. + Nessuna registrazione necessaria. Non salviamo il tuo file fino al momento dell'ordine e la stima è effettuata tramite vero slicing.

  • Formati supportati: STL, 3MF, STEP, OBJ
  • -
  • Materiali disponibili: PLA, PETG, TPU
  • Qualità: bozza, standard, alta definizione
@@ -45,19 +48,9 @@
  • Scegli materiale e qualità
  • Ricevi subito costo e tempo
  • -
    -
    - Modalità - Rapida / Avanzata -
    -
    - Output - Ordina o richiedi consulenza -
    -
    Apri calcolatore - Parla con noi + Parla con noi
    @@ -74,20 +67,32 @@
    +
    + +

    Prototipazione veloce

    -

    Valida idee e funzioni in pochi giorni con preventivo immediato.

    +

    Dal file digitale al modello fisico in 24/48 ore. Verifica ergonomia, incastri e funzionamento prima dello stampo definitivo.

    +
    + +

    Pezzi personalizzati

    -

    Componenti unici o in mini serie per clienti, macchine e prodotti.

    +

    Componenti unici impossibili da trovare in commercio. Riproduciamo parti rotte o creiamo adattamenti su misura.

    +
    + +

    Piccole serie

    -

    Produzione controllata fino a 500 pezzi con qualità costante.

    +

    Produzione ponte o serie limitate (10-500 pezzi) con qualità ripetibile. Ideale per validazione di mercato.

    +
    + +

    Consulenza e CAD

    -

    Supporto tecnico per progettazione, modifiche e ottimizzazione.

    +

    Non hai il file 3D? Ti aiutiamo a progettarlo, ottimizzarlo per la stampa e scegliere il materiale giusto.

    @@ -108,7 +113,7 @@
    Scopri i prodotti - Richiedi una soluzione + Richiedi una soluzione
    @@ -136,25 +141,12 @@ 3D fab è un laboratorio tecnico di stampa 3D. Seguiamo progetti dalla consulenza iniziale alla produzione, con tempi chiari e supporto diretto.

    -

    - Qui puoi inserire descrizioni più dettagliate del team, del laboratorio e dei progetti in corso. -

    - Contattaci + Contattaci
    -
    -
    -
    -

    Foto laboratorio / stampanti

    -
    -
    -
    -

    Dettagli qualità e finiture

    -
    -
    -
    -

    Team, prototipi o casi studio

    -
    +
    + + Foto Founders
    diff --git a/frontend/src/app/features/home/home.component.scss b/frontend/src/app/features/home/home.component.scss index 5e406d9..147d469 100644 --- a/frontend/src/app/features/home/home.component.scss +++ b/frontend/src/app/features/home/home.component.scss @@ -15,10 +15,10 @@ position: absolute; inset: 0; @include patterns.pattern-grid(var(--color-neutral-900), 40px, 1px); - opacity: 0.12; + opacity: 0.06; z-index: 0; pointer-events: none; - mask-image: linear-gradient(to bottom, black 40%, transparent 100%); + mask-image: linear-gradient(to bottom, black 70%, transparent 100%); } } @@ -43,6 +43,7 @@ position: relative; z-index: 1; } + .hero-copy { animation: fadeUp 0.8s ease both; } .hero-panel { animation: fadeUp 0.8s ease 0.15s both; } @@ -61,10 +62,18 @@ letter-spacing: -0.02em; margin-bottom: var(--space-4); } + .hero-lead { + font-size: 1.35rem; + font-weight: 500; + color: var(--color-neutral-900); + margin-bottom: var(--space-3); + max-width: 600px; + } .hero-subtitle { - font-size: 1.2rem; + font-size: 1.1rem; color: var(--color-text-muted); max-width: 560px; + line-height: 1.6; } .hero-actions { display: flex; @@ -135,6 +144,9 @@ padding: 0.35rem 0.75rem; font-size: 0.8rem; font-weight: 600; + color: var(--color-brand-600); + background: var(--color-brand-50); + border-color: var(--color-brand-200); } .quote-steps { list-style: none; @@ -177,14 +189,10 @@ .capabilities { position: relative; + border-bottom: 1px solid var(--color-border); } .capabilities-bg { - position: absolute; - inset: 0; - @include patterns.pattern-rectilinear(var(--color-neutral-900), 24px, 1px); - opacity: 0.05; - pointer-events: none; - z-index: 0; + display: none; } .section { padding: 5.5rem 0; position: relative; } @@ -194,24 +202,13 @@ .text-muted { color: var(--color-text-muted); } .calculator { - background: var(--color-neutral-50); - border-top: 1px solid var(--color-border); - border-bottom: 1px solid var(--color-border); position: relative; - // Honeycomb Pattern - &::before { - content: ''; - position: absolute; - inset: 0; - @include patterns.pattern-honeycomb(var(--color-neutral-900), 24px); - opacity: 0.04; - pointer-events: none; - } + border-bottom: 1px solid var(--color-border); } .calculator-grid { display: grid; gap: var(--space-10); - align-items: center; + align-items: start; position: relative; z-index: 1; } @@ -225,6 +222,19 @@ gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); } + + .card-image-placeholder { + width: 100%; + height: 160px; + background: var(--color-neutral-100); + margin: -1.5rem -1.5rem 1.5rem -1.5rem; /* Negative margins to bleed to edge */ + width: calc(100% + 3rem); + border-bottom: 1px solid var(--color-border); + display: flex; + align-items: center; + justify-content: center; + color: var(--color-neutral-400); + } .shop { background: var(--color-neutral-50); @@ -282,24 +292,21 @@ align-items: center; } .about-media { - display: grid; - gap: var(--space-4); + position: relative; } - .media-grid { - display: grid; - gap: var(--space-4); - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - } - .media-tile { - display: grid; - gap: var(--space-2); - } - .media-photo { + + .about-feature-image { width: 100%; - aspect-ratio: 4 / 3; + height: 100%; + min-height: 320px; + object-fit: cover; border-radius: var(--radius-lg); background: var(--color-neutral-100); border: 1px solid var(--color-border); + display: flex; + align-items: center; + justify-content: center; + color: var(--color-text-muted); } .media-tile p { margin: 0; @@ -313,6 +320,7 @@ @media (min-width: 960px) { .hero-grid { grid-template-columns: 1.1fr 0.9fr; } .calculator-grid { grid-template-columns: 1.1fr 0.9fr; } + .calculator-grid { grid-template-columns: 1.1fr 0.9fr; } .split { grid-template-columns: 1.1fr 0.9fr; } .about-grid { grid-template-columns: 1.1fr 0.9fr; } } diff --git a/frontend/src/app/shared/components/app-locations/app-locations.component.html b/frontend/src/app/shared/components/app-locations/app-locations.component.html new file mode 100644 index 0000000..e8a827c --- /dev/null +++ b/frontend/src/app/shared/components/app-locations/app-locations.component.html @@ -0,0 +1,57 @@ +
    +
    +
    +

    {{ 'LOCATIONS.TITLE' | translate }}

    +

    {{ 'LOCATIONS.SUBTITLE' | translate }}

    +
    + +
    +
    +
    + + +
    + +
    +
    +

    {{ 'LOCATIONS.TICINO' | translate }}

    +

    {{ 'LOCATIONS.ADDRESS_TICINO' | translate }}

    +
    +
    +

    {{ 'LOCATIONS.BIENNE' | translate }}

    +

    {{ 'LOCATIONS.ADDRESS_BIENNE' | translate }}

    +
    + + +
    +
    + +
    + + +
    +
    +
    +
    diff --git a/frontend/src/app/shared/components/app-locations/app-locations.component.scss b/frontend/src/app/shared/components/app-locations/app-locations.component.scss new file mode 100644 index 0000000..2396f8d --- /dev/null +++ b/frontend/src/app/shared/components/app-locations/app-locations.component.scss @@ -0,0 +1,116 @@ +.locations-section { + padding: 6rem 0; + background: var(--color-surface-card); + border-top: 1px solid var(--color-border); +} + +.section-header { + text-align: center; + margin-bottom: 4rem; + + h2 { + font-size: 2.5rem; + margin-bottom: 1rem; + color: var(--color-text-main); + } + + .subtitle { + font-size: 1.1rem; + color: var(--color-text-muted); + max-width: 600px; + margin: 0 auto; + } +} + +.locations-grid { + display: grid; + grid-template-columns: 1fr; + gap: 3rem; + align-items: start; + + @media(min-width: 992px) { + grid-template-columns: 1fr 2fr; + } +} + +.location-tabs { + display: flex; + gap: 1rem; + margin-bottom: 2rem; + background: var(--color-bg); + padding: 0.5rem; + border-radius: var(--radius-md); + border: 1px solid var(--color-border); +} + +.tab-btn { + flex: 1; + padding: 0.75rem; + border: none; + background: transparent; + border-radius: var(--radius-sm); + color: var(--color-text-muted); + font-weight: 600; + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + color: var(--color-text-main); + } + + &.active { + background: var(--color-primary-500); + color: var(--color-neutral-900); + box-shadow: var(--shadow-sm); + } +} + +.location-details { + padding: 2rem; + background: var(--color-bg); + border-radius: var(--radius-lg); + border: 1px solid var(--color-border); + box-shadow: var(--shadow-md); + + h3 { + margin-bottom: 1rem; + font-size: 1.5rem; + } + + p { + color: var(--color-text-muted); + margin-bottom: 2rem; + line-height: 1.6; + } +} + +.contact-btn { + display: inline-block; + padding: 0.75rem 2rem; + background: var(--color-primary-500); + color: var(--color-neutral-900); + text-decoration: none; + border-radius: var(--radius-md); + font-weight: 600; + transition: all 0.2s ease; + + &:hover { + background: var(--color-primary-600); + transform: translateY(-2px); + box-shadow: var(--shadow-md); + } +} + +.map-container { + border-radius: var(--radius-lg); + overflow: hidden; + border: 1px solid var(--color-border); + box-shadow: var(--shadow-lg); + background: var(--color-bg); + height: 450px; + + iframe { + width: 100%; + height: 100%; + } +} diff --git a/frontend/src/app/shared/components/app-locations/app-locations.component.ts b/frontend/src/app/shared/components/app-locations/app-locations.component.ts new file mode 100644 index 0000000..89988ff --- /dev/null +++ b/frontend/src/app/shared/components/app-locations/app-locations.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { TranslateModule } from '@ngx-translate/core'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-locations', + standalone: true, + imports: [CommonModule, TranslateModule, RouterLink], + templateUrl: './app-locations.component.html', + styleUrl: './app-locations.component.scss' +}) +export class AppLocationsComponent { + selectedLocation: 'ticino' | 'bienne' = 'ticino'; + + selectLocation(location: 'ticino' | 'bienne') { + this.selectedLocation = location; + } +} diff --git a/frontend/src/assets/i18n/en.json b/frontend/src/assets/i18n/en.json index 0566e16..8091b49 100644 --- a/frontend/src/assets/i18n/en.json +++ b/frontend/src/assets/i18n/en.json @@ -68,6 +68,15 @@ "TARGET_TEXT": "Small businesses, freelancers, makers and customers looking for a ready-made product from the shop.", "TEAM_TITLE": "Our Team" }, + "LOCATIONS": { + "TITLE": "Our Locations", + "SUBTITLE": "We have two locations to serve you better. Select a location to see details.", + "TICINO": "Ticino", + "BIENNE": "Bienne", + "ADDRESS_TICINO": "Ticino Office, Switzerland", + "ADDRESS_BIENNE": "Bienne Office, Switzerland", + "CONTACT_US": "Contact Us" + }, "CONTACT": { "TITLE": "Contact Us", "SEND": "Send Message", diff --git a/frontend/src/assets/i18n/it.json b/frontend/src/assets/i18n/it.json index d1ee0c5..98e4dc8 100644 --- a/frontend/src/assets/i18n/it.json +++ b/frontend/src/assets/i18n/it.json @@ -70,6 +70,15 @@ "TARGET_TEXT": "Piccole aziende, freelance, smanettoni e clienti che cercano un prodotto già pronto dallo shop.", "TEAM_TITLE": "Il Nostro Team" }, + "LOCATIONS": { + "TITLE": "Le Nostre Sedi", + "SUBTITLE": "Siamo presenti in due sedi per coprire meglio il territorio. Seleziona la sede per vedere i dettagli.", + "TICINO": "Ticino", + "BIENNE": "Bienne", + "ADDRESS_TICINO": "Sede Ticino, Svizzera", + "ADDRESS_BIENNE": "Sede Bienne, Svizzera", + "CONTACT_US": "Contattaci" + }, "CONTACT": { "TITLE": "Contattaci", "SEND": "Invia Messaggio",