#22 ✨ feat(responsividade): ajustes de layout e navegacao para mobile e tablet

Đã hợp nhất
joycekepler đã nhập 16 commit từ joycekepler/feature/IGAL-JOY-ajustes-de-responsividade vào [3]s 2 ngày trước cách đây

+ 4 - 0
app/assets/main.css

@@ -3,6 +3,10 @@
 
 @import url('https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
 
+html {
+  scroll-behavior: smooth;
+}
+
 body {
   font-family: 'Exo', sans-serif;
   color: #202020;

+ 87 - 12
app/components/AppHeader.vue

@@ -1,30 +1,105 @@
 <template>
-  <header class="absolute top-7 center-0 z-50 bg-black/60">
-    <nav class="w-full flex items-center justify-center h-[55px] px-4">
+  <header ref="headerRef" class="w-9/10 lg:w-auto absolute top-7 center-0 z-50 bg-black/80 lg:bg-black/60">
+    <nav class="flex items-center justify-center h-[55px] px-4 relative">
+      <div class="hidden md:flex items-center justify-center gap-1">
+        <NuxtLink
+          v-for="item in navItems"
+          :key="item.label"
+          :to="item.href"
+          class="relative text-xs font-open-sans font-semibold px-3 uppercase transition-colors duration-200 pb-1 leading-7"
+          :class="[
+            activeSection === item.href.slice(1)
+              ? 'text-[#E3FA6D] after:absolute after:bottom-0 after:left-0 after:w-full after:h-0.5 after:bg-[#E3FA6D]'
+              : 'text-white hover:text-white/85'
+          ]"
+        >
+          {{ item.label }}
+        </NuxtLink>
+      </div>
+
+      <NuxtLink to="#hero" class="md:hidden absolute left-4">
+        <NuxtImg src="/img/logo_2.png" class="h-9 w-auto object-contain" />
+      </NuxtLink>
+
+      <button
+        class="md:hidden absolute right-4 text-white focus:outline-none"
+        aria-label="Abrir menu"
+        @click.stop="menuOpen = !menuOpen"
+      >
+        <svg v-if="!menuOpen" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
+        </svg>
+        <svg v-else xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
+        </svg>
+      </button>
+    </nav>
+
+    <div
+      v-if="menuOpen"
+      class="md:hidden flex flex-col items-center py-4 gap-4"
+    >
       <NuxtLink
         v-for="item in navItems"
         :key="item.label"
         :to="item.href"
-        class="relative text-xs font-open-sans font-semibold px-3 uppercase transition-colors duration-200 pb-1 leading-7"
+        class="relative text-xs font-open-sans font-semibold uppercase transition-colors duration-200"
         :class="[
-          item.active
-            ? 'text-[#E3FA6D] after:absolute after:bottom-0 after:left-0 after:w-full after:h-0.5 after:bg-[#E3FA6D]'
+          activeSection === item.href.slice(1)
+            ? 'text-[#E3FA6D]'
             : 'text-white hover:text-white/85'
         ]"
+        @click="menuOpen = false"
       >
         {{ item.label }}
       </NuxtLink>
-    </nav>
+    </div>
   </header>
 </template>
 
 <script setup lang="ts">
+const menuOpen = ref(false)
+const headerRef = ref<HTMLElement | null>(null)
+const activeSection = ref('hero')
+
 const navItems = [
-  { label: 'Home', href: '#hero', active: true },
-  { label: 'A Imersão', href: '#imersao', active: false },
-  { label: 'Metodologia', href: '#metodologia', active: false },
-  { label: 'Executores', href: '#executores', active: false },
-  { label: 'Próximos Destinos', href: '#destinos', active: false },
-  { label: 'Contato', href: '#contato', active: false },
+  { label: 'Home', href: '#hero' },
+  { label: 'A Imersão', href: '#imersao' },
+  { label: 'Metodologia', href: '#metodologia' },
+  { label: 'Executores', href: '#executores' },
+  { label: 'Próximos Destinos', href: '#destinos' },
+  { label: 'Contato', href: '#contato' },
 ]
+
+function handleClickOutside(event: MouseEvent) {
+  if (menuOpen.value && headerRef.value && !headerRef.value.contains(event.target as Node)) {
+    menuOpen.value = false
+  }
+}
+
+onMounted(() => {
+  document.addEventListener('click', handleClickOutside)
+
+  const sectionIds = navItems.map(i => i.href.slice(1))
+  const observer = new IntersectionObserver(
+    (entries) => {
+      for (const entry of entries) {
+        if (entry.isIntersecting) {
+          activeSection.value = entry.target.id
+        }
+      }
+    },
+    { threshold: 0.3 }
+  )
+
+  sectionIds.forEach(id => {
+    const el = document.getElementById(id)
+    if (el) observer.observe(el)
+  })
+
+  onUnmounted(() => {
+    document.removeEventListener('click', handleClickOutside)
+    observer.disconnect()
+  })
+})
 </script>

+ 9 - 0
app/components/CtaButton.vue

@@ -0,0 +1,9 @@
+<template>
+  <button
+    class="group bg-linear-to-r from-[#8DC63F] to-[#5F980F] text-white text-lg md:text-xl lg:text-2xl font-semibold flex justify-center items-center gap-3 border border-[#E3FA6D] rounded-lg px-3 py-4 lg:py-6 lg:px-8 whitespace-nowrap transition-all duration-300 ease-in-out hover:scale-[1.03] hover:shadow-[0_0_28px_rgba(227,250,109,0.45)] hover:brightness-110 cursor-pointer"
+    v-bind="$attrs"
+  >
+    <slot>Fale com um especialista agora!</slot>
+    <NuxtImg src="/img/cta_btn_icon.svg" width="30" class="transition-transform duration-300 group-hover:translate-x-1.5" />
+  </button>
+</template>

+ 1 - 8
app/components/SectionDestinations.vue

@@ -33,14 +33,7 @@
           bg-position-class="md:bg-bottom lg:bg-position-[center_800%]"
         />
       </div>
-      <button
-        class="self-stretch lg:self-start group bg-linear-to-r from-[#8DC63F] to-[#5F980F] text-white text-base md:text-lg lg:text-[23px] font-semibold flex justify-center items-center gap-4 border border-[#E3FA6D] rounded-lg py-3 px-8 transition-all duration-300 ease-in-out hover:scale-[1.03] hover:shadow-[0_0_28px_rgba(227,250,109,0.45)] hover:brightness-110 cursor-pointer">
-        Fale com um especialista agora!
-        <NuxtImg 
-          src="/img/cta_btn_icon.svg"
-          class="w-6 md:w-8 lg:w-10 transition-transform duration-300 group-hover:translate-x-1.5" 
-        />
-      </button>
+      <CtaButton class="self-stretch lg:self-start justify-center" />
     </div>
   </section>
 </template>

+ 7 - 7
app/components/SectionExecutors.vue

@@ -1,29 +1,29 @@
 <template>
-  <section class="bg-[#F6FFE9] py-20 flex flex-col items-center gap-15">
-    <h2 class="text-[50px] uppercase text-[#080E00] font-semibold">
+  <section class="bg-[#F6FFE9] py-12 lg:py-20 flex flex-col items-center gap-15">
+    <h2 class="text-[40px] md:text-[46px] lg:text-[50px] uppercase text-[#080E00] font-semibold">
       Os Executores
     </h2>
 
-    <div class="w-full max-w-[1170px] flex flex-col gap-10 px-8">
+    <div class="w-full max-w-[1170px] flex flex-col gap-10 px-4">
       <div
         v-for="(executor, index) in executores"
         :key="index"
         class="flex flex-col lg:flex-row gap-12 items-center"
         :class="index % 2 === 1 ? 'lg:flex-row-reverse' : 'lg:flex-row'"
       >
-        <div class="flex-1 flex flex-col gap-5">
+        <div class="flex-1 flex flex-col gap-5 order-2 lg:order-0">
           <span class="self-start text-[10px] font-semibold text-[#F6FFE9] bg-[#8AAB10] border border-[#8DC63F] rounded-full py-2 px-4 uppercase tracking-wide">
             {{ executor.tag }}
           </span>
-          <h3 class="text-[40px] text-[#202121] font-semibold">
+          <h3 class="text-3xl md:text-4xl lg:text-[40px] text-[#202121] font-semibold">
             {{ executor.name }}
           </h3>
-          <p class="text-lg text-[#202121] font-medium">
+          <p class="text-base lg:text-lg text-[#202121] font-medium">
             {{ executor.description }}
           </p>
         </div>
 
-        <div class="shrink-0  w-full md:w-full lg:w-[496px] h-[420px] md:h-[520px] lg:h-[620px] overflow-hidden flex justify-center items-center">
+        <div class="shrink-0 w-full md:w-[340px] lg:w-[496px] h-[420px] md:h-[480px] lg:h-[620px] overflow-hidden flex justify-center items-center">
           <NuxtImg
             :src="executor.image"
             :alt="executor.name"

+ 1 - 1
app/components/SectionGallery.vue

@@ -1,5 +1,5 @@
 <template>
-  <section class="bg-[#050f05] py-16 flex flex-col items-center gap-20 overflow-hidden">
+  <section class="bg-[#050f05] py-12 md:py-16 flex flex-col items-center gap-20 overflow-hidden">
     <h2 class="max-w-[1021px] text-[22px] md:text-[32px] lg:text-[45px] text-center font-semibold text-white leading-snug md:leading-13 px-4">
       O programa não entrega apenas informação,
       <span class="text-gradient">conecta empresários ao ambiente onde decisões e oportunidades são construídas.</span>

+ 9 - 11
app/components/SectionHero.vue

@@ -1,21 +1,19 @@
 <template>
-  <section class="relative bg-[url('/img/hero_bg.png')] bg-cover bg-center h-screen flex justify-center">
+  <section class="relative bg-[url('/img/hero_bg.png')] bg-black bg-size-[380%_auto] md:bg-cover bg-top bg-no-repeat md:bg-center h-svh flex justify-center">
     <AppHeader />
-    <div class="w-[1241px] flex justify-between items-center absolute bottom-20">
-      <div class="flex flex-col gap-5 w-1/2">
-        <NuxtImg src="/img/logo.png" width="308" />
-        <h1 class="max-w-[620px] text-[46px] font-bold text-gradient">
+    <div class="md:hidden absolute inset-0 bg-linear-to-t from-black to-transparent z-0 pointer-events-none" />
+    <div class="w-full lg:max-w-7xl flex flex-col md:flex-row justify-between items-center absolute bottom-7 md:bottom-20 lg:bottom-10 xl:bottom-20 px-4">
+      <div class="flex flex-col gap-5 md:w-1/2">
+        <NuxtImg src="/img/logo_2.png" class="hidden md:block w-[308px]" />
+        <h1 class="text-3xl md:text-4xl lg:text-[46px] font-bold text-gradient">
           Não apenas planeje. Execute sua expansão internacional com segurança.
         </h1>
       </div>
-      <div class="flex flex-col gap-5 w-1/2 max-w-[516px]">
-        <p class="text-white text-2xl font-medium">
+      <div class="flex flex-col gap-5 md:w-1/2 md:max-w-[516px]">
+        <p class="text-white text-lg md:text-xl lg:text-2xl font-medium leading-9">
           A Iguassu Alliance conecta sua empresa ao ecossistema de negócios do Paraguai através da 3ª edição de programa estratégico.
         </p>
-        <button class="group self-start bg-linear-to-r from-[#8DC63F] to-[#5F980F] text-white text-2xl font-semibold flex items-center gap-3 border border-[#E3FA6D] rounded-lg py-6 px-8 whitespace-nowrap transition-all duration-300 ease-in-out hover:scale-[1.03] hover:shadow-[0_0_28px_rgba(227,250,109,0.45)] hover:brightness-110 cursor-pointer">
-          Fale com o um especialista agora!
-          <NuxtImg src="/img/cta_btn_icon.svg" width="30" class="transition-transform duration-300 group-hover:translate-x-1.5" />
-        </button>
+        <CtaButton class="md:self-start" />
       </div>
     </div>
   </section>

+ 1 - 6
app/components/SectionPartnership.vue

@@ -23,12 +23,7 @@
       />
     </div>
 
-    <button class="group bg-linear-to-r from-[#8DC63F] to-[#5F980F] 
-    text-white text-[23px] font-semibold flex justify-center items-center gap-4 border border-[#E3FA6D] rounded-lg py-3 px-8 
-    transition-all duration-300 ease-in-out hover:scale-[1.03] hover:shadow-[0_0_28px_rgba(227,250,109,0.45)] hover:brightness-110 cursor-pointer m-4 md:mt-0">
-      Fale com um especialista agora!
-      <NuxtImg src="/img/cta_btn_icon.svg" width="45" class="transition-transform duration-300 group-hover:translate-x-1.5" />
-    </button>
+    <CtaButton class="justify-center m-4 md:mt-0" />
   </section>
 
 </template>

+ 4 - 3
app/components/SectionRoadMap.vue

@@ -1,11 +1,12 @@
 <template>
-  <section class="bg-[url('/img/roadmap_bg.png')] bg-cover py-24 flex flex-col items-center gap-24">
-    <h1 class="max-w-[762px] text-[50px] uppercase font-semibold text-gradient text-center leading-tight">
+  <section class="bg-[url('/img/roadmap_bg.png')] bg-cover py-16 lg:py-24 flex flex-col items-center gap-16 lg:gap-24 px-4">
+    <h1 class="max-w-[762px] text-4xl md:text-[40px] lg:text-[50px] uppercase font-semibold text-gradient text-center leading-tight">
       É hora de viver os melhores anos da sua vida
     </h1>
 
     <div>
-      <NuxtImg src="/img/roadmap_img.png" width="950" />
+      <NuxtImg src="/img/roadmap_img.png" width="950" class="hidden md:block" />
+      <NuxtImg src="/img/roadmap_img_mobile.png" class="w-full block md:hidden" />
     </div>
   </section>
 </template>

+ 19 - 14
app/components/SectionSecondary.vue

@@ -1,28 +1,33 @@
 <template>
-  <section class="w-full bg-[#080E00] relative flex flex-col items-center justify-end overflow-hidden" :style="{ minHeight: '1556px' }">
-    <NuxtImg src="/img/hexagon.svg" width="1546" class="absolute inset-0 m-auto z-0 pointer-events-none" aria-hidden="true" />
-    <NuxtImg src="/img/hexagons_right.svg" class="absolute top-0 left-0 z-10 pointer-events-none" aria-hidden="true" />
-    <NuxtImg src="/img/hexagons_left.svg" class="absolute bottom-0 right-0 z-10 pointer-events-none" aria-hidden="true" />
+  <section class="w-full bg-[#080E00] pt-20 md:pt-32 lg:pt-46 relative flex flex-col items-center justify-end overflow-hidden px-4">
+    <NuxtImg src="/img/hexagon.svg" width="1546" class="absolute inset-0 m-auto z-0 pointer-events-none hidden sm:block" aria-hidden="true" />
+    <NuxtImg src="/img/hexagons_right.svg" class="absolute top-0 left-0 lg:z-50 pointer-events-none w-1/2 sm:w-auto" aria-hidden="true" />
+    <NuxtImg src="/img/hexagons_left.svg" class="absolute bottom-0 right-0 lg:z-50 pointer-events-none w-1/2 sm:w-auto" aria-hidden="true" />
 
-    <div class="bg-[#F6FFE9] rounded-t-[30px] flex flex-col gap-5 justify-center items-center text-center relative z-20 px-4 mx-auto">
-      <NuxtImg src="/img/arrow_group.svg" width="220" />
-      <NuxtImg src="/img/logo.png" width="330" />
-      <h1 class="max-w-[788px] text-6xl uppercase bg-linear-to-r to-[#474747] from-[#111111] bg-clip-text text-transparent font-semibold">
+    <div class="w-full sm:w-5/6 lg:w-[70%] xl:w-full xl:max-w-[1189px] bg-[#F6FFE9] rounded-t-[30px] flex flex-col gap-3 md:gap-5 justify-center items-center text-center relative z-20 px-4 md:px-10 pb-8 md:pb-16 lg:pb-24 mx-auto">
+      <NuxtImg src="/img/paraguay_flag.png" class="w-40 md:w-80 lg:w-150 absolute left-2 md:left-12 lg:left-24 bottom-0" />
+      <NuxtImg src="/img/arrow_group.svg" width="220" class="w-32 md:w-44 lg:w-[220px]" />
+      <NuxtImg src="/img/logo.png" width="330" class="w-48 md:w-64 lg:w-[330px]" />
+      <h1 class="w-full lg:max-w-[788px] text-3xl md:text-5xl xl:text-6xl uppercase bg-linear-to-r to-[#474747] from-[#111111] bg-clip-text text-transparent font-semibold">
         Onde a ESTRATÉGIA encontra a Execução!
       </h1>
-      <p class="text-2xl text-[#202020] max-w-[532px]">
+      <p class="text-base md:text-xl lg:text-2xl text-[#202020] lg:max-w-[532px]">
         Muitos empresários conhecem a teoria, <span class="font-bold">mas poucos dominam o "como".</span>
       </p>
-      <p class="text-2xl text-[#202020] max-w-[640px]">
+      <p class="text-base md:text-xl lg:text-2xl text-[#202020] lg:max-w-[640px]">
         Utilizamos a metodologia consolidada do Expansão Sem Fronteiras <span class="font-bold">para entregar o que você
           realmente precisa:</span>
       </p>
-      <div class="flex items-center gap-3">
-        <div v-for="delivery in deliverys" :key="delivery" class="border border-[#E6E6E6] rounded-full px-6 py-2">
-          <span class="text-xl text-[#A7A7A7] font-medium">{{ delivery }}</span>
+      <div class="flex flex-wrap justify-center items-center gap-3">
+        <div
+          v-for="delivery in deliverys"
+          :key="delivery"
+          class="border border-[#E6E6E6] rounded-full px-4 md:px-6 py-2"
+        >
+          <span class="text-base md:text-lg lg:text-xl text-[#A7A7A7] font-medium">{{ delivery }}</span>
         </div>
       </div>
-      <NuxtImg src="/img/group.png" width="800" />
+      <NuxtImg src="/img/group.png" width="890" class="w-full max-w-[890px]" />
     </div>
   </section>
 </template>

+ 10 - 10
app/components/SectionTertiary.vue

@@ -1,22 +1,22 @@
 <template>
-  <section class="relative bg-[url('/img/section_tertiary_bg.svg')] bg-cover py-28 flex items-center justify-center overflow-hidden">
-    <div class="relative z-10 w-[525px] flex flex-col justify-center gap-10 ml-24">
-      <h2 class="max-w-[452px] text-[50px] uppercase font-semibold text-gradient leading-tight">
+  <section class="relative bg-[url('/img/section_tertiary_bg.svg')] bg-cover py-16 lg:py-28 flex items-center justify-center px-4">
+    <div class="relative z-10 lg:w-[525px] flex flex-col justify-center gap-10 lg:ml-10 xl:ml-20">
+      <h2 class="lg:max-w-[452px] text-4xl md:text-[46px] lg:text-[50px] uppercase font-semibold text-gradient leading-tight">
         IMERSÃO IGUASSU ALLIANCE
       </h2>
-      <div class="flex flex-col gap-5">
+      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-1 gap-5 w-full">
         <SectionTertiaryCard
           v-for="(card, index) in cards" :key="index"
-          :title="card.title" 
-          :description="card.description" 
+          :title="card.title"
+          :description="card.description"
         />
       </div>
     </div>
 
-    <NuxtImg 
-      src="/img/hexagons_photos.png" 
-      width="1000" 
-      class="relative -ml-45 z-0" 
+    <NuxtImg
+      src="/img/hexagons_photos.png"
+      width="1000"
+      class="hidden lg:block relative lg:w-[580px] xl:w-[700px] lg:-ml-16 xl:-ml-30 z-0"
     />
   </section>
 </template>

+ 4 - 4
app/components/SectionTertiaryCard.vue

@@ -1,10 +1,10 @@
 <template>
-    <div class="w-full h-[285px] px-10 py-5 bg-[url('/img/section_tertiary_card_bg.png')] bg-cover border border-[#E3FA6D80] rounded-[10px] flex flex-col gap-[9px]">
-        <NuxtImg src="/img/card_tertiary_img.svg" width="106" />
-        <h3 class="text-[27px] font-bold text-gradient">
+    <div class="w-full lg:h-60 px-5 lg:px-10 py-5 bg-[url('/img/section_tertiary_card_bg.png')] bg-cover border border-[#E3FA6D80] rounded-[10px] flex flex-col gap-3">
+        <NuxtImg src="/img/logo_2.png" width="160" />
+        <h3 class="text-xl md:text-2xl lg:text-[27px] font-bold text-gradient">
             {{ title }}
         </h3>
-        <p class="text-[22px] text-white max-w-[352px] leading-6.5">
+        <p class="text-base mt:text-lg lg:text-[22px] text-white max-w-[352px] leading-6.5">
             {{ description }}
         </p>
     </div>

+ 6 - 6
app/pages/index.vue

@@ -1,13 +1,13 @@
 <template>
-  <SectionHero />
-  <SectionSecondary />
+  <SectionHero id="hero" />
+  <SectionSecondary id="imersao" />
   <SectionTertiary />
   <SectionPartnership />
-  <SectionRoadMap />
-  <SectionExecutors />
+  <SectionRoadMap id="metodologia" />
+  <SectionExecutors id="executores" />
   <SectionGallery />
-  <SectionDestinations />
-  <FormSection />
+  <SectionDestinations id="destinos" />
+  <FormSection id="contato" />
   <FaqSection />
 </template>
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 8
public/img/card_tertiary_img.svg


BIN
public/img/logo.png


BIN
public/img/roadmap_img_mobile.png


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác