/* ==========================================================================
   Sulwhasoo — Main Stylesheet (전체 통합본)
   섹션 순서는 실제 페이지 섹션 순서와 동일합니다.
   ========================================================================== */

/* ==========================================================================
   Base — reset, design tokens (Figma variables), global typography
   ========================================================================== */

@import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700&family=Cormorant+Garamond:wght@500;600;700&family=Work+Sans:wght@300&display=swap");

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  /* 뷰포트가 1920px보다 좁을 때 페이지 하단 가로 스크롤바 제거.
     overflow-x:hidden은 다른 축(overflow-y)을 auto로 강제해 html/body를 스크롤
     컨테이너로 만들어버려서, 하위 position:sticky 요소(.review 등)의 기준이
     뷰포트가 아니라 그 컨테이너가 되어 sticky가 아예 동작하지 않게 된다.
     overflow-x:clip은 같은 시각적 클리핑 효과를 내면서도 스크롤 컨테이너를
     만들지 않아 sticky가 정상 동작한다. */
  overflow-x: clip;
}

body {
  font-family: var(--font_body);
  color: var(--color_black);
  background: var(--color_cream);
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  max-width: none;
}

button {
  font-family: inherit;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

p {
  margin: 0;
}

:root {
  /* ---- Colors (Figma variable defs) ---- */
  --color_orange: #f47321;       /* 폰트컬러/orange_normal */
  --color_hero_reveal_base: #bfbfbf; /* hero 헤드카피 스크롤 채색 시작색 (message_title reveal_word와 동일) */
  --color_orange_bright: #ff6300; /* wordmark "S" 강조색 */
  --color_black: #2c2d32;        /* 폰트컬러/black */
  --color_gray_1: #989898;       /* 폰트컬러/gray_nomal1 */
  --color_gray_2: #707070;       /* 폰트컬러/gray_nomal2 */
  --color_orange_gray: #978f80;  /* 폰트컬러/orange_gray */
  --color_brown_light: #deab75;  /* 폰트컬러/brown_light */
  --color_yellow_light: #fbefd2; /* 폰트컬러/yellow_light */
  --color_white: #ffffff;
  --color_cream: #f5ecd7;        /* Figma 대부분 섹션 배경 fill */

  /* ---- 섹션별 로컬 컬러 (Figma 코드에서 그대로 추출) ---- */
  --color_review_card_bg: #f7e6cd;
  --color_salon_border: #dacab6;
  --color_divider: #aaaaaa;
  --color_dot_inactive: #978f80;
  --color_dot_active: #cfcfcf;
  --color_culture_overlay: rgba(22, 22, 22, 0.6);
  --color_flagship_overlay: rgba(47, 47, 47, 0.4);
  --color_flagship_box_bg: rgba(222, 171, 117, 0.2);
  --color_flagship_border: #dea675;
  --color_stationery_heading: #212121;
  --color_culture_button: #e27813;

  /* ---- Fonts ---- */
  --font_body: "Open Sans", sans-serif;
  --font_logo: "Cormorant Garamond", serif;
  --font_quote: "Work Sans", sans-serif;

  /* ---- Font-size tokens (Figma 변수 그대로) ---- */
  --fs_display_l: 120px;   /* Display L */
  --fs_h1: 80px;           /* H1 600 */
  --fs_h2: 72px;           /* H2 400 */
  --fs_h3: 48px;           /* H3 300 */
  --fs_h4: 40px;           /* H4 300 */
  --fs_h6: 22px;           /* H6 300 */
  --fs_h7: 18px;           /* H7 300 */
  --fs_h8: 16px;           /* H8 300 */
  --fs_small: 14px;        /* Small 300 */
  --fs_nav: 25px;          /* nav 400 */

  --site_width: 1920px;
}


/* ==========================================================================
   Layout — page wrapper, generic section reset
   ========================================================================== */

.site {
  width: var(--site_width);
  margin: 0 auto;
  position: relative;
  /* overflow-x는 여기 두지 않음: overflow-y가 auto로 강제되면서
     하위 position:sticky 요소들의 기준이 뷰포트가 아니라 이 래퍼가 되어버려
     sticky가 동작하지 않게 됨. 대신 html/body 쪽에서 처리. */
}

.section {
  position: relative;
  width: 100%;
}

.visually_hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* ==========================================================================
   Hero — main_visual_all (node 3572:1229)
   1920 x 1505
   ========================================================================== */

/* 헤드카피가 첫 글자부터 마지막 글자까지 오렌지로 다 물들 때까지 화면을 고정.
   실제 높이보다 여유 있는 래퍼 안에 position:sticky로 넣어, 래퍼의 남는 높이
   (runway)만큼 스크롤하는 동안 hero가
   화면에 붙박여 있고, js/home.js의 setupHeroTextReveal이 그 구간의 스크롤 진행률을
   글자 채우기 진행률로 그대로 변환한다.
   --hero_reveal_fill: 채색이 시작해서 끝날 때까지 필요한 스크롤 거리(느릴수록 값↑).
   --hero_reveal_hold: 다 칠해진 뒤에도 화면이 그대로 고정된 채 더 버티는 스크롤
   거리(스크롤 두어 번 더 해야 다음 섹션으로 넘어가도록 하는 여유 구간). */
.hero_pin_wrapper {
  position: relative;
  --hero_reveal_fill: 1200px;
  --hero_reveal_hold: 1000px;
  /* hero_left_img/hero_right_img가 .hero의 top 기준으로 최대 1262px(hero_right_img
     하단)까지 내려가는데, .hero 자체 높이가 100vh뿐이면(뷰포트가 1262px보다 낮은
     경우가 대부분) sticky 고정이 풀리는 순간 바로 다음 섹션(image_text)이 그 아래를
     덮어 이미지 하단이 잘려 보인다. .hero/.hero_pin_wrapper 양쪽에 똑같이 500px를
     더해 sticky 릴리즈 시점(wrapper.height - hero.height = fill+hold)은 그대로
     유지하면서 hero 박스 자체를 늘려 이미지가 안에 다 들어오게 한다. 늘어난 500px는
     .culture_pin_wrapper의 여유 유지 구간에서 그대로 빼서 전체 문서 높이를 상쇄한다. */
  --hero_extra: 500px;
  height: calc(100vh + var(--hero_extra) + var(--hero_reveal_fill) + var(--hero_reveal_hold));
}

.hero {
  position: sticky;
  top: 0;
  width: 100%;
  height: calc(100vh + var(--hero_extra));
  overflow: visible; /* nav 배지가 섹션 상단 밖으로 살짝 잘려 나가는 Figma 크롭을 그대로 재현 */
  background-color: #f5ecd7; /* main_visual_all fill */
}

/* ---- 배경 데코 이미지 ---- */
.hero_left_img {
  position: absolute;
  left: -55px;
  top: -7px;
  width: 490px;
  height: 984px;
}

.hero_right_img {
  position: absolute;
  left: 1432px;
  top: 31px;
  width: 463.6px;
  height: 1178.95px;
}

/* ---- 헤드카피 + 제품 이미지 ---- */
.hero_middle {
  position: absolute;
  left: 236px;
  top: 241px;
  width: 1304px;
  height: 623px;
}

/* index2(./yultest)의 절차적 3D 유리병을 그대로 렌더링하는 캔버스.
   hero_jar_slot이 기존 hero_product 정적 이미지와 같은 자리/크기를 예약해 두고,
   캔버스가 나중에(스크롤로 다른 슬롯에 도착) 빠져나가도 레이아웃이 흔들리지 않게 한다. */
.hero_jar_slot {
  position: absolute;
  left: 784px;
  top: 55px;
  width: 520px;
  height: 568px;
}

/* hero_jar_slot(home) <-> image_text_media(arrived) 를 오가는 단 하나의 실제 캔버스
   (js/hero_jar.js 의 setupHeroJarTravel). 평소엔 슬롯을 100% 채우고, 두 슬롯 사이를
   이동하는 동안만 position:fixed로 전환된다 — 이때 top/left:0 + width/height:100%가
   뷰포트 전체(고정 위치 요소의 %는 뷰포트 기준)를 덮고, 병이 화면 어디로 가야 하는지는
   3D 장면 안에서(js/hero_jar.js) 계산한다. */
.hero_jar_canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.hero_jar_canvas.is_traveling {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  pointer-events: none;
}

.hero_headline {
  position: absolute;
  left: 0;
  top: -47px;
  text-align: right;
  font-family: var(--font_body);
  font-weight: 600;
  font-size: 60px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.hero_headline_line1 {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: flex-end;
}

/* "Sulwhasoo" 만 워드마크 서체로 크게 */
.hero_headline_wordmark {
  font-family: var(--font_logo);
  font-weight: 600;
  font-size: 96px;
  line-height: 1.2;
  letter-spacing: normal;
}

/* 초기값은 #BFBFBF 단색(message_title reveal_word와 동일). JS(setupHeroTextReveal)가
   스크롤 진행률에 맞춰 각 span의 background-image를 (오렌지 -> #BFBFBF) 좌->우 그라디언트로 갈아끼우고
   background-clip:text로 텍스트에만 입혀, 글자 앞부분부터 픽셀 단위로 서서히
   오렌지색으로 물드는 것처럼 보이게 한다. */
.hero_reveal {
  color: var(--color_hero_reveal_base);
  background-image: linear-gradient(to right, var(--color_hero_reveal_base) 0%, var(--color_hero_reveal_base) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* hero_headline_wordmark(Sulwhasoo)는 나머지 hero_reveal과 달리 기존 베이지색(#EACEB0)을
   채색 시작색으로 그대로 유지한다 (js/home.js의 WORDMARK_BASE와 동일). */
.hero_headline_wordmark.hero_reveal {
  color: #eaceb0;
  background-image: linear-gradient(to right, #eaceb0 0%, #eaceb0 100%);
}

/* 원형 네비게이션 배지: shared component (components/header)로 대체 —
   position:fixed 오버레이라 이 안에서는 별도 배치가 필요 없습니다. */


/* ==========================================================================
   Image Text — image_txt (node 3572:1254), 1920 x 1680
   ========================================================================== */

/* 높이는 js/hero_jar.js(setupHeroJarTravel)가 런타임에 다시 잰다 — hero_jar가
   도착해 사라지는 구간 + timeless_top(eyebrow/subhead)이 이어서 떠오르는 구간 +
   (예전에 별도 timeless 섹션이 차지하던 만큼 화면에 붙박여 있다가 풀리는 구간을
   합친 만큼의 "여유(runway)"를 더해서 넣어야, 고정 애니메이션들이 화면이 끊기지
   않고 이어진다. 2600px는 그 계산 전까지의 기본값(최소 보장 높이)일 뿐이다. */
.image_text {
  position: relative;
  z-index: 1;
  height: 2600px;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* justify-content:center 대신 flex-start + padding-top을 쓴다 — center를 쓰면
     아래에서 height를 늘릴 때마다 콘텐츠 위치까지 같이 밀려서(순환 의존) 도착
     트리거 지점 계산이 틀어진다. word ↔ timeless_top 사이 간격은 CSS gap이 아니라
     JS가 margin-top으로 정밀하게 채워 넣으므로 여기서는 0으로 둔다.
     padding-top은 (S)ulwhasoo 줄의 문서상 위치, 즉 hero_jar가 이동을 마치는
     지점까지의 실제 스크롤 거리를 정한다 — 너무 작으면(예: 600px) 도착 트리거
     지점까지 스크롤 몇 번 만에 다 도달해버려서, LERP로 뒤따라가는 병이 미처
     따라잡지 못한 채 도착 슬롯으로 스냅되어 마지막에 툭 끊기는 것처럼 보인다.
     이동 애니메이션이 자연스럽게 따라붙을 수 있도록 넉넉한 스크롤 여유를 둔다. */
  justify-content: flex-start;
  padding-top: 1450px;
  /* 예전에는 이 크림색→베이지 전환을 image_text가, 베이지→크림 복귀는 뒤이은
     별도의 timeless 섹션이 나눠 맡았다. 이제 그 구간을 이 섹션 하나가 전부
     떠안으므로(아래 .image_text_word 주석 참고), brandstory로 넘어가기 직전에
     다시 크림색으로 돌아오는 세 번째 stop을 추가해 이어붙인다. */
  background: linear-gradient(to bottom, #f5ecd7 0%, #d4c8ab 45%, #d4c8ab 70%, #d4c8ab 96%);
}

/* hero_jar가 (S)ulwhasoo 자리에 도착한 뒤 사라지는 동안, 화면이 그 자리에 멈춰 있는
   것처럼 보이게 한다 — top 값은 js/hero_jar.js가 도착 트리거 위치(뷰포트 기준)에
   맞춰 인라인으로 채워 넣는다. */
.image_text_word {
  display: flex;
  align-items: center;
  position: sticky;
  font-family: var(--font_logo);
  font-weight: 700;
  font-size: 250px;
  line-height: 1;
  color: var(--color_white);
  white-space: nowrap;
}

.image_text_bracket {
  color: var(--color_white);
}

/* hero_jar 캔버스가 스크롤을 따라 도착하는 자리(js/hero_jar.js 의 setupHeroJarTravel) */
.image_text_media {
  position: relative;
  width: 235px;
  height: 350px;
  overflow: hidden;
}

/* hero_jar가 이 자리에서 완전히 사라진 뒤, 그 자리를 이어받아 아래에서 위로
   올라와 자리 잡는 오렌지 "S". 이 요소의 정지 상태(bottom:0, translateY(0))는
   부모 .image_text_media의 바닥과 정확히 맞닿아 있고, 그 부모의 overflow:hidden
   경계선이 곧 "S"의 최종 위치 바닥에 고정된 와이프 라인 역할을 한다 — S 자신은
   translateY로 그 라인 아래에서 위로 밀고 올라오고, 라인 위로 넘어온 부분만 그
   순간 그대로(불투명하게, 페이드 없이) 드러난다. 기본값(translateY(100%))은
   완전히 라인 아래에 숨어 있는 시작 상태 — js/hero_jar.js(applySReveal)가 스크롤에
   따라 갱신한다. */
.image_text_s {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 44px;
  text-align: center;
  color: var(--color_orange_bright);
  pointer-events: none;
  transform: translateY(100%);
}

.image_text_word .lowercase {
  text-transform: lowercase;
}

/* hero_jar가 다 사라진 뒤 이어서(같은 고정 구간 안에서) 떠오르는 카피 — 원래
   timeless 섹션 맨 위에 있던 걸 여기로 옮겨왔다. top/margin-top/opacity는
   js/hero_jar.js(setupHeroJarTravel의 applyReveal)가 스크롤 진행률에 맞춰
   인라인으로 채운다. */
.timeless_top {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  font-family: var(--font_body);
  font-weight: 300;
  color: var(--color_white);
  position: sticky;
  opacity: 0;
}

.timeless_eyebrow,
.timeless_subhead {
  opacity: 0;
}

.timeless_eyebrow {
  font-size: var(--fs_h6);
  line-height: 1.8;
}

.timeless_subhead {
  font-size: var(--fs_h4);
  line-height: 1;
  white-space: nowrap;
}

/* timeless_top이 다 뜬 뒤 이어서 나타나는 CTA(Figma node 4496:2195) — top은
   js/hero_jar.js(measure)가 워드마크 줄 바로 아래 자리에 맞춰 인라인으로 채우고,
   opacity/translateY는 applyDiscoverReveal이 스크롤 진행률에 맞춰 채운다. */
.discover_story {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  position: sticky;
  text-decoration: none;
  color: var(--color_white);
  opacity: 0;
  pointer-events: none;
  cursor: pointer;
}

.discover_story_text {
  font-family: var(--font_body);
  font-weight: 300;
  font-size: calc(var(--fs_h4) - 4px);
  line-height: 1;
  white-space: nowrap;
  display: inline-block;
}

@keyframes discover_story_float {
  0%, 100% { transform: translateX(-8px); }
  50% { transform: translateX(8px); }
}

.discover_story_arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 24px;
  color: var(--color_orange);
  /* hero_jar가 제자리에서 sin(t*0.8) 사인파로 살짝 떠 있는 것(js/hero_jar.js의
     tick() 안 floatingY)과 같은 종류의 idle 플로팅이되, 폭은 2배 / 왕복 주기는
     1/2로 더 빠르고 크게 움직인다. */
  animation: discover_story_float 3.925s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .discover_story_arrow {
    animation: none;
  }
}

.discover_story_arrow svg {
  display: block;
  transform: rotate(-90deg);
}


/* ==========================================================================
   Brand Story — brandstory (node 4327:563), 1920 x 1600
   ========================================================================== */

.brandstory {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  padding: 300px 0;
  background-color: #f5ecd7; /* brandstory fill */
  font-family: var(--font_body);
  color: var(--color_black);
  text-align: center;
}

.brandstory_eyebrow {
  padding: 0 10px;
  font-weight: 400;
  font-size: 16px;
  line-height: 1;
}

.brandstory_content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 102px;
  width: 100%;
}

.brandstory_copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 101px;
  width: 100%;
}

.brandstory_heading {
  display: flex;
  flex-direction: column;
  margin: 0;
  font-weight: 300;
  font-size: 128px;
  line-height: 1.2;
  letter-spacing: -3.2px;
  white-space: nowrap;
}

.brandstory_desc {
  width: 678px;
  margin: 0 auto;
  font-weight: 400;
  font-size: 24px;
  line-height: 1.34;
}

.brandstory_cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 261px;
  height: 68px;
  border-radius: 6px;
  background-color: var(--color_white);
  color: var(--color_black);
  font-weight: 600;
  font-size: 14px;
  line-height: 1;
  text-decoration: none;
}


/* ==========================================================================
   Culture — culture (node 3572:1273), 11520 x 1815 (1920 x 6 panels, 가로 스크롤)
   ========================================================================== */

/* stationery_pin_wrapper와 동일한 sticky + 여유 높이 방식: 헤딩/카드/View More
   버튼이 뷰포트 안에 다 들어온 상태에 도달하면 스크롤 두 번 정도 분량만큼
   화면에 그대로 붙박여 있다가 그 뒤에야 다음 섹션(salon)으로 넘어간다. */
.culture_pin_wrapper {
  position: relative;
  /* image_text 하단(TIMELESS_HOLD_WINDOW 동안 콘텐츠가 이미 다 뜬 채 정지해
     있는 여유 구간, js/hero_jar.js 참고) 쪽으로 끌어올려, 스크롤해서 culture로
     넘어갈 때 둥근 상단(.culture_wrapper의 border-radius)이 image_text 위를
     덮으며 올라오는 것처럼 보이게 한다. */
  margin-top: -500px;
  /* 1815px(섹션 높이) + 600px(고정 유지 여유 구간, 스크롤 두 번 정도) - 500px(hero가
     이미지 잘림 방지를 위해 늘어난 만큼 상쇄, css .hero_pin_wrapper 참고). hero_jar.js는
     이 섹션 높이를 참조하지 않으므로 hero_jar 이동/타이밍에는 영향이 없다. */
  height: calc(1815px + 600px - 500px);
}

.culture {
  position: sticky;
  top: -381px; /* culture_heading의 top(381px)만큼 올려, 헤딩이 뷰포트 맨 위에 오는 상태로 고정 */
  z-index: 2;
  height: 1815px;
  display: flex;
  align-items: center;
  background-color: #d4c8ab; /* culture fill — 패널 상/하 500px 여백에 노출 */
}

.culture_wrapper {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 300px 300px 0 0;
  background-color: #1F1D21;
  z-index: 0;
}

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

.culture_track {
  position: relative;
  z-index: 1;
  display: flex;
  width: 100%;
  height: 815px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none; /* Firefox */
  cursor: grab;
  user-select: none;
}

.culture_track.is_dragging {
  cursor: grabbing;
  scroll-snap-type: none;
}

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

/* 카드 대부분이 이미지라 그냥 두면 잡는 순간 브라우저 네이티브 이미지
   드래그(고스트 이미지)가 먼저 시작되어 커스텀 드래그 스크롤이 씹힌다. */
.culture_track img {
  -webkit-user-drag: none;
}

.culture_panel {
  position: relative;
  flex: 0 0 1920px;
  width: 1920px;
  height: 815px;
  scroll-snap-align: start;
  overflow: hidden;
}

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

.culture_overlay {
  position: absolute;
  inset: 0;
  background-color: var(--color_culture_overlay);
}

.culture_tag {
  position: absolute;
  left: 241px;
  top: 131px;
  padding: 0 10px;
  border: 1px solid var(--color_white);
  color: var(--color_white);
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h7);
  line-height: 1.8;
  white-space: nowrap;
}

.culture_body {
  position: absolute;
  left: 0;
  top: 175px;
  width: 1920px;
  height: 462px;
  padding: 24px 361px 24px 240px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-top: 1px solid var(--color_white);
  border-bottom: 1px solid var(--color_white);
  color: var(--color_white);
  font-family: var(--font_body);
  font-weight: 300;
}

.culture_title {
  font-size: var(--fs_h4);
  line-height: 1;
  white-space: nowrap;
}

.culture_desc {
  width: 1050px;
  font-size: var(--fs_h6);
  line-height: 1.8;
}

.culture_poster_col {
  position: absolute;
  left: 1300px;
  top: 50%;
  transform: translateY(-50%);
  width: 380px;
  height: 815px;
  border-left: 1px solid var(--color_white);
  border-right: 1px solid var(--color_white);
}

.culture_poster_caption {
  position: absolute;
  left: 9px;
  top: 137px;
  color: var(--color_white);
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h7);
  line-height: 1.8;
  white-space: nowrap;
}

.culture_poster {
  position: absolute;
  left: 0;
  top: 175px;
  width: 100%;
  height: 463px;
  object-fit: cover;
}

.culture_heading {
  position: absolute;
  left: 322.5px;
  top: 381px;
  transform: translateX(-50%);
  z-index: 2;
  color: var(--color_white);
  font-family: var(--font_logo);
  font-weight: 600;
  font-size: 68px;
  line-height: 1;
  text-transform: capitalize;
  text-align: center;
  white-space: nowrap;
}

.culture_more_btn {
  position: absolute;
  left: 1528px;
  top: 409px;
  z-index: 2;
  width: 152px;
  padding: 6px 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 60px;
  background-color: var(--color_culture_button);
  color: var(--color_white);
  font-family: var(--font_body);
  font-weight: 300;
  font-size: 20px;
  line-height: 1.8;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
}

/* 패널마다 있던 dot을 culture 섹션 하나에 고정 오버레이로 통합.
   500px(트랙 상단 여백) + 717px(기존 패널 내부 dot 위치) = 1217px */
.culture_dots {
  position: absolute;
  left: 50%;
  top: 1217px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 14px;
  z-index: 2;
}

.culture_dot {
  position: relative;
  width: 10px;
  height: 10px;
  border-radius: 60px;
  overflow: hidden;
  background-color: var(--color_dot_inactive);
  /* transition을 여기 두지 않음: is_active가 빠질 때(비활성화)는 애니메이션 없이 즉시 원상태로 스냅 */
}

.culture_dot.is_active {
  width: 30px;
  transition: width 0.2s ease; /* 활성화될 때만 작은 점 -> 알약 모양으로 확장 애니메이션 */
}

.culture_dot_fill {
  position: absolute;
  inset: 0;
  width: 0%;
  background-color: var(--color_dot_active);
  /* transition을 여기 두지 않음: is_active가 빠질 때는 애니메이션 없이 즉시 0%로 스냅 */
}

.culture_dot.is_active .culture_dot_fill {
  width: 100%;
  transition: width 2s linear; /* 활성화될 때만 자동 스크롤 전환 시간(2초)과 동일하게 차오름 */
}


/* ==========================================================================
   Salon / Story list — salon (node 3572:1376), 1920 x 4992
   ========================================================================== */

.salon {
  height: 4992px; /* 506px 상단 여백 + 4486px 그리드 콘텐츠. 기존엔 flex 중앙 정렬로 하단에도
    동일한 506px 여백이 생겨, 06 소멸 뒤 salon_final_title이 나타나기 전까지 빈 공백이 있었음.
    padding-top으로 상단 여백만 남기고 하단 여백은 제거해 salon_final_pin_wrapper로 바로 이어지게 함. */
  padding-top: 506px;
  background-color: #f5ecd7; /* salon fill */
}

/* 실제 CSS Grid: 열 439/980/439px, 위/아래 242px는 grid row(1행, 8행)로 확보.
   전체 높이는 이전과 동일(242 + 667*6 + 242 = 4486px).
   그리드 선은 콘텐츠 박스에 개별 border를 주지 않고, 아래 .salon_lines 안에서
   딱 9개(세로 2 + 가로 7)의 절대좌표 선으로 한 번씩만 그려서 겹치는 부분이 생기지 않게 함. */
.salon_grid {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 439px 980px 439px;
  grid-template-rows: 242px repeat(6, 667px) 242px;
  justify-content: center;
}

.salon_row_1 { grid-row: 2; }
.salon_row_2 { grid-row: 3; }
.salon_row_3 { grid-row: 4; }
.salon_row_4 { grid-row: 5; }
.salon_row_5 { grid-row: 6; }
.salon_row_6 { grid-row: 7; }

.salon_image_box {
  position: relative;
  height: 667px;
  overflow: hidden;
}

/* 기본값(js/home.js가 실제 크기를 계산해 인라인 width/height/left로 덮어쓰기 전까지의
   폴백)은 기존과 동일하게 object-fit: cover로 프레임을 꽉 채운 상태.
   JS가 붙으면 top: 0 고정 + translateY로만 세로 위치를 이동시키는 팬(pan) 방식으로 전환된다. */
.salon_image_box img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: translateY(0);
  will-change: transform;
}

.salon_image_box_left {
  grid-column: 1;
}

.salon_image_box_right {
  grid-column: 3;
}

/* 텍스트 오버레이. top(vh)은 js/main.js가 스크롤마다 계산해서 실시간으로 갱신함:
   각 행이 뷰포트 60%선을 지나는 순간부터 자기 행 높이(667px)만큼 스크롤하는 동안
   4%씩 위로 이동, 다음 행으로 넘어가면 그 지점(56%→52%→48%…)에서 이어받음. */
.salon_fixed_text {
  position: fixed;
  width: 980px;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
  z-index: 5;
}

.salon_fixed_text.is_visible {
  opacity: 1;
}

.salon_panel {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font-family: var(--font_body);
  font-weight: 300;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.salon_panel.is_active {
  opacity: 1;
}

/* ---- 그리드 선: 1920px 기준 좌표로 한 번씩만 그리는 절대좌표 라인 9개 ---- */
.salon_lines {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.salon_line_v {
  position: absolute;
  top: 0;
  width: 1px;
  height: 100%;
  background-color: var(--color_salon_border); /* #DACAB6 */
}

.salon_line_v_1 { left: 470px; }
.salon_line_v_2 { left: 1450px; }

.salon_line_h {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background-color: var(--color_salon_border); /* #DACAB6 */
}

.salon_line_h_1 { top: 242px; }
.salon_line_h_2 { top: 909px; }
.salon_line_h_3 { top: 1576px; }
.salon_line_h_4 { top: 2243px; }
.salon_line_h_5 { top: 2910px; }
.salon_line_h_6 { top: 3577px; }
.salon_line_h_7 { top: 4244px; }

.salon_number {
  font-size: var(--fs_h7);
  line-height: 1.8;
  color: var(--color_orange);
}

.salon_title {
  width: 550px;
  text-align: center;
  font-size: var(--fs_h4);
  line-height: 1;
  color: var(--color_black);
}

.salon_title span {
  display: block;
}

/* 06 텍스트가 그리드 하단선에 닿아 사라진 뒤, 기존 View Programs가 있던 자리를 이어받는
   클로징 문구. stationery_pin_wrapper와 동일한 sticky + 여유 높이 방식으로, 계속 스크롤하면
   뷰포트 정중앙까지 내려와 여유 구간만큼 멈춰 있다가 다음 섹션으로 넘어간다. */
.salon_final_pin_wrapper {
  position: relative;
  height: 180vh; /* 100vh(정중앙 도달) + 80vh(멈춰 있는 여유 구간) */
  background-color: #f5ecd7;
}

.salon_final_pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 피그마(node 4496:1812)의 폰트/사이즈/간격을 그대로 따른다 */
.salon_final_panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 66px;
  width: 980px;
  font-weight: 300;
}

.salon_final_title_group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 80px;
}

/* title → desc → cta 순서로 각 요소에 is_active가 순차 추가되며 나타난다
   (js의 setupSalonFinalReveal, 핀이 걸리는 순간 스크롤 없이 시간차로 트리거) */
.salon_final_title,
.salon_final_desc,
.salon_final_cta {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.salon_final_title.is_active,
.salon_final_desc.is_active,
.salon_final_cta.is_active {
  opacity: 1;
  transform: translateY(0);
}

.salon_final_title {
  font-size: 88px;
  line-height: 1.2;
  letter-spacing: -2.2px;
  color: var(--color_black);
  text-align: center;
}

.salon_final_title span {
  display: block;
  white-space: nowrap;
}

.salon_final_desc {
  font-weight: 400;
  font-size: 20px;
  line-height: 1.34;
  color: var(--color_black);
  text-align: center;
}

.salon_final_desc span {
  display: block;
  white-space: nowrap;
}

.salon_final_cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 238px;
  height: 62px;
  border-radius: 8px;
  background-color: var(--color_orange);
  font-size: var(--fs_h7);
  line-height: 1.8;
  color: var(--color_white);
  text-decoration: none;
  cursor: pointer;
}

/* 등장 애니메이션(opacity/transform)과 별개로 호버는 더 짧고 즉각적으로 반응하게 함 */
.salon_final_cta:hover {
  transition: background-color 0.2s ease, color 0.2s ease;
  background-color: #fff;
  color: var(--color_black);
}

/* discover_story_arrow(discover_story_float)와 같은 종류의 idle floating이되
   방향만 상하로 바꿔 cta 박스 자체에 건다. 등장 트랜지션(opacity/translateY)이
   먼저 끝나도록 transition 지속시간(0.6s)만큼 animation-delay를 줘서, 트랜지션이
   translateY(0)에 도달한 뒤 애니메이션이 이어받아 자연스럽게 넘어가게 한다. */
@keyframes salon_final_cta_float {
  0%, 100% { transform: translateY(-8px); }
  50% { transform: translateY(8px); }
}

.salon_final_cta.is_active {
  animation: salon_final_cta_float 3.925s ease-in-out infinite;
  animation-delay: 0.6s;
}

@media (prefers-reduced-motion: reduce) {
  .salon_final_cta.is_active {
    animation: none;
  }
}


/* ==========================================================================
   Stationery — stationery (node 3572:1422), 1920 x 1080
   ========================================================================== */

/* 뷰포트 안에 다 들어온(화면 캡처와 같은) 상태에 도달하면, hero/review와 같은
   방식으로 스크롤 두 번 정도 분량만큼 화면에 그대로 붙박여 있다가 그 뒤에야
   다음 섹션으로 넘어가도록 함. */
.stationery_pin_wrapper {
  position: relative;
  height: calc(1080px + 1200px); /* 1080px(섹션 높이) + 600px(고정 유지 여유 구간, 스크롤 두 번 정도) */
}

.stationery {
  position: sticky;
  top: -10vh; /* 고정(멈춤) 위치를 뷰포트 기준 10% 위로 올림(기존 top:0 대비) */
  height: 1080px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f5ecd7; /* stationery fill */
}

.stationery_inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 80px;
}

.stationery_top {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.stationery_heading {
  font-family: var(--font_body);
  font-weight: 600;
  font-size: var(--fs_h1);
  line-height: 1.4;
  color: var(--color_stationery_heading);
  text-align: center;
  white-space: nowrap;
}

.stationery_heading_row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

/* stationery_icon 자리에 예약된 빈 공간 — hero_travel_image 가 이 자리를 떠나도
   (position:fixed 로 전환되어도) heading 텍스트 줄바꿈/간격이 흔들리지 않도록 함 */
.stationery_icon_slot {
  display: inline-block;
  width: 102px;
  height: 127px;
}

/* stationery_icon 자리 <-> best_seller_hero_image_serum 자리를 오가는 단 하나의
   실제 이미지(js/home.js 의 setupStationeryMorph). 상태에 따라 클래스가 바뀐다:
   - --home: stationery_icon_slot 안에 정적으로 위치
   - --travel: 스크롤 중 position:fixed 로 화면을 가로질러 이동. 목표 지점(슬라이드1의
     best_seller_hero_image_serum)에 완전히 겹치는 순간부터는 위치는 그 자리에 고정된
     채(더 스크롤해도 값이 바뀌지 않음) is_faded가 붙어 opacity만 0으로 크로스페이드되고,
     그 아래 깔려 있던 best_seller_hero_image_serum이 opacity 1로 나타난다(아래 .is_arrived
     참고) — 실제 이미지가 사라지는 게 아니라 "같은 사진"끼리 자리를 넘겨주는 방식이라
     전환이 눈에 띄지 않는다. 스크롤을 되돌리면 정확히 같은 경계에서 반대로 재생된다. */
.hero_travel_image {
  display: block;
  object-fit: cover;
}

.hero_travel_image_home {
  width: 102px;
  height: 127px;
}

.hero_travel_image_travel {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  pointer-events: none;
  will-change: top, left, width, height, opacity;
  transition: opacity 0.35s ease;
}

.hero_travel_image_travel.is_faded {
  opacity: 0;
}

.stationery_bottom {
  width: 685px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.stationery_eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h7);
  line-height: 1.8;
  color: var(--color_orange);
}

.stationery_eyebrow_dot {
  width: 6px;
  height: 6px;
  background-color: var(--color_orange);
}

.stationery_desc {
  text-align: center;
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h6);
  line-height: 1.8;
  color: var(--color_black);
}


/* ==========================================================================
   Best Seller — best_seller (Figma node 4217:1436 기반). hero/stationery와
   같은 pin-wrapper 패턴으로 섹션이 화면에 고정된 채, 스크롤이 슬라이드를
   다이얼처럼 한 칸씩 자동으로 회전시켜 중앙에 스냅한다 — 중앙에 가까울수록
   커지고 정면을 향하며, 멀어질수록 옆으로 기울고 작아지며 흐려진다
   (js/home.js setupBestSellerDial).
   슬라이드1(First Care Activating Serum VI)의 .best_seller_hero_image_serum은
   stationery 섹션 이미지가 스크롤에 맞춰 날아와 커지는 모프 애니메이션
   (js/home.js setupStationeryMorph)의 도착지 — 평소 opacity:0으로 숨겨져 있다가
   hero_travel_image와 정확히 겹치는 순간 크로스페이드로 나타난다(크기 446x554는 이전과 동일).
   ========================================================================== */

/* 여유 스크롤 구간(runway) 확보용 래퍼 — 실제 높이(섹션 높이 + 슬라이드
   전환당 스크롤 거리)는 js/home.js setupBestSellerDial이 런타임에 계산해
   채워 넣는다. */
.best_seller_pin_wrapper {
  position: relative;
}

.best_seller {
  position: sticky;
  top: -40px; /* 고정(멈춤) 위치를 40px 위로 올림(기존 top:0 대비) */
  width: 100%;
  padding: 160px 0 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 70px;
  background: linear-gradient(to bottom, #f5ecd7, #ffffff);
  overflow: hidden;
}

.best_seller_txt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}

.best_seller_label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

.best_seller_label_mark {
  width: 20px;
  height: 20px;
  background-color: var(--color_orange);
}

.best_seller_label_text {
  font-family: var(--font_body);
  font-weight: 600;
  font-size: var(--fs_h3);
  line-height: 1;
  color: var(--color_orange);
}

.best_seller_subcopy {
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h7);
  line-height: 1.45;
  color: var(--color_black);
  text-align: center;
}

/* ---- dial: 헤더의 아치형 다이얼 내비게이션(components/header/header.js)과
   동일한 방식 — 각 슬라이드가 고정된 각도를 유지한 채 하나의 회전값
   (dialRotation)만큼 큰 타원 궤도를 따라 함께 움직인다. 스크롤이 한 칸(=슬라이드
   하나) 경계를 넘을 때마다 그 슬라이드가 각도 0(=하단 정중앙)으로 자동
   스냅된다 (js/home.js setupBestSellerDial). ---- */
.best_seller_dial {
  position: relative;
  width: 100%;
  height: 820px;
  user-select: none;
  transform: translateY(-80px); /* 스크롤에 따라 회전하는 슬라이드 묶음을 80px 위로 올림 */
}

.best_seller_dial img {
  -webkit-user-drag: none;
  pointer-events: none;
}

.best_seller_slide {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 600px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  will-change: transform, opacity;
}

.best_seller_slide.is_active {
  cursor: default;
}

.best_seller_slide_cta {
  width: 420px;
  text-decoration: none;
}

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

.best_seller_hero {
  position: relative;
  width: 446px;
}

.best_seller_hero_visual {
  position: relative;
  width: 446px;
  height: 554px;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

/* 슬라이드1(세럼) 전용 — hero_travel_image가 정확히 이 자리에 도착하기 전까지는
   best_seller_hero_image_serum(같은 사진의 정적 사본)을 완전히 숨겨 둔다
   (js/home.js setupStationeryMorph가 도착 시 .is_arrived를 붙인다). */
.best_seller_slide_serum .best_seller_hero_visual {
  opacity: 0;
  transition: opacity 0.35s ease;
}

.best_seller_slide_serum .best_seller_hero_visual.is_arrived {
  opacity: 1;
}

.best_seller_hero_texture {
  position: absolute;
  left: 50%;
  top: 46%;
  width: 300px;
  transform: translate(-50%, -50%) rotate(150deg);
  opacity: 0.5;
  pointer-events: none;
}

.best_seller_hero_texture_cream {
  width: 380px;
  transform: translate(-58%, -55%) rotate(20deg) scaleY(-1);
  opacity: 0.7;
}

.best_seller_hero_texture_sunscreen {
  width: 420px;
  transform: translate(-50%, -48%) rotate(0deg);
  opacity: 0.85;
}

.best_seller_hero_texture_serum {
  /* 왼쪽 44+10=54px, 아래로 10+10=20px, 크기 10% 축소 */
  transform: translate(calc(-50% - 54px), calc(-50% + 20px)) rotate(150deg) scale(0.9);
}

.best_seller_hero_image {
  position: relative;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

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

.best_seller_hero_image_cream {
  width: 260px;
}

.best_seller_slide.is_active .best_seller_hero_image_cream {
  transform: translateY(-40px); /* 중앙(is_active)에 있을 때 40px 위로 */
}

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

/* 가운데(is_active)가 아닌 슬라이드는 텍스트를 완전히 숨긴다. 가운데로 스냅되어
   is_active가 붙는 순간에만 살짝 지연을 두고 서서히 위로 떠오르며 나타난다 —
   "제품이 먼저 자리 잡고, 그 뒤를 따라 텍스트가 떠오르는" 순서를 만들기 위함.
   숨길 때는 지연 없이 빠르게 사라진다. */
.best_seller_stats,
.best_seller_product_name {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
}

.best_seller_slide.is_active .best_seller_stats,
.best_seller_slide.is_active .best_seller_product_name {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.45s ease 0.15s, transform 0.45s ease 0.15s;
  pointer-events: auto;
}

.best_seller_stats {
  position: absolute;
  left: 100%;
  bottom: 0;
  margin-left: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  white-space: nowrap;
  text-align: right;
  font-family: var(--font_body);
  font-weight: 300;
}

.best_seller_stat {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.best_seller_stat_label {
  font-size: var(--fs_h8);
  color: var(--color_orange_gray);
}

.best_seller_stat_value {
  font-size: var(--fs_h6);
  letter-spacing: -1px;
  color: var(--color_orange);
}

.best_seller_product_name {
  font-family: var(--font_body);
  font-weight: 400;
  font-size: var(--fs_h6);
  line-height: 1.2;
  color: var(--color_black);
  text-align: center;
}

/* ---- slide 4: View More CTA ---- */
.best_seller_button {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px 30px 20px 50px;
  border-radius: 50px 10px 50px 10px;
  background: linear-gradient(to bottom, #ff8124, #ffbf8f);
  box-shadow: inset 0 6px 15.1px 0 rgba(36, 36, 36, 0.24);
  color: var(--color_white);
  font-family: var(--font_body);
  font-weight: 400;
  font-size: 32px;
  line-height: 1;
  text-align: center;
}

.best_seller_button_arrow {
  width: 44px;
  height: 44px;
}


/* ==========================================================================
   Review — review (node 4529:2781), 1920 x (1440x2845 카드 캔버스 + 여유분)
   Figma에서 review는 9개의 후기 카드가 1440x2845 캔버스 위에 자유롭게 흩뿌려져
   있고, 그 위로 "Chosen by the world Sulwhasoo" 헤드카피가 뷰포트 정중앙에
   고정된 채 카드들이 그 뒤로 스크롤되어 지나가는 구성이다. 실제 .review_canvas
   높이는 Figma 값(2845px)에서 1000px을 더해 3845px로 늘렸는데, 마지막 카드
   (review_card_08, top:2526px)가 진입해서 뷰포트 위로 완전히 사라질 때까지
   스크롤할 여유 공간이 필요해서다(카드 자체 높이 + 뷰포트 한 화면 분량).

   헤드카피를 .review_heading(맨 앞 자식)에 두고 카드 캔버스(.review_canvas)를
   그 뒤에 두면, 헤드카피의 자기 높이(600px)만큼만 자연스럽게 앞서 스크롤된 뒤
   곧바로 고정(top: calc(50vh - 300px))되고, 뒤이은 캔버스 높이(3845px) + 여유
   유지 구간(--review_reveal_hold)만큼을 고정 유지 구간(runway)으로 그대로
   활용할 수 있다 — hero/기존 review가 쓰던 "래퍼보다 작은 sticky 자식" 패턴과
   동일한 원리를, 별도 래퍼 없이 형제 콘텐츠 자체의 높이로 구현한 것. 마지막
   카드가 지나간 뒤에도 --review_reveal_hold만큼은 계속 화면 중앙에 고정된 채
   버텨, 다음 섹션(flagship)으로 넘어갈 때 헤드카피가 바로 튕겨나가지 않고
   자연스럽게 이어진다.

   헤드카피는 카드보다 먼저(DOM상 위) 오지만 z-index를 따로 주지 않아, 뒤에
   오는 .review_canvas(카드)가 기본 쌓임 순서상 항상 헤드카피 위에 그려진다 —
   헤드카피가 카드 뒤에 깔려 카드에 가려지는 부분은 자연스럽게 카드에 덮인다. */
.review {
  position: relative;
  background-color: var(--color_white); /* review fill (bg-white) */
  --review_reveal_hold: 500px;
  padding-bottom: var(--review_reveal_hold);
}

.review_heading {
  position: sticky;
  top: calc(50vh - 300px); /* 300px = 헤드카피 박스 높이(600px)의 절반 */
  width: 1200px;
  margin: 0 auto;
  text-align: center;
  font-family: var(--font_body);
  font-weight: 700;
  font-size: 150px;
  line-height: 1;
  color: var(--color_black);
  pointer-events: none; /* 카드 위로 겹쳐도 클릭을 막지 않음 */
}

/* 헤드카피 위에만 씌우는 반투명 블랙 필터. DOM상 .review_heading 다음, .review_canvas
   앞에 두어 별도 z-index 없이도 "카드보다 아래, 헤드카피보다 위" 쌓임 순서가 자연스럽게 나온다. */
.review_heading_overlay {
  position: sticky;
  top: calc(50vh - 300px);
  width: 1200px;
  height: 600px;
  margin: 0 auto;
  background-color: rgba(0, 0, 0, 0.14);
  pointer-events: none;
}

.review_canvas {
  position: relative;
  width: 1440px;
  height: 3845px;
  margin: 0 auto;
}

.review_card_float {
  position: absolute;
  box-sizing: border-box;
  padding: 30px;
  border-radius: 20px;
  background-color: var(--color_review_card_bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  filter: blur(0);
  transition: filter 0.4s ease;
}

/* 뷰포트 top:60% 라인을 아직 통과하지 못한 카드(js의 setupReviewCardBlur) */
.review_card_float.is_blurred {
  filter: blur(4px);
}

.review_card_top {
  display: flex;
  align-items: flex-start;
  gap: 0;
}

.review_card_inner {
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.review_quote_mark {
  font-family: var(--font_quote);
  font-weight: 300;
  font-size: 80px;
  line-height: 54px;
  height: 54px;
  color: var(--color_black);
  width: 28px;
  flex: none;
}

.review_quote_mark_close {
  transform: rotate(180deg);
}

.review_card_body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.review_stars {
  display: flex;
  align-items: center;
}

.review_stars img {
  width: 20px;
  height: 20px;
}

.review_quote {
  width: 368px;
  text-align: center;
  font-family: var(--font_body);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.8;
  color: var(--color_black);
}

.review_quote_nowrap {
  white-space: nowrap;
}

.review_product {
  display: block;
  font-family: var(--font_body);
  font-weight: 300;
  font-size: 12px;
  line-height: 1.8;
  color: var(--color_black);
  text-align: center;
  white-space: nowrap;
}

.review_product_link {
  text-decoration: none;
  cursor: pointer;
}

/* ---- 카드별 배치 (Figma 좌표 그대로) ---- */
.review_card_01 { left: 0px; top: 570px; width: 484px; }
.review_card_02 { left: 1000px; top: 857px; width: 440px; }
.review_card_02 .review_quote { width: 324px; }
.review_card_03 { left: 1066px; top: 1478px; width: 374px; }
.review_card_03 .review_quote { width: 258px; }
.review_card_04 { left: 834px; top: 397px; width: 484px; }
.review_card_05 { left: 956px; top: 2300px; width: 484px; }
.review_card_06 { left: 312px; top: 1017px; width: 338px; }
.review_card_06 .review_quote { width: 222px; }
.review_card_07 { left: 427px; top: 2025px; width: 484px; }
.review_card_08 { left: 199px; top: 2526px; width: 484px; }
.review_card_09 { left: 80px; top: 1621px; width: 484px; }


/* ==========================================================================
   Flagship Store — flagship (node 3572:1557), 1920 x 1006
   ========================================================================== */

.flagship {
  position: relative;
  height: 1006px;
  overflow: hidden;
}

.flagship_bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1);
  opacity: 0;
  transition: transform 0.6s ease, opacity 0.6s ease;
}

.flagship_bg.is_active {
  opacity: 1;
}

.flagship.is_cursor_active .flagship_bg {
  transform: scale(1.05);
}

.flagship_overlay {
  position: absolute;
  inset: 0;
  background-color: var(--color_flagship_overlay);
}

.flagship_text {
  position: absolute;
  left: 232px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 100px;
  font-family: var(--font_body);
  font-weight: 300;
}

.flagship_title {
  font-size: var(--fs_display_l);
  line-height: 1.1;
  letter-spacing: -2.4px;
  color: var(--color_white);
  white-space: nowrap;
}

.flagship_desc {
  width: 967px;
  margin-left: 10px;
  font-size: var(--fs_h6);
  line-height: 1.8;
  color: var(--color_yellow_light);
}

.flagship_card {
  position: absolute;
  right: 0;
  top: 0;
  width: 470px;
  height: 1006px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 115px 45px;
  background-color: var(--color_flagship_box_bg);
}

.flagship_card_inner {
  width: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 80px;
}

.flagship_card_slides {
  display: grid;
  width: 100%;
}

/* card01/card02가 같은 그리드 셀에 겹쳐 쌓이고, opacity로만 전환된다(레이아웃 흔들림 없음) */
.flagship_card_top {
  grid-area: 1 / 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 30px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
}

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

.flagship_card_media {
  width: 316px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.flagship_card_image_wrap {
  position: relative;
  width: 316px;
  height: 459px;
}

.flagship_card_image {
  position: absolute;
  left: 0;
  top: 51px;
  width: 316px;
  height: 408px;
  object-fit: cover;
}

.flagship_card_title {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  font-family: var(--font_body);
  font-weight: 400;
  font-size: var(--fs_h2);
  line-height: 1.2;
  letter-spacing: -1.44px;
  color: var(--color_yellow_light);
  white-space: nowrap;
}

.flagship_card_desc {
  width: 100%;
  text-align: center;
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h7);
  line-height: 1.8;
  color: var(--color_yellow_light);
}

.flagship_counter {
  position: relative;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50px;
  border: 1px solid var(--color_flagship_border);
  font-family: var(--font_body);
  font-weight: 300;
  font-size: var(--fs_h8);
  line-height: 1.5;
  color: var(--color_brown_light);
}

.flagship_counter_ring {
  position: absolute;
  inset: 0;
  transform: rotate(-90deg); /* 12시 방향에서 시작해 시계 방향으로 채워지도록 */
}

.flagship_counter_ring_fill {
  fill: none;
  stroke: var(--color_flagship_border);
  stroke-width: 2px;
  stroke-linecap: round;
  stroke-dasharray: 245;
  stroke-dashoffset: 245;
  /* transition을 여기 두지 않음: is_active가 빠질 때는 애니메이션 없이 즉시 빈 상태로 스냅 (.culture_dot_fill과 동일한 패턴) */
}

.flagship_counter.is_active .flagship_counter_ring_fill {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.5s linear; /* 카드 전환 주기(1.5초)와 동일하게 원이 차오름 */
}

.flagship_counter_num {
  position: relative;
}

.flagship_link {
  position: absolute;
  inset: 0;
  z-index: 10;
}

/* 커서를 따라다니는 'Click' 배지 (Figma node 4456:383). fixed라 뷰포트
   좌표(clientX/Y)로 바로 위치를 잡을 수 있고, 스크롤 중이어도 어긋나지 않는다. */
.flagship_cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  z-index: 11;
  transition: opacity 0.25s ease;
}

.flagship_cursor::before {
  content: "";
  position: absolute;
  inset: -35px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(232, 110, 37, 0.85) 0%, rgba(232, 110, 37, 0.45) 42%, rgba(232, 110, 37, 0) 72%);
  filter: blur(6px);
}

.flagship_cursor span {
  position: relative;
  font-family: var(--font_body);
  font-weight: 300;
  font-size: 12px;
  color: var(--color_white);
  white-space: nowrap;
}

.flagship.is_cursor_active .flagship_link {
  cursor: none;
}

.flagship.is_cursor_active .flagship_cursor {
  opacity: 1;
}


/* Footer: shared component (components/footer)로 대체 — footer.css 참고 */

