feat(frontend): update images, and desing home
All checks were successful
Build, Test and Deploy / test-backend (push) Successful in 42s
Build, Test and Deploy / build-and-push (push) Successful in 42s
Build, Test and Deploy / deploy (push) Successful in 10s

This commit is contained in:
2026-02-26 19:09:59 +01:00
parent c58d674a70
commit b6230e69e4
14 changed files with 221 additions and 51 deletions

View File

@@ -277,8 +277,8 @@
</td>
<td class="seller-block">
<div th:text="${sellerDisplayName}">3D Fab Switzerland</div>
<div th:text="${sellerAddressLine1}">Sede Ticino, Svizzera</div>
<div th:text="${sellerAddressLine2}">Sede Bienne, Svizzera</div>
<div th:text="${sellerAddressLine1}">Via G. pioda 29a - 6710 Biasca, Svizzera</div>
<div th:text="${sellerAddressLine2}">Lyss-Strasse 71 - 2560 Nidau, Svizzera</div>
</td>
<td class="website-block">
www.3d-fab.ch

View File

@@ -63,28 +63,28 @@
<div class="cap-cards">
<app-card>
<div class="card-image-placeholder">
<!-- <img src="..." alt="..."> -->
<img src="assets/images/home/prototipi.jpg" alt="">
</div>
<h3>{{ 'HOME.CAP_1_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_1_TEXT' | translate }}</p>
</app-card>
<app-card>
<div class="card-image-placeholder">
<!-- <img src="..." alt="..."> -->
<img src="assets/images/home/original-vs-3dprinted.jpg" alt="">
</div>
<h3>{{ 'HOME.CAP_2_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_2_TEXT' | translate }}</p>
</app-card>
<app-card>
<div class="card-image-placeholder">
<!-- <img src="..." alt="..."> -->
<img src="assets/images/home/serie.jpg" alt="">
</div>
<h3>{{ 'HOME.CAP_3_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_3_TEXT' | translate }}</p>
</app-card>
<app-card>
<div class="card-image-placeholder">
<!-- <img src="..." alt="..."> -->
<img src="assets/images/home/cad.jpg" alt="">
</div>
<h3>{{ 'HOME.CAP_4_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_4_TEXT' | translate }}</p>
@@ -110,6 +110,11 @@
<app-button variant="outline" routerLink="/contact">{{ 'HOME.BTN_REQ_SOLUTION' | translate }}</app-button>
</div>
</div>
<div class="shop-gallery" tabindex="0" aria-label="Gallery prodotti shop">
<figure class="shop-gallery-item" *ngFor="let image of shopGalleryImages">
<img [src]="image.src" [alt]="image.alt">
</figure>
</div>
<div class="shop-cards">
<app-card>
<h3>{{ 'HOME.CARD_SHOP_1_TITLE' | translate }}</h3>
@@ -134,12 +139,36 @@
<p>
{{ 'HOME.SEC_ABOUT_TEXT' | translate }}
</p>
<app-button variant="outline" routerLink="/contact">{{ 'HOME.BTN_CONTACT' | translate }}</app-button>
<div class="about-actions">
<app-button variant="primary" routerLink="/about">{{ 'HOME.SEC_ABOUT_TITLE' | translate }}</app-button>
<app-button variant="outline" routerLink="/contact">{{ 'HOME.BTN_CONTACT' | translate }}</app-button>
</div>
</div>
<div class="about-media">
<div class="about-feature-image">
<!-- Foto founders -->
<span class="text-sm">{{ 'HOME.FOUNDERS_PHOTO' | translate }}</span>
<img
class="about-feature-photo"
[src]="founderImages[founderImageIndex].src"
[alt]="founderImages[founderImageIndex].alt"
width="1200"
height="900"
>
<button
type="button"
class="founder-nav founder-nav-prev"
(click)="prevFounderImage()"
aria-label="Foto precedente"
>
</button>
<button
type="button"
class="founder-nav founder-nav-next"
(click)="nextFounderImage()"
aria-label="Foto successiva"
>
</button>
</div>
</div>
</div>

View File

@@ -1,14 +1,16 @@
@use '../../../styles/patterns';
.home-page {
background: var(--color-bg);
--home-bg: #faf9f6;
--color-bg-card: #f7f7f7;
background: var(--home-bg);
}
.hero {
position: relative;
padding: 6rem 0 5rem;
overflow: hidden;
background: var(--color-bg);
background: var(--home-bg);
// Enhanced Grid Pattern
&::after {
content: '';
@@ -234,20 +236,23 @@
align-items: center;
justify-content: center;
color: var(--color-neutral-400);
overflow: hidden;
}
.card-image-placeholder img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.shop {
background: var(--color-neutral-50);
background: var(--home-bg);
position: relative;
// Triangular/Isogrid Pattern
&::before {
content: '';
position: absolute;
inset: 0;
@include patterns.pattern-triangular(var(--color-neutral-900), 40px);
opacity: 0.03;
pointer-events: none;
}
}
.shop .split { align-items: start; }
.shop-copy {
max-width: 760px;
}
.split {
display: grid;
@@ -266,25 +271,61 @@
flex-wrap: wrap;
gap: var(--space-3);
}
.shop-gallery {
display: flex;
gap: var(--space-4);
overflow-x: auto;
scroll-snap-type: x mandatory;
padding-bottom: var(--space-2);
scrollbar-width: thin;
width: min(100%, 440px);
justify-self: end;
aspect-ratio: 16 / 11;
}
.shop-gallery-item {
flex: 0 0 100%;
margin: 0;
border-radius: var(--radius-lg);
overflow: hidden;
border: 1px solid var(--color-border);
background: var(--color-neutral-100);
box-shadow: var(--shadow-sm);
scroll-snap-align: start;
aspect-ratio: 16 / 10;
}
.shop-gallery-item img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.shop-cards {
display: grid;
gap: var(--space-4);
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.shop-cards h3 {
margin-top: 0;
margin-bottom: var(--space-2);
}
.shop-cards p {
margin: 0;
}
.about {
background: var(--color-neutral-50);
background: transparent;
border-top: 1px solid var(--color-border);
position: relative;
// Gyroid Pattern
&::before {
content: '';
position: absolute;
inset: 0;
@include patterns.pattern-gyroid(var(--color-neutral-900), 40px);
opacity: 0.03;
pointer-events: none;
}
}
.about-actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-3);
}
.about-grid {
display: grid;
@@ -293,20 +334,61 @@
}
.about-media {
position: relative;
display: flex;
justify-content: flex-end;
}
.about-feature-image {
width: 100%;
height: 100%;
min-height: 320px;
object-fit: cover;
max-width: 620px;
aspect-ratio: 16 / 10;
border-radius: var(--radius-lg);
background: var(--color-neutral-100);
border: 1px solid var(--color-border);
display: flex;
position: relative;
overflow: hidden;
contain: layout paint;
}
.about-feature-photo {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.founder-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 2.25rem;
height: 2.25rem;
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, 0.6);
background: rgba(17, 24, 39, 0.45);
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--color-text-muted);
font-size: 1.5rem;
line-height: 1;
cursor: pointer;
z-index: 1;
transition: background-color 0.2s ease;
}
.founder-nav:hover {
background: rgba(17, 24, 39, 0.7);
}
.founder-nav-prev { left: 0.75rem; }
.founder-nav-next { right: 0.75rem; }
.founder-nav:focus-visible {
outline: 2px solid var(--color-brand);
outline-offset: 2px;
}
.media-tile p {
margin: 0;
@@ -322,12 +404,38 @@
.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; }
.shop-copy { grid-column: 1; }
.shop-gallery { grid-column: 2; }
.shop-cards {
grid-column: 1 / -1;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.about-grid { grid-template-columns: 1.1fr 0.9fr; }
}
@media (max-width: 640px) {
.hero-actions { flex-direction: column; align-items: stretch; }
.quote-meta { grid-template-columns: 1fr; }
.shop-gallery {
width: min(100%, 320px);
justify-self: start;
}
.shop-gallery-item {
aspect-ratio: 16 / 11;
}
.shop-cards { grid-template-columns: 1fr; }
.about-media {
justify-content: flex-start;
}
.about-feature-image {
max-width: min(100%, 360px);
aspect-ratio: 16 / 11;
}
.founder-nav {
width: 2rem;
height: 2rem;
font-size: 1.25rem;
}
}
@keyframes fadeUp {

View File

@@ -12,4 +12,38 @@ import { AppCardComponent } from '../../shared/components/app-card/app-card.comp
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent {}
export class HomeComponent {
readonly shopGalleryImages = [
{
src: 'assets/images/home/supporto-bici.jpg',
alt: 'Prodotto tecnico stampato in 3D'
}
];
readonly founderImages = [
{
src: 'assets/images/home/da-cambiare.jpg',
alt: 'Founder - da cambiare'
},
{
src: 'assets/images/home/vino.JPG',
alt: 'Founder - vino'
}
];
founderImageIndex = 0;
prevFounderImage(): void {
this.founderImageIndex =
this.founderImageIndex === 0
? this.founderImages.length - 1
: this.founderImageIndex - 1;
}
nextFounderImage(): void {
this.founderImageIndex =
this.founderImageIndex === this.founderImages.length - 1
? 0
: this.founderImageIndex + 1;
}
}

View File

@@ -21,7 +21,7 @@
"BTN_CONTACT": "Parla con noi",
"SEC_CALC_TITLE": "Prezzo corretto in pochi secondi",
"SEC_CALC_SUBTITLE": "Nessuna registrazione necessaria. La stima è effettuata tramite vero slicing.",
"SEC_CALC_LIST_1": "Formati supportati: STL, 3MF, STEP, OBJ",
"SEC_CALC_LIST_1": "Formati supportati: STL, 3MF, STEP",
"CARD_CALC_EYEBROW": "Calcolo automatico",
"CARD_CALC_TITLE": "Prezzo e tempi in un click",
"CARD_CALC_TAG": "Senza registrazione",

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1018 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -25,14 +25,13 @@
}
// 3. Hexagonal (Honeycomb Infill)
// Best structural integrity to weight ratio.
// Flat top-view hex lattice (no 3D depth effect).
@mixin pattern-honeycomb($color, $size: 32px) {
background-image:
radial-gradient(circle, transparent 65%, $color 66%, $color 70%, transparent 71%);
background-size: $size $size;
// This creates a "Dot/Ring" pattern that resembles printed layers or nozzle paths
// A true CSS honeycomb is complex and brittle across browsers.
// Using this "Nozzle Path" aesthetic instead which feels organic.
background-color: transparent;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='52' height='45' viewBox='0 0 52 45'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.25'%3E%3Cpath d='M13 0H39L52 22.5L39 45H13L0 22.5Z'/%3E%3Cpath d='M39 -22.5H65L78 0L65 22.5H39L26 0Z'/%3E%3Cpath d='M39 22.5H65L78 45L65 67.5H39L26 45Z'/%3E%3C/g%3E%3C/svg%3E");
background-size: $size calc(#{$size} * 0.8653846);
background-position: 0 0;
background-repeat: repeat;
}
// 4. Diagonal (Rectilinear 45deg)

View File

@@ -1,9 +1,9 @@
/* src/styles/theme.scss */
@use 'tokens';
@use './tokens';
:root {
/* Semantic Colors - Theming Layer */
--color-bg: #ffffff;
--color-bg: #faf9f6;
--color-bg-card: #ffffff;
--color-text: var(--color-neutral-900);
--color-text-muted: var(--color-secondary-500);