dev #8

Closed
JoeKung wants to merge 72 commits from dev into int
14 changed files with 221 additions and 51 deletions
Showing only changes of commit b6230e69e4 - Show all commits

View File

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

View File

@@ -63,28 +63,28 @@
<div class="cap-cards"> <div class="cap-cards">
<app-card> <app-card>
<div class="card-image-placeholder"> <div class="card-image-placeholder">
<!-- <img src="..." alt="..."> --> <img src="assets/images/home/prototipi.jpg" alt="">
</div> </div>
<h3>{{ 'HOME.CAP_1_TITLE' | translate }}</h3> <h3>{{ 'HOME.CAP_1_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_1_TEXT' | translate }}</p> <p class="text-muted">{{ 'HOME.CAP_1_TEXT' | translate }}</p>
</app-card> </app-card>
<app-card> <app-card>
<div class="card-image-placeholder"> <div class="card-image-placeholder">
<!-- <img src="..." alt="..."> --> <img src="assets/images/home/original-vs-3dprinted.jpg" alt="">
</div> </div>
<h3>{{ 'HOME.CAP_2_TITLE' | translate }}</h3> <h3>{{ 'HOME.CAP_2_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_2_TEXT' | translate }}</p> <p class="text-muted">{{ 'HOME.CAP_2_TEXT' | translate }}</p>
</app-card> </app-card>
<app-card> <app-card>
<div class="card-image-placeholder"> <div class="card-image-placeholder">
<!-- <img src="..." alt="..."> --> <img src="assets/images/home/serie.jpg" alt="">
</div> </div>
<h3>{{ 'HOME.CAP_3_TITLE' | translate }}</h3> <h3>{{ 'HOME.CAP_3_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_3_TEXT' | translate }}</p> <p class="text-muted">{{ 'HOME.CAP_3_TEXT' | translate }}</p>
</app-card> </app-card>
<app-card> <app-card>
<div class="card-image-placeholder"> <div class="card-image-placeholder">
<!-- <img src="..." alt="..."> --> <img src="assets/images/home/cad.jpg" alt="">
</div> </div>
<h3>{{ 'HOME.CAP_4_TITLE' | translate }}</h3> <h3>{{ 'HOME.CAP_4_TITLE' | translate }}</h3>
<p class="text-muted">{{ 'HOME.CAP_4_TEXT' | translate }}</p> <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> <app-button variant="outline" routerLink="/contact">{{ 'HOME.BTN_REQ_SOLUTION' | translate }}</app-button>
</div> </div>
</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"> <div class="shop-cards">
<app-card> <app-card>
<h3>{{ 'HOME.CARD_SHOP_1_TITLE' | translate }}</h3> <h3>{{ 'HOME.CARD_SHOP_1_TITLE' | translate }}</h3>
@@ -134,12 +139,36 @@
<p> <p>
{{ 'HOME.SEC_ABOUT_TEXT' | translate }} {{ 'HOME.SEC_ABOUT_TEXT' | translate }}
</p> </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>
<div class="about-media"> <div class="about-media">
<div class="about-feature-image"> <div class="about-feature-image">
<!-- Foto founders --> <img
<span class="text-sm">{{ 'HOME.FOUNDERS_PHOTO' | translate }}</span> 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> </div>
</div> </div>

View File

@@ -1,14 +1,16 @@
@use '../../../styles/patterns'; @use '../../../styles/patterns';
.home-page { .home-page {
background: var(--color-bg); --home-bg: #faf9f6;
--color-bg-card: #f7f7f7;
background: var(--home-bg);
} }
.hero { .hero {
position: relative; position: relative;
padding: 6rem 0 5rem; padding: 6rem 0 5rem;
overflow: hidden; overflow: hidden;
background: var(--color-bg); background: var(--home-bg);
// Enhanced Grid Pattern // Enhanced Grid Pattern
&::after { &::after {
content: ''; content: '';
@@ -43,7 +45,7 @@
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
.hero-copy { animation: fadeUp 0.8s ease both; } .hero-copy { animation: fadeUp 0.8s ease both; }
.hero-panel { animation: fadeUp 0.8s ease 0.15s both; } .hero-panel { animation: fadeUp 0.8s ease 0.15s both; }
@@ -194,7 +196,7 @@
.capabilities-bg { .capabilities-bg {
display: none; display: none;
} }
.section { padding: 5.5rem 0; position: relative; } .section { padding: 5.5rem 0; position: relative; }
.section-head { margin-bottom: var(--space-8); } .section-head { margin-bottom: var(--space-8); }
.section-title { font-size: clamp(2rem, 1.8vw + 1.2rem, 2.8rem); margin-bottom: var(--space-3); } .section-title { font-size: clamp(2rem, 1.8vw + 1.2rem, 2.8rem); margin-bottom: var(--space-3); }
@@ -222,7 +224,7 @@
gap: var(--space-4); gap: var(--space-4);
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
} }
.card-image-placeholder { .card-image-placeholder {
width: 100%; width: 100%;
height: 160px; height: 160px;
@@ -234,20 +236,23 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: var(--color-neutral-400); color: var(--color-neutral-400);
overflow: hidden;
}
.card-image-placeholder img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
} }
.shop { .shop {
background: var(--color-neutral-50); background: var(--home-bg);
position: relative; position: relative;
// Triangular/Isogrid Pattern }
&::before { .shop .split { align-items: start; }
content: ''; .shop-copy {
position: absolute; max-width: 760px;
inset: 0;
@include patterns.pattern-triangular(var(--color-neutral-900), 40px);
opacity: 0.03;
pointer-events: none;
}
} }
.split { .split {
display: grid; display: grid;
@@ -266,25 +271,61 @@
flex-wrap: wrap; flex-wrap: wrap;
gap: var(--space-3); 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 { .shop-cards {
display: grid; display: grid;
gap: var(--space-4); gap: var(--space-4);
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); 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 { .about {
background: var(--color-neutral-50); background: transparent;
border-top: 1px solid var(--color-border); border-top: 1px solid var(--color-border);
position: relative; position: relative;
// Gyroid Pattern }
&::before { .about-actions {
content: ''; display: flex;
position: absolute; flex-wrap: wrap;
inset: 0; gap: var(--space-3);
@include patterns.pattern-gyroid(var(--color-neutral-900), 40px);
opacity: 0.03;
pointer-events: none;
}
} }
.about-grid { .about-grid {
display: grid; display: grid;
@@ -293,20 +334,61 @@
} }
.about-media { .about-media {
position: relative; position: relative;
display: flex;
justify-content: flex-end;
} }
.about-feature-image { .about-feature-image {
width: 100%; width: 100%;
height: 100%; max-width: 620px;
min-height: 320px; aspect-ratio: 16 / 10;
object-fit: cover;
border-radius: var(--radius-lg); border-radius: var(--radius-lg);
background: var(--color-neutral-100); background: var(--color-neutral-100);
border: 1px solid var(--color-border); 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; align-items: center;
justify-content: 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 { .media-tile p {
margin: 0; margin: 0;
@@ -322,12 +404,38 @@
.calculator-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; } .calculator-grid { grid-template-columns: 1.1fr 0.9fr; }
.split { 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; } .about-grid { grid-template-columns: 1.1fr 0.9fr; }
} }
@media (max-width: 640px) { @media (max-width: 640px) {
.hero-actions { flex-direction: column; align-items: stretch; } .hero-actions { flex-direction: column; align-items: stretch; }
.quote-meta { grid-template-columns: 1fr; } .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 { @keyframes fadeUp {

View File

@@ -12,4 +12,38 @@ import { AppCardComponent } from '../../shared/components/app-card/app-card.comp
templateUrl: './home.component.html', templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'] 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", "BTN_CONTACT": "Parla con noi",
"SEC_CALC_TITLE": "Prezzo corretto in pochi secondi", "SEC_CALC_TITLE": "Prezzo corretto in pochi secondi",
"SEC_CALC_SUBTITLE": "Nessuna registrazione necessaria. La stima è effettuata tramite vero slicing.", "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_EYEBROW": "Calcolo automatico",
"CARD_CALC_TITLE": "Prezzo e tempi in un click", "CARD_CALC_TITLE": "Prezzo e tempi in un click",
"CARD_CALC_TAG": "Senza registrazione", "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) // 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) { @mixin pattern-honeycomb($color, $size: 32px) {
background-image: background-color: transparent;
radial-gradient(circle, transparent 65%, $color 66%, $color 70%, transparent 71%); 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 $size; background-size: $size calc(#{$size} * 0.8653846);
// This creates a "Dot/Ring" pattern that resembles printed layers or nozzle paths background-position: 0 0;
// A true CSS honeycomb is complex and brittle across browsers. background-repeat: repeat;
// Using this "Nozzle Path" aesthetic instead which feels organic.
} }
// 4. Diagonal (Rectilinear 45deg) // 4. Diagonal (Rectilinear 45deg)

View File

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