@charset "utf-8";

/* =========================================================
   shop 페이지 전용 토큰
   출처: Figma 4조 한복판 - 차이킴, node 1523:1094 (shop_박효민)
   ========================================================= */

:root {
  --color_text_secondary: #4a4a42;
  --color_border_default: #e2ddd5;
  --color_price: #343330;
  --color_bg_alt: #f7f7f7;

  /* motif_detail은 페이지에서 유일하게 어두운 배경 위에 올라가는 섹션이라
     반전 색이 따로 필요합니다(Figma의 background-inverse / text-inverse). */
  --color_bg_inverse: #0a0a0a;
  --color_text_inverse: #fffdf9;
  --color_text_subtle: #aaaaaa;
}

/* main와 동일하게 body/.main은 창 너비에 맞춰 늘어납니다.
   Figma 좌표(1920 기준) 절대배치가 필요한 부분만 섹션별로 1920px 고정
   프레임을 두고 가운데 정렬합니다(현재는 hero_section만 해당). */
.main {
  display: block;
  width: 100%;
}

/* =========================================================
   hero_section
   ========================================================= */

.hero_section {
  position: relative;
  width: 100%;
  height: 1770px;
  overflow: hidden;
  color: var(--color_text_on_dark);
}

.hero_section_media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

/* watermark/gallery/nav의 절대배치 좌표는 1920px 기준이라, 창이 더 넓어도
   이 프레임만 1920px로 고정하고 가운데 정렬합니다. 배경(.hero_section_media)은
   위에서 이미 전체 폭을 채우고 있어 그대로 둡니다. */
.hero_section_frame {
  position: relative;
  width: 1920px;
  max-width: none;
  height: 100%;
  margin: 0 auto;
}

.hero_section_bg {
  position: absolute;
  left: 0;
  top: -92.46%;
  width: 100%;
  height: 192.46%;
  object-fit: cover;
}

.hero_section_overlay {
  position: absolute;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.56);
}

.hero_section_watermark {
  position: absolute;
  left: 566px;
  top: 1335px;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--font_display);
  font-weight: 200;
  font-size: 450px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.25);
  white-space: nowrap;
}

.hero_gallery {
  position: absolute;
  /* 화면상 원통 중심은 유지하고 WebGL 렌더 영역만 좌우로 넓혀
     회전 중인 카드가 캔버스 경계에서 잘리지 않게 합니다. */
  left: -162px;
  top: 40px;
  width: 1700px;
  height: 1280px;
}

/* WebGL 카드 링이 준비되기 전(로딩 중이거나 Three.js/WebGL을 못 쓰는 환경)에는
   정지 이미지를 보여주고, js/shop.js가 초기화에 성공하면 .hero_gallery에
   is_ready를 붙여 canvas로 바꿔 보여줍니다(brand 섹션의 기본 레이아웃 →
   조건부 가로 스크롤 패턴과 동일한 점진적 향상 방식). */
.hero_gallery_fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero_gallery_canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
}

.hero_gallery.is_ready .hero_gallery_fallback {
  display: none;
}

.hero_gallery.is_ready .hero_gallery_canvas {
  opacity: 1;
}

/* 모바일 스와이프 트랙 (768px 미만).
   그 폭에서는 WebGL 원통을 만들지 않아 사진이 한 장만 보이고 조작이 없었습니다.
   js/shop.js가 카테고리 8장을 담은 트랙을 만들고 .is_swipe_ready를 붙입니다.
   가로 스와이프는 브라우저 기본 스크롤 + scroll-snap이 처리하므로 제스처를
   직접 계산하지 않습니다(관성·고무줄이 기기 기본 동작 그대로 남습니다).

   ★ 트랙은 js가 만들 때만 존재합니다. 스크립트가 실패하면 이 규칙들이 아무것도
     매칭하지 않고 .hero_gallery_fallback 정지 이미지가 그대로 남습니다. */
/* ★ 768px 미만에서 .hero_gallery는 position: static입니다(아래 1023 블록).
   그대로 두면 트랙의 absolute가 .hero_section_frame을 기준으로 잡혀
   히어로 전체(360×810)를 덮고 카테고리를 가립니다. 기준을 되돌립니다. */
.hero_gallery.is_swipe_ready {
  position: relative;
  /* ★ static일 때는 무시되던 기본 규칙의 left/top(-162px / 40px)이 relative가
     되는 순간 살아납니다. 같이 지우지 않으면 갤러리가 화면 왼쪽 밖으로 나가고
     아래 카테고리와 겹칩니다. */
  left: auto;
  top: auto;
}

.hero_gallery.is_swipe_ready .hero_gallery_fallback {
  display: none;
}

.hero_gallery_track {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.hero_gallery_track::-webkit-scrollbar {
  display: none;
}

.hero_gallery_slide {
  /* 한 장이 트랙 폭을 정확히 채워야 scrollLeft / clientWidth가 곧 사진 번호가
     됩니다. shrink를 0으로 두지 않으면 8장이 서로 눌려 계산이 어긋납니다. */
  flex: 0 0 100%;
  scroll-snap-align: center;
}

.hero_gallery_slide_img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero_nav {
  --hero_nav_x: 0;
  --hero_nav_y: -200px;
  position: absolute;
  inset: 0;
  transform: translate(var(--hero_nav_x), var(--hero_nav_y));
  pointer-events: none;
}

.hero_nav_item {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}

.hero_nav_item_all_new { left: 1608px; top: 594px; }
.hero_nav_item_dress { left: 1608px; top: 637px; }
.hero_nav_item_top { left: 1608px; top: 672px; }
.hero_nav_item_knit { left: 1608px; top: 707px; }
.hero_nav_item_bottom { left: 1608px; top: 742px; }
.hero_nav_item_outer { left: 1608px; top: 777px; }
.hero_nav_item_living { left: 1608px; top: 812px; }
.hero_nav_item_acc { left: 1608px; top: 847px; }

.hero_nav_link {
  display: inline-block;
  min-width: 110px;
  /* ★ button은 기본 text-align이 center입니다. min-width가 110px이라
     지정하지 않으면 짧은 항목(TOP, ACC)만 안쪽으로 밀려 왼쪽 선이 어긋납니다. */
  text-align: left;
  color: var(--color_text_on_dark);
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.57;
  opacity: 1;
  transform: translateX(0);
  transform-origin: left center;
  pointer-events: auto;
  transition:
    opacity 320ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 420ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform, opacity;
}

.hero_nav_link_lg {
  letter-spacing: normal;
}

.hero_nav_link_sm {
  letter-spacing: normal;
}

.hero_nav.has_active .hero_nav_link {
  opacity: 0.22;
}

.hero_nav .hero_nav_link.is_active {
  font-weight: 600;
  font-size: 14px;
  line-height: 1.57;
  letter-spacing: 1.08px;
  opacity: 1;
  transform: translateX(5px) scale(1.2857);
  text-decoration: none;
}

/* =========================================================
   banner
   ========================================================= */

.banner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 720px;
  overflow: hidden;
}

.banner_bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.banner_content {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
}

.banner_headline_group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
}

.banner_headline_wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.banner_eyebrow {
  margin: 0;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.38;
  letter-spacing: 1.28px;
  color: var(--color_text_secondary);
  text-align: center;
}

.banner_title {
  width: 720px;
  margin: 0;
  font-family: var(--font_display);
  font-weight: 400;
  font-size: 52px;
  line-height: 1.4;
  letter-spacing: -1.04px;
  color: var(--color_text);
  text-align: center;
}

.banner_title_em {
  font-weight: 600;
  font-style: italic;
}

.banner_divider {
  width: 45px;
  height: 1px;
  border: none;
  border-top: 1px solid var(--color_text);
  margin: 0;
}

.banner_crosslink_group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

.banner_crosslink_label {
  margin: 0;
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.63;
  color: var(--color_text_secondary);
}

/* 스태거 등장 중에는 공통 버튼의 hover용 transform transition과 충돌하지 않게 합니다. */
.banner.is_revealing .banner_crosslink_link {
  transition: none;
}

/* =========================================================
   garment_story
   ========================================================= */

/* 섹션 높이는 반드시 화면 높이(100vh)와 같아야 합니다. sticky top:0으로
   붙는 순간 보이는 영역은 섹션의 위쪽 100vh뿐인데, 내용은 frame의
   align-items:center로 "섹션 높이의 절반" 위치에 놓이기 때문입니다.
   섹션이 화면보다 크면(예전 1600px) 그 중심이 화면 아래로 밀려나
   내용이 화면 하단에 걸린 채로 스크롤이 잠깁니다.

   높이를 바꿔야 한다면 아래 두 곳을 "같이" 바꿉니다:
   1) .garment_story_section의 height (= 화면 높이)
   2) .garment_story_scroll의 height (섹션 높이 + 여유 스크롤 구간)
   .garment_story_frame은 height:100%로 섹션 높이를 따라가므로 여기에
   직접 px 높이를 주지 마세요. */
.garment_story_scroll {
  /* ★ Garment Story 위·아래 여백 조절 위치
     숫자를 키우면 앞·뒤 섹션과의 간격이 커집니다. Wheel이 잘리지 않도록
     100vh인 section 내부가 아니라 바깥 scroll 래퍼에 여백을 둡니다. */
  --garment_story_section_gap: clamp(160px, 18vh, 240px);
  position: relative;
  padding-block: var(--garment_story_section_gap);
}

.garment_story_section {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background-color: #fffdf9;
}

/* illustration_group의 절대좌표(1920 기준)를 그대로 쓰기 위한 고정 프레임.
   hero_section_frame과 같은 패턴입니다. 높이는 항상 섹션과 동일해야 하므로
   100%로 둡니다 — 여기에 직접 px 높이를 주지 마세요. */
.garment_story_frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: 1920px;
  height: 100%;
  margin: 0 auto;
  padding: 0 180px;
  overflow: hidden;
}

.garment_story_section.is_drag_ready .garment_story_frame {
  cursor: grab;
}

.garment_story_section.is_dragging .garment_story_frame {
  cursor: grabbing;
  user-select: none;
}

/* 원형 내비 — 중심(400,400) 반지름 436(라벨) / 400(마커) 기준.
   Figma 주석: "30도 간격 슬롯, 활성 슬롯 0도, 나머지 +30/+60/-30".
   슬롯 4개 = 가먼트 4개라 항상 전부 자리를 차지합니다(숨는 항목 없음). */
.garment_orbit {
  --garment_orbit_scale: 1;
  position: absolute;
  left: -335px;
  top: 50%;
  transform: translateY(-50%) scale(var(--garment_orbit_scale));
  transform-origin: left center;
  width: 968px;
  height: 912px;
  pointer-events: none;
}

/* 높이가 짧은 데스크톱에서는 912px Wheel이 화면 위아래로 잘리지 않도록
   원·라벨·마커를 한 묶음으로 줄입니다. 일반적인 1080px 화면은 원래 크기입니다. */
@media (min-width: 1280px) and (max-height: 920px) {
  .garment_orbit {
    --garment_orbit_scale: 0.82;
  }
}

@media (min-width: 1280px) and (max-height: 760px) {
  .garment_orbit {
    --garment_orbit_scale: 0.74;
  }
}

.garment_orbit_circle {
  position: absolute;
  left: 0;
  top: 50%;
  width: 800px;
  height: 800px;
  transform: translateY(calc(-50% - 56px));
}

/* left/top 초기값은 js/shop.js가 매 프레임 활성 항목 자리에 맞춰
   다시 계산해 넣습니다(JS 실행 전 기본값과 동일한 좌표). */
.garment_orbit_marker {
  position: absolute;
  left: 800px;
  top: 400px;
  transform: translate(-50%, -50%);
}

.garment_orbit_marker_outer {
  width: 20px;
  height: 20px;
}

.garment_orbit_marker_inner {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 12px;
  transform: translate(-50%, -50%);
}

.garment_orbit_list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 자리(left/top/rotate)는 js/shop.js가 휠 진행도에 맞춰 매 프레임 인라인
   스타일로 계산해 넣습니다(연속적인 회전이라 CSS transition을 걸면 GSAP의
   자체 보간과 겹쳐 오히려 버벅여서, 위치 관련 속성은 여기서 트랜지션을
   걸지 않습니다). color만 활성/비활성 전환 시 부드럽게 바뀝니다. */
/* 라벨은 "가운데"가 아니라 "안쪽 끝(원에 가까운 쪽 왼쪽 모서리)"을 기준점에
   맞춥니다. 가운데를 기준으로 두면 글자가 길수록 안쪽 모서리가 원 쪽으로
   더 파고들어, 점과 글자 사이 간격이 항목마다 달라집니다(Sapok baji는 점에
   거의 붙었습니다). transform-origin을 왼쪽 가운데로 두면 그 지점이 회전
   중심이자 배치 기준점이 되어, 글자 길이와 상관없이 간격이 일정해집니다. */
.garment_orbit_item {
  position: absolute;
  left: 418px;
  top: 400px;
  transform-origin: left center;
  transform: translate(0, -50%);
  margin: 0;
  font-family: var(--font_display);
  font-weight: 500;
  font-size: 32px;
  letter-spacing: -0.32px;
  line-height: 1.41;
  color: var(--color-text-disabled, #c9c9c9);
  white-space: nowrap;
  transition: color var(--duration_base) var(--easing_base);
}

.garment_orbit_item.is_pos_active {
  color: var(--color_point);
}

.garment_content {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 39px;
}

.garment_info {
  position: relative;
  display: grid;
  width: 584px;
}

.garment_panel {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 39px;
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}

.garment_panel.is_active {
  opacity: 1;
  pointer-events: auto;
}

.garment_label {
  margin: 0 0 8px;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 1.28px;
  color: #a7a7a7;
}

.garment_title {
  margin: 0 0 40px;
  font-family: var(--font_display);
  font-weight: 600;
  font-size: 48px;
  line-height: 1.29;
  letter-spacing: -0.48px;
  color: var(--color_text);
}

.garment_desc {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 40px;
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.63;
  color: var(--color_text);
}

.garment_desc p {
  margin: 0;
}

.garment_details_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 15px;
  border: 1px solid var(--color_border_default);
  border-radius: 25px;
  background-color: #fff;
  font-family: var(--font_body);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 2.42px;
  color: var(--color_text);
  transition: border-color var(--duration_fast) var(--easing_base),
              background-color var(--duration_fast) var(--easing_base),
              color var(--duration_fast) var(--easing_base);
}

/* Figma BUTTON/Primary의 "속성 2=Hover" 변형(node 1461:2791): 배경과 테두리가
   둘 다 --color_point로 바뀝니다. 테두리를 같이 안 바꾸면 진한 초록 버튼에
   밝은 회색 테두리(--color_border_default)가 그대로 남아 테를 두른 것처럼
   보입니다. */
.garment_details_button:hover,
.garment_details_button:focus-visible {
  border-color: var(--color_point);
  background-color: var(--color_point);
  color: var(--color_text_inverse);
}

.garment_media {
  position: relative;
  width: 311px;
  height: 576px;
  flex-shrink: 0;
}

.garment_media_img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  will-change: transform, opacity;
}

.garment_media_img.is_active {
  opacity: 1;
}

/* =========================================================
   card_product — new_arrivals_section / shop 공용
   ========================================================= */

.card_product {
  /* hover 시 이미지가 추가로 커지는 배율. 상품별 확대(--card_img_zoom)에
     곱해지므로, 확대를 걸어둔 카드도 hover 반응은 똑같은 비율로 납니다. */
  --card_img_hover_grow: 1.04;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* 이미지와 상품 헤더를 누르면 상세 페이지로 가게 합니다. article 전체를 <a>로
   감싸면 swatch 버튼과 링크가 중첩돼 잘못된 HTML이 되므로 두 군데로 나눕니다.

     사진 영역  → .card_product_media_link (사진을 직접 감싼 링크)
     상품 헤더  → .card_product_link의 ::after

   설명·태그·swatch에는 확장 링크가 닿지 않아 각각 독립적으로 동작합니다. */
.card_product_link {
  color: inherit;
}

.card_product_content {
  position: relative;
}

.card_product_link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* 사진 링크는 키보드·스크린리더에서는 건너뜁니다. 같은 곳으로 가는 링크가
   카드마다 두 개씩 잡히면 탭 이동만 길어지기 때문입니다. 상품명 링크가
   그 역할을 대신합니다. */
.card_product_media_link {
  position: absolute;
  inset: 0;
  display: block;
}

/* ─── hover 등장 타이밍 (all / new 공용) ─────────────────────────────
   여기 다섯 값만 고치면 원단 사진과 아이콘이 나타나는 속도·순서가 전부
   바뀝니다. 마우스를 뗄 때는 지연 없이 한 번에 돌아갑니다.

     --card_hover_fade         원단 사진이 바뀌는 데 걸리는 시간
     --card_hover_delay        원단 사진이 바뀌기 시작하는 시점
     --card_icon_fade          아이콘 하나가 나타나는 데 걸리는 시간
     --card_icon_delay         첫 아이콘이 나타나는 시점
     --card_icon_stagger       아이콘과 아이콘 사이 간격

   순서는 이렇게 흘러갑니다(기본값 기준):
     0ms   원단 사진 교체 시작
     140ms 하트 아이콘 등장
     230ms 장바구니 아이콘 등장  (= 140 + 90)

   섹션별로 다르게 하고 싶으면 .new_arrivals_inner / .shop_section에,
   상품 하나만 다르게 하고 싶으면 그 카드의 .card_product_media에 얹으면
   됩니다(변수라 가까운 쪽이 이깁니다).

   아이콘 순번(--card_action_index)은 js/shop.js가 0, 1, 2… 로 넣어줍니다. */
.card_product_media {
  --card_hover_fade: 420ms;
  --card_hover_delay: 0ms;
  --card_icon_fade: 260ms;
  --card_icon_delay: 140ms;
  --card_icon_stagger: 90ms;

  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 10px;
  width: 100%;
  overflow: hidden;
  padding: 24px;
}

/* object-fit: cover라 이미지는 프레임을 꽉 채우고 넘치는 쪽이 잘립니다.
   "어디를 남기고 자를지"는 상품마다 다르므로 값을 카드에서 받아씁니다.
   둘 다 안 주면 지금까지처럼 가운데(50% 50%)로 잘립니다.

     --card_img_pos         hover 전 기본 이미지의 크롭 위치
     --card_img_hover_pos   hover 이미지의 크롭 위치
     --card_img_zoom        hover 전 기본 이미지의 확대 배율 (1 = 원래대로)
     --card_img_hover_zoom  hover 이미지의 확대 배율

   넷 다 서로 독립이라 필요한 것만 주면 나머지는 기본값 그대로입니다.
   위치는 두 번째 값이 세로 기준이고, 작을수록 위쪽을 더 보여줍니다(0% = 맨 위).

   변수는 상속되므로 두 단계로 쓸 수 있습니다. 아래쪽(가까운 쪽)이 이깁니다.

   1) 섹션 전체 기본값 — new / shop을 다르게 두고 싶을 때.
      원본 비율이 섹션마다 달라(new는 정사각, shop은 세로형) 잘리는 방향도
      다르므로 보통 여기서 갈립니다.
        .new_arrivals_inner { --card_img_pos: 50% 20%; }
        .shop_section       { --card_img_pos: 50% 35%; }

   2) 상품 하나만 — 그 카드의 .card_product_media에 인라인으로.
        <div class="card_product_media" style="--card_img_pos: 50% 0%; --card_img_zoom: 1.9">

   섹션 기본값을 안 주면 그 섹션은 전부 가운데(50% 50%)로 남고, 개별 지정한
   카드만 달라집니다. 손댈 필요 없는 사진은 아무것도 안 쓰면 됩니다.

   확대의 기준점(transform-origin)은 크롭 위치를 그대로 따라갑니다. 위쪽을
   보여주도록 맞춰둔 카드는 확대해도 위쪽이 고정된 채 커져서, 두 값을 같이
   써도 서로 어긋나지 않습니다.

   img가 아니라 컨테이너에 넣는 이유: hover 이미지는 js/shop.js가 나중에
   만들어 붙이는데 인라인 style을 복사하지 않습니다. 컨테이너에 두면 나중에
   생기는 이미지까지 값을 상속받습니다. */
.card_product_img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--card_img_pos, 50% 50%);
  transform: scale(var(--card_img_zoom, 1));
  transform-origin: var(--card_img_pos, 50% 50%);
  transition: opacity var(--card_hover_fade) var(--easing_base),
              transform var(--duration_base) var(--easing_base);
}

/* .card_product_img와 같은 특정도(클래스 1개)라, 뒤에 오는 이 규칙이 이깁니다. */
.card_product_img_hover {
  opacity: 0;
  object-position: var(--card_img_hover_pos, 50% 50%);
  transform: scale(var(--card_img_hover_zoom, 1));
  transform-origin: var(--card_img_hover_pos, 50% 50%);
}

/* 카드 전체(.card_product)가 아니라 사진 영역(.card_product_media)에 마우스를
   올렸을 때만 원단 사진으로 바뀝니다. 아래 상품명·설명·태그 위를 지나갈
   때는 사진이 그대로 있습니다. 키보드 사용자를 위해 :focus-within도 같이
   둡니다(사진 안의 아이콘에 포커스가 들어온 경우). */
.card_product_media.has_hover_image:hover .card_product_img_default,
.card_product_media.has_hover_image:focus-within .card_product_img_default {
  opacity: 0;
  transition-delay: var(--card_hover_delay);
}

.card_product_media.has_hover_image:hover .card_product_img_hover,
.card_product_media.has_hover_image:focus-within .card_product_img_hover {
  opacity: 1;
  transition-delay: var(--card_hover_delay);
}

/* 상품별 확대에 hover 배율을 "곱합니다". scale(1.04)로 덮어쓰면
   --card_img_zoom을 걸어둔 카드가 hover 시 오히려 작아집니다. */
.card_product_media:hover .card_product_img {
  transform: scale(calc(var(--card_img_zoom, 1) * var(--card_img_hover_grow, 1.04)));
}

/* 위 규칙과 특정도가 같아, 뒤에 있는 이 규칙이 hover 이미지에 적용됩니다. */
.card_product_media:hover .card_product_img_hover {
  transform: scale(calc(var(--card_img_hover_zoom, 1) * var(--card_img_hover_grow, 1.04)));
}

.card_product_action {
  position: relative;
  /* 카드 전체를 덮는 상세 링크(.card_product_link::after, z-index 1)보다 위에
     있어야 아이콘을 따로 누를 수 있습니다. */
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 6px;
  isolation: isolate;
  overflow: hidden;
  background-color: #fff;
  opacity: 0;
  transition: opacity var(--card_icon_fade) var(--easing_base),
              background-color var(--duration_fast) var(--easing_base);
}

.card_product_action::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--color_point);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 320ms var(--easing_base);
}

/* 아이콘이 한꺼번에 툭 나타나지 않고 순번(--card_action_index)에 따라 하나씩
   이어서 나타납니다. delay를 transition-delay로 따로 주지 않고 shorthand에
   넣는 이유: transition-delay는 background-color에도 걸려서, 아이콘에 마우스를
   올렸을 때 초록으로 바뀌는 것까지 늦어집니다. */
.card_product_media:hover .card_product_action,
.card_product_media:focus-within .card_product_action {
  opacity: 1;
  transition: opacity var(--card_icon_fade) var(--easing_base)
                var(--card_icon_delay),
              background-color var(--duration_fast) var(--easing_base);
}

.card_product_action_icon {
  position: relative;
  z-index: 1;
  width: 20px;
  height: 20px;
  transition: filter 140ms var(--easing_base) 90ms;
}

.card_product_action:hover,
.card_product_action:focus-visible {
  background-color: #fff;
}

.card_product_action:hover::before,
.card_product_action:focus-visible::before {
  transform: scaleY(1);
}

.card_product_action:hover .card_product_action_icon,
.card_product_action:focus-visible .card_product_action_icon {
  filter: brightness(0) invert(1);
}

.card_product_wishlist_button.is_selected::before {
  transform: scaleY(1);
}

.card_product_wishlist_button.is_selected .card_product_action_icon {
  filter: brightness(0) invert(1);
}

.shop_action_toast {
  position: fixed;
  left: 50%;
  bottom: max(24px, env(safe-area-inset-bottom));
  z-index: 9997;
  width: max-content;
  max-width: calc(100vw - 32px);
  min-height: 44px;
  padding: 12px 18px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: var(--color_point);
  color: var(--color_text_on_dark);
  box-shadow: 0 8px 24px rgba(10, 10, 10, 0.16);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate(-50%, 14px);
  transition: opacity 0.24s ease,
              transform 0.32s var(--easing_base),
              visibility 0s linear 0.32s;
  font-family: var(--font_ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.5;
}

.shop_action_toast.is_visible {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
}

/* 장바구니 추가 직후에는 공통 스크롤 헤더가 숨김 상태여도 3초간 확인할 수 있게 합니다. */
.header.is_cart_revealed {
  transform: translateY(0);
}

.card_product_content {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
  padding: 20px 16px 0;
}

.card_product_primary {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
}

.card_product_header {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
}

.card_product_name {
  margin: 0;
  font-family: var(--font_display);
  font-weight: 500;
  font-size: 32px;
  line-height: 1.41;
  letter-spacing: -0.32px;
  color: var(--color_text);
}

.card_product_price {
  flex-shrink: 0;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 24px;
  line-height: 1.42;
  letter-spacing: 0.24px;
  color: var(--color_price);
}

.card_product_swatches {
  position: relative;
  z-index: 2;
  display: flex;
  gap: 8px;
  width: fit-content;
}

.card_product_swatch {
  display: block;
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 0;
  box-shadow: none;
  appearance: none;
  cursor: pointer;
  transition: border-color 0.2s ease,
              box-shadow 0.2s ease;
}

.card_product_swatches:not(.is_initialized) .card_product_swatch:first-child,
.card_product_swatch.is_selected {
  border: 1px solid #fff;
  box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, 0.25);
}

.card_product_swatch:not(.is_selected):hover {
  border-color: #fff;
  box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, 0.25);
}

.card_product_swatch:focus-visible {
  outline: 1px solid var(--color_text);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .card_product_swatch,
  .shop_action_toast {
    transition: none;
  }
}

.card_product_supporting {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
}

.card_product_desc {
  margin: 0;
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.63;
  color: var(--color_text_secondary);
}

.card_product_tags {
  display: flex;
  align-items: center;
  gap: 16px;
}

.card_product_tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 20px;
  border-radius: 35px;
  border: 1px solid var(--color_border_default);
  background-color: #fff;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 1.28px;
  color: var(--color_text);
}

.card_product_tag_status {
  border-color: var(--color_point);
  color: var(--color_point);
}

.card_product_tag_status.is_filled {
  background-color: var(--color_point);
  color: #fff;
}

/* size modifier: New (2열, 800x930) */
.card_product.is_size_new {
  width: 800px;
}

.card_product.is_size_new .card_product_media {
  height: 640px;
}

/* size modifier: Shop (3열, 528x950) */
.card_product.is_size_shop {
  width: 528px;
}

.card_product.is_size_shop .card_product_media {
  height: 660px;
}

.card_product.is_size_shop .card_product_header {
  min-height: 76px;
}

/* =========================================================
   new_arrivals_section
   ========================================================= */

.new_arrivals_section {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 65px 0;
  background-color: var(--color_bg_alt);
}

.new_arrivals_inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 79px;
}

.new_arrivals_title {
  margin: 0;
  font-family: var(--font_display);
  font-weight: 600;
  font-size: 48px;
  line-height: 1.29;
  letter-spacing: -0.48px;
  color: #0d0d0c;
}

.new_arrivals_grid {
  display: flex;
  flex-direction: column;
  gap: 79px;
}

.new_arrivals_row {
  display: flex;
  gap: 79px;
}

/* =========================================================
   shop
   ========================================================= */

.shop_section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 95px;
  width: 100%;
  padding-bottom: 220px;
  background-color: #fff;
}

.shop_filter_bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 18px;
  width: 1712px;
  padding: 80px 0;
}

.shop_search {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 400px;
  height: 70px;
  padding: 0 25px;
  border: 1px solid var(--color_border_default);
  background-color: #fff;
  transition: width var(--duration_base) var(--easing_base);
}

.shop_search:focus-within {
  width: 520px;
}

.shop_search_icon {
  flex-shrink: 0;
  width: 25px;
  height: 25px;
}

.shop_search_input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font_body);
  font-size: 16px;
  line-height: 1.63;
  color: var(--color_text);
}

.shop_search_input::placeholder {
  color: var(--color_text_secondary);
}

.shop_select {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 276px;
  height: 70px;
  padding: 0 25px;
  border: 1px solid var(--color_border_default);
  background-color: #fff;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 1.28px;
  color: var(--color_point);
}

.shop_select_icon {
  width: 30px;
  height: 30px;
  transition: transform var(--duration_base) var(--easing_base);
}

/* 열려 있는 동안 화살표가 뒤집혀서, 목록이 닫힐 곳을 가리킵니다. */
.shop_select[aria-expanded="true"] .shop_select_icon {
  transform: rotate(180deg);
}

/* ─── 카테고리 목록 ────────────────────────────────────────────────
   버튼 아래에 겹쳐 열립니다. 목록이 자리를 차지하면 열 때마다 아래 상품
   그리드가 밀려 내려가므로 absolute로 띄웁니다.

   위 카드 아이콘(z-index 2)과 카드 전체 링크(z-index 1)보다 위에 있어야
   목록이 가려지지 않습니다. */
.shop_select_wrap {
  position: relative;
  z-index: 5;
}

/* 등장 타이밍은 이 세 값만 고치면 전부 바뀝니다. 카드 아이콘 stagger와
   같은 방식이라 값의 의미도 그대로입니다.

     --shop_select_fade      항목 하나가 나타나는 데 걸리는 시간
     --shop_select_delay     첫 항목이 나타나는 시점
     --shop_select_stagger   항목과 항목 사이 간격

   기본값 기준으로 DRESS가 60ms, LIVING이 330ms(= 60 + 6 × 45)에 나타나고
   전체가 다 보이는 데 650ms가 걸립니다. 닫을 때는 지연 없이 한 번에
   사라집니다. 순번(--shop_select_index)은 js/shop.js가 0, 1, 2… 로 넣어줍니다. */
.shop_select_list {
  --shop_select_fade: 320ms;
  --shop_select_delay: 60ms;
  --shop_select_stagger: 45ms;

  position: absolute;
  /* 버튼과 목록의 테두리가 1px씩 겹쳐서 한 줄로 보이게 끌어올립니다. */
  top: calc(100% - 1px);
  left: 0;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--color_border_default);
  background-color: #fff;
  /* 닫혀 있는 동안에는 마우스도 탭 이동도 목록에 닿지 않습니다.
     visibility는 항목이 다 사라진 뒤에 꺼지도록 늦춥니다. */
  visibility: hidden;
  transition: visibility 0s linear var(--shop_select_fade);
}

.shop_select_list.is_open {
  visibility: visible;
  transition-delay: 0s;
}

.shop_select_item {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity var(--shop_select_fade) var(--easing_base),
              transform var(--shop_select_fade) var(--easing_base);
}

/* 순번만큼 늦게 나타납니다. 지연을 여는 쪽에만 두었기 때문에, 닫을 때는
   일곱 개가 기다리지 않고 같이 사라집니다. */
.shop_select_list.is_open .shop_select_item {
  opacity: 1;
  transform: none;
  transition-delay: calc(
    var(--shop_select_delay) + var(--shop_select_index, 0) * var(--shop_select_stagger)
  );
}

/* hover 배경색은 항목(li)이 아니라 버튼에 둡니다. li에 두면 위 등장 지연이
   배경색에도 걸려서, 마우스를 올렸을 때 색이 늦게 따라옵니다. */
.shop_select_option {
  display: flex;
  align-items: center;
  width: 100%;
  height: 56px;
  padding: 0 25px;
  border: 0;
  background: none;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 1.28px;
  color: var(--color_point);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--duration_fast) var(--easing_base);
}

.shop_select_option:hover,
.shop_select_option:focus-visible {
  background-color: var(--color_bg_alt);
}

.shop_select_item.is_selected .shop_select_option {
  background-color: var(--color_bg_alt);
  font-weight: 600;
}

.shop_filter_button {
  display: flex;
  align-items: center;
  gap: 20px;
  width: 145px;
  height: 70px;
  padding: 0 25px;
  border: 1px solid var(--color_border_default);
  border-radius: 50px;
  background-color: #fff;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 1.28px;
  color: var(--color_point);
}

.shop_filter_button_icon {
  width: 24px;
  height: 24px;
}

.shop_list_wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 140px;
}

.shop_list_section {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 38px;
}

.shop_list_title {
  margin: 0;
  font-family: var(--font_display);
  font-weight: 600;
  font-size: 48px;
  line-height: 1.29;
  letter-spacing: -0.48px;
  color: #0d0d0c;
}

.shop_grid {
  display: flex;
  flex-direction: column;
  gap: 90px;
}

.shop_row {
  display: flex;
  gap: 90px;
}

.shop_more_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 194px;
  height: 64px;
  padding: 15px 20px;
  background-color: var(--color_point);
  font-family: var(--font_body);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: 1.08px;
  color: var(--color_text_on_dark);
  text-align: center;
}

.shop_more_button:hover,
.shop_more_button:focus-visible {
  opacity: 0.85;
}

/* =========================================================
   motif_detail
   출처: Figma node 1649:3009 (motif_detail)
   ========================================================= */

.motif_detail_section {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 250px 0;
  /* 상품 스트립이 컨테이너(1523px)보다 넓어 좌우로 흘러넘치는 디자인입니다.
     clip은 hidden과 달리 스크롤 컨테이너를 만들지 않아 아래 sticky를 막지 않습니다. */
  overflow-x: clip;
  overflow-y: visible;
  background-color: var(--color_bg_inverse);
}

.motif_detail_container {
  display: flex;
  flex-direction: column;
  gap: 280px;
  width: 1523px;
}

/* 왼쪽 reference의 sticky 범위는 이 부모의 높이(= 오른쪽 영상 높이)로 제한됩니다.
   영상 끝에 도달하면 reference도 함께 풀려 아래 related 영역으로 넘어갑니다. */
.motif_hero {
  display: flex;
  align-items: flex-start;
  gap: 100px;
}

.motif_reference {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
  width: 380px;
  height: 100vh;
  align-self: flex-start;
  flex-shrink: 0;
}

.motif_reference_image {
  width: 380px;
  height: 380px;
  overflow: hidden;
}

.motif_reference_img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.motif_reference_copy {
  display: flex;
  flex-direction: column;
  gap: 25px;
}

.motif_reference_heading {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.motif_reference_eyebrow {
  margin: 0;
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.38;
  letter-spacing: 1.28px;
  color: var(--color_text_subtle);
}

.motif_reference_title {
  margin: 0;
  font-family: var(--font_display);
  font-weight: 600;
  font-size: 48px;
  line-height: 1.29;
  letter-spacing: -0.48px;
  color: var(--color_text_inverse);
}

.motif_reference_desc {
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.63;
  color: var(--color_text_inverse);
}

/* 시안에서 두 문단은 사이 간격 없이 행간으로만 이어집니다. */
.motif_reference_desc p {
  margin: 0;
}

.motif_video {
  width: 1043px;
  height: 1826px;
  flex-shrink: 0;
  overflow: hidden;
}

.motif_video_media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.motif_related {
  display: flex;
  flex-direction: column;
  gap: 80px;
}

.motif_related_title {
  margin: 0;
  font-family: var(--font_display);
  font-weight: 500;
  font-size: 32px;
  line-height: 1.41;
  letter-spacing: -0.32px;
  color: var(--color_text_inverse);
}

/* 카드가 커지고 작아질 때 형제 카드가 좌우로 밀려나야 하므로 flex 배치를
   유지하고, transform: scale이 아니라 width/height 자체를 바꿉니다.
   scale로 하면 카드가 제자리에서 부풀어 옆 카드를 덮어버립니다
   (Figma 주석: "card 자체를 scale로 겹쳐 확대하지 않고 크기를 변경한다"). */
.motif_product_strip {
  /* Hover effect controls — change only these values to tune the frosted look. */
  --motif_layer_blur: 3px;
  --motif_layer_tint: rgba(255, 255, 255, 0.58);
  --motif_layer_glow: 0.34;

  display: flex;
  align-items: flex-end;
  align-self: center;
  gap: 20px;
  width: calc(100vw - 80px);
  max-width: 1840px;
  /* 선택된 카드 높이(309px)로 고정합니다. 높이를 auto로 두면 전환하는 동안
     커지는 카드와 작아지는 카드가 둘 다 중간 크기를 지나면서 가장 큰 카드가
     309보다 작아지는 순간이 생기고, 그때마다 스트립 높이가 출렁여서 아래
     영역이 덜컥거립니다. */
  height: 309px;
}

/* 크기 3단계 — 기본(가장 작음) / 양옆(중간) / 선택(가장 큼).
   이미지 자체를 바꾸지 않고 카드 레이아웃만 긴 ease-out 곡선으로 이동합니다. */
.motif_product_card {
  position: relative;
  /* The strip keeps a constant outer width. Cards trade space inside it, so
     selecting an edge item never pushes the opposite edge outside the view. */
  flex: 207 1 0;
  min-width: 0;
  height: 209px;
  will-change: flex-grow, height;
  transition: flex-grow 620ms cubic-bezier(0.22, 1, 0.36, 1),
              height 620ms cubic-bezier(0.22, 1, 0.36, 1);
}

.motif_product_card.is_selected {
  flex-grow: 307;
  height: 309px;
}

/* 선택된 카드의 오른쪽 이웃과 왼쪽 이웃. 왼쪽은 CSS에 이전 형제 선택자가
   없어서 :has()로 "바로 뒤가 선택된 카드인 것"을 잡습니다. */
.motif_product_card.is_selected + .motif_product_card,
.motif_product_card:has(+ .motif_product_card.is_selected) {
  flex-grow: 237;
  height: 239px;
}

/* 전역 :focus-visible은 어두운 초록(--color_point)이라 검은 배경에서 거의
   안 보입니다. 이 섹션에서만 밝은 색으로 바꿉니다. */
.motif_product_card:focus-visible {
  outline: 2px solid var(--color_text_inverse);
  outline-offset: 4px;
}

.motif_product_media {
  position: relative;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.motif_product_img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: blur(0);
  transition: filter 620ms cubic-bezier(0.22, 1, 0.36, 1);
}

.motif_product_card.is_selected:hover .motif_product_img,
.motif_product_card.is_selected:focus-visible .motif_product_img {
  filter: blur(var(--motif_layer_blur));
}

/* 가장 커진 카드에 마우스를 올리고 있는 동안에만 뜨는 상세 패널.
   시안(Figma node 1680:2933)의 effect 프레임 구조를 그대로 옮겼습니다.

   시안의 effect 프레임 자체에는 배경이 없지만, 배경 없이 흰 글씨만 얹으면
   흰 바탕 상품 사진(체크/레오파드/빨강 등) 위에서 전혀 안 읽힙니다. 그래서
   어두운 덮개를 넣었습니다. 사진이 살짝 비쳐 보이는 정도로 잡았고, 값은
   아래 background-color 한 곳만 고치면 됩니다(0이면 시안 그대로, 1이면 완전
   불투명). */
.motif_product_overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
  padding: clamp(22px, 2.2vw, 42px);
  isolation: isolate;
  overflow: hidden;
  background: transparent;
  opacity: 0;
  /* 카드가 커지는 동안 글이 좁은 칸에 끼어 보이지 않도록, 사라질 때는 바로
     빠지고 나타날 때만 살짝 늦게 뜹니다(아래 hover 규칙의 delay). */
  pointer-events: none;
  transition: opacity 520ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Frosted white panel is kept on its own layer so the product copy remains
   perfectly sharp above both the tint and backdrop blur. */
.motif_product_overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border: 1px solid rgba(255, 255, 255, 0.7);
  background: var(--motif_layer_tint);
  box-shadow: 0 0 32px rgba(255, 255, 255, var(--motif_layer_glow));
  opacity: 0;
  transform: scale(0.96);
  transition: opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 620ms cubic-bezier(0.22, 1, 0.36, 1);
}

.motif_product_overlay > * {
  position: relative;
  z-index: 1;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 420ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
}

.motif_product_card.is_selected:hover .motif_product_overlay,
.motif_product_card.is_selected:focus-visible .motif_product_overlay {
  opacity: 1;
}

.motif_product_card.is_selected:hover .motif_product_overlay::before,
.motif_product_card.is_selected:focus-visible .motif_product_overlay::before {
  opacity: 1;
  transform: scale(1);
}

.motif_product_card.is_selected:hover .motif_product_head,
.motif_product_card.is_selected:focus-visible .motif_product_head {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 90ms;
}

.motif_product_card.is_selected:hover .motif_product_foot,
.motif_product_card.is_selected:focus-visible .motif_product_foot {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 150ms;
}

.motif_product_head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.motif_product_name {
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 20px;
  line-height: 1.6;
  color: var(--color_text);
}

.motif_product_sub {
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.63;
  color: var(--color_text);
}

.motif_product_foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
}

.motif_product_meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.motif_product_line {
  width: 77px;
  height: 1px;
  background-color: var(--color_text);
}

.motif_product_price {
  font-family: var(--font_body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.38;
  letter-spacing: 1.28px;
  color: var(--color_text);
}

/* garment_details_button과 같은 형태지만 시안에서 모서리가 각져 있어
   border-radius만 다릅니다. */
.motif_product_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 15px;
  border: 1px solid var(--color_border_default);
  background-color: #fff;
  font-family: var(--font_body);
  font-weight: 600;
  font-size: 11px;
  line-height: 1.55;
  letter-spacing: 2.42px;
  color: var(--color_text);
  white-space: nowrap;
}

/* 공통 1920px zoom은 common/css/common.css에서 관리합니다.
   Shop의 garment story는 ScrollTrigger pin 계산에 zoom이 중복 반영되므로 이 구간만 원래 크기로 복원합니다. */

@media (min-width: 1850px) and (max-width: 1990px) {
  /* garment story만 축소에서 빼냅니다(1 ÷ 0.75 = 원래 크기로 복귀).

     이 섹션은 GSAP ScrollTrigger가 pin으로 붙잡습니다. pin이 걸리는 순간
     ScrollTrigger는 getBoundingClientRect로 잰 크기를 그대로 인라인
     height/width에 써넣는데, 그 값에는 이미 zoom이 반영돼 있습니다.
     거기에 zoom이 한 번 더 곱해져 섹션이 화면의 위 607px만 덮고
     아래 473px로 다음 섹션이 비쳤습니다.

     여기서 zoom을 1로 되돌리면 이 안에서는 잰 값과 실제 값이 같아져
     그 문제가 사라집니다. 대가는 이 섹션만 원래 크기로 보인다는 것인데,
     원래 화면을 꽉 채우도록 만든 전체화면 구성이라 어색하지 않습니다. */
  .garment_story_scroll {
    zoom: calc(1 / var(--site_view_scale));
  }

  /* html zoom으로 100vh가 화면상 810px로 줄어드는 것을 상쇄해,
     발표 화면에서도 reference가 실제 뷰포트 1080px를 채우게 합니다. */
  .motif_reference {
    height: calc(100vh / var(--site_view_scale));
  }
}

/* =========================================================
   반응형 (2026-08-09) — 360 / 768 / 1280

   ★ 1920 Shop 결과는 기존 공통화 전과 동일합니다.
   아래 규칙은 전부 max-width: 1849px 이하 미디어쿼리 "안에만" 있습니다.
   1920 창은 뷰포트가 1905~1920이라 이 조건에 걸릴 수 없고,
   공통 zoom 블록(1850~1990)의 결과가 그대로 유지됩니다. 2560도 무영향입니다.
   측정으로 확인한 게 아니라 구간이 겹치지 않아 구조적으로 보장됩니다.
   기존 규칙은 한 줄도 수정하지 않았고 여기에 덧붙이기만 했습니다.

   ★ 규칙 이탈 보고 (AGENTS.md "모바일부터 작성")
   mobile-first(min-width)로 쓰려면 미디어쿼리 밖 기본 규칙을 모바일 값으로
   다시 써야 하고, 그 순간 1920 결과가 바뀝니다. "1920 불변"이 더 강한
   제약이라 desktop-first(max-width)로 작성했습니다.

   브레이크포인트는 docs/PRD.md 14항 기준입니다.
   479px 한 개만 PRD에 없는 값인데, 360px에서 상품 카드를 2열로 두면
   카드 한 장이 약 160px이라 가격·설명·태그가 읽히지 않아 1열로 내리는
   지점이 필요했습니다.
   ========================================================= */

/* ---------------------------------------------------------
   ~1849px — 데스크톱 축소 구간
   1920 고정 프레임을 풀고 유동으로 바꿉니다. 상품 그리드 열 수는
   아직 시안 그대로(New 2열 / Shop 3열)입니다.
   --------------------------------------------------------- */
@media (max-width: 1849px) {

  /* hero — 1920 절대좌표(워터마크 566/1335, 갤러리 -162/40, 내비 1608px)를
     버리고 세로 흐름으로 바꿉니다. .hero_nav_item에 position: static을 주면
     .hero_nav_item_* 8개의 left/top이 자동으로 무효가 되므로 개별 좌표를
     하나씩 덮을 필요가 없습니다. */
  .hero_section {
    height: auto;
  }

  .hero_section_frame {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 48px;
    width: 100%;
    padding: 180px 40px 100px;
  }

  .hero_section_watermark {
    position: static;
    transform: none;
    font-size: min(20vw, 340px);
    text-align: center;
  }

  .hero_gallery {
    position: static;
    width: 100%;
    max-width: 1100px;
    height: min(62vw, 720px);
  }

  .hero_nav {
    position: static;
    inset: auto;
    transform: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 14px 30px;
    pointer-events: auto;
  }

  .hero_nav_item {
    position: static;
  }

  .hero_nav_link {
    min-width: 0;
  }

  /* 가로로 늘어선 상태에서 1.29배로 키우면 옆 항목을 덮습니다. */
  .hero_nav .hero_nav_link.is_active {
    transform: none;
  }

  /* banner */
  .banner {
    height: auto;
    padding: 110px 40px;
  }

  .banner_title {
    width: auto;
    max-width: 720px;
  }

  /* garment_story — 이 구간은 휠 재킹을 유지합니다(해제는 1279 이하).
     원형 내비를 왼쪽으로 더 빼고, 글+사진 묶음이 원을 덮지 않도록
     최대 폭을 "남는 자리"로 제한합니다. 420px = 화면에 보이는 원의 폭
     (968 - 560) + 여유 12px. */
  .garment_story_frame {
    width: 100%;
    padding: 0 clamp(32px, 4vw, 180px);
  }

  .garment_orbit {
    left: -560px;
  }

  .garment_content {
    width: 100%;
    max-width: min(934px, calc(100% - 420px));
    margin-left: auto;
  }

  .garment_info {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
  }

  /* new_arrivals — .new_arrivals_row가 고정 행이라 열 수를 바꿀 수 없어서,
     행을 display: contents로 없애고 카드를 grid 직계 자식으로 올립니다.
     HTML은 건드리지 않습니다. */
  .new_arrivals_section {
    padding-right: 40px;
    padding-left: 40px;
  }

  .new_arrivals_inner {
    width: 100%;
    max-width: 1679px;
  }

  .new_arrivals_grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 56px;
    width: 100%;
  }

  .new_arrivals_row {
    display: contents;
  }

  .card_product.is_size_new {
    width: auto;
  }

  /* 고정 높이(640px)를 비율로 바꿔야 카드가 좁아질 때 사진이 세로로 늘어진
     채 남지 않습니다. .card_product_img는 이미 object-fit: cover라 크롭만
     달라지고 --card_img_pos 설정은 그대로 살아 있습니다. */
  .card_product.is_size_new .card_product_media {
    height: auto;
    aspect-ratio: 800 / 640;
  }

  /* shop */
  .shop_section {
    padding-right: 40px;
    padding-left: 40px;
  }

  .shop_filter_bar {
    flex-wrap: wrap;
    width: 100%;
    max-width: 1712px;
    padding-top: 60px;
    padding-bottom: 60px;
  }

  .shop_list_wrap,
  .shop_list_section {
    width: 100%;
  }

  .shop_grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 56px;
    width: 100%;
  }

  .shop_row {
    display: contents;
  }

  .card_product.is_size_shop {
    width: auto;
  }

  .card_product.is_size_shop .card_product_media {
    height: auto;
    aspect-ratio: 528 / 660;
  }

  /* motif_detail — .motif_product_strip은 이미 calc(100vw - 80px)라 유동입니다. */
  .motif_detail_section {
    padding: 160px 40px;
  }

  .motif_detail_container {
    gap: 180px;
    width: 100%;
    max-width: 1523px;
  }

  .motif_hero {
    gap: 60px;
  }

  .motif_video {
    width: auto;
    height: auto;
    min-width: 0;
    flex: 1 1 0;
    aspect-ratio: 1043 / 1826;
  }
}

/* ---------------------------------------------------------
   ~1280px — 태블릿. 상품 그리드 2열.

   1279가 아니라 1280인 이유: 브라우저는 창 1280px에서 미디어쿼리를 1280으로
   평가합니다(스크롤바를 뺀 1265가 아닙니다 — 실측 확인). max-width: 1279px로
   두면 PRD의 태블릿 기준점인 1280에서 규칙이 하나도 안 걸립니다.
   --------------------------------------------------------- */
@media (max-width: 1280px) {

  .hero_section_frame {
    gap: 40px;
    padding: 150px 32px 80px;
  }

  .hero_gallery {
    height: min(70vw, 560px);
  }

  .banner {
    padding: 90px 32px;
  }

  .garment_title {
    margin-bottom: 24px;
    font-size: 36px;
  }

  /* 상품 그리드 2열 */
  .new_arrivals_section,
  .shop_section {
    padding-right: 32px;
    padding-left: 32px;
  }

  .new_arrivals_grid,
  .shop_grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 40px;
  }

  .new_arrivals_inner {
    gap: 48px;
  }

  .new_arrivals_title,
  .shop_list_title {
    font-size: 36px;
  }

  .shop_filter_bar {
    justify-content: flex-start;
    padding-top: 48px;
    padding-bottom: 48px;
  }

  .shop_search {
    flex: 1 1 260px;
    width: auto;
  }

  /* width를 flex로 넘겼으므로 포커스 시 넓어지는 연출은 이 폭에서 끕니다.
     그대로 두면 형제 요소가 밀려 필터바가 줄바꿈했다 풀렸다 합니다. */
  .shop_search:focus-within {
    width: auto;
  }

  .shop_select {
    flex: 0 1 240px;
    width: auto;
  }

  .shop_list_wrap {
    gap: 90px;
  }

  /* motif_detail — 사진+글 2단을 세로로 */
  .motif_detail_section {
    padding: 120px 32px;
  }

  .motif_detail_container {
    gap: 120px;
  }

  .motif_hero {
    flex-direction: column;
    gap: 48px;
  }

  .motif_reference {
    position: static;
    height: auto;
    justify-content: flex-start;
    width: 100%;
    max-width: 520px;
  }

  .motif_reference_image {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
  }

  .motif_video {
    width: 100%;
    max-width: 720px;
    align-self: center;
  }

  .motif_related {
    gap: 56px;
  }

  /* 상품 스트립 — 한 줄 나눠 갖기 → 가로 스와이프

     기본 배치는 카드 8장이 스트립 폭을 flex-grow 비율로 나눠 갖습니다.
     1920에서는 스트립이 넓어 카드가 약 210px이지만, 1085px 화면에서는
     한 장이 100 × 165px까지 눌려 옷이 보이지 않습니다(원본 828 × 836).
     높이만 키우면 세로로 길어질 뿐이라 가로 폭을 확보해야 합니다.

     그래서 flex-grow 배분을 끄고(flex-basis 고정) 스트립을 옆으로 밀어
     보게 합니다. 누르면 커지는 기존 인터랙션은 그대로 살아 있고,
     transition 대상만 flex-grow → flex-basis로 바뀝니다. */
  .motif_product_strip {
    width: 100%;
    max-width: none;
    /* 선택된 카드(320) + 스크롤바 자리(20). 높이를 auto로 두면 선택이
       바뀔 때마다 가장 큰 카드가 달라져 스트립 높이가 출렁입니다
       (기본 규칙의 주석과 같은 이유). */
    height: 340px;
    padding-bottom: 20px;
    gap: 16px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }

  .motif_product_card {
    flex: 0 0 190px;
    height: 250px;
    scroll-snap-align: center;
    transition: flex-basis 620ms cubic-bezier(0.22, 1, 0.36, 1),
                height 620ms cubic-bezier(0.22, 1, 0.36, 1);
  }

  .motif_product_card.is_selected {
    flex-basis: 270px;
    height: 320px;
  }

  .motif_product_card.is_selected + .motif_product_card,
  .motif_product_card:has(+ .motif_product_card.is_selected) {
    flex-basis: 220px;
    height: 285px;
  }
}

/* ---------------------------------------------------------
   ~1279px — garment_story 휠 재킹 해제

   ★ 이 블록만 1279입니다. js/shop.js의 게이트가
   `matchMedia("(min-width: 1280px)")`라 정확히 짝이 맞아야 합니다.
   1280으로 넓히면 1280에서 JS는 pin을 걸고 CSS는 세로로 쌓아 어긋납니다.
   (선택 사항: 그리드는 "1280에서 2열", 재킹은 "1280 미만에서 해제")
   --------------------------------------------------------- */
@media (max-width: 1279px) {

  .garment_story_scroll {
    --garment_story_section_gap: 80px;
  }

  /* JS가 초기화를 건너뛰므로 pin도 sticky도 없습니다.
     화면 높이 고정(100vh)을 풀고 일반 흐름으로 되돌립니다. */
  .garment_story_section {
    height: auto;
  }

  .garment_story_frame {
    display: block;
    width: 100%;
    height: auto;
    padding: 128px 32px;
  }

  /* 원형 내비는 휠 회전 전용 장치라 재킹이 없으면 의미가 없습니다.
     JS가 매 프레임 좌표를 다시 쓰는 대상이기도 해서 남겨두면 어긋납니다. */
  .garment_orbit {
    display: none;
  }

  /* .garment_info(글 4개)와 .garment_media(사진 4장)가 서로 다른 부모에
     들어 있어 CSS만으로는 짝지을 수 없습니다. 두 컨테이너를 display: contents로
     없애 8개 요소를 .garment_content의 grid 직계 자식으로 올린 뒤,
     grid-row를 사진1·글1·사진2·글2… 순서로 직접 지정해 짝을 맞춥니다.
     HTML은 건드리지 않습니다. */
  .garment_content {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
  }

  .garment_info,
  .garment_media {
    display: contents;
  }

  /* 기본 상태가 opacity: 0(JS가 is_active로 켬)이라 여기서 되살립니다. */
  .garment_panel {
    grid-area: auto;
    opacity: 1;
    pointer-events: auto;
  }

  .garment_media_img {
    position: static;
    justify-self: center;
    width: 100%;
    max-width: 420px;
    height: auto;
    aspect-ratio: 311 / 576;
    opacity: 1;
  }

  .garment_media_img:nth-child(1) { grid-row: 1; }
  .garment_panel:nth-child(1)     { grid-row: 2; }
  .garment_media_img:nth-child(2) { grid-row: 3; }
  .garment_panel:nth-child(2)     { grid-row: 4; }
  .garment_media_img:nth-child(3) { grid-row: 5; }
  .garment_panel:nth-child(3)     { grid-row: 6; }
  .garment_media_img:nth-child(4) { grid-row: 7; }
  .garment_panel:nth-child(4)     { grid-row: 8; }
}

/* ---------------------------------------------------------
   ~767px — 모바일
   hero의 WebGL 원통은 js/shop.js가 이 폭에서 초기화를 건너뛰므로
   .hero_gallery_fallback 정지 이미지가 그대로 보입니다.
   --------------------------------------------------------- */
@media (max-width: 767px) {

  .garment_story_scroll {
    --garment_story_section_gap: 56px;
  }

  .hero_section_frame {
    gap: 28px;
    padding: 120px 20px 60px;
  }

  .hero_section_watermark {
    font-size: min(26vw, 180px);
  }

  /* is_ready가 붙지 않으므로 fallback 이미지가 보이는 상태입니다.
     세로로 긴 원통 비율(1700×1280) 대신 사진 한 장에 맞는 비율로 둡니다. */
  .hero_gallery {
    height: auto;
    aspect-ratio: 3 / 4;
    max-width: 420px;
  }

  .hero_nav {
    gap: 10px 20px;
  }

  .banner {
    padding: 64px 20px;
  }

  .garment_story_frame {
    padding: 88px 20px;
  }

  .garment_content {
    gap: 32px;
  }

  .garment_title {
    font-size: 30px;
  }

  .new_arrivals_section,
  .shop_section {
    padding-right: 20px;
    padding-left: 20px;
  }

  .new_arrivals_grid,
  .shop_grid {
    gap: 24px;
  }

  .new_arrivals_title,
  .shop_list_title {
    font-size: 28px;
  }

  .shop_filter_bar {
    gap: 12px;
    padding-top: 36px;
    padding-bottom: 36px;
  }

  .shop_search,
  .shop_select,
  .shop_filter_button {
    flex: 1 1 100%;
    width: auto;
    height: 56px;
  }

  .shop_list_wrap {
    gap: 64px;
  }

  .motif_detail_section {
    padding: 80px 20px;
  }

  .motif_detail_container {
    gap: 80px;
  }

  /* 스와이프 스트립은 유지하고 한 단계만 작게. 360px에서 카드 155px은
     화면의 43%라 옷이 알아볼 만한 크기로 남습니다. */
  .motif_product_strip {
    height: 300px;
    padding-bottom: 16px;
    gap: 12px;
  }

  .motif_product_card {
    flex-basis: 155px;
    height: 215px;
  }

  .motif_product_card.is_selected {
    flex-basis: 215px;
    height: 284px;
  }

  .motif_product_card.is_selected + .motif_product_card,
  .motif_product_card:has(+ .motif_product_card.is_selected) {
    flex-basis: 180px;
    height: 250px;
  }
}

/* ---------------------------------------------------------
   ~479px — 상품 카드 1열
   360px에서 2열이면 카드 한 장이 약 160px이라 가격·설명·태그가
   읽히지 않습니다. PRD에 없는 브레이크포인트라 여기에만 씁니다.
   --------------------------------------------------------- */
@media (max-width: 479px) {

  .new_arrivals_grid,
  .shop_grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }
}
