@charset "utf-8";
/* components.css - 공통 UI 컴포넌트 영역
   Button / Card / Badge / Tab / Form Control / Pagination / Modal / Empty State 등
   페이지 전반에서 재사용되는 컴포넌트 스타일을 정의한다.
   디자인 확정 전이므로 실제 구현은 하지 않는다. */

/* TODO: Button */
/* TODO: Card */
/* TODO: Badge */
/* TODO: Tab */
/* TODO: Form Control (input / select / textarea / checkbox / radio) */
/* TODO: Breadcrumb */
/* TODO: Pagination */
/* TODO: Modal */
/* TODO: Empty State */


/* ==================================================
   Header Components
   Header의 구조적 Layout은 layout.css 에 있다.
   여기서는 GNB / Utility Action / Dropdown / Badge 표현만 다룬다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - GNB Gap 40px / Active Indicator 2px, 하단 offset 8px
   - Icon 22px / Notification Dot 6px
   - Dropdown Width 300px(위치), 380px(알림)
================================================== */

/* ---------- Logo ----------
   실제 asset은 160x30(RGBA)으로 wrapper와 종횡비가 동일하다.
   다른 비율의 asset으로 교체되더라도 contain으로 왜곡 없이 들어간다. */

.header__logo-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: left center;
}


/* ---------- GNB ---------- */

.gnb {
  display: flex;
  align-items: stretch;
  /* v4: Header Frame이 1680 -> 1400으로 좁아지며 48 -> 42px (-12.5%) 압축.
     Font Size는 줄이지 않는다 (Typography 위계 유지).
     TODO: 화면 검토 후 Token 승격 검토 */
  gap: 42px;
}

.gnb__item {
  display: flex;
}

.gnb__link {
  position: relative;
  display: flex;
  align-items: center;
  color: var(--text-primary);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition: color var(--transition-fast);
}

/* Hover : 텍스트 컬러 변화만 사용 (배경 / Shadow / Underline 없음) */
.gnb__link:hover {
  color: var(--brand-secondary);
}

/* Active */
.gnb__link.is-active {
  color: var(--brand-primary);
  font-weight: var(--font-weight-bold);
}

/* Focus : Hit Area는 Header 높이 전체로 유지하되,
   Focus Ring은 Link(90px)가 아니라 Label(텍스트) 주변에만 표시한다. */
.gnb__link:focus-visible {
  outline: none;
}

.gnb__link:focus-visible .gnb__label {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Active Indicator : Header 하단 Border에 붙지 않도록 8px 띄운다 */
.gnb__link.is-active::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 20px;
  left: 0;
  height: 2px;
  background-color: var(--brand-secondary);
}


/* ---------- Header Icon Wrapper ----------
   아이콘 Asset을 감싸는 공통 wrapper.
   Wrapper가 22x22 Box를 고정하므로 내부 Asset이 바뀌어도
   Header 높이 / Item 정렬은 영향을 받지 않는다. */

.header-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 22px;  /* TODO: 실제 아이콘 asset 확정 후 Token 승격 검토 */
  height: 22px;
  font-size: var(--font-size-base);
  line-height: 1;
}

/* 실제 Asset : assets/icons/header/*.svg
   원본 viewBox 비율이 서로 달라(알림 62x62 / 위치 46x60) contain으로 맞춘다.
   Asset의 path / 색상 / viewBox는 수정하지 않고 표시 크기만 CSS가 결정한다. */
.header-icon__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}


/* ---------- Utility : 위치 설정 ---------- */

.header-location {
  position: relative;
  display: flex;
  align-items: center;
}

.header-location__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--brand-primary); /* 현재 검색 지역 Context. Hover는 아래에서 덮는다 */
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  line-height: var(--text-label-line-height);
  white-space: nowrap;
  transition: color var(--transition-fast), background-color var(--transition-fast);
}

/* Label : 단순 부가 표시가 아니라 "현재 검색 지역"을 알리는 Context다.
   로그인(15px / medium)과 같은 크기를 유지하되 Weight로만 한 단계 강조해
   Header 높이 / 로그인 / 회원가입 CTA와 경쟁하지 않게 한다. */
.header-location__label {
  font-size: 15px; /* Token에 15px가 없어 구현값 유지. TODO: Token 승격 검토 */
  font-weight: var(--font-weight-semibold);
}

.header-location__trigger:hover {
  color: var(--brand-secondary);
}

.header-location__arrow {
  font-size: var(--font-size-xs);
  line-height: 1;
}

/* Open 상태 */
.header-location.is-open .header-location__trigger {
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
  border-radius: var(--radius-md);
}


/* ---------- Utility : 알림 ---------- */

.header-notification {
  position: relative;
  display: flex;
  align-items: center;
}

.header-notification__trigger {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  transition: color var(--transition-fast), background-color var(--transition-fast);
}

.header-notification__trigger:hover {
  color: var(--brand-secondary);
}

.header-notification.is-open .header-notification__trigger {
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
}

/* 읽지 않은 알림 Red Dot Badge */
.header-notification__dot {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;  /* TODO: 화면 검토 후 Token 승격 검토 */
  height: 6px;
  border-radius: var(--radius-pill);
  background-color: var(--error);
}


/* ---------- Utility : 로그인 (단일 Account CTA) ----------
   v5에서 회원가입 Filled CTA(.header-account__cta)를 제거했다.
   (Header 외 사용처가 없어 base / :hover / :focus-visible 규칙 전부 삭제)

   v6: 로그인이 Header의 유일한 Account CTA가 되었으므로
       Text Link -> Navy Filled Rounded Button 으로 승격한다.
       Class명(.header-account__link)은 유지해 Markup 변경을 만들지 않는다.

   Color 선택:
     Hero의 Title Accent("한 곳")가 #084BE7, Search CTA가 --brand-secondary라
     로그인까지 밝은 Blue로 두면 Blue CTA가 3중으로 반복된다.
     그래서 Logo / Hero Title과 같은 Navy Family인 --brand-primary를 쓴다.
     Hover는 같은 Family에서 한 단계 밝은 --brand-secondary로 올린다.
     (기존 Button 시스템의 base -> 한 단계 밝게 패턴을 그대로 따른다.
      --brand-interaction(#084BE7)은 위 이유로 쓰지 않는다)

   NOTE(CLAUDE.md): 문서에는 "--brand-primary를 일반 Primary Button에 쓰지
     않는다"는 규칙이 있다. 이 버튼은 일반 Primary Button이 아니라
     Header 단 하나뿐인 Brand Account Entry라 예외로 적용했다.
     완료 보고에 기록했으며, 정책 확정 시 되돌리기는 background-color
     한 줄이다.

   Gradient / Shadow / Glow / Border / Icon / Transform 을 쓰지 않는다. */

.header-account__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;    /* TODO: 화면 검토 후 Token 승격 검토 */
  padding: 0 18px; /* TODO: 화면 검토 후 Token 승격 검토 */
  border-radius: var(--radius-md); /* 10px. Pill(--radius-pill) 사용 금지 */
  background-color: var(--brand-primary);
  color: var(--text-inverse);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition: background-color var(--transition-fast);
}

.header-account__link:hover {
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
}


/* ---------- Header Dropdown (공통 Shell) ---------- */

.header-dropdown {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: var(--z-dropdown);
  padding: var(--space-3);
  background-color: var(--surface-default);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md); /* Floating UI이므로 Shadow 사용 */
  text-align: left;
}

.header-dropdown[hidden] {
  display: none;
}

.header-dropdown--location {
  width: 300px; /* TODO: 화면 검토 후 Token 승격 검토 */
}

.header-dropdown--notification {
  width: 380px; /* TODO: 화면 검토 후 Token 승격 검토 */
}

.header-dropdown__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.header-dropdown__title {
  padding: var(--space-2) var(--space-3);
  color: var(--text-primary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
}

.header-dropdown__action {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--brand-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  transition: background-color var(--transition-fast);
}

.header-dropdown__action:hover {
  background-color: var(--surface-hover);
}

.header-dropdown__list {
  display: flex;
  flex-direction: column;
  margin-top: var(--space-1);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-light);
}

.header-dropdown__item {
  display: flex;
  align-items: center;
  width: 100%;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-align: left;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.header-dropdown__item:hover {
  background-color: var(--surface-hover);
  color: var(--text-primary);
}

.header-dropdown__more {
  display: block;
  margin-top: var(--space-2);
  padding: var(--space-3);
  border-top: 1px solid var(--border-light);
  color: var(--brand-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  text-align: center;
}


/* ---------- 알림 목록 ---------- */

.notice-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-light);
}

.notice-list__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background-color: var(--surface-default);
  transition: background-color var(--transition-fast);
}

.notice-list__text {
  color: var(--text-primary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}

.notice-list__time {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
}

/* 읽지 않은 알림 */
.notice-list__item.is-unread .notice-list__link {
  background-color: var(--bg-brand-light);
}

.notice-list__link:hover,
.notice-list__item.is-unread .notice-list__link:hover {
  background-color: var(--surface-hover);
}


/* ---------- Header Focus 상태 ----------
   Hover와 Focus를 동일하게 처리하지 않는다. */

.header__logo:focus-visible,
.header-location__trigger:focus-visible,
.header-notification__trigger:focus-visible,
.header-dropdown__action:focus-visible,
.header-dropdown__item:focus-visible,
.header-dropdown__more:focus-visible,
.notice-list__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* 로그인은 v6에서 Filled Button이 되었으므로 Focus Ring Radius를
   Button 자체 Radius(md)에 맞춘다. 나머지 Focus 패턴은 위와 동일하다. */
.header-account__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-md);
}


/* ==================================================
   Hero Components
   Hero의 구조적 Layout(Intro Background Layer의 위치 / 크기 포함)은
   layout.css 에 있다.
   여기서는 Intro Background 표현 / Copy / Search / 인기검색어 표현을 다룬다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Title 42px / Subtitle 18px / Search 64px, Radius 16px
   - Search Input 17px / Search Button 112x48px, Radius 12px
   - Search Icon 20px / Trending Icon 16px
================================================== */

/* ---------- Intro Background (Header + Hero 공용) ----------
   Header와 Hero가 하나의 제주 Landscape 위에 놓이도록
   Image와 Overlay Gradient를 이 한 Element가 모두 소유한다.

   Overlay를 Hero(400px)가 아니라 Intro Layer(490px)에 걸어야
   Header 하단에서 Overlay가 갑자기 시작되는 가로 경계선이 생기지 않는다.

   Overlay 방향 (v4 - Alpha와 영향 "범위"를 함께 축소):
     좌측(Hero Copy 영역)  White 0.38 -> 0.30
     중앙                  White 0.12
     우측                  White 0.02 -> 0 (72%에서 종료)

     v3(0.52 / 0.42 / 0.20 / 0.04 / 0)는 Alpha를 낮췄어도 White Effect가
     Layer 끝(100%)까지 길게 남아 좌측이 여전히 뿌옇게 보였다.
     v4는 Alpha를 한 번 더 낮추면서 종료 지점을 100% -> 72%로 당겨
     Layer 우측 28%를 완전한 원본 Background로 만든다.

     목표는 [거의 White] -> [Landscape] 가 아니라
            [밝은 Landscape] -> [원본 Landscape] 로 보이게 하는 것이다.

   세로 방향으로는 값이 변하지 않는다.
   세로 변화를 주면 Header <-> Hero 사이에 Overlay 경계가 다시 보이기 때문이다.
   Header 영역(상단 90px)은 원본 Sky가 밝아 이 값만으로 Navy Typography
   대비가 확보되므로 별도 Header Surface / backdrop-filter를 쓰지 않는다.

   Stop 위치 (v4에서 Intro Layer가 다시 1400px가 되었으므로 재계산):
     28% =  392px
     48% =  672px
     65% =  910px
     72% = 1008px  <- Overlay 종료. 1008~1400px는 원본 Background 그대로.
   Hero Content는 Layer 기준 x 80~860px(5.7%~61.4%) 구간을 사용한다.

   TODO: Token 승격 검토 (Overlay rgba / Intro Background 구현값) */

.hero__background {
  background-image:
    linear-gradient(
      90deg,
      rgba(255, 255, 255, 0.38) 0%,
      rgba(255, 255, 255, 0.30) 28%,
      rgba(255, 255, 255, 0.12) 48%,
      rgba(255, 255, 255, 0.02) 65%,
      rgba(255, 255, 255, 0) 72%
    ),
    url("../images/common/hero.png");
  background-position: center 60%;
  background-size: cover;
  background-repeat: no-repeat;
}


/* ---------- Hero Copy ---------- */

/* Title (v4) : 50px -> 52px
   Hero 620px Scale에 맞춘 값이다.
   line-height 1.15 -> 1.14 (권장 범위 1.12~1.16).
   Block Height = 52 * 1.14 * 2 = 118.56px (v3 115px)
   font-weight / color 는 기존 값을 그대로 둔다. 2줄 유지.
   TODO: Token 승격 검토 */
.hero__title {
  color: var(--brand-primary);
  font-size: 52px;
  font-weight: var(--font-weight-bold);
  line-height: 1.14;
}

/* Title Accent : "한 곳"
   아이탐라의 Value Proposition("제주의 모든 생활을 한 곳에서") 중
   핵심 어절만 Brand Accent Color로 강조한다.
   Decoration이 아니므로 underline / background / gradient / shadow 를
   일절 쓰지 않고 Color만 바꾼다. "에서"는 기존 Title Color 유지.

   #084BE7 은 --brand-interaction 과 값이 같지만 그 Token의 의미는
   Hover / Focus 등 "Interaction State"다. 여기는 정적 Brand Accent이므로
   의미가 맞지 않아 Token을 재사용하지 않고 구현값을 쓴다.
   TODO: Hero Accent Token 승격 검토 */
.hero__title-accent {
  color: #084BE7;
}

.hero__subtitle {
  margin-top: var(--space-4); /* 메인 ↔ 서브 16px */
  color: var(--brand-primary);
  font-size: 18px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-medium);
  line-height: 1.6;
}


/* ---------- Hero Search ---------- */

.hero-search {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  height: 64px; /* TODO: Token 승격 검토 */
  /* 세로 8px + 48px 버튼 + 8px = 64px */
  margin-top: var(--space-5); /* 카피 ↔ 검색 40px */
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5);
  border-radius: 16px; /* TODO: Token 승격 검토 */
  background-color: var(--surface-default);
  box-shadow: var(--shadow-md);
}

/* Icon wrapper (22x22 고정).
   기존 임시 Emoji를 assets/icons/search/search-magnifier.svg 로 교체했다.
   Wrapper Size를 그대로 두었으므로 Search Bar 높이 / Input 정렬은 바뀌지 않는다.
   Asset은 viewBox 0 0 62 62 에 도형이 거의 꽉 차 있어
   Wrapper(22px)보다 약간 작은 20px로 그려 Input Text와 시각 크기를 맞춘다. */
.hero-search__icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
}

.hero-search__icon-image {
  display: block;
  width: 20px; /* TODO: Token 승격 검토 */
  height: 20px;
  object-fit: contain;
}

.hero-search__input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  font-size: 17px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}

.hero-search__input::placeholder {
  color: var(--text-tertiary);
}

.hero-search__input:focus {
  outline: none; /* Focus Ring은 검색창 전체(:focus-within)에 표시한다 */
}

.hero-search:focus-within {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
}

.hero-search__button {
  flex-shrink: 0;
  width: 112px; /* TODO: Token 승격 검토 */
  height: 48px;
  border-radius: 12px; /* TODO: Token 승격 검토 */
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  transition: background-color var(--transition-fast);
}

.hero-search__button:hover {
  background-color: var(--brand-interaction);
}

.hero-search__button:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 12px;
}


/* ---------- Hero 인기검색어 ---------- */

.hero-keyword {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* Trending Icon + Label.
   Icon(16px)이 Label line-height(13px * 1.5 = 19.5px)보다 작으므로
   Keyword Row 높이(태그 32px 기준)는 변하지 않는다.
   Color: Intro Overlay가 White 계열이라 기존 White Text는 읽히지 않는다.
          Dark Text 계열로 전환한다. */
.hero-keyword__title {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
}

/* Icon wrapper (16x16 고정).
   Asset(assets/icons/search/search-trending.svg)은 viewBox 0 0 62 62 이며
   자체 Blue(#1154E4)를 그대로 사용한다. Keyword Pill보다 강해지지 않도록
   Search Icon(20px)보다 작은 16px로 둔다. */
.hero-keyword__icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 16px; /* TODO: Token 승격 검토 */
  height: 16px;
}

.hero-keyword__icon-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.hero-keyword__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2); /* 태그 간 8px */
}

.hero-keyword__tag {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  /* Intro Overlay가 White 계열로 바뀌어 기존 White on White 조합은 읽히지 않는다.
     Height / Padding / Radius / Typography 는 그대로 두고 Color만 바꾼다.
     완전 불투명 White 대신 0.85로 두어 Landscape가 살짝 비치게 한다. */
  background-color: rgba(255, 255, 255, 0.85);
  color: var(--brand-primary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition: background-color var(--transition-fast);
}

.hero-keyword__tag:hover {
  background-color: var(--surface-default);
}

.hero-keyword__tag:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-pill);
}


/* ==================================================
   Wing Banner Components
   Wing의 구조적 Layout(폭 / Stack / Sticky / Slot Size)은 layout.css 에 있다.
   여기서는 Banner 표현만 다룬다.

   Main과 Wing 사이에는 Divider를 두지 않고 40px whitespace로만 분리한다.
   Wing 배경을 별도 Gray Panel로 만들지 않는다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Banner Radius 12px
================================================== */

.wing-banner {
  position: relative; /* AD Badge Overlay 기준점 */
  display: block;
  overflow: hidden;
  width: 100%;
  height: 100%;
  border-radius: 12px; /* TODO: Token 승격 검토 */
  background-color: var(--surface-default);
}

/* 광고 식별 Badge
   이미지에 합성하지 않고 UI Overlay로 분리해 Asset 교체 / Fade 순환에도
   각 광고에 그대로 따라가게 한다. Banner 크기·비율에는 영향을 주지 않는다.

   v1 QA: Dark Translucent(rgba(17,24,39,0.62))가 광고 이미지 위에서 너무 강해
          은은한 Gray-Blue(#C1CBE3 기반)로 변경했다.
          Border / Shadow는 사용하지 않고 Background만 바꾼다.
          배경이 밝아졌으므로 텍스트는 White 대신 --mono-900 을 쓴다.
   TODO: Token 승격 검토 */
.wing-banner__ad {
  position: absolute;
  top: 8px;   /* TODO: Token 승격 검토 */
  right: 8px;
  display: inline-flex;
  align-items: center;
  padding: 3px 6px; /* TODO: Token 승격 검토 */
  border-radius: var(--radius-sm);
  background-color: rgba(193, 203, 227, 0.88);
  color: var(--mono-900);
  font-size: 10px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  letter-spacing: 0.04em;
}

/* 원본 비율이 240x320(3:4)과 달라도 Wrapper 안에서 cover 처리한다 */
.wing-banner__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.wing-banner:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 12px; /* Banner Radius와 동일 */
}


/* ==================================================
   Main Category Components (v2.0)
   Category의 구조적 Layout(폭 / Overlap / Grid / Item Size)은 layout.css 에 있다.
   여기서는 Panel 표현 / Divider / Typography만 다룬다.

   v2.0에서는 6개 개별 Card가 아니라 하나의 통합 White Panel이다.
   Item은 Border / Radius / Shadow를 갖지 않고 Divider로만 구분한다.
   (.category-card 클래스명은 참조 범위를 넓히지 않기 위해 유지했다)

   Shadow는 Panel이 실제로 Hero 위에 떠 있는 요소라서 사용한다.
   Modal처럼 보이지 않도록 --shadow-lg 가 아닌 --shadow-md 를 쓴다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Icon 52px / Category Name 17px / Name→Sub 6px / Divider Inset 20px
================================================== */

/* 통합 Panel : Hero 위에 올라오는 White Surface.
   Item Hover 배경이 Panel Radius를 넘지 않도록 overflow: hidden 을 쓴다. */
.main-category__panel {
  overflow: hidden;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-xl); /* 20px */
  background-color: var(--surface-default);
  box-shadow: var(--shadow-md);
}

/* Item 사이 Vertical Divider.
   두 번째 Item부터 왼쪽에 그리므로 6개 Item에 Divider는 5개다.
   Panel 높이를 꽉 채우지 않도록 상하 20px inset을 준다. */
.category-grid__item + .category-grid__item::before {
  content: "";
  position: absolute;
  top: var(--space-5);    /* 20px */
  bottom: var(--space-5);
  left: 0;
  width: 1px;
  background-color: var(--border-light);
}

/* Item : 개별 Card 표현(Border / Radius / Shadow / 자체 배경)을 갖지 않는다. */
.category-card {
  text-align: center;
  transition:
    background-color var(--transition-fast),
    color var(--transition-fast);
}

/* Hover : 아주 연한 배경 + 이름 색상만. Shadow / transform / scale / border 사용 안 함 */
.category-card:hover {
  background-color: var(--bg-brand-light);
}

.category-card:hover .category-card__name {
  color: var(--brand-secondary);
}

/* Panel이 overflow:hidden 이므로 Focus Ring을 안쪽에 그린다 */
.category-card:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: -2px;
}

/* Icon : SVG(viewBox 0 0 62 62)에 원형 배경이 포함되어 있어
   별도 Icon Container를 두지 않는다. 표시 크기만 축소한다. */
.category-card__icon {
  display: block;
  width: 52px;  /* TODO: 화면 QA 후 48/52/56/62 중 확정 */
  height: 52px;
}

.category-card__name {
  margin-top: var(--space-3); /* Icon → Name 12px */
  color: var(--text-primary);
  font-size: 17px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  transition: color var(--transition-fast);
}

/* 소분류는 한 줄로 표시한다. 1400px Grid(카드 약 220px)에서는 전문이 보이며,
   좁은 Viewport에서만 말줄임으로 넘침을 방어한다. */
.category-card__sub {
  max-width: 100%;
  margin-top: 6px; /* Name → Sub. TODO: Token 승격 검토 */
  overflow: hidden;
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ==================================================
   Common Media Components
   특정 Section 전용이 아니라 "사진을 가진 콘텐츠" 전반에서 재사용하는 표현.

   .photo-count 는 Recommend Card 전용이 아니다.
   향후 매물 목록 / 부동산 상세 / 중고차 상세 / Gallery 등에서
   동일한 마크업 + 동일한 Visual Language로 그대로 재사용한다.
     <span class="photo-count photo-count--overlay">
       <img class="photo-count__icon" src="assets/icons/media/media-photo.svg" alt="" aria-hidden="true">
       <span class="sr-only">사진 </span>
       <span class="photo-count__value">12</span>
       <span class="sr-only">장</span>
     </span>

   Asset 분리 원칙:
     Icon Asset(media-photo.svg)은 White Pictogram 하나만 담당한다.
     Badge 배경 / 크기 / 위치 / 숫자는 전부 CSS와 마크업이 담당하므로
     SVG 안에 배경 · 숫자 · Badge Shape를 넣지 않는다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Badge Height 26px / Icon 15px / Overlay Offset 12px
================================================== */

/* Badge 본체 : 배치를 갖지 않는 순수 Chip이라
   Overlay(사진 위) / Inline(정보 줄 안) 어디에도 그대로 쓸 수 있다. */
.photo-count {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1); /* Icon ↔ 숫자 4px */
  height: 26px;        /* TODO: Token 승격 검토 */
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm); /* 6px */
  /* 매물 사진은 밝기가 제각각이라 White Icon / White 숫자를 사진 위에 직접 올리지 않고
     항상 Navy 반투명 Surface를 함께 깐다.
     --brand-primary(#0B2A63)를 알파와 함께 쓰는 값이라 기존 Color Token으로는
     그대로 표현되지 않으므로 구현값을 사용한다. backdrop-filter는 쓰지 않는다.
     TODO: Token 승격 검토 */
  background-color: rgba(11, 42, 99, 0.68);
  color: var(--text-inverse);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}

/* 사진 위에 얹는 배치. 기준점(position: relative)은 사진 Wrapper가 갖는다.
   우측 상단 Favorite / 좌측 상단 Badge와 겹치지 않는 우측 하단을 사용한다. */
.photo-count--overlay {
  position: absolute;
  right: 12px; /* TODO: Token 승격 검토 */
  bottom: 12px;
}

/* Asset은 viewBox="0 0 62 62" 정사각이라 Wrapper와 비율이 같다.
   Asset 내부(path / fill / viewBox)를 수정하지 않고 표시 크기만 CSS가 결정한다. */
.photo-count__icon {
  display: block;
  flex-shrink: 0;
  width: 15px; /* TODO: Token 승격 검토 */
  height: 15px;
  object-fit: contain;
}

/* 숫자만 노출한다. "사진 12장"처럼 길게 쓰지 않는다.
   (Screen Reader용 "사진" / "장"은 마크업의 .sr-only 가 담당한다) */
.photo-count__value {
  font-variant-numeric: tabular-nums;
}


/* ==================================================
   Main Section Panel
   Recommend / Popular / Today Jeju 를 감싸는 독립 Section Container.
   Layout(Padding / Width)은 layout.css 에 있고 여기서는 표현만 다룬다.

   Utility Section 제외 (v3):
     .main-utility 는 아래 Selector에서 제외한다. Utility는 콘텐츠 Section이 아니라
     "서비스 종료 → 공지 / 고객지원 / 행동 유도 → Footer" 로 넘어가는 Transition
     영역이므로, 1400px White Panel 문법을 여기서 의도적으로 끊는다.
     Section은 투명 Layout Wrapper가 되고 Information / CTA 두 Panel이 각각
     자기 Background / Radius / Padding을 갖는다.
     Selector에서 이름을 빼는 방식이라 Override(!important / 재선언)가 필요 없다.

   Section은 Interactive Card가 아니다. 따라서
     - Hover / Focus / Transition 없음
     - Gradient / Gray 배경 없음
     - overflow 를 지정하지 않는다 (기본값 visible 유지)

   Shadow (QA):
     1px Border만으로는 White Panel과 Page 배경의 경계가 약해
     Border를 "보조"하는 수준의 아주 옅은 Shadow를 하나만 둔다.
     Card처럼 떠 보이면 안 되므로 Hover / Transition / transform 은 없다.
   특히 overflow: hidden 을 넣으면 Recommend Carousel Arrow(right:-20px)처럼
   Grid Edge 밖으로 나가는 UI가 잘리므로 사용하지 않는다.
   (좌우 30px Padding 도입 후 Arrow는 Section Border를 넘지 않고
    Content Right Edge에 걸치며, Border 안쪽 10px 지점까지만 나간다)

   Section Radius(18px)와 내부 Card Radius(12 / 14 / 16px)는 별개다.
   Section에 맞추려고 내부 Component Radius를 바꾸지 않는다.

   Header / Hero / Category / Footer 에는 적용하지 않는다.
================================================== */

.main-recommend,
.main-popular,
.main-today-jeju,
.main-event {
  border: 1px solid var(--border-light);
  border-radius: 18px; /* --radius-lg(14) / --radius-xl(20) 와 어긋나는 값.
                          TODO: Section radius token 승격 검토 */
  background-color: var(--surface-default);
  /* 하단 중심의 아주 약한 단일 Shadow.
     기존 Token 재사용을 먼저 검토했으나 이번 의도보다 명확히 강하다.
       --shadow-sm : 0 1px 3px  rgba(17,32,51,0.06) → Blur가 좁아 Border와 겹쳐 보임
       --shadow-md : 0 4px 16px rgba(17,32,51,0.08) → 형태는 같으나 alpha가 2배 이상
     1400px Panel에서는 alpha 차이가 그대로 존재감 차이가 되므로 구현값을 사용한다.
     TODO: Section panel shadow token 승격 검토 */
  box-shadow: 0 4px 14px rgba(17, 24, 39, 0.035);
}


/* ==================================================
   Main Recommend Components
   Recommend의 구조적 Layout(폭 / Header 배치 / Grid)은 layout.css 에 있다.
   여기서는 Filter / Card / Badge / Arrow 표현과 Typography만 다룬다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Filter 40px / padding 18px / radius 10px
   - Card Radius 14px / Badge 28px·radius 6px / Favorite 34px
   - Card Title 17px / Location 26px·radius 8px
   - Photo Count는 공용 .photo-count (Common Media Components) 를 사용한다
================================================== */

/* ---------- Section Header ---------- */

.main-recommend__title {
  color: var(--text-primary);
  font-size: var(--font-size-3xl); /* 28px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight); /* 1.3 */
  white-space: nowrap;
}

.main-recommend__subtitle {
  overflow: hidden;
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ---------- Filter ----------
   실제 Filter Switching JS는 이번 단계에서 구현하지 않는다.
   Tab Interaction이 없으므로 role="tablist" 등을 적용하지 않는다. */

.recommend-filter__item {
  height: 40px;
  padding: 0 18px;
  border: 1px solid var(--border-light);
  border-radius: 10px;
  background-color: var(--surface-default);
  color: var(--text-secondary);
  font-size: 15px; /* Token에 15px가 없어 구현값 유지. TODO: Token 승격 검토 */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.recommend-filter__item:hover {
  border-color: var(--brand-secondary);
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
}

/* Active : Primary Button과 동일한 Brand Blue(--brand-secondary #1246A3).
   Popular Period Button Active와 같은 값을 사용한다. */
.recommend-filter__item.is-active,
.recommend-filter__item.is-active:hover {
  border-color: var(--brand-secondary);
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
  font-weight: var(--font-weight-semibold);
}

.recommend-filter__item:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 10px;
}


/* ---------- 전체보기 ---------- */

.main-recommend__more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition: color var(--transition-fast);
}

.main-recommend__more:hover {
  color: var(--brand-secondary);
}

.main-recommend__more:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.main-recommend__more-arrow {
  font-size: var(--font-size-base);
  line-height: 1;
}


/* ---------- Recommend Card ---------- */

.recommend-card {
  position: relative; /* 제목 Link의 ::after 기준점 */
  overflow: hidden;
  border: 1px solid var(--border-light);
  /* 값(14px)은 그대로이고 구현값을 --radius-lg Token 참조로 정리했다.
     Section Radius(18px)와는 별개다. */
  border-radius: var(--radius-lg);
  background-color: var(--surface-default);
  transition:
    border-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

/* Hover : Border + 약한 Shadow만. transform / scale 사용 안 함 */
.recommend-card:hover {
  border-color: var(--border-default);
  box-shadow: var(--shadow-sm);
}

/* Image 영역
   v2 : 16/10 -> 4/3.
   Card에서 Image가 차지하는 비율을 50.6% -> 약 56%로 끌어올려
   매물 사진의 상품성이 먼저 읽히게 한다.
   Card Height 증가분(+37px)은 아래 Body의 Vertical Gap 정리(-10px)로
   일부 상쇄해 Section 전체 증가를 최소화한다.
   4개 Card 모두 같은 Wrapper 비율을 쓰므로 Image Height는 항상 동일하다. */
.recommend-card__media {
  position: relative;
  aspect-ratio: 4 / 3;
}

/* 실제 Asset : 원본 비율이 달라도 16:10 Wrapper 안에서 cover 처리한다 */
.recommend-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Badge : Type별 색상을 나누지 않고 Blue Brand 체계를 유지한다 */
.recommend-card__badge {
  position: absolute;
  top: 12px;
  left: 12px;
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: 6px;
  background-color: rgba(255, 255, 255, 0.92);
  color: var(--brand-secondary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}

/* 사진 수 : Recommend 전용 Class를 만들지 않고 공용 .photo-count 를 그대로 쓴다.
   정의는 위 "Common Media Components" 에 있으며 여기서 재선언하지 않는다.
   기준점(position: relative)은 .recommend-card__media 가 이미 갖고 있다. */

/* 찜 : 카드 Link(<a>)의 형제 요소이며 z-index로 Link 위에 놓인다.
   따라서 Nested Interactive Element가 생기지 않는다. */
.recommend-card__favorite {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border-light);
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.92);
  color: var(--text-secondary);
  transition: color var(--transition-fast);
}

.recommend-card__favorite:hover {
  color: var(--brand-secondary);
}

.recommend-card__favorite:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 50%;
}

.recommend-card__favorite-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
}


/* ---------- Card Content ---------- */

.recommend-card__body {
  padding: var(--space-4); /* 16px */
}

/* v2 : Brand Blue -> Text Secondary.
   Blue를 Price 하나에만 남겨 "가격이 먼저 스캔되는" 위계를 만든다.
   Type은 Category Label이므로 보조 정보 색을 쓴다. */
.recommend-card__type {
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-snug); /* 1.4 */
}

.recommend-card__title {
  margin-top: 6px; /* Type → Title. TODO: Token 승격 검토 */
  overflow: hidden;
  color: var(--text-primary);
  font-size: 17px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-semibold);
  line-height: 1.45;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 제목 Link가 ::after 로 카드 전체를 덮어 카드 전체 클릭을 만든다 */
.recommend-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.recommend-card__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* v2 : DOM 순서가 Title → Price → Meta 로 바뀌어 Price 다음에 온다 */
.recommend-card__meta {
  margin-top: var(--space-2); /* Price → Meta 8px */
  overflow: hidden;
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal); /* 1.5 */
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* v2 : Information Hierarchy 변경
   위치  Meta 다음 -> Title 바로 다음 (Image > Title > Price > Meta)
   Color --text-primary -> --brand-secondary (Brand Blue로 Scan 포인트를 만든다)
   Size  20px 유지. Title(17px) 대비 1.18배라 과하게 커지지 않는다. */
.recommend-card__price {
  margin-top: var(--space-2); /* Title → Price 8px */
  color: var(--brand-secondary);
  font-size: var(--font-size-xl); /* 20px */
  font-weight: var(--font-weight-bold);
  line-height: 1.35;
}

.recommend-card__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-3); /* v2: Meta → Bottom 14px -> 12px (Token 재사용) */
}

.recommend-card__location {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border-radius: 8px; /* TODO: Token 승격 검토 */
  background-color: var(--bg-subtle);
  color: var(--text-secondary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
}

.recommend-card__views {
  color: var(--text-tertiary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  white-space: nowrap;
}


/* ---------- Carousel Navigation ----------
   현재는 UI Shell이다. Sliding JS는 구현하지 않는다. */

.recommend-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border-light);
  border-radius: 50%;
  background-color: var(--surface-default);
  box-shadow: var(--shadow-sm);
  color: var(--text-secondary);
  transition: color var(--transition-fast), border-color var(--transition-fast);
}

.recommend-nav:hover {
  border-color: var(--brand-secondary);
  color: var(--brand-secondary);
}

.recommend-nav:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 50%;
}

.recommend-nav__icon {
  font-size: 18px;
  line-height: 1;
}


/* ==================================================
   Main Popular Components
   Popular의 구조적 Layout(폭 / Header 배치 / Grid / Row Grid)은 layout.css 에 있다.
   여기서는 Panel / Ranking Item / Chart / Legend / Period Button 표현만 다룬다.

   Recommend가 Card Gallery라면 Popular은 정보 List다.
   따라서 Card Hover(Shadow / Scale / Translate)를 사용하지 않고
   Row 배경만 아주 약하게 변한다.

   Rank 변화 색상은 tokens.css 의 Ranking 토큰을 그대로 사용한다.
     ▲ --rank-up / ▼ --rank-down / NEW --rank-hot

   Chart Palette는 Category Card의 Multi Color와 성격이 다르므로
   Brand Blue → Blue Gray 로 이어지는 5단계 통계 전용 Ramp만 사용한다.
   (모두 기존 Token이며 신규 Hex를 만들지 않았다)

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Period Button 40px / Radius 10px / 15px (Recommend Filter와 동일 값)
   - Thumbnail Radius 8px / Location Pill 26px, Radius 8px
   - Legend Dot 10px / Donut Stroke Width 22 (SVG 좌표계)
================================================== */

.main-popular__title {
  color: var(--text-primary);
  font-size: var(--font-size-3xl); /* 28px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight); /* 1.3 */
  white-space: nowrap;
}

.main-popular__subtitle {
  overflow: hidden;
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ---------- Period Filter ----------
   .recommend-filter__item 과 동일한 Button 언어(높이 40 / Radius 10 / 15px /
   Active Brand Blue)를 사용한다. 새로운 Button 디자인을 만들지 않았다.
   기존 Recommend 규칙을 수정하지 않기 위해 선택자를 합치지 않고 값을 맞췄으므로,
   Filter Button 디자인이 바뀌면 두 블록을 함께 수정한다.

   기간 전환 JS는 이번 단계에서 구현하지 않는다.
   Tab Interaction이 없으므로 role="tablist" 등을 적용하지 않는다. */

.popular-period__button {
  height: 40px;
  padding: 0 18px;
  border: 1px solid var(--border-light);
  border-radius: 10px;
  background-color: var(--surface-default);
  color: var(--text-secondary);
  font-size: 15px; /* Token에 15px가 없어 구현값 유지. TODO: Token 승격 검토 */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.popular-period__button:hover {
  border-color: var(--brand-secondary);
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
}

/* Active : Recommend Filter Active와 동일한 Brand Blue(--brand-secondary #1246A3) */
.popular-period__button.is-active,
.popular-period__button.is-active:hover {
  border-color: var(--brand-secondary);
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
  font-weight: var(--font-weight-semibold);
}

.popular-period__button:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 10px;
}


/* ---------- Ranking Panel ----------
   Shadow를 사용하지 않고 Border + 배경으로만 구분한다. */

/* v2 : .popular-ranking 의 Panel Box(Border / Radius / Background / overflow)를
   제거했다. Section 전체가 이미 하나의 Panel인데 그 안에서 좌우를 다시 Card로
   나누면 Dashboard처럼 읽히기 때문이다. 표현이 하나도 남지 않아 Selector 자체를
   삭제했고, Layout(flex column)은 layout.css 가 계속 담당한다.
   좌우 구분은 .popular-list 의 Vertical Divider 하나만 사용한다. */


/* ---------- Section 내부 Sub Heading (v2) ----------
   좌측 "실시간 인기 매물" / 우측 "인기 검색어".
   기존 .popular-category__title 이 쓰던 Section 내부 Heading Language를
   그대로 승계한다. Main Section Title(28px)보다 확실히 작다. */

.popular-ranking__title,
.popular-search__title {
  /* v3 : 앞에 의미 Icon을 두기 위해 flex로 바꿨다.
     Icon(16px) < line-height(18 * 1.4 = 25.2px) 이므로
     준 타이틀 Row 높이는 그대로 25.2px를 유지한다. */
  display: flex;
  align-items: center;
  gap: var(--space-2); /* Icon ↔ Text 8px. Hero 인기검색어와 동일 */
  color: var(--text-primary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug);
  margin-bottom: var(--space-4); /* Sub Heading → List 16px */
}

/* ---------- 준 타이틀 의미 Icon (v3) ----------
   좌 불꽃(assets/icons/search/search-trending.svg)
     = 인기 / Hot. Hero 인기검색어에서 쓰는 Asset을 그대로 재사용한다.
   우 번개(assets/icons/app/app-feature-easy-use.svg)
     = 실시간성 / 빠른 관심. 앱 소개 영역 "간편한 이용"에서 쓰는 Asset이다.

   Wrapper 크기 / img 채우기 방식 모두 Hero의 .hero-keyword__icon 관례를
   그대로 따른다. 원형 배경 / Badge / Shadow / Gradient / Border / Animation
   을 붙이지 않고, Asset 고유 색(둘 다 Blue 계열)을 그대로 쓴다.
   Section Main Title(28px)보다 강해지지 않도록 16px로 둔다. */

.popular-ranking__icon,
.popular-search__icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 16px; /* TODO: Token 승격 검토 */
  height: 16px;
}

.popular-ranking__icon-image,
.popular-search__icon-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Row 사이 Divider. Table / List 처럼 읽히도록 Card 분리를 하지 않는다. */
.popular-list__item + .popular-list__item {
  border-top: 1px solid var(--border-light);
}


/* ---------- Ranking Item ----------
   Row 전체가 하나의 <a> 이며 내부에 별도 Interactive 요소를 두지 않는다. */

.popular-item {
  transition: background-color var(--transition-fast);
}

/* Hover : 배경만 아주 약하게. Shadow / transform / scale / border 변화 없음 */
.popular-item:hover {
  background-color: var(--surface-hover);
}

/* Row가 Panel 폭 전체를 차지하므로 Focus Ring을 안쪽에 그린다 */
.popular-item:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: -2px;
}

/* Rank : Badge를 만들지 않고 숫자 자체를 Visual Anchor로 사용한다.
   Brand Identity 전용인 --brand-primary 대신 일반 Primary Blue를 사용한다. */
/* v2 : Leading Zero(01~05) -> 1~5 로 바뀌면서 숫자 폭이 줄었다.
   Rank가 장식이 되지 않도록 28px -> 20px 로 낮추고,
   1위만 24px로 한 단계 올려 최소한의 위계만 준다.
   Medal / Circle Badge / Gradient / 금·은·동 색을 쓰지 않고
   기존 Blue(--brand-secondary)를 그대로 유지한다. */
.popular-item__rank {
  color: var(--brand-secondary);
  font-size: var(--font-size-xl); /* 20px */
  font-weight: var(--font-weight-bold);
  line-height: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.popular-list__item:first-child .popular-item__rank {
  font-size: var(--font-size-2xl); /* 24px */
}

/* Thumbnail : 112 x 72 고정. 이미지 로딩 전에도 Row 높이가 흔들리지 않는다. */
.popular-item__thumb {
  display: block;
  overflow: hidden;
  width: 110px;  /* v2: 112x72 -> 110x74 (Compact Ranking Thumbnail 범위 유지) */
  height: 74px;
  border-radius: 8px; /* TODO: Token 승격 검토 */
  background-color: var(--bg-muted);
}

.popular-item__thumb-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Asset이 없는 카테고리용 Neutral Placeholder (기존 Category Icon 재사용) */
.popular-item__thumb--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--bg-brand-light);
}

.popular-item__thumb-icon {
  width: 40px; /* TODO: Token 승격 검토 */
  height: 40px;
}

.popular-item__category {
  overflow: hidden;
  color: var(--brand-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-snug); /* 1.4 */
  text-overflow: ellipsis;
  white-space: nowrap;
}

.popular-item__title {
  overflow: hidden;
  color: var(--text-primary);
  font-size: var(--font-size-base); /* 16px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug); /* 1.4 */
  text-overflow: ellipsis;
  white-space: nowrap;
}

.popular-item__meta {
  overflow: hidden;
  color: var(--text-tertiary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal); /* 1.5 */
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Location Pill : Recommend Card의 Location Pill과 동일한 표현을 사용한다.
   값이 없는 경우 빈 Pill을 만들지 않고 이 요소 자체를 렌더하지 않는다. */
.popular-item__location {
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  height: 26px;
  padding: 0 10px;
  border-radius: 8px; /* TODO: Token 승격 검토 */
  background-color: var(--bg-subtle);
  color: var(--text-secondary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Views : "조회"는 muted, 숫자만 한 단계 강조 */
.popular-item__views {
  color: var(--text-tertiary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  white-space: nowrap;
}

.popular-item__views-count {
  color: var(--text-secondary);
  font-weight: var(--font-weight-medium);
  font-variant-numeric: tabular-nums;
}

/* Rank Change : 색상은 tokens.css 의 Ranking Token만 사용한다 */
.popular-item__change {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* TODO(icon): ▲ / ▼ 는 임시 문자다. 이 wrapper 내부만 SVG로 교체하면 된다. */
.popular-item__change-icon {
  line-height: 1;
}

.popular-item__change--up {
  color: var(--rank-up);
}

.popular-item__change--down {
  color: var(--rank-down);
}

.popular-item__change--new {
  color: var(--rank-hot);
}

/* v2 : 변동 없음("-"). 신규 Color Policy를 만들지 않고
   기존 보조 텍스트 Token을 그대로 쓴다. */
.popular-item__change--same {
  color: var(--text-tertiary);
}


/* ---------- Ranking Footer ----------
   Panel 하단 전체를 차지하되 별도 Button 형태로 키우지 않는다. */

.popular-ranking__footer {
  border-top: 1px solid var(--border-light);
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  transition:
    background-color var(--transition-fast),
    color var(--transition-fast);
}

.popular-ranking__footer:hover {
  background-color: var(--surface-hover);
  color: var(--brand-secondary);
}

.popular-ranking__footer:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: -2px;
}

.popular-ranking__footer-arrow {
  margin-left: var(--space-1);
  font-size: var(--font-size-base);
  line-height: 1;
}


/* ---------- Popular Search Ranking (v2) ----------
   기존 "많이 본 카테고리 + Donut Chart"를 대체한다.
   Donut / Legend 관련 Selector(.popular-category*, .popular-donut*)는
   프로젝트 전수 검색 결과 Popular Section 전용이었고 사용처가 0이 되어 삭제했다.
   (다른 Section에서 재사용하는 Chart Style은 존재하지 않았다)

   Right = Simple 원칙: 검색량 / Sparkline / Tag / Description을 두지 않고
   Rank / Keyword / Trend 3가지만 보여준다. */

.popular-search__item + .popular-search__item {
  border-top: 1px solid var(--border-light);
}

/* Hover : 배경만 아주 약하게. transform / scale / shadow 를 쓰지 않는다.
   좌측 .popular-item Hover와 동일한 Language다. */
.popular-search__link {
  transition: background-color var(--transition-fast);
}

.popular-search__link:hover {
  background-color: var(--surface-hover);
}

.popular-search__link:hover .popular-search__keyword {
  color: var(--brand-secondary);
}

.popular-search__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: -2px;
}

/* Rank : 좌측 Ranking(20 / 1위 24px)보다 한 단계 작게 둔다.
   1위만 과도하게 키우지 않는다. */
.popular-search__rank {
  color: var(--brand-secondary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-bold);
  line-height: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.popular-search__keyword {
  overflow: hidden;
  color: var(--text-primary);
  font-size: 15px; /* Token에 15px가 없어 구현값 유지. TODO: Token 승격 검토 */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-snug);
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color var(--transition-fast);
}


/* ==================================================
   Main Today Jeju Components
   Today Jeju의 구조적 Layout(폭 / Grid / Spacing)은 layout.css 에 있다.
   여기서는 Weather Card / Metrics / Filter / Place Card / Shortcut 표현만 다룬다.

   Panel Radius는 바로 위 Popular Section의 Panel과 같은 --radius-lg(14px)를 쓴다.

   Weather Card 배경은 전용 이미지 Asset이 없어 기존 Token만으로
   Light Blue Gradient를 구성했다. 신규 Hex를 만들지 않았다.

   Filter Button은 .recommend-filter__item / .popular-period__button 과
   동일한 Button 언어(높이 40 / Radius 10 / 15px / Active Brand Blue)를 사용한다.
   기존 규칙을 수정하지 않기 위해 선택자를 합치지 않고 값을 맞췄으므로,
   Filter Button 디자인이 바뀌면 세 블록을 함께 수정한다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Filter 40px / Radius 10px / 15px
   - Status Pill 28px / Temperature 70px / Tag 24px
   - Place Card Image 1:1 (v2.0) / Image Radius 16px / Divider Inset 8~12px
================================================== */

.main-today-jeju__title {
  color: var(--text-primary);
  font-size: var(--font-size-3xl); /* 28px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight); /* 1.3 */
  white-space: nowrap;
}

.main-today-jeju__subtitle {
  overflow: hidden;
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ---------- Today Location ----------
   Header Location(전역 검색 지역)보다 한 단계 약하게 표현해
   Section 내부 보조 Context로 읽히게 한다. */

.today-location__label {
  color: var(--text-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  white-space: nowrap;
}

/* TODO(js): 실제 지역 변경 동작은 구현하지 않은 정적 UI다. */
.today-location__change {
  height: 28px; /* TODO: Token 승격 검토 */
  padding: 0 var(--space-3);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  background-color: var(--surface-default);
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.today-location__change:hover {
  border-color: var(--brand-secondary);
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
}

.today-location__change:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}


/* ---------- Weather Card ----------
   전용 날씨 이미지 Asset이 없어 기존 Token 3개로 Gradient를 구성했다.
   Shadow를 쓰지 않고 Gradient + Border로만 깊이를 만든다. */

.today-weather {
  position: relative; /* ::before Overlay / 본문 z-index 기준점 */
  overflow: hidden;   /* 배경 이미지가 Card Radius를 넘지 않게 */
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg); /* 14px */
  background-color: var(--bg-brand-light); /* 이미지 로딩 전 Fallback */
  background-image: url("../images/main/today-weather-jeju.png");
  background-position: right center; /* 제주 해안·산 실루엣이 잘리지 않는 쪽 */
  background-size: cover;
  background-repeat: no-repeat;
}

/* 가독성 Overlay
   본문(Status / Temperature / Description)이 놓이는 좌상단은 강하게,
   풍경이 보이는 우하단은 약하게 덮어 Visual 존재감과 가독성을 함께 유지한다.
   Hero Overlay와 동일하게 Token이 아닌 rgba 구현값을 사용한다.
   alpha 단계는 0.78 / 0.45 / 0.10 세 단계로만 제한한다.
   (v1 QA: 0.85 / 0.55 / 0.15 → 제주 해안 풍경의 존재감을 높이기 위해 한 단계 완화)
   TODO: Token 승격 검토 */
.today-weather::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(
    165deg,
    rgba(255, 255, 255, 0.78) 0%,
    rgba(255, 255, 255, 0.45) 40%,
    rgba(255, 255, 255, 0.10) 100%
  );
}

/* 본문은 항상 배경/Overlay 위에 쌓인다 */
.today-weather > * {
  position: relative;
  z-index: 1;
}

/* Status : 향후 Weather API의 condition label로 교체 가능한 Pill */
.today-weather__status {
  display: inline-flex;
  align-items: center;
  height: 48px; /* TODO: Token 승격 검토 */
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  background-color: var(--surface-default);
  color: var(--brand-interaction);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  white-space: nowrap;
}

/* Temperature : Card 안에서 가장 강한 정보.
   v3.1 : v3.0에서 40px로 줄였던 값을 v2.1 기준(70px)으로 되돌린다.
          Weather Card가 다시 정보형 UI가 되면서 Icon(120) / Metrics(4종)와
          함께 Card 상단을 지탱하는 Main Number 역할을 회복한다. */
.today-weather__temperature {
  color: var(--brand-primary);
  font-size: 70px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  font-variant-numeric: tabular-nums;
}

.today-weather__unit {
  margin-left: 2px; /* TODO: Token 승격 검토 */
  font-size: var(--font-size-3xl); /* 28px */
  font-weight: var(--font-weight-semibold);
}

.today-weather__feels-like {
    margin-top: var(--space-1);
    color: var(--brand-primary);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-normal);
}

/* Description : 현재 날씨 상태를 한 문장으로 풀어 쓴 설명.
   v3.1 : "그래서 어떤 장소를 골랐는가"는 우측 Recommendation Description이 담당하고,
          여기서는 날씨 자체에 대한 설명까지만 남긴다. */
.today-weather__description {
  margin-top: var(--space-5);
  color: var(--brand-secondary);
  font-size: var(--font-size-base); /* 16px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-relaxed); /* 1.7 */
}


/* ---------- Weather Metrics ----------
   Divider는 두 번째 Metric부터 왼쪽에 그리므로 4개 중 3개다. */

/* Metrics : 배경 이미지에서 가장 진한 바다 영역 위에 놓이므로
   Divider Layout은 그대로 두고 아주 옅은 반투명 Surface만 깔아 가독성을 확보한다.
   개별 Metric Card 4개로 분리하지 않는다.
   Card 하단의 정보 밀도와 시각적 균형을 담당하는 블록이라 4종을 모두 유지한다. */
.today-weather__metrics {
  border-radius: var(--radius-md);
  background-color: rgba(255, 255, 255, 0.72);
}

.today-weather__metric + .today-weather__metric::before {
  content: "";
  position: absolute;
  top: var(--space-1);
  bottom: var(--space-1);
  left: 0;
  width: 1px;
  background-color: var(--border-light);
}

.today-weather__metric-label {
  color: var(--text-tertiary);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  white-space: nowrap;
}

.today-weather__metric-value {
  margin-top: var(--space-1);
  color: var(--text-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  white-space: nowrap;
}


/* ---------- Recommendation Heading / Filter ---------- */

.today-recommend__heading {
  color: var(--text-primary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug);
}

/* v3.1 : 좌측 Weather 수치(강수확률 80%)를 근거로 받아
   왜 이 Card들을 골랐는지 설명하는 한 줄. Heading보다 확실히 약하게 둔다.
   Section Subtitle과 같은 14px / regular / --text-secondary 를 재사용한다. */
.today-recommend__description {
  margin-top: var(--space-2); /* Heading → Description 8px */
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}

.today-recommend__filter {
  height: 40px;
  padding: 0 18px;
  border: 1px solid var(--border-light);
  border-radius: 10px;
  background-color: var(--surface-default);
  color: var(--text-secondary);
  font-size: 15px; /* Token에 15px가 없어 구현값 유지. TODO: Token 승격 검토 */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.today-recommend__filter:hover {
  border-color: var(--brand-secondary);
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
}

/* Active : Recommend Filter / Popular Period Button과 동일한 Brand Blue */
.today-recommend__filter.is-active,
.today-recommend__filter.is-active:hover {
  border-color: var(--brand-secondary);
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
  font-weight: var(--font-weight-semibold);
}

.today-recommend__filter:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 10px;
}


/* ---------- Place Card ----------
   Favorite / Carousel이 없으므로 Card 전체가 단일 <a> 다. */

/* v2.0 : Card 전체를 감싸던 Box(Border / Radius / White 배경 / overflow)를 제거한다.
   "Image = 독립 Visual Card" + "Text = 이미지 아래 열린 정보 영역" 구조가 되어
   Recommend Card Gallery와 다른 UI 언어를 갖는다. */
.today-place-card {
  overflow: visible;
  border: 0;
  border-radius: 0;
  background-color: transparent;
  box-shadow: none;
}

/* Hover : Box가 없으므로 Border / Shadow 대신 Image만 아주 약하게 변한다.
   transform / scale / 강한 Shadow는 사용하지 않는다. */
.today-place-card:hover .today-place-card__image {
  opacity: 0.88;
}

/* Box가 사라져도 Focus는 Image + Content 전체를 감싸도록 바깥쪽에 그린다.
   border-radius는 Focus Ring 모양만 다듬으며 평상시 시각 변화는 없다. */
.today-place-card:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 4px;
  border-radius: 16px; /* TODO: Token 승격 검토 */
}

/* v2.0 : 이미지 자체가 독립 Visual Card다.
   Border / Shadow 없이 Radius + 이미지만으로 Card처럼 읽히게 한다.

   v2.1 : Card 하단 ↔ Utility Bar 사이에 남던 Vertical Space를
          Text 확대가 아니라 이미지 높이로 흡수한다.
          Weather Card(min-height 520)가 Body Row 높이를 결정하고 있어
          Recommendation Column이 커져도 Section 높이는 변하지 않는다.
            Recommendation 실측 높이 465.77 → 478.27px (< 520)
          고정 height 대신 Card 실폭에 맞춘 ratio로 처리한다.
            Card 폭 212.5px x 18 / 17 = 225px
          Card Width / Grid Gap / 4 Columns / Text 영역은 그대로다.
   TODO: Token 승격 검토 */
.today-place-card__image {
  position: relative; /* Type Icon Overlay 기준점 */
  display: block;
  overflow: hidden;
  aspect-ratio: 17 / 18;  /* v2.1 : 225px (v2.0: 1 / 1 = 212.5px, v1.0: 16 / 10) */
  border-radius: 16px;  /* TODO: Token 승격 검토 */
  background-color: var(--bg-muted);
  transition: opacity var(--transition-fast);
}

/* 장소 유형 Icon
   Asset(assets/icons/places/*.svg)이 흰 Squircle 배경을 이미 포함하고 있어
   별도 Container Background / Border / Shadow를 만들지 않는다.
   Card 안에 장소명·카테고리·지역 텍스트가 이미 있으므로 장식 요소로 처리한다.
   absolute overlay라 Card Width / Height / Image 비율에 영향을 주지 않는다.
   v2.0 : Action Button(찜 / 메뉴)처럼 보이지 않도록 좌측 상단 Category Badge
          위치로 고정한다. 별도 Label Text는 두지 않는다. */
.today-place-card__type-icon {
  position: absolute;
  top: 12px;   /* v2.0 : 우측 상단 → 좌측 상단. TODO: Token 승격 검토 */
  left: 12px;
  display: block;
  width: 35px; /* TODO: Token 승격 검토 */
  height: 35px;
}

.today-place-card__type-icon-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 실제 장소 사진. 원본 비율이 제각각(1.34 / 1.78 / 1.00 / 1.60)이라
   1:1 Wrapper 안에서 cover로 맞춘다. Card 높이는 Wrapper가 결정하므로 변하지 않는다. */
.today-place-card__image-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Asset이 없는 Card를 위한 Neutral Placeholder (기존 Category Icon 재사용).
   현재 4개 Card는 모두 실제 사진을 쓰지만, Filter 전환 시 사진이 없는 Card가
   나올 수 있어 Fallback 표현으로 남겨 둔다. */
.today-place-card__image--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--bg-brand-light);
}

.today-place-card__image-icon {
  width: 48px; /* TODO: Token 승격 검토 */
  height: 48px;
}

.today-place-card__name {
  overflow: hidden;
  color: var(--text-primary);
  font-size: var(--font-size-base); /* 16px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug); /* 1.4 */
  text-overflow: ellipsis;
  white-space: nowrap;
}

.today-place-card__meta {
  margin-top: 6px; /* Title → Meta. TODO: Token 승격 검토 */
  overflow: hidden;
  color: var(--text-tertiary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Description : 최대 2줄 */
.today-place-card__description {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-top: var(--space-3); /* Meta → Description 12px */
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-relaxed); /* 1.7 */
}

/* Tag : Popular / Recommend의 Location Pill과 동일한 표현.
   1개 Card당 최대 2개까지만 노출한다. */
.today-place-card__tag {
  display: inline-flex;
  align-items: center;
  height: 24px; /* TODO: Token 승격 검토 */
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background-color: var(--bg-subtle);
  color: var(--text-secondary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
}


/* ---------- Life Shortcut Panel ----------
   Divider는 두 번째 Item부터 왼쪽에 그리므로 4개 중 3개다. */

.today-shortcuts {
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg); /* 14px */
  background-color: var(--bg-subtle);
}

.today-shortcuts__title {
  color: var(--text-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
}

.today-shortcuts__item + .today-shortcuts__item::before {
  content: "";
  position: absolute;
  top: var(--space-2);
  bottom: var(--space-2);
  left: 0;
  width: 1px;
  background-color: var(--border-default);
}

.today-shortcuts__link {
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  transition:
    background-color var(--transition-fast),
    color var(--transition-fast);
}

/* Hover : 배경 + 텍스트/아이콘 강조만 */
.today-shortcuts__link:hover {
  background-color: var(--surface-default);
  color: var(--brand-secondary);
}

.today-shortcuts__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}

/* Icon : assets/icons/shortcut/*.svg 실제 Asset을 사용한다.
   Asset의 디자인을 그대로 살리기 위해 Placeholder 시절의
   Container Box(Border / White 배경 / Radius)를 제거했다.
   Colored Circle이나 Rounded Box 배경을 새로 만들지 않는다. */
.today-shortcuts__icon-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.today-shortcuts__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.today-shortcuts__arrow {
  flex-shrink: 0;
  color: var(--text-tertiary);
  font-size: var(--font-size-base);
  line-height: 1;
}

.today-shortcuts__link:hover .today-shortcuts__arrow {
  color: var(--brand-secondary);
}

/* ---------- Update Notice ----------
   갱신 주기를 알리는 보조 정보다. 강조 CTA가 아니므로
   Brand Blue / Navy를 쓰지 않고 본문보다 한 단계 약하게 표현한다.
   실제 Timer / API 갱신은 구현하지 않은 정적 문구다. */

.main-today-jeju__notice {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal); /* 1.5 */
}

/* TODO(icon): 임시 Unicode 문자(ⓘ)다. 전용 SVG 확보 시
               이 wrapper 내부만 <img>로 교체하면 구조 변경이 필요 없다. */
.main-today-jeju__notice-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 16px; /* TODO: Token 승격 검토 */
  height: 16px;
  font-size: 16px; /* TODO: Token 승격 검토 */
  line-height: 1;
}


/* ==================================================
   Main Event Components
   Event Section의 구조적 Layout(폭 / Header 배치 / Grid)은 layout.css 에 있다.
   여기서는 Filter / Card / Badge / Tag / App Panel / Recap 표현과 Typography만 다룬다.

   Section Panel(Border / Radius 18 / Background / Shadow)은
   위 "Main Section Panel" 공통 블록이 담당한다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Filter 40px·padding 20px·radius 10px / Region 128x40px
   - Card Image 6:5 / Info Icon 16px·gap 6px
   - Card Radius 14px / Badge 28px·radius 6px / Favorite 34px / Tag 28px
   - App Panel Radius 16px / Phone 175px / QR 68px / Store 128x38px
   - Recap Item 54px·radius 10px / Recap Icon 26px
================================================== */

/* ---------- Section Header ----------
   Title 32px / Subtitle 18px.
   Recommend / Popular / Today(28px / 14px)보다 한 단계 큰 위계를 사용해
   메인페이지 마지막 Discovery Section임을 드러내고 Icon 46px과 균형을 맞춘다. */

.main-event__title {
  color: var(--text-primary);
  font-size: var(--font-size-4xl); /* 32px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight); /* 1.3 */
}

.main-event__subtitle {
  margin-top: 6px; /* Title → Subtitle. TODO: Token 승격 검토 */
  color: var(--text-secondary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal); /* 1.5 */
}


/* ---------- 기간 Filter ----------
   Recommend Filter / Popular Period Button과 동일한 Interaction Language를 재사용한다.
   신규 Interaction을 만들지 않고 Horizontal Padding(18 → 20)만 다르다.
   실제 Filter Switching JS는 이번 단계에서 구현하지 않는다. */

.event-filter__item {
  height: 40px;
  padding: 0 var(--space-5); /* 20px */
  border: 1px solid var(--border-light);
  border-radius: 10px;
  background-color: var(--surface-default);
  color: var(--text-secondary);
  font-size: 15px; /* TODO: Token 승격 검토 */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.event-filter__item:hover {
  border-color: var(--brand-secondary);
  background-color: var(--bg-brand-light);
  color: var(--brand-secondary);
}

/* Active : Recommend Filter / Popular Period Button과 같은 Brand Blue(--brand-secondary) */
.event-filter__item.is-active,
.event-filter__item.is-active:hover {
  border-color: var(--brand-secondary);
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
  font-weight: var(--font-weight-semibold);
}

.event-filter__item:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 10px;
}


/* ---------- 지역 Selector ----------
   기간 Filter와 같은 Height / Radius를 사용하되 Active 상태가 아니라
   Select Control로 읽히도록 Border를 한 단계 강하게 둔다.
   TODO(js): Dropdown 목록 / 열림 상태는 구현하지 않는다. Visual Shell이다. */

.event-region {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 128px; /* TODO: Token 승격 검토 */
  height: 40px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: 10px;
  background-color: var(--surface-default);
  color: var(--text-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition:
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.event-region:hover {
  border-color: var(--brand-secondary);
  color: var(--brand-secondary);
}

.event-region:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 10px;
}

/* 임시 문자 Icon. 전용 Chevron SVG 확보 시 이 요소 내부만 교체한다. */
.event-region__arrow {
  flex-shrink: 0;
  color: var(--text-tertiary);
  font-size: var(--font-size-xs);
  line-height: 1;
}


/* ---------- Event Card ----------
   Recommend Card와 같은 Card Language(Border + 약한 Shadow Hover)를 사용한다.
   행사는 사진 자체가 탐색 동기이므로 Recommend(16:10)보다 이미지 비중을 키워 4:3을 쓴다.

   Card는 flex column이라 Main Row가 App Panel 높이만큼 stretch되어도
   Tag Row가 항상 Card 하단에 붙어 세 Card의 Bottom Line이 정확히 일치한다. */

/* v2 : v1의 display:flex(column)를 제거했다.
   Card를 Row 높이에 맞춰 stretch 시키지 않게 되면서 Body의 flex:1 /
   Tag의 margin-top:auto 가 모두 필요 없어졌고, flex item의 자동 최소 크기
   (min-height:auto) 때문에 세로 원본 이미지에서 media의 aspect-ratio가 무시되고
   이미지 고유 비율까지 늘어나는 문제가 있었다.
   Recommend Card와 동일한 Block Card로 되돌린다. */
.event-card {
  position: relative; /* 제목 Link의 ::after 기준점 */
  overflow: hidden;
  border: 1px solid var(--border-light);
  border-radius: 14px; /* TODO: Token 승격 검토 */
  background-color: var(--surface-default);
  transition:
    border-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

/* Hover : Border + 약한 Shadow만. transform / scale 사용 안 함 */
.event-card:hover {
  border-color: var(--border-default);
  box-shadow: var(--shadow-sm);
}

/* v2 : 행사는 사진 자체가 탐색 동기이므로 이미지 비중을 한 단계 더 키운다.
   4:3(213px) → 6:5(1.2:1). Card Content Width 284px 기준 약 284 x 236.67px.
   고정 px가 아니라 Ratio 기반이라 Card 폭이 바뀌어도 비율이 유지된다.
   background-color는 이미지 로드 전 빈 칸을 막는 Fallback이다.
   TODO: Card image ratio token 승격 검토

   v3 (App Panel Bottom Rhythm QA) : 6/5(1.2, 236.7px) → 10/9(1.111, 255.6px).
   좌측 Event Card Bottom이 우측 App Panel Bottom보다 눈에 띄게 위에서 끝나
   이미지 높이만 약 19px 키워 Bottom 격차를 줄인다. Text 영역/Card Width는 손대지 않는다. */
.event-card__media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 10 / 9;
  background-color: var(--bg-muted);
}

.event-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Status Badge : 색을 장식이 아니라 정보로 쓴다. 상태별로 의미를 고정한다.
     --soon    임박(D-n)   : 기존 Error Semantic Token (긴급/마감 임박)
     --period  기간(이번 주말): 기존 Warning Semantic Token
     --ongoing 진행중        : 기존 Success Semantic Token
   행사마다 임의 색을 만들지 않고 위 3계열만 사용한다. */
.event-card__badge {
  position: absolute;
  top: 14px;
  left: 14px;
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-sm); /* 6px */
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  white-space: nowrap;
}

.event-card__badge--soon {
  background-color: var(--error-bg);
  color: var(--error);
}

.event-card__badge--period {
  background-color: var(--warning-bg);
  color: var(--warning);
}

.event-card__badge--ongoing {
  background-color: var(--success-bg);
  color: var(--success);
}

/* 찜 : 카드 Link(<a>)의 형제 요소이며 z-index로 Link 위에 놓인다.
   따라서 Nested Interactive Element가 생기지 않는다.
   Recommend Card Favorite와 같은 표현을 그대로 재사용한다.
   TODO(js): 실제 찜 동작은 구현하지 않는다. */
.event-card__favorite {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border-light);
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.92);
  color: var(--text-secondary);
  transition: color var(--transition-fast);
}

.event-card__favorite:hover {
  color: var(--brand-secondary);
}

.event-card__favorite:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 50%;
}

/* 임시 문자 Icon wrapper. 추후 SVG로 교체해도 구조는 그대로다. */
.event-card__favorite-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
}


/* ---------- Event Card Content ---------- */

.event-card__body {
  padding: var(--space-4); /* 16px */
}

.event-card__type {
  color: var(--brand-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug); /* 1.4 */
}

/* 최대 2줄 clamp는 유지하되, v1의 min-height(항상 2줄 확보)는 제거했다.
   Mock 3건이 모두 1줄이라 Title 아래에 빈 줄이 그대로 남아
   Text Body가 늘어져 보이는 원인이었다. */
.event-card__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-top: 6px; /* Type → Title. TODO: Token 승격 검토 */
  color: var(--text-primary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-semibold);
  line-height: 1.4;
}

/* 제목 Link가 ::after 로 카드 전체를 덮어 카드 전체 클릭을 만든다 */
.event-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.event-card__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* v2 : Title → Info 16px → 12px. Text Body 수직 여백 압축. */
.event-card__info {
  margin-top: var(--space-3); /* Title → Event Info 12px */
}

.event-card__date,
.event-card__location {
  display: flex;
  align-items: center;
  gap: 6px; /* Icon ↔ Text. TODO: Token 승격 검토 */
  min-width: 0;
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal); /* 1.5 */
}

.event-card__date {
  color: var(--text-secondary);
}

.event-card__location {
  margin-top: var(--space-2); /* Date → Location 8px */
  color: var(--text-tertiary);
}

/* Date / Location 앞 Icon.
   Asset(assets/icons/events/*.svg)은 viewBox 62x62이고 자체 배경 Shape이 없어
   별도 Circle / Background Container를 만들지 않고 CSS로만 축소한다. */
.event-card__info-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 16px; /* TODO: Token 승격 검토 */
  height: 16px;
}

.event-card__info-icon img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Location은 1줄 Ellipsis. Icon이 잘리지 않도록 Text만 축소된다. */
.event-card__info-text {
  overflow: hidden;
  min-width: 0;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* v2 : v1의 margin-top: auto 를 제거했다.
   Card를 App Panel 높이에 맞춰 stretch 시키면서 Tag만 하단으로 밀려
   Location과 Tag 사이에 큰 빈 공간이 생겼기 때문이다.
   이제 Card는 Natural Height를 쓰고 Tag는 Location 바로 아래에 붙는다. */
.event-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px; /* TODO: Token 승격 검토 */
  margin-top: var(--space-3); /* Location → Tags 12px */
}

/* Recommend / Today의 Location Pill과 같은 Neutral 표현.
   행사마다 색을 다르게 쓰지 않는다. */
.event-card__tag {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-sm); /* 6px */
  background-color: var(--bg-subtle);
  color: var(--text-secondary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
}


/* ---------- App Panel ----------
   광고 배너가 아니라 Product Promotion Panel이다.

   금지: 강한 Saturation / Red·Orange CTA / 쿠폰 강조 / 강한 Shadow / Animation / Gradient
   허용: 아주 옅은 Blue 계열 단색 Surface

   Section 내부 Card(14px)와 조화를 이루도록 Radius는 16px을 사용한다.
   Section Panel(18px)에 맞추지 않는다. */

.event-app {
  padding: 24px 24px 20px 24px; /* 24px */
  border: 1px solid var(--border-light);
  border-radius: 16px; /* TODO: Token 승격 검토 */
  /* v3 : Gradient를 제거하고 단색 Surface로 교체. Saturation을 올리지 않고 Panel 구분만 만든다.
     #EEF5FE와 정확히 일치하는 Token이 없어 구현값을 사용한다.
       --bg-brand-light(#F3F7FD)   → 명확히 더 옅어 White Section Panel과 구분이 약함
       --surface-selected(#EEF4FF) → 색은 사실상 동일하나 "선택 상태" Semantic이라 재사용하지 않음
     TODO: App Panel surface token 승격 검토 */
  background-color: #EEF5FE;
}

.event-app__badge {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  background-color: var(--surface-default);
  color: var(--brand-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}

.event-app__headline {
  margin-top: var(--space-4); /* Badge → Headline 16px */
  color: var(--text-primary);
  font-size: var(--font-size-2xl); /* 24px */
  font-weight: var(--font-weight-bold);
  line-height: 1.25;
}

.event-app__description {
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal); /* 1.5 */
}

/* Feature Icon : 실제 Asset(assets/icons/app/*.svg)을 사용한다.
   Asset의 디자인을 그대로 살리기 위해 Placeholder 시절의 Circle 배경 / Ring을
   제거했다. (Today Shortcut Icon과 같은 처리)
   Asset이 자체 배경 Shape을 갖고 있지 않으므로 Container Background를 새로 만들지 않는다. */
.event-app__feature-icon {
  margin-top: 2px;
}

.event-app__feature-title {
  color: var(--text-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug); /* 1.4 */
}

.event-app__feature-desc {
  margin-top: 2px;
  color: var(--text-tertiary);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-snug); /* 1.4 */
  /* v4 : Phone 확대로 좌측 Column이 146px로 좁아져 가장 긴 설명 1건이 2줄이 된다.
     음절 중간("정보 제/공")이 아니라 어절 단위로 꺾이도록 keep-all을 사용한다. */
  word-break: keep-all;
}

/* Phone Mockup : 실제 Asset(assets/images/app/app-phone-mockup.png, 887x1774 = 1:2).
   Asset 자체가 단말 Frame과 앱 화면을 모두 포함하므로
   Placeholder 시절의 가짜 Frame(padding / Border / Radius / Notch / Screen)은 제거했다.
   Container Background를 새로 만들지 않는다.

   v4 : Phone을 핵심 Product Visual로 키우면서 absolute + max-height 방식을 버리고
        In-flow width:100% / height:auto 로 전환했다. Wrapper Column 폭이
        표시 폭을 결정하고 고유 비율(1:2)에 따라 표시 높이가 Panel을 늘린다.
        (v3까지는 Cell 높이에 맞춰 축소되어 Phone이 장식 수준으로 작았다)
   crop / resize / 비율 왜곡 없이 CSS 표시 크기만 바꾼다.

   Asset Box에 포함된 상하 투명 여백을 음수 margin으로 상쇄한다.
   (Google Play Badge와 동일한 투명 여백 보정 기법)
   실측 alpha bounding box : 상단 92px / 하단 85px (원본 1774px 기준)

   v6 (App Panel 재배치 QA) : Phone Column 210 → 220px. 배치 구조(Intro~Feature 옆
        row 1/span3)가 바뀌어도 Asset 자체의 투명 여백은 동일하므로 보정 로직은 유지하고
        220px 표시 배율로 재계산했다. 이 보정이 없으면 Phone의 투명 상하 42px이
        Layout Box에 그대로 남아 Phone Top이 Intro Top보다 처지고 Panel Bottom도
        그만큼 밀린다 — 새 구조에서도 여전히 필요한 보정이라 유지를 선택했다.
        220px 표시 배율(220 / 887 = 0.24803, 세로도 동일 배율)로 환산하면
          상단 92 x 0.24803 = 22.82px / 하단 85 x 0.24803 = 21.08px
        좌우 투명 여백(약 10 / 13px)은 Feature Column ↔ Phone 시각 여백을 겸하므로
        보정하지 않는다. */
.event-app__phone-image {
  display: block;
  width: 100%;
  height: auto;
  margin: -22.82px 0 -21.08px;
}

/* QR : 실제 Asset(assets/images/app/app-download-qr.png, 460x448).
   스캔 가능성이 중요하므로 opacity / filter / blur를 적용하지 않고
   비율이 정확히 유지되도록 contain을 사용한다.

   v4 : #EEF5FE Panel 위에 QR을 바로 올리면 흑백 패턴과 배경 경계가 거칠어
        QR 전용 White Rounded Surface(__qr-box)로 받친다.
        Border / Shadow 없이 White + Radius만 사용한다.
        (실측상 #EEF5FE와 White의 경계가 충분히 구분된다) */
.event-app__qr-box {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 84px;  /* QR 68 + Padding 8 x 2. TODO: Token 승격 검토 */
  height: 84px;
  border-radius: var(--radius-md); /* 10px. 권장값 12px과 2px 차이라 Token을 우선 재사용 */
  background-color: var(--surface-default);
}

.event-app__qr-code {
  flex-shrink: 0;
  width: 68px; /* TODO: Token 승격 검토 */
  height: 68px;
  object-fit: contain;
}

.event-app__qr-text {
  color: var(--text-secondary);
  font-size: var(--font-size-base); /* 16px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
}

/* Store CTA : 공식 App Store / Google Play Badge Asset을 그대로 사용한다.
   Badge Image 자체가 CTA Visual이므로 Placeholder 시절의
   Border / Radius / Background / Text Shell / 가짜 Logo Square를 모두 제거했다.
   별도 Icon / 중복 Text / 대형 "앱 다운로드" Button을 추가하지 않는다.
   QR + Store 두 경로 자체가 Conversion CTA다. */
.event-app__store {
  transition: opacity var(--transition-fast);
}

.event-app__store:hover {
  opacity: 0.82;
}

.event-app__store:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Badge는 원본 비율이 서로 다르므로 폭을 억지로 맞추지 않고
   height + width:auto 로 비율을 유지한다.

   단 두 Asset의 투명 여백이 달라 같은 height를 줘도 검은 Badge 자체의
   시각 높이가 어긋난다. (실측 alpha bounding box 기준)
     app-store-download.png  540x167 / 투명 여백 0        → 시각 높이 = box 높이의 100%
     google-play-download.png 629x228 / 상하 여백 각 27px → 시각 높이 = box 높이의 76.32%
   따라서 App Store는 52px, Google Play는 52 / 0.7632 = 68px로 두어
   두 Badge의 "보이는" 높이를 52px로 일치시킨다.
   이미지는 crop / resize 하지 않는다. */
.event-app__store-image {
  display: block;
  width: auto;
  height: 52px; /* TODO: Token 승격 검토 */
}

/* Google Play Badge : Box를 키운 뒤 투명 여백만큼 음수 margin으로 상쇄해
   Link의 Layout Box가 실제 보이는 Badge와 일치하게 만든다.
   (68 / 228 = 0.2982 배율 → 상하 27px = 8.05px, 좌 30px = 8.95px, 우 27px = 8.05px)
   v4 : Badge 38 → 52px 확대 시 갱신되지 않았던 보정값을 현재 배율로 재계산. */
.event-app__store-image--play {
  height: 68px;
  margin: -8.05px -8.05px -8.05px -8.95px;
}


/* ---------- Category Recap ----------
   Today Section의 Life Shortcut Bar와 같은 Utility Bar 표현을 사용해
   상단 Category Section(큰 Icon + Subcategory)의 복제처럼 보이지 않게 한다.
   Item은 Border + Radius만 가지며 Shadow / transform을 사용하지 않는다. */

.event-recap {
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg); /* 14px */
  background-color: var(--bg-subtle);
}

/* Section Header(28px)보다 확실히 작은 Utility Bar Label 위계 */
.event-recap__title {
  color: var(--text-primary);
  font-size: var(--font-size-base); /* 16px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug); /* 1.4 */
}

.event-recap__link {
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md); /* 10px */
  background-color: var(--surface-default);
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  transition:
    border-color var(--transition-fast),
    color var(--transition-fast);
}

/* Hover는 매우 약하게. Shadow / transform 없음 */
.event-recap__link:hover {
  border-color: var(--brand-secondary);
  color: var(--brand-secondary);
}

.event-recap__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}

/* Recap 전용 Asset(assets/icons/category-recap/*.svg, viewBox 62x62)을 사용한다.
   상단 Category Card(52px, Circle 배경 포함 Asset)와 달리
   배경 Shape이 없는 Line Icon이라 Compact Item 기준으로 축소만 한다. */
.event-recap__icon {
  display: block;
  flex-shrink: 0;
  width: 26px; /* TODO: Token 승격 검토 */
  height: 26px;
  object-fit: contain;
}

.event-recap__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ==================================================
   Main Utility Components
   Utility Section의 구조적 Layout(폭 / Grid / Padding)은 layout.css 에 있다.
   여기서는 Divider / Typography / CTA Panel 표현만 다룬다.

   이 Section은 Interactive Card가 아니다.
     - Section 자체에 Hover / Transform / Animation 없음
     - Notice / Customer Block에 별도 Background / Shadow 없음
     - Notice ↔ Customer 구분은 1px Divider 하나로만 만든다

   강조 위계:
     Notice / Customer = 담백한 정보 Group (아주 연한 Neutral Background)
     CTA               = 이 Section에서 유일한 강조 Panel (Navy Fill)
   Information Group은 Background 한 겹만 쓰고 Border / Shadow를 쓰지 않아
   Outer Section Panel과 이중 Box가 되지 않게 한다.
   CTA도 Event App Panel보다 커지지 않도록 408 x 150px로 제한한다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Block Title 18px / CTA Radius 14px / CTA Button 38px·radius 8px
================================================== */

/* ---------- Notice / Customer 공통 Block Title ----------
   Section 전체 H2(28px)가 없는 Section이므로 Block Title이 이 Section의
   가장 큰 Typography다. Recommend / Event의 Section Title(28px)보다
   명확히 작게 두어 마지막 Utility 영역이 콘텐츠 Section처럼 보이지 않게 한다. */

.utility-notice__heading,
.utility-customer__heading {
  color: var(--text-primary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-snug); /* 1.4 */
}


/* ---------- Information Group ----------
   Notice + Customer를 "사이트 정보 / 고객지원" 하나의 Group으로 읽히게 한다.
   Layout(910px / 430 + 480 / 상하 Padding)은 layout.css 에 있다.

   v3 : Outer Section Panel이 사라지면서 이 Wrapper가 Page 배경(White) 위에
        직접 놓이는 실제 Panel이 되었다. 이전에는 Outer Border와 겹쳐 이중 Box가
        되는 것을 피하려고 Border를 뺐지만, 이제 그 이유가 없어졌고
        오히려 Border가 없으면 CTA와 대등한 Panel로 읽히지 않는다.
        --border-light + --bg-subtle 조합은 .today-shortcuts 와 동일한 선례다.

   강도 (가장 중요):
     Border는 가장 약한 --border-light 한 겹, Shadow는 쓰지 않는다.
     위계는 반드시  CTA(Navy Fill) > Information Panel(연한 Neutral)  이다.
     Panel에 Brand 계열 Fill / 진한 Border / Shadow를 쓰지 않는다.

   Radius : CTA와 같은 --radius-lg(14px). 두 형제 Panel의 Radius를 일치시킨다.

   Width : Border 1 x 2 + Padding 20 x 2 를 포함해 정확히 910px이다.
           (box-sizing: border-box) */

.utility-info {
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg); /* 14px */
  background-color: var(--bg-page);
}


/* ---------- Notice ---------- */

/* Button 형태로 만들지 않는다. Recommend "전체보기"와 같은 Text Link 표현이다. */
.utility-notice__more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition: color var(--transition-fast);
}

.utility-notice__more:hover {
  color: var(--brand-secondary);
}

.utility-notice__more-arrow {
  font-size: var(--font-size-md);
  line-height: 1;
}

.utility-notice__dot {
  background-color: var(--brand-secondary);
}

/* 공지 제목은 길이가 일정하지 않으므로 한 줄로 자른다. */
.utility-notice__title {
  overflow: hidden;
  color: var(--text-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color var(--transition-fast);
}

.utility-notice__link:hover .utility-notice__title {
  color: var(--brand-secondary);
}

.utility-notice__date {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}


/* ---------- Customer Center ----------
   Divider : Information Group 내부에서 Notice와 Customer를 나누는 유일한 요소다.
   Notice / Customer 각각에 Background나 Shadow를 추가해 나누지 않는다.

   v2 : Group 배경이 --bg-subtle(#F7F9FC)로 바뀌면서
        기존 --border-light(#EEF1F5)는 배경과 거의 같은 명도라 Divider가 사라진다.
        --border-default(#E2E7EE)로 한 단계만 올린다.
        (연한 Neutral 배경 위 세로 Divider에 --border-default 를 쓰는 처리는
         .today-shortcuts__item::before 와 동일한 선례다) */

.utility-customer {
  border-left: 1px solid var(--border-default);
}

/* Shortcut : 강한 Filled Button으로 만들지 않는다.
   Icon Asset이 이미 원형 배경을 갖고 있으므로 Hover에서도
   Background Box를 새로 만들지 않고 Label Color만 강조한다. */
.utility-customer__label {
  overflow: hidden;
  max-width: 100%;
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color var(--transition-fast);
}

.utility-customer__link:hover .utility-customer__label {
  color: var(--brand-secondary);
}

/* 전화 정보 : Footer 고객센터와 같은 값을 사용한다. (index.html Footer 기준) */
.utility-customer__phone-label {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
}

.utility-customer__phone-number {
  color: var(--text-primary);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

.utility-customer__phone-hours {
  color: var(--text-secondary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}


/* ---------- 매물 등록 CTA ----------
   Section에서 유일하게 색을 채우는 Panel이다.
   Brand Identity Color(--brand-primary)를 Panel 배경으로 사용하고
   Button은 그 위의 White Surface로 대비를 만든다.
   떠 있는 요소가 아니므로 Shadow / Hover Transform 은 두지 않는다. */

.utility-cta {
  border-radius: var(--radius-lg); /* 14px */
  background-color: var(--brand-primary);
}

.utility-cta__copy {
  color: var(--text-inverse);
  font-size: var(--font-size-lg); /* 18px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-snug); /* 1.4 */
}

/* Navy Panel 위 White Button. 새 Color Token을 만들지 않고
   기존 Surface / Brand Token 조합만 사용한다. */
.utility-cta__button {
  border-radius: 8px; /* TODO: Token 승격 검토 */
  background-color: var(--surface-default);
  color: var(--brand-primary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  transition: background-color var(--transition-fast);
}

.utility-cta__button:hover {
  background-color: var(--surface-hover);
}


/* ---------- Utility Focus 상태 ----------
   Notice Link / Customer Shortcut / CTA Button 모두 :focus-visible 을 유지한다. */

.utility-notice__more:focus-visible,
.utility-notice__link:focus-visible,
.utility-customer__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Navy Panel 위에서는 Focus Ring이 묻히므로 White Ring을 사용한다. */
.utility-cta__button:focus-visible {
  outline: 2px solid var(--surface-default);
  outline-offset: 3px;
}


/* ==================================================
   Footer Components
   Footer의 구조적 Layout은 layout.css 에 있다.

   Dark Background 위의 White 계열 텍스트는 새 Color Token을 만들지 않고
   rgba(255,255,255,*) 구현값을 사용한다. 사용 단계는 아래 5개로 제한한다.
     1.00 : Footer Logo / Policy Hover / Phone
     0.90 : 개인정보처리방침 (강조 Policy)
     0.70 : Policy 기본 / 고객센터 Label
     0.58 : 회사정보 / 고객센터 운영정보
     0.40 : Copyright
     0.15 : Policy Separator   0.10 : Divider

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Logo 표시 150px / Policy 15px / Company 13px / Copyright 12px
   - Phone 26px / Label→Phone 6px / CTA 200x44 / CTA Radius 8px
================================================== */

/* ---------- Footer Logo ----------
   Asset: assets/images/common/logo-footer-white.png (원본 160x30, RGBA)
   원본 White Asset을 그대로 사용하며 CSS filter로 색상을 변경하지 않는다.
   고정 height를 주지 않고 height:auto로 원본 종횡비를 유지한다. */

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

.footer__logo-image {
  display: block;
  width: 150px; /* Header Logo(160px)보다 한 단계 작게. TODO: 화면 검토 후 Token 승격 검토 */
  height: auto;
  max-width: 100%;
}


/* ---------- Footer Policy ---------- */

.footer-policy {
  margin-top: var(--space-6); /* Logo → Policy 24px */
}

.footer-policy__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-6); /* Link 12px | Separator | 12px Link */
}

/* Separator : HTML 문자 "|"를 쓰지 않고 pseudo-element로 처리한다 */
.footer-policy__item {
  position: relative;
}

.footer-policy__item + .footer-policy__item::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(var(--space-6) / -2);
  width: 1px;
  height: 12px;
  background-color: rgba(255, 255, 255, 0.15);
  transform: translateY(-50%);
}

.footer-policy__link {
  color: rgba(255, 255, 255, 0.70);
  font-size: 15px; /* Token에 15px가 없어 구현값 유지. TODO: 화면 검토 후 Token 승격 검토 */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  transition: color var(--transition-fast);
}

.footer-policy__link:hover {
  color: #FFFFFF;
}

/* 개인정보처리방침만 한 단계 강조 */
.footer-policy__link--strong {
  color: rgba(255, 255, 255, 0.90);
  font-weight: var(--font-weight-semibold);
}


/* ---------- Footer Divider ----------
   Footer의 장식 요소가 되지 않도록 매우 약하게 표현한다. */

.footer__divider {
  width: min(760px, 100%); /* TODO: 화면 검토 후 Token 승격 검토 */
  height: 1px;
  margin-top: var(--space-6); /* Policy → Divider 24px */
  background-color: rgba(255, 255, 255, 0.10);
}


/* ---------- Footer Company Information ---------- */

.footer-company {
  margin-top: var(--space-5); /* Divider → Company 20px */
  font-style: normal; /* address 기본 italic 해제 */
}

.footer-company__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4); /* 항목 8px | Separator | 8px 항목 */
}

.footer-company__item {
  position: relative;
  color: rgba(255, 255, 255, 0.58);
  font-size: 13px; /* TODO: 화면 검토 후 Token 승격 검토 */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-relaxed); /* 1.7 */
}

/* 구분자도 HTML 문자 대신 pseudo-element로 처리한다 */
.footer-company__item + .footer-company__item::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(var(--space-4) / -2);
  width: 1px;
  height: 11px;
  background-color: rgba(255, 255, 255, 0.15);
  transform: translateY(-50%);
}


/* ---------- Footer Copyright ----------
   Footer에서 가장 낮은 Typography 위계 */

.footer__copyright {
  margin-top: var(--space-3); /* Company → Copyright 12px */
  color: rgba(255, 255, 255, 0.40);
  font-size: var(--font-size-xs); /* 12px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}


/* ---------- Footer Customer Center ---------- */

.footer-customer__label {
  color: rgba(255, 255, 255, 0.70);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
}

.footer-customer__phone {
  margin-top: 6px; /* Label → Phone. TODO: 화면 검토 후 Token 승격 검토 */
  color: #FFFFFF;
  font-size: 26px; /* TODO: 화면 검토 후 Token 승격 검토 */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight); /* 1.3 */
}

.footer-customer__detail {
  margin-top: var(--space-3); /* Phone → Detail 12px */
  color: rgba(255, 255, 255, 0.58);
  font-size: 13px; /* TODO: 화면 검토 후 Token 승격 검토 */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-relaxed); /* 1.7 */
}

/* 빠른고객상담 CTA : Shadow / Scale / Translate 사용 안 함 */
.footer-customer__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 200px;  /* TODO: 화면 검토 후 Token 승격 검토 */
  height: 44px;
  margin-top: var(--space-5); /* Detail → CTA 20px */
  border-radius: 8px; /* 초기 디자인 기준값. Pill 사용 금지 */
  background-color: var(--brand-secondary);
  color: var(--text-inverse);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-normal);
  white-space: nowrap;
  transition: background-color var(--transition-fast);
}

.footer-customer__cta:hover {
  background-color: var(--brand-interaction);
  color: var(--text-inverse);
}


/* ---------- Footer Focus 상태 ---------- */

.footer-policy__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.footer-customer__cta:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: 8px; /* Button 자체 Radius와 일치 */
}


/* ==================================================
   Common Breadcrumb
   Source Fragment: components/breadcrumb.html

   Sub Page에서 "현재 위치"를 알리는 공통 Navigation이다.
   특정 Domain 전용이 아니므로 부동산 / 중고차 / 구인구직 등에서
   동일 마크업 + 동일 Visual Language로 그대로 재사용한다.

   - Page Title보다 위계가 낮아야 하므로 Caption(13px) 크기를 쓴다.
   - 마지막 Item은 Link가 아니라 Text이며 aria-current="page" 를 갖는다.
   - Separator는 Markup(문자)이 아니라 CSS ::before 로 만든다.
     Screen Reader가 "슬래시"를 읽지 않게 하기 위함이다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Separator Gap 8px
================================================== */

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.breadcrumb__item {
  display: inline-flex;
  align-items: center;
  color: var(--text-tertiary);
  font-size: var(--font-size-sm); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
}

/* Separator : 첫 Item 앞에는 생성되지 않는다 */
.breadcrumb__item + .breadcrumb__item::before {
  content: "/";
  margin: 0 var(--space-2);
  color: var(--border-strong);
}

.breadcrumb__link {
  color: var(--text-tertiary);
  transition: color var(--transition-fast);
}

.breadcrumb__link:hover {
  color: var(--brand-secondary);
}

.breadcrumb__link:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* 현재 페이지 : Link가 아니므로 Hover가 없고 한 단계 진하게 둔다 */
.breadcrumb__current {
  color: var(--text-secondary);
  font-weight: var(--font-weight-medium);
}


/* ==================================================
   Common Pagination
   Source Fragment: components/pagination.html

   목록 화면 공통 Paging이다. 부동산 / 중고차 / 구인구직 / 공지사항 등
   모든 목록에서 동일 마크업으로 재사용하며 Domain별로 복제하지 않는다.

   - 목록 하단 가운데 정렬.
   - Prev / Next 는 첫 / 마지막 페이지에서 disabled 상태를 갖는다.
     (Link가 아니라 button 으로 두어야 disabled 표현이 가능하다)
   - 현재 페이지는 .is-active + aria-current="page".

   Shadow를 쓰지 않는다. 떠 있는 요소가 아니라 목록의 끝을 알리는
   Inline Control이기 때문이다.

   아래 수치는 실제 화면 검토 전 초기 구현값이며 Token으로 승격하지 않았다.
   - Cell 36px / Gap 4px / Radius 8px
================================================== */

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.pagination__list {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.pagination__link,
.pagination__nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px; /* TODO: Token 승격 검토 */
  height: 36px;
  padding: 0 var(--space-2);
  border-radius: 8px; /* TODO: Token 승격 검토 */
  color: var(--text-secondary);
  font-size: var(--font-size-md); /* 14px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.pagination__link:hover,
.pagination__nav:not(:disabled):hover {
  background-color: var(--surface-hover);
  color: var(--brand-secondary);
}

/* 현재 페이지 : Filled가 아니라 Brand Text + 연한 Surface.
   목록 Card보다 강해지지 않게 한다. */
.pagination__link.is-active,
.pagination__link.is-active:hover {
  background-color: var(--surface-selected);
  color: var(--brand-secondary);
  font-weight: var(--font-weight-bold);
}

.pagination__nav {
  border: 1px solid var(--border-default);
  color: var(--text-tertiary);
}

.pagination__nav:disabled {
  border-color: var(--border-light);
  color: var(--text-disabled);
  background-color: transparent;
}

.pagination__link:focus-visible,
.pagination__nav:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}
