Explorar el Código

feat: move printing nuances to a dedicated page and update navigation

unknown hace 2 meses
padre
commit
cfe53b47d9
Se han modificado 4 ficheros con 161 adiciones y 2 borrados
  1. 1 0
      src/components/Header.vue
  2. 0 2
      src/pages/Index.vue
  3. 159 0
      src/pages/Nuances.vue
  4. 1 0
      src/router/index.ts

+ 1 - 0
src/components/Header.vue

@@ -174,6 +174,7 @@ const isAdmin = computed(() => authStore.user?.role === "admin");
 const navLinks = computed(() => [
   { label: t("nav.services"), href: `/${activeLang.value}/#services`, isInternal: true },
   { label: t("nav.materials"), href: `/${activeLang.value}/#materials`, isInternal: true },
+  { label: t("nav.nuances"), href: `/${activeLang.value}/nuances`, isInternal: true },
   { label: t("nav.howItWorks"), href: `/${activeLang.value}/#process`, isInternal: true },
   { label: t("nav.portfolio"), href: `/${activeLang.value}/portfolio`, isInternal: true },
   { label: t("nav.philosophy"), href: `/${activeLang.value}/#philosophy`, isInternal: true },

+ 0 - 2
src/pages/Index.vue

@@ -4,7 +4,6 @@
     <main>
       <HeroSection />
       <ServicesSection />
-      <PrintingNuancesSection />
       <ModelUploadSection />
       <QuotingSection />
       <ProcessSection />
@@ -55,7 +54,6 @@ useHead({
   ]
 });
 
-const PrintingNuancesSection = defineAsyncComponent(() => import("@/components/PrintingNuancesSection.vue"));
 const ModelUploadSection = defineAsyncComponent(() => import("@/components/ModelUploadSection.vue"));
 const QuotingSection = defineAsyncComponent(() => import("@/components/QuotingSection.vue"));
 const ProcessSection = defineAsyncComponent(() => import("@/components/ProcessSection.vue"));

+ 159 - 0
src/pages/Nuances.vue

@@ -0,0 +1,159 @@
+<template>
+  <div class="min-h-screen bg-background">
+    <Header />
+    
+    <main class="pt-24 sm:pt-32 pb-20">
+      <div class="container mx-auto px-4">
+        <!-- Hero Section -->
+        <div class="text-center mb-16 animate-slide-up">
+          <span class="text-primary font-display text-sm tracking-widest uppercase mb-4 block">{{ t("nuances.subtitle") }}</span>
+          <h1 class="font-display text-4xl sm:text-5xl lg:text-6xl font-bold mb-6">
+            {{ t("nuances.title") }}
+          </h1>
+          <p class="text-muted-foreground max-w-2xl mx-auto text-lg leading-relaxed">
+            {{ t("nuances.description") }}
+          </p>
+        </div>
+
+        <!-- Nuances Grid -->
+        <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-7xl mx-auto">
+          <div 
+            v-for="(nuance, key) in nuances" 
+            :key="key"
+            class="group bg-card border border-border/50 rounded-[2rem] overflow-hidden hover:border-primary/30 transition-all duration-500 shadow-sm hover:shadow-xl"
+          >
+            <!-- Visual Example -->
+            <div class="aspect-video bg-muted overflow-hidden relative">
+              <img 
+                v-if="nuance.image" 
+                :src="nuance.image" 
+                :alt="t(`nuances.items.${key}.title`)"
+                loading="lazy"
+                class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
+              />
+              <div v-else class="w-full h-full flex items-center justify-center bg-primary/5">
+                <component :is="nuance.icon" class="w-12 h-12 text-primary/20" />
+              </div>
+              <div class="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
+            </div>
+
+            <!-- Content -->
+            <div class="p-8">
+              <div class="flex items-center gap-3 mb-4">
+                <div class="w-10 h-10 bg-primary/10 rounded-xl flex items-center justify-center text-primary group-hover:bg-primary group-hover:text-white transition-all duration-500">
+                  <component :is="nuance.icon" class="w-5 h-5" />
+                </div>
+                <h3 class="font-display text-xl font-bold">{{ t(`nuances.items.${key}.title`) }}</h3>
+              </div>
+              
+              <p class="text-muted-foreground mb-6 text-sm leading-relaxed">
+                {{ t(`nuances.items.${key}.description`) }}
+              </p>
+              
+              <div class="pt-6 border-t border-border/50">
+                <div class="flex items-start gap-3">
+                  <Info class="w-4 h-4 text-primary/40 mt-0.5" />
+                  <p class="text-xs text-muted-foreground/70 italic leading-relaxed">
+                    {{ t(`nuances.items.${key}.details`) }}
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- AI Disclaimer -->
+        <div class="mt-8 text-center animate-fade-in">
+          <p class="text-[10px] uppercase tracking-widest text-muted-foreground/40 font-bold flex items-center justify-center gap-2">
+            <Sparkles class="w-3 h-3" />
+            {{ t("nuances.aiDisclaimer") }}
+          </p>
+        </div>
+
+        <!-- Global Disclaimer -->
+        <div class="mt-20 max-w-4xl mx-auto p-8 sm:p-12 bg-primary/5 rounded-[2.5rem] border border-primary/10 relative overflow-hidden group">
+          <div class="relative z-10 flex flex-col md:flex-row items-center gap-8">
+            <div class="w-20 h-20 bg-white rounded-3xl flex items-center justify-center shadow-lg group-hover:rotate-12 transition-transform duration-500">
+              <ShieldCheck class="w-10 h-10 text-primary" />
+            </div>
+            <div class="text-center md:text-left">
+              <h2 class="font-display text-2xl font-bold mb-3">{{ t("nuances.disclaimer.title") }}</h2>
+              <p class="text-muted-foreground leading-relaxed">
+                {{ t("nuances.disclaimer.text") }}
+              </p>
+            </div>
+          </div>
+          <!-- Decor -->
+          <div class="absolute -top-12 -right-12 w-40 h-40 bg-primary/10 rounded-full blur-3xl" />
+        </div>
+      </div>
+    </main>
+
+    <Footer />
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useI18n } from "vue-i18n";
+import { computed } from "vue";
+import { useHead } from "@unhead/vue";
+import Header from "@/components/Header.vue";
+import Footer from "@/components/Footer.vue";
+import { 
+  Layers, 
+  Grid, 
+  Scaling, 
+  Spline, 
+  Triangle, 
+  Ruler, 
+  Palette, 
+  Zap,
+  Info,
+  ShieldCheck,
+  Sparkles
+} from "lucide-vue-next";
+
+const { t } = useI18n();
+
+useHead({
+  title: computed(() => t('nuances.title')),
+  meta: [
+    { name: 'description', content: computed(() => t('nuances.description')) }
+  ]
+});
+
+const nuances = {
+  layerStructure: {
+    image: "/fdm_layer_lines_photo_1776031229473.webp",
+    icon: Layers
+  },
+  supportMarks: {
+    image: "/fdm_supports_photo_1776031246690.webp",
+    icon: Scaling
+  },
+  zSeam: {
+    image: "/fdm_zseam_photo_1776031258273.webp",
+    icon: Spline
+  },
+  surfaceImperfections: {
+    image: "/fdm_surface_photo_1776031404133.webp",
+    icon: Grid
+  },
+  overhangs: {
+    image: "/fdm_overhangs_photo_v2_1776032258991.webp",
+    icon: Triangle
+  },
+  dimensionalTolerances: {
+    image: "/fdm_tolerances_photo_1776031451173.webp",
+    icon: Ruler
+  },
+  colorVariations: {
+    image: "/fdm_color_photo_1776031463894.webp",
+    icon: Palette
+  },
+  stringing: {
+    image: "/fdm_stringing_photo_1776031432344.webp",
+    icon: Zap
+  }
+};
+</script>

+ 1 - 0
src/router/index.ts

@@ -22,6 +22,7 @@ const routes = [
       { path: "contact",   name: "contact",   component: () => import("@/pages/Contact.vue"),   meta: { title: "Contact" } },
       { path: "help",      name: "help",      component: () => import("@/pages/HelpCenter.vue"), meta: { title: "Help Center" } },
       { path: "guidelines", name: "guidelines", component: () => import("@/pages/Guidelines.vue"), meta: { title: "Guidelines" } },
+      { path: "nuances",    name: "nuances",    component: () => import("@/pages/Nuances.vue"),    meta: { title: "Nuances" } },
       { path: "terms",     name: "terms",     component: () => import("@/pages/Terms.vue"),      meta: { title: "Terms of Service" } },
     ]
   },