Parcourir la source

컨테이너사이즈 1920 max 처리

송용우 il y a 1 mois
Parent
commit
b2c34e5cbb

+ 228 - 108
app/assets/scss/admin.scss

@@ -142,7 +142,8 @@ html {
 
 //풀사이즈 레이아웃 구성
 .detail--container--full{
-
+  max-width:1920px;
+  margin:0 auto;
   .thumb--solo{
     overflow: hidden;
     border-radius: 20px;    
@@ -371,6 +372,10 @@ html {
   width:100%;
   position: relative;
 
+  &.video{
+
+  }
+
 
   &.mask--hidden{
     &:before{
@@ -380,9 +385,11 @@ html {
 
   &[data-type="cover"] {
     >div {
-      position: relative;
-      height:100vh;
+      position: relative;      
       overflow: hidden;
+      &:nth-of-type(1){
+        height:100vh;
+      }
     }
     img{
       object-fit: cover;
@@ -458,6 +465,53 @@ html {
     }
   }
 
+  &[data-text-location="topleft"]{
+
+  }
+
+  
+  &[data-text-location="bottomleft"]{
+    &:before{
+      background: linear-gradient(rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0) 50%);    
+    }
+
+    .alt--text{      
+      bottom:auto;
+      top:40px;      
+    }
+
+    .sub--title{
+      bottom:auto;
+      top:90px;
+    }
+
+    .btn--wrapper{
+      bottom:auto;
+      top:150px;
+    }
+  }
+
+
+  .caution--text--small{
+    margin: 0px;
+    color: rgba(252, 252, 253, 0.7);    
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 12px;
+    line-height: 20px;
+    font-stretch: 105%;
+    padding: 0 var(--page-margin) var(--spacing-relative-xl) var(--page-margin);
+
+    @media (min-width: 768px) {      
+      background: transparent;
+      pointer-events: auto;
+      padding: var(--spacing-relative-lg) var(--page-margin) var(--spacing-relative-xl) var(--page-margin);
+    }  
+  }
+
+
+
   .alt--text{   
     color: rgb(252, 252, 253);    
     letter-spacing: 0px;
@@ -510,125 +564,191 @@ html {
     gap:10px;
   }
 
+
+
+  &.video{
+    &[data-text-location="bottomleft"]{
+      &:before{
+        background: linear-gradient(rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0) 50%);    
+      }
+  
+      .alt--text{              
+        top:auto;
+        bottom:330px;      
+      }
+  
+      .sub--title{        
+        top:auto;
+        bottom:90px;
+      }
+  
+      .btn--wrapper{        
+        top:auto;
+        bottom:250px;
+
+        .default--round--btn{
+          background: rgb(101, 112, 129);
+          color: rgb(252, 252, 253);
+          box-shadow: rgba(101, 112, 129, 0) 0px 0px 0px 1px inset;
+          transition-property: color, background, box-shadow;
+          &:hover{
+            background: rgb(44, 52, 63);
+            color: rgb(252, 252, 253);
+            box-shadow: rgba(219, 223, 230, 0.2) 0px 0px 0px 1px inset;
+          }
+
+          &.reverse{
+            background-color: rgb(24, 29, 37);
+            color: rgb(252, 252, 253);
+            box-shadow: rgb(44, 52, 63) 0px 0px 0px 1px inset;
+            transition-property: color, box-shadow, background-color;
+
+            &:hover{
+              background-color: rgb(44, 52, 63);
+              color: rgb(252, 252, 253);
+              box-shadow: rgba(219, 223, 230, 0.2) 0px 0px 0px 1px inset;
+            }
+          }
+        }
+
+      }
+    }
+  }
+
 }
 
 
 //풀사이즈 패럴렉스 1형
-.prallax--banner--wrapper{
-  position: relative;
-  overflow: hidden;
-  height:1000px;
-  
-  .prallax--banner{
-    position: absolute;    
-    width: 100%;
-    height: 120%;    
-    transform: translate3d(0, 0, 0); // 초기값 GPU 레이어 생성
-    -webkit-transform: translate3d(0, 0, 0);
-    backface-visibility: hidden;
-    -webkit-backface-visibility: hidden;
-    //perspective: 1000px;
-    //-webkit-perspective: 1000px;
-    position: absolute;
-    top: -17%;
-    left: 50%;
-    will-change: transform;
-    backface-visibility: hidden;
+.prallax--banner--wrappers{
+  width:100%;
+  .prallax--banner--wrapper{
+    position: relative;
+    overflow: hidden;
+    width:100%;
+    height:1000px;
     
-    picture {
+    .prallax--banner{      
       width: 100%;
-      height: 100%;
-      display: block;
+      height: 120%;    
+      transform: translate3d(0, 0, 0); // 초기값 GPU 레이어 생성
+      -webkit-transform: translate3d(0, 0, 0);
+      backface-visibility: hidden;
+      -webkit-backface-visibility: hidden;
+      //perspective: 1000px;
+      //-webkit-perspective: 1000px;
+      position: absolute;
+      top: -17%;
+      left: 50%;
+      will-change: transform;
+      backface-visibility: hidden;
+      
+      picture {
+        width: 100%;
+        height: 100%;
+        display: block;
+      }
+      
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+        object-position: center;
+        transform: translateZ(0); // GPU 가속
+        -webkit-transform: translateZ(0);
+      }
     }
     
-    img {
+    .text--box--wrapper{
+      position: absolute;
+      backface-visibility: hidden;
+      -webkit-backface-visibility: hidden;
       width: 100%;
-      height: 100%;
-      object-fit: cover;
-      object-position: center;
-      transform: translateZ(0); // GPU 가속
-      -webkit-transform: translateZ(0);
-    }
-  }
-  
-  .text--box--wrapper{
-    position: absolute;
-    backface-visibility: hidden;
-    -webkit-backface-visibility: hidden;
-    width: 100%;
-    top:147px;
-    left: 0px;
-    z-index: 1;
-    will-change: transform, opacity;
-    transform: translate3d(0, 0, 0); // 초기값 GPU 레이어 생성
-    -webkit-transform: translate3d(0, 0, 0);
-    display: flex;
-    -webkit-box-pack: center;
-    justify-content: center;
-    transition: opacity 0.1s ease-out;
-    perspective: 1000px;
-    -webkit-perspective: 1000px;
-
-    .text--container{
-      max-width:50%;
-      position: relative;
-      box-sizing: border-box;
-      background: linear-gradient(134deg, rgb(44, 52, 63) 0%, rgb(35, 42, 52) 100%);
-      backdrop-filter: blur(60px);
+      top:147px;
+      left: 0px;
+      z-index: 1;
+      will-change: transform, opacity;
+      transform: translate3d(0, 0, 0); // 초기값 GPU 레이어 생성
+      -webkit-transform: translate3d(0, 0, 0);
       display: flex;
-      flex-direction: column;
-      gap: 24px;
-      flex-shrink: 0;
-      flex-basis: 86%;
-      margin: 88px auto 0 auto;
-      padding: 40px;
-      border-radius: 20px;
-      left: 4%;
-      flex-basis: 44%;
-      h2{
-        margin: 0px;
-        color: rgb(252, 252, 253);    
-        letter-spacing: 0px;
-        font-weight: 400;
-        text-decoration: none;
-        font-size: 24px;
-        line-height: 36px;
-        font-stretch: 130%;
-      }
-      p{
-        margin: 0px;
-        color: rgba(252, 252, 253, 0.7);
-        font-family: AudiType, sans-serif;
-        letter-spacing: 0px;
-        font-weight: 400;
-        text-decoration: none;
-        font-size: 16px;
-        line-height: 24px;
-        font-stretch: 105%;
-      }
-      a{
-        transition-timing-function: 
-        cubic-bezier(0.75, 0.02, 0.5, 1);
-        transition-duration: 250ms;
-        transition-property: color, text-decoration-color;
-        display: inline-flex ;
-        -webkit-box-align: center;
-        align-items: center;
-        font-family: AudiType, sans-serif;
-        letter-spacing: 0px;
-        font-weight: 400;
-        text-decoration: underline 1px rgb(252, 252, 253);
-        font-size: 16px;
-        line-height: 24px;
-        font-stretch: 105%;
-        color: rgb(252, 252, 253);
+      -webkit-box-pack: center;
+      justify-content: center;
+      transition: opacity 0.1s ease-out;
+      perspective: 1000px;
+      -webkit-perspective: 1000px;
+  
+      .text--container{
+        max-width:50%;
+        position: relative;
         box-sizing: border-box;
-        text-underline-offset: 7px;
-        padding-bottom: 2px;
-        min-height: 24px;
+        background: linear-gradient(134deg, rgb(44, 52, 63) 0%, rgb(35, 42, 52) 100%);
+        backdrop-filter: blur(60px);
+        display: flex;
+        flex-direction: column;
+        gap: 24px;
+        flex-shrink: 0;
+        flex-basis: 86%;
+        margin: 88px auto 0 auto;
+        padding: 40px;
+        border-radius: 20px;
+        left: 4%;
+        flex-basis: 44%;
+        h2{
+          margin: 0px;
+          color: rgb(252, 252, 253);    
+          letter-spacing: 0px;
+          font-weight: 400;
+          text-decoration: none;
+          font-size: 24px;
+          line-height: 36px;
+          font-stretch: 130%;
+        }
+        p{
+          margin: 0px;
+          color: rgba(252, 252, 253, 0.7);
+          font-family: AudiType, sans-serif;
+          letter-spacing: 0px;
+          font-weight: 400;
+          text-decoration: none;
+          font-size: 16px;
+          line-height: 24px;
+          font-stretch: 105%;
+        }
+        a{
+          transition-timing-function: 
+          cubic-bezier(0.75, 0.02, 0.5, 1);
+          transition-duration: 250ms;
+          transition-property: color, text-decoration-color;
+          display: inline-flex ;
+          -webkit-box-align: center;
+          align-items: center;
+          font-family: AudiType, sans-serif;
+          letter-spacing: 0px;
+          font-weight: 400;
+          text-decoration: underline 1px rgb(252, 252, 253);
+          font-size: 16px;
+          line-height: 24px;
+          font-stretch: 105%;
+          color: rgb(252, 252, 253);
+          box-sizing: border-box;
+          text-underline-offset: 7px;
+          padding-bottom: 2px;
+          min-height: 24px;
+        }
       }
     }
   }
+  .caution--text{
+    padding:0 var(--spacing-relative-3xl);
+    margin: 0px;
+    margin: var(--spacing-relative-md) 0 var(--spacing-relative-xl) 0;
+    color: rgba(252, 252, 253, 0.7);    
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 14px;
+    line-height: 24px;
+    font-stretch: 105%;
+  }
 }
 
 //Swiper 배너 컴포넌트 (30% + 70% 레이아웃)

+ 87 - 83
app/assets/scss/responsive.scss

@@ -1,78 +1,44 @@
-//컴포넌트 풀사이즈 배너 텍스트 1줄용
-@media (min-width:1920px) {  
-  .img--section--full {  
-    img {
-      min-height: 800px;      
-    }
-    
-    div .alt--text {
-      font-size: 44px;
-    }
-  }
-  .prallax--banner--wrapper{
-    .prallax--banner{}
-    .text--box--wrapper{
-      .text--container{
-        margin:120px 0px 0px;
-        h2{
-          font-size: 36px;
-          line-height: 52px;
-        }
-      }
-    }
-  }
-}
 
-@media (min-width:1440px) and (max-width:1919px) { 
-  .img--section--full {      
-    div .alt--text {
-      font-size: 40px;
+
+@media (max-width: 520px) {
+  .admin--login {
+    .login--box {
+      padding: 40px 24px;
     }
-  }
-  .prallax--banner--wrapper{
-    height:1600px;
-    .prallax--banner{}
-    .text--box--wrapper{
-      .text--container{
-       
-        margin: 88px 0 0;
-        h2{
-          font-size: 32px;
-          line-height: 44px;
-        }
+    
+    .login--logo {
+      h1 {
+        font-size: 36px;
+        letter-spacing: 6px;
       }
     }
   }
 }
 
-@media (min-width:1440px) {
-  
-}
-
-@media (min-width:1024px) and (max-width:1439px) { 
+@media (max-width:767px) { 
   .img--section--full {  
     img {
       min-height: 640px;      
     }
     
     div .alt--text {
-      font-size: 36px;
+      font-size: 24px;
+      line-height: 32px;
     }
   }
+}
 
 
-  .prallax--banner--wrapper{
-    .prallax--banner{}
-    .text--box--wrapper{
-      .text--container{
-        margin:88px 60px 0px;
-        h2{
-          font-size: 28px;
-          line-height: 40px;
-        }
+@media (min-width:768px){
+  .prallax--banner--wrappers{
+    .prallax--banner--wrapper{
+      height:1400px;    
+      .text--box--wrapper{
+        -webkit-box-pack: start;
+        justify-content: flex-start;      
       }
     }
-  }
+  }  
 }
 
 @media (min-width:768px) and (max-width:1023px) { 
@@ -88,54 +54,92 @@
     }
   }
 
-  .prallax--banner--wrapper{
-    .prallax--banner{}
-    .text--box--wrapper{
-      .text--container{
-        margin:88px 40px 0;
+  .prallax--banner--wrappers{
+    .prallax--banner--wrapper{    
+      .text--box--wrapper{
+        .text--container{
+          margin:88px 40px 0;
+        }
       }
     }
   }
 }
 
-@media (min-width:768px){
-  .prallax--banner--wrapper{
-    height:1400px;
-    .prallax--banner{}
-    .text--box--wrapper{
-      -webkit-box-pack: start;
-      justify-content: flex-start;      
+@media (min-width:1024px) and (max-width:1439px) { 
+  .img--section--full {  
+    img {
+      min-height: 640px;      
+    }
+    
+    div .alt--text {
+      font-size: 36px;
+    }
+  }
+
+
+  .prallax--banner--wrappers{
+    .prallax--banner--wrapper{    
+      .text--box--wrapper{
+        .text--container{
+          margin:88px 60px 0px;
+          h2{
+            font-size: 28px;
+            line-height: 40px;
+          }
+        }
+      }
     }
   }
-  
 }
 
-@media (max-width: 520px) {
-  .admin--login {
-    .login--box {
-      padding: 40px 24px;
+
+@media (min-width:1440px) and (max-width:1919px) { 
+  .img--section--full {      
+    div .alt--text {
+      font-size: 40px;
     }
-    
-    .login--logo {
-      h1 {
-        font-size: 36px;
-        letter-spacing: 6px;
+  }
+  .prallax--banner--wrappers{
+    .prallax--banner--wrapper{
+      height:1600px;    
+      .text--box--wrapper{
+        .text--container{         
+          margin: 88px 0 0;
+          h2{
+            font-size: 32px;
+            line-height: 44px;
+          }
+        }
       }
     }
   }
 }
 
-@media (max-width:767px) { 
+
+
+//컴포넌트 풀사이즈 배너 텍스트 1줄용
+@media (min-width:1920px) {  
   .img--section--full {  
     img {
-      min-height: 640px;      
+      min-height: 800px;      
     }
     
     div .alt--text {
-      font-size: 24px;
-      line-height: 32px;
+      font-size: 44px;
+    }
+  }
+  .prallax--banner--wrappers{
+    .prallax--banner--wrapper{    
+      .text--box--wrapper{
+        .text--container{
+          margin:120px 0px 0px;
+          h2{
+            font-size: 36px;
+            line-height: 52px;
+          }
+        }
+      }
     }
   }
 }
 
-

+ 156 - 0
app/components/block/TrimInfoColumn.vue

@@ -0,0 +1,156 @@
+<template>
+  <div class="trim--info--column3">
+    <ul>
+      <li v-for="(item, index) in items" :key="index">
+        <h2>{{ item.title }}</h2>
+        <div>
+          <span>{{ item.value }}</span>
+          <em>{{ item.unit }}</em>
+        </div>
+        <div v-if="item.subText">{{ item.subText }}</div>
+      </li>
+    </ul>
+    <div class="caution--text">
+      <span v-if="cautionText" v-html="cautionText"></span>
+    </div>
+  </div>
+</template>
+
+<script setup>
+  defineProps({
+    items: {
+      type: Array,
+      required: true,
+      default: () => [],
+    },
+    cautionText: {
+      type: String,
+      default: "",
+    },
+  });
+</script>
+
+<style scoped>
+  .trim--info--column3 {
+    width: 100%;
+    padding: 0 var(--page-margin) var(--spacing-relative-xl) var(--page-margin);
+  }
+
+  .trim--info--column3 ul {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    width: 100%;
+    margin: 0 auto;
+    list-style: none;
+    padding: 0;
+    overflow: hidden;
+    border-radius: 10px;
+  }
+
+  .trim--info--column3 li {
+    width: 100%;
+    text-align: center;
+    -webkit-box-flex: 1;
+    flex-grow: 1;
+    background-color: rgba(252, 252, 253, 0.15);
+    padding: 24px 28px;
+    display: flex;
+    flex-direction: column;
+    -webkit-box-align: center;
+    align-items: center;
+    -webkit-box-pack: start;
+    justify-content: flex-start;
+    animation-fill-mode: forwards;
+    animation-iteration-count: 1;
+    animation-delay: 0s;
+    text-align: center;
+    border-right: 1px solid rgb(16, 19, 25);
+  }
+
+  .trim--info--column3 h2 {
+    margin: 0px;
+    color: rgba(252, 252, 253, 0.7);
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 16px;
+    line-height: 24px;
+    font-stretch: 105%;
+    padding-bottom: var(--spacing-relative-md);
+  }
+
+  .trim--info--column3 li > div:first-of-type {
+    display: flex;
+    align-items: baseline;
+    justify-content: center;
+    gap: 5px;
+    margin-bottom: 10px;
+    padding-bottom: 4px;
+  }
+
+  .trim--info--column3 span {
+    color: rgb(252, 252, 253);
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 52px;
+    line-height: 76px;
+    font-stretch: 130%;
+  }
+
+  .trim--info--column3 em {
+    color: rgba(252, 252, 253, 0.7);
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 16px;
+    line-height: 24px;
+    font-style: normal;
+    font-stretch: 105%;
+  }
+
+  .trim--info--column3 li > div:last-child {
+    color: rgba(252, 252, 253, 0.7);
+    font-family: AudiType, sans-serif;
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 16px;
+    line-height: 24px;
+    font-stretch: 105%;
+  }
+
+  .trim--info--column3 .caution--text {
+    padding-top: var(--spacing-relative-lg);
+    margin: var(--spacing-relative-xs) 0 0 0;
+  }
+  .trim--info--column3 .caution--text span {
+    color: rgba(252, 252, 253, 0.7);
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 12px;
+    line-height: 20px;
+    font-stretch: 105%;
+  }
+
+  /* 반응형 */
+  @media (max-width: 768px) {
+    .trim--info--column3 {
+      padding: 40px 20px;
+    }
+
+    .trim--info--column3 ul {
+      grid-template-columns: 1fr;
+      gap: 30px;
+    }
+
+    .trim--info--column3 span {
+      font-size: 36px;
+    }
+
+    .trim--info--column3 em {
+      font-size: 16px;
+    }
+  }
+</style>

+ 118 - 0
app/components/block/fullSizeBannerVideo.vue

@@ -0,0 +1,118 @@
+<template>
+  <section
+    class="img--section--full"
+    :class="mask"
+    :data-type="type"
+    :data-text-location="textLocation"
+  >
+    <div :style="{ height: height + 'px' }">
+      <video
+        :autoplay="true"
+        :loop="true"
+        :muted="true"
+        crossorigin="anonymous"
+        controls=""
+        playsinline=""
+        poster=""
+        controlslist="nodownload noplaybackrate"
+        disablepictureinpicture=""
+        preload="metadata"
+        class="VideoPlayer__VideoComponent-sc-72ae48fe-2 dAzSac"
+      >
+        <source media="(min-width:320px)" :src="videoPath" />
+      </video>
+
+      <div class="alt--text" v-if="altText" :style="'color:' + textColor">
+        {{ altText }}
+      </div>
+      <div class="sub--title" v-if="subTitle" :style="'color:' + textColor">
+        {{ subTitle }}
+      </div>
+      <div class="btn--wrapper" v-if="btnText">
+        <NuxtLink :to="btnLink" :target="btnTarget" class="default--round--btn">
+          {{ btnText }}
+        </NuxtLink>
+
+        <NuxtLink
+          v-if="btnText2"
+          :to="btnText2"
+          :target="btnTarget2"
+          class="default--round--btn reverse"
+        >
+          {{ btnText2 }}
+        </NuxtLink>
+      </div>
+    </div>
+    <div v-if="cautionText" class="caution--text--small" v-html="cautionText"></div>
+  </section>
+</template>
+
+<script setup>
+  // Props 정의
+  const props = defineProps({
+    height: {
+      type: String,
+      default: "100vh",
+    },
+    videoPath: {
+      type: String,
+      default: "",
+    },
+    mask: {
+      type: String,
+      default: "",
+      validator: (value) => ["", "hidden"].includes(value),
+    },
+    textLocation: {
+      type: String,
+      default: "bottom",
+      validator: (value) => ["bottom", "top", "left", "right"].includes(value),
+    },
+    textColor: {
+      type: String,
+      default: "#fff",
+      validator: (value) => ["#fff", "#020203"].includes(value),
+    },
+    cautionText: {
+      type: String,
+      default: "",
+    },
+    altText: {
+      type: String,
+      default: "",
+    },
+    subTitle: {
+      type: String,
+      default: "",
+    },
+    btnText: {
+      type: String,
+      default: "",
+    },
+    btnLink: {
+      type: String,
+      default: "",
+    },
+    btnTarget: {
+      type: String,
+      default: "",
+    },
+    btnText2: {
+      type: String,
+      default: "",
+    },
+    btnLink2: {
+      type: String,
+      default: "",
+    },
+    btnTarget2: {
+      type: String,
+      default: "",
+    },
+    type: {
+      type: String,
+      default: "contain", // 'horz' , 'vert'
+      validator: (value) => ["contain", "cover"].includes(value),
+    },
+  });
+</script>

+ 51 - 45
app/components/block/parallaxBanner.vue

@@ -1,43 +1,46 @@
 <template>
-  <section class="prallax--banner--wrapper" ref="parallaxWrapper">
-    <div class="prallax--banner" ref="parallaxBanner">
-      <picture>
-        <source
-          media="(min-width:1440px)"
-          :srcset="`${images.xl} 1920w, ${images.xl2x || images.xl} 3840w`"
-          sizes="(min-width:1920px) 1920px, 100vw"
-          width="1920"
-          height="2000"
-        />
-        <source
-          media="(min-width:768px)"
-          :srcset="`${images.m} 1439w, ${images.m2x || images.m} 2878w`"
-          sizes="100vw"
-          width="1439"
-          height="1750"
-        />
-        <source
-          media="(min-width:375px)"
-          :srcset="`${images.s} 787w, ${images.s2x || images.s} 1574w`"
-          sizes="100vw"
-          width="787"
-          height="1250"
-        />
-        <img
-          :alt="imageAlt"
-          loading="lazy"
-          :src="images.xs"
-          :srcset="`${images.xs} 374w, ${images.xs2x || images.xs} 748w`"
-        />
-      </picture>
-    </div>
-    <div class="text--box--wrapper" ref="textWrapper">
-      <div class="text--container">
-        <h2>{{ title }}</h2>
-        <p>{{ description }}</p>
-        <a v-if="linkUrl && linkText" :href="linkUrl">{{ linkText }}</a>
+  <section class="prallax--banner--wrappers">
+    <section class="prallax--banner--wrapper" ref="parallaxWrapper">
+      <div class="prallax--banner" ref="parallaxBanner">
+        <picture>
+          <source
+            media="(min-width:1440px)"
+            :srcset="`${images.xl} 1920w, ${images.xl2x || images.xl} 3840w`"
+            sizes="(min-width:1920px) 1920px, 100vw"
+            width="1920"
+            height="2000"
+          />
+          <source
+            media="(min-width:768px)"
+            :srcset="`${images.m} 1439w, ${images.m2x || images.m} 2878w`"
+            sizes="100vw"
+            width="1439"
+            height="1750"
+          />
+          <source
+            media="(min-width:375px)"
+            :srcset="`${images.s} 787w, ${images.s2x || images.s} 1574w`"
+            sizes="100vw"
+            width="787"
+            height="1250"
+          />
+          <img
+            :alt="imageAlt"
+            loading="lazy"
+            :src="images.xs"
+            :srcset="`${images.xs} 374w, ${images.xs2x || images.xs} 748w`"
+          />
+        </picture>
       </div>
-    </div>
+      <div class="text--box--wrapper" ref="textWrapper">
+        <div class="text--container">
+          <h2>{{ title }}</h2>
+          <p>{{ description }}</p>
+          <a v-if="linkUrl && linkText" :href="linkUrl">{{ linkText }}</a>
+        </div>
+      </div>
+    </section>
+    <div class="caution--text" v-if="cautionText" v-html="cautionText"></div>
   </section>
 </template>
 
@@ -69,28 +72,31 @@
     // 이미지 alt 텍스트
     imageAlt: {
       type: String,
-      default: "Audi Exclusive",
+      default: "",
     },
     // 제목
     title: {
       type: String,
-      default: "Audi exclusive order 주문하기",
+      default: "",
+    },
+    cautionText: {
+      type: String,
+      default: "",
     },
     // 설명
     description: {
       type: String,
-      default:
-        "당신만의 특별한 아우디 주문은 아우디 딜러샵을 통해 신청 가능하며, 자세한 딜러 네트워크 정보는 아래 버튼을 통해 확인하실 수 있습니다.",
+      default: "",
     },
     // 링크 URL
     linkUrl: {
       type: String,
-      default: "/",
+      default: "",
     },
     // 링크 텍스트
     linkText: {
       type: String,
-      default: "아우디 딜러 네트워크 알아보기",
+      default: "",
     },
   });
   // Refs
@@ -122,7 +128,7 @@
       const easedProgress = easeOutQuart(scrollProgress);
 
       // 배경 이미지 패럴렉스 효과 (아우디 실제 로직: 스크롤 거리의 25%만큼 움직임) - translate3d로 GPU 가속
-      const scrollDistance = (windowHeight - rect.top);
+      const scrollDistance = windowHeight - rect.top;
       const bgTranslateY = scrollDistance * 0.25;
       parallaxBanner.value.style.transform = `translate3d(-50%, ${bgTranslateY}px, 0)`;
       parallaxBanner.value.style.webkitTransform = `translate3d(-50%, ${bgTranslateY}px, 0)`;

+ 443 - 0
app/pages/models/detail/s-etron-gt.vue

@@ -0,0 +1,443 @@
+<template>
+  <main>
+    <div class="detail--container--full">
+      <!-- 풀사이즈 배너 텍스트 1줄용 -->
+      <fullSizeBannerVideo
+        :height="856"
+        :videoPath="bannerVideoPath"
+        class="video"
+        textLocation="bottomleft"
+        type="cover"
+        altText="The new Audi S e-tron GT"
+        btnText="상담신청"
+        btnLink="/"
+        btnTarget="_blank"
+        btnText2="내 차량 만들기"
+        btnLink2="/"
+        btnTarget2="_blank"
+        cautionText="전력 소비량: 3.7 km/kWh (복합), CO2 배출량 (복합): 0g/km, 배출 등급: 4등급"
+      />
+
+      <TrimInfoColumn :items="trimInfoItems" />
+
+      <!-- 타이틀 비주얼 컴포넌트 -->
+      <TitleVisual
+        title="Adrenaline, Fully<br/> Charged"
+        description=""
+        textAlign="center"
+        theme="dark"
+        :animation="true"
+        :animationDelay="300"
+      />
+
+      <!-- 링크 리스트 컴포넌트 -->
+      <LinkList class="mt--20" :links="reservationLinks" />
+
+      <!-- 풀사이즈 패럴랙스 배너 (커스텀 데이터 예시) -->
+      <ParallaxBanner
+        :images="customParallaxImages"
+        imageAlt="한눈에 확인하는 성능"
+        title="한눈에 확인하는 성능"
+        description="향상된 주행 경험을 느끼고 들어보세요. 새로운 아우디 RS 6 아반트 퍼포먼스에는 현재까지 가장 강력한 RS 6 엔진이 탑재되었습니다. 퍼포먼스는 애티튜드입니다."
+        cautionText="공인 표준 연비 (km/l) : 복합: 7.1 / 도심: 6.1 / 고속: 9.0 (5등급), 배출량: 243(g/km)"
+      />
+
+      <!-- 
+        Swiper 배너 (30% + 70% 레이아웃)
+        type="vertical", 
+        type="horizental"
+      -->
+      <SwiperBanner
+        :slides="bannerSlides"
+        title="Audi Exclusive Collection"
+        subtitle="당신만을 위한 특별한 아우디"
+        smalldesc="유럽 인증 기준"
+        notice=""
+        :autoplay="{ delay: 0 }"
+        :loop="false"
+      />
+
+      <!-- 타이틀 비주얼 컴포넌트 -->
+      <TitleVisual
+        title="맞춤형 페인팅 시스템"
+        description="Audi exclusive order의 맞춤형 페인트 마감은 매우 특별하게 구현됩니다. 색상의 혼합부터 다양한 페인트 레이어 적용까지 정밀한 작업을 통해 페인팅 시스템이 완성됩니다."
+        textAlign="left"
+        theme="dark"
+        :animation="true"
+        :animationDelay="300"
+      />
+
+      <SwiperBanner
+        :slides="bannerSlides2"
+        notice=""
+        :autoplay="{ delay: 0 }"
+        :loop="false"
+      />
+
+      <!-- 타이틀 비주얼 컴포넌트 -->
+      <TitleVisual
+        title="당신만의 색상을 선택하세요"
+        description=""
+        textAlign="left"
+        theme="dark"
+        :animation="true"
+        :animationDelay="300"
+      />
+
+      <SwiperBanner
+        :slides="bannerSlides3"
+        :autoplay="false"
+        :loop="false"
+        type="vertical"
+      />
+
+      <!-- 타이틀 비주얼 컴포넌트 -->
+      <TitleVisual
+        title="당신을 드러내는 색상"
+        description="차체 색상으로 첫인상을 남길 수 있는 기회는 단 한 번뿐입니다. Audi exclusive order의 다양한 색상 중에서 당신을 드러내는 외관 페인트 마감을 선택하세요. 아우디에서 테스트하고 승인한 맞춤형 페인트 마감은 아래와 같습니다. 원하는 차량에 원하는 색상을 적용할 수 있는지 확인하려면 아우디 파트너에게 문의해 주세요."
+        textAlign="left"
+        theme="dark"
+        :animation="true"
+        :animationDelay="300"
+      />
+
+      <SwiperBanner
+        :slides="bannerSlides4"
+        :autoplay="false"
+        :loop="false"
+        type="vertical"
+      />
+
+      <SwiperBanner
+        :slides="bannerSlides5"
+        :autoplay="false"
+        :loop="false"
+        class="mt--80"
+        type="vertical"
+      />
+
+      <!-- 타이틀 비주얼 컴포넌트 -->
+      <TitleVisual
+        title="인테리어에도 특별함을 더하다"
+        description="다양한 가죽 트림 옵션, 컬러 장식 스티칭 등의 장식으로 모든 인테리어를 마감하고 특별한 개성을 드러낼 수 있습니다."
+        textAlign="left"
+        theme="dark"
+        :animation="true"
+        :animationDelay="300"
+        class="mt--100"
+      />
+
+      <SwiperBanner :slides="bannerSlides6" :autoplay="false" :loop="false" type="" />
+
+      <SwiperBanner
+        :slides="bannerSlides7"
+        :autoplay="false"
+        :loop="false"
+        class="mt--80"
+        type="vertical"
+      />
+
+      <SwiperBanner
+        :slides="bannerSlides8"
+        :autoplay="false"
+        :loop="false"
+        class="mt--80"
+        type="vertical"
+      />
+
+      <CautionText />
+    </div>
+  </main>
+</template>
+
+<script setup>
+  // 컴포넌트 import
+  import fullSizeBannerVideo from "~/components/block/fullSizeBannerVideo.vue";
+  import ParallaxBanner from "~/components/block/parallaxBanner.vue";
+  import SwiperBanner from "~/components/block/SwiperBanner.vue";
+  import TitleVisual from "~/components/block/TitleVisual.vue";
+  import CautionText from "~/components/block/cautionText.vue";
+  import LinkList from "~/components/block/LinkList.vue";
+  import TrimInfoColumn from "~/components/block/TrimInfoColumn.vue";
+
+  // Runtime Config 가져오기
+  const config = useRuntimeConfig();
+
+  const bannerVideoPath = ref(
+    "https://media.audi.com/is/content/audi/nemo/models/audi-e-tron-gt/s-e-tron-gt/my-2025/stage/Running_Footage_Se-tronGT-L-2.mp4#t=0.001"
+  );
+
+  // Trim 정보 데이터
+  const trimInfoItems = ref([
+    {
+      title: "최대 주행 가능 거리 (복합 기준)",
+      value: "420",
+      unit: "km",
+      subText: "10분내",
+    },
+    {
+      title: "재충전 주행 가능 거리 (유럽 WLTP 기준)",
+      value: "280",
+      unit: "km",
+      subText: "10분내",
+    },
+    {
+      title: "충전 용량 10%에서 80%까지 소요 시간 (유럽 WLTP 기준)",
+      value: "18",
+      unit: "분",
+      subText: "최고 320kW의 최대 DC 전력 충전 시",
+    },
+  ]);
+
+  // 링크 데이터 배열
+  const reservationLinks = ref([
+    {
+      text: "내 차량 만들기",
+      url:
+        "https://www.audi.co.kr/ko/models/e-tron-gt/s-e-tron-gt-master-2025/konfigurator/?ulid=1762749286140&pr=F8PR9D0_2025%7CL5L5%7CFO#configurator",
+      target: "_blank",
+      showIcon: true,
+    },
+    {
+      text: "차량 상담",
+      url: config.public.testdrive,
+      target: "_blank",
+      showIcon: true,
+    },
+    {
+      text: "전시장/AS센터",
+      url: "/company/serviceCenter",
+      target: "_blank",
+      showIcon: true,
+    },
+    {
+      text: "카탈로그 다운로드",
+      url: "https://indd.adobe.com/view/8aee0a52-9278-4af3-9dea-e7e0fc354ff6",
+      target: "_blank",
+      showIcon: true,
+    },
+    {
+      text: "디지털 카탈로그",
+      url:
+        "https://www.audikoreaevent.co.kr/aca/ecatalog/download/Audi_SETGT25_&_RSETGTPFM25_catalog.pdf",
+      target: "_blank",
+      showIcon: true,
+    },
+  ]);
+  // 커스텀 이미지 세트 예시 (필요시 사용)
+  const customParallaxImages = {
+    xl: "/img/models/e-tron-gt/RS_6_2022_4355-XL.jpg?auto=webp&width=1920",
+    xl2x: "/img/models/e-tron-gt/RS_6_2022_4355-XL.jpg?auto=webp&width=3840",
+    m: "/img/models/e-tron-gt/RS_6_2022_4355-M.jpg?auto=webp&width=1439",
+    m2x: "/img/models/e-tron-gt/RS_6_2022_4355-M.jpg?auto=webp&width=2878",
+    s: "/img/models/e-tron-gt/RS_6_2022_4355-S.jpg?auto=webp&width=787",
+    s2x: "/img/models/e-tron-gt/RS_6_2022_4355-S.jpg?auto=webp&width=1574",
+    xs: "/img/models/e-tron-gt/RS_6_2022_4355-XS.jpg?auto=webp&width=374",
+    xs2x: "/img/models/e-tron-gt/RS_6_2022_4355-XS.jpg?auto=webp&width=748",
+  };
+
+  // Swiper 배너 슬라이드 데이터 (30% + 70% 레이아웃용)
+  const bannerSlides = ref([
+    {
+      image: "/img/exclusive/03_r8_2021_3105_57994-S-L.jpg",
+      alt: "당신만을 위해 반영된 특별함",
+      title: "당신만을 위해 반영된 특별함",
+      subtitle:
+        "색상부터 스티칭 요소까지, Audi exclusive order를 통해 오직 당신을 위한 아우디를 만나보세요.",
+      smalldesc: "유럽인증",
+    },
+    {
+      image: "/img/exclusive/05_rsegt_ae_2021_2376-S-L.jpg",
+      alt: "원하는 컬러를 선택하다",
+      title: "원하는 컬러를 선택하다",
+      subtitle:
+        "노을의 골드, 와인의 레드, 에메랄드 반지의 그린 등 아우디 차체 색상으로 원하는 색상을 선택할 수 있습니다.",
+      smalldesc: "유럽인증",
+    },
+    {
+      image: "/img/exclusive/04_r8_2021_3106_58054-S-L.jpg",
+      alt: "보고, 느끼고, 매료되다",
+      title: "보고, 느끼고, 매료되다",
+      subtitle:
+        "Audi exclusive order 인테리어 트림을 사용하면 다양한 옵션을 선택할 수 있습니다. 가장 상위 카테고리로 고급 가죽을 선택할 수 있습니다.",
+      smalldesc: "유럽인증",
+    },
+  ]);
+
+  const bannerSlides2 = ref([
+    {
+      image: "/img/exclusive/06_AQUA_151004_7823-S-L.jpg",
+      alt: "개성이 담긴 색상",
+      title: "개성이 담긴 색상",
+      subtitle:
+        "선택하는 색상은 결합제, 용제, 다양한 첨가제뿐만 아니라 유기 및 무기 안료의 혼합으로 이루어집니다. 유기 안료는 색상의 휘도와 선명도를 제공하고 무기 안료는 마감재의 내후성을 보장합니다. 메탈 소판(metal platelet)을 추가하면 메탈릭 페인트 마감의 매혹적인 이펙트가 나타납니다.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/07_AU140766_large-S-L.jpg",
+      alt: "차체에 페인트를 적용하는 방법",
+      title: "차체에 페인트를 적용하는 방법",
+      subtitle:
+        "아우디의 페인트 마감은 4겹으로 구성되지만 한 겹의 두께는 사람의 머리카락보다 굵지 않습니다. 먼저 부식을 방지하는 프라이머를 본체에 도포합니다. 이 단계에서 전체 차량이 딥 탱크를 통해 회전하여 안으로 들어간 모든 부분의 모든 면을 페인트로 코팅합니다. 그런 다음, 본체를 180°C에서 45분 동안 건조시킵니다.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/08_AU140767_large-S-L.jpg",
+      alt: "이후 공정",
+      title: "이후 공정",
+      subtitle:
+        "두 번째 단계는 필러 레이어라고 합니다. 필러 레이어는 표면의 요철을 매끄럽게 하고 주행 중 날아오는 돌이나 모래로 마감이 갈라지는 것을 방지하는 데 필요한 탄성을 제공합니다. 세 번째 레이어는 컬러 페인트 마감입니다. 빠르게 회전하는 분무기로 아우디 표면에 이 베이스 마감을 적용합니다. 네 번째 단계에서는 투명한 바니시 보호층을 추가한 후 140°C에서 30분 동안 경화시켜야 합니다.",
+      smalldesc: "",
+    },
+  ]);
+
+  const bannerSlides3 = ref([
+    {
+      image: "/img/exclusive/09_rs7_ae_2020_2428-L.jpg",
+      alt: "",
+      title: "",
+      subtitle:
+        "Ascari blue metallic 색상의 아우디 RS 7 Sportback. 연비(km/l) : 7.4 (에너지소비효율등급 5등급 / 복합), 6.2 (도심), 9.5 (고속도로), CO₂ 배출량(g/km): 239",
+      smalldesc: "",
+      morelink: "/",
+    },
+    {
+      image: "/img/exclusive/11_a8_ae_2021_3214_58435-L.jpg",
+      alt: "",
+      title: "",
+      subtitle: "Night Blue Pearl Effect의 아우디 A8.",
+      smalldesc: "",
+      morelink: "/",
+    },
+    {
+      image: "/img/exclusive/12_rs6_ae_2020_2426_55361-L.jpg",
+      alt: "",
+      title: "",
+      subtitle:
+        "Panther black crystall effect의 아우디 RS 6 Avant. 연비(km/l) : 7.0 (에너지소비효율등급 5등급/복합), 6.1 (도심), 8.6 (고속도로), CO₂ 배출량(g/km) : 250",
+      smalldesc: "",
+      morelink: "/",
+    },
+  ]);
+
+  const bannerSlides4 = ref([
+    {
+      image: "/img/exclusive/metallic.jpg",
+      alt: "",
+      title: "Metallic 페인트 마감:",
+      subtitle: "은은하게 반짝이는 우아함.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/pearleffect.jpg",
+      alt: "",
+      title: "Pearl effect 페인트 마감:",
+      subtitle: "빛나는 광채.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/uni.jpg",
+      alt: "",
+      title: "단일 페인트 마감: ",
+      subtitle: "심플한 아름다움.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/crystal.jpg",
+      alt: "",
+      title: "Crystall effect 페인트 마감: ",
+      subtitle: "숨이 멎을 듯 강렬한 럭셔리함. ",
+      smalldesc: "",
+    },
+  ]);
+
+  const bannerSlides5 = ref([
+    {
+      image: "/img/exclusive/metallic-shiny-L.jpg",
+      alt: "",
+      title: "Metallic 페인트 마감:",
+      subtitle: "은은하게 반짝이는 우아함.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/metallic-L.jpg",
+      alt: "",
+      title: "Metallic 페인트 마감:",
+      subtitle: "은은하게 반짝이는 우아함.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/pearl-effect-L.jpg",
+      alt: "",
+      title: "Pearl effect 페인트 마감:",
+      subtitle: "빛나는 광채.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/uni-color-L.jpg",
+      alt: "",
+      title: "단일 페인트 마감: ",
+      subtitle: "심플한 아름다움. ",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/crystal-effect-L.jpg",
+      alt: "",
+      title: "Crystall effect 페인트 마감: ",
+      subtitle: "숨이 멎을 듯 강렬한 럭셔리함. ",
+      smalldesc: "",
+    },
+  ]);
+
+  const bannerSlides6 = ref([
+    {
+      image: "/img/exclusive/AQUA_171047_1_51L_rgb-L.jpg",
+      alt: "",
+      title: "가죽의 제작 과정",
+      subtitle:
+        "30가지 이상의 다양한 테스트를 실시한 후 적합한 가죽을 선택합니다. 이러한 테스트는 내마모성, 내광성, 수축 거동, 굽힘 강도 그리고 인장력, 방출 및 가연성에 대한 저항성과 같은 요소를 확인하도록 설계되었습니다.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/19_AL090111_large-S-L.jpg",
+      alt: "",
+      title: "신중하게 처리되는 공정",
+      subtitle:
+        "가죽의 진성을 유지하기 위해 식물성 염료를 포함한 물질로 부드럽게 정제합니다. 그 결과 내구성이 강하고 오래 지속되며 매우 감성적인 재료가 만들어집니다.",
+      smalldesc: "",
+    },
+    {
+      image: "/img/exclusive/needle.jpg",
+      alt: "",
+      title: "타임리스 스티칭",
+      subtitle: "맞춤형 스티칭은 Audi 전용 차량에 완벽함 마무리 터치를 더합니다.",
+      smalldesc: "",
+    },
+  ]);
+
+  const bannerSlides7 = ref([
+    {
+      image: "/img/exclusive/27_rs6_ae_2020_2427_1_55902-L.jpg",
+      alt: "",
+      title: "",
+      subtitle:
+        "아우디 RS 6 Avant의 인테리어에는 Diamond silver black 색상의 발코나 Audi exclusive 가죽 커버와 이에 대비되는 Diamond silver 스티칭을 사용했습니다.",
+      smalldesc: "",
+      morelink:
+        "https://www.audi.co.kr/ko/models/a6/rs-6-avant-performance-2024/configurator/",
+      morelinktitle: "아우디 RS 6 내 차량 만들기",
+      morelinktarget: "_blank",
+    },
+  ]);
+
+  const bannerSlides8 = ref([
+    {
+      image: "/img/exclusive/28_Audi_R8_Coupe_Blau_07-2019_4-L.jpg",
+      alt: "",
+      title: "무엇이든 가능하게:",
+      subtitle:
+        "탁월하게 제작된 섬세한 재료와 다양한 조합을 통해 브랜드의 감성을 다면적으로 반영합니다.",
+      smalldesc: "",
+    },
+  ]);
+</script>

+ 2 - 1
nuxt.config.ts

@@ -60,7 +60,8 @@ export default defineNuxtConfig({
   runtimeConfig: {
     public: {
       apiBase: process.env.NUXT_PUBLIC_API_BASE || 'http://gojinaudi.mycafe24.com',
-      imageBase: process.env.NUXT_PUBLIC_IMAGE_BASE || 'http://gojinaudi.mycafe24.com'
+      imageBase: process.env.NUXT_PUBLIC_IMAGE_BASE || 'http://gojinaudi.mycafe24.com',
+      testdrive: process.env.NUXT_PUBLIC_TESTDRIVE
     }
   }
 })

BIN
public/img/models/e-tron-gt/RS_6_2022_4343-L.avif


BIN
public/img/models/e-tron-gt/RS_6_2022_4348_1-L.avif


BIN
public/img/models/e-tron-gt/RS_6_2022_4355-M.jpg


BIN
public/img/models/e-tron-gt/RS_6_2022_4355-S.jpg


BIN
public/img/models/e-tron-gt/RS_6_2022_4355-XL.jpg


BIN
public/img/models/e-tron-gt/RS_6_2022_4355-XS.jpg


+ 1 - 1
public/models.json

@@ -8,7 +8,7 @@
       "priceText": "170,120,000원",
       "description": "가장 강력한 아우디 S 모델로, 그란 투리스모 순수 전기차",
       "image": "/img/models/thumb/s-etron-gt.webp",      
-      "link": "/models/s-etron-gt",
+      "link": "/models/detail/s-etron-gt",
       "stock": 0,
       "isNew": true,
       "fuelType": "etron",