* { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* Color */
  --teal: #3fb6a8;
  --teal-dark: #2a8f84;
  --blue: #4f8bf0;
  --blue-light: #eaf1ff;
  --red: #e0322f;
  --yellow: #e0a82f;
  --green: #2fae62;
  --gray-bg: #f4f5f6;
  --text: #1b1c1e;
  --text-dim: #7a7d82;
  --border: #e8e9eb;

  /* Typography */
  --font-sans: "Pretendard", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;

  --fs-title: 28px;        /* 큰 타이틀 (응암역, 모달 헤더) */
  --fw-title: 800;

  --fs-heading: 19px;      /* 섹션 제목 */
  --fw-heading: 800;

  --fs-meta: 13.5px;       /* 부가 설명 텍스트 */
  --fw-meta: 400;

  --fs-button: 13px;       /* 필/버튼 라벨 */
  --fw-button: 600;

  --fs-overlay-label: 10px;   /* 이미지 카드 오버레이 - 라벨 */
  --fw-overlay-label: 500;
  --fs-overlay-value: 13px;   /* 이미지 카드 오버레이 - 값 */
  --fw-overlay-value: 800;

  --fs-tab: 15px;
  --fw-tab: 500;
  --fw-tab-active: 700;

  /* Shape */
  --radius-pill: 20px;
  --radius-card: 16px;
  --pill-pad-y: 7px;
  --pill-pad-x: 14px;

  /* Motion */
  --transition-fast: 140ms ease;
}

html, body {
  background: #2b2d31;
  color: var(--text);
  font-family: var(--font-sans);
  letter-spacing: -0.035em;
  min-height: 100vh;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 24px 12px;
}

/* 앱 컨테이너: 430px 고정, PC에서는 중앙 정렬 */
.phone {
  width: 100%;
  max-width: 430px;
  background: #fff;
  border-radius: 28px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,.45);
  display: flex;
  flex-direction: column;
  /* 안드로이드 상태바/내비바가 .phone 기준 position:absolute로 붙을 수 있는
     containing block이 되어준다(아래 안드로이드 상태바 섹션 설명 참고). */
  position: relative;
  /* admin CMS 미리보기 iframe(.preview-frame-wrap)과 동일한 844px 고정 높이 -
     .content의 flex:1 + overflow-y:auto가 실제로 작동하려면(내용만 내부 스크롤)
     .phone 자체가 min-height가 아니라 "제한된" 높이를 가져야 한다. 브라우저 창이
     844px보다 작으면 max-height로 화면에 맞게 줄어든다. */
  height: 844px;
  max-height: calc(100vh - 48px);
}

/* ---------- 안드로이드 상태바/내비게이션 바 (실제 폰처럼 보이게 하는 장식용 UI) ----------
 * layout.androidChrome.enabled 로 켜고 끈다(기본 꺼짐). script.js가 .phone에
 * has-android-chrome 클래스를 붙였을 때만 보인다.
 * 데스크톱(기본, 480px 초과)에서는 .phone이 844px 고정 높이 박스라 더 이상
 * 뷰포트보다 커지지 않는다 - 그래서 .phone 기준 position:absolute로 붙이면
 * .phone이 화면 중앙으로 이동해도(body의 align-items:center) 항상 같이 붙어
 * 다닌다. 모바일(480px 이하)에서는 .phone이 다시 내용만큼 늘어나며 문서
 * 전체가 스크롤되므로, 그 구간만 미디어 쿼리로 뷰포트 기준 position:fixed로
 * 되돌린다(맨 아래 모바일 브레이크포인트 참고). */
.android-statusbar, .android-navbar { display: none; }
.phone.has-android-chrome .android-statusbar,
.phone.has-android-chrome .android-navbar { display: flex; }
/* .phone에 padding-top을 주면 topbar/tabs의 "제자리(스크롤 안 했을 때 위치)" 자체가
 * 상태바 높이만큼 자연스럽게 밀린다 - sticky는 그 밀린 제자리를 그대로 유지해주기만
 * 하면 되므로 topbar/tabs의 top 값(0px, 64px)은 원래 값 그대로 둔다(실험해보니 여기에
 * 상태바 높이를 더해서 top을 다시 늘리면 sticky가 그만큼 한 번 더 밀려서 이중으로
 * 내려가 버린다 - .tabs가 .topbar 밑에 겹쳐 보이거나 .content 제목이 .tabs 밑에
 * 가려지는 원인이었다). padding-top 하나로만 상태바 자리를 확보한다. */
.phone.has-android-chrome { padding-top: var(--android-statusbar-h, 32px); }
.phone.has-android-chrome .content { padding-bottom: var(--android-navbar-h, 52px); }

.android-statusbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 30;
  height: var(--android-statusbar-h, 32px);
  border-radius: 28px 28px 0 0;
  align-items: center;
  justify-content: space-between;
  padding: 0 18px;
  background: #fff;
  color: #101114;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.android-statusbar-icons { display: flex; align-items: center; gap: 6px; }
.android-statusbar-network { font-size: 11px; font-weight: 700; line-height: 1; }
.android-statusbar-battery-pct { font-size: 12px; font-weight: 600; line-height: 1; }
.android-status-icon { width: 16px; height: 12px; color: #101114; flex-shrink: 0; }
.android-status-icon.android-battery { width: 21px; height: 12px; }
.android-signal-icon .signal-bar { opacity: 1; }
.android-signal-icon .signal-slash { opacity: 0; }
.android-signal-icon.signal-disconnected .signal-bar { opacity: 0.3; }
.android-signal-icon.signal-disconnected .signal-slash { opacity: 1; }
.android-battery.battery-low { color: #d93025; }

.android-navbar {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  z-index: 30;
  height: var(--android-navbar-h, 52px);
  border-radius: 0 0 28px 28px;
  align-items: center;
  justify-content: space-around;
  background: #fff;
}
.android-nav-icon svg {
  width: 20px; height: 20px;
  fill: none;
  stroke: #3c3c3c;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- UI icon system ----------
   일반 UI 아이콘(뒤로가기/닫기/별/화살표/눈/스피커 등)만 여기 대상.
   .ui-icon 클래스 하나로 stroke-width, 크기, linecap/linejoin, 색을 통일한다.
   공포 전용 아이콘과 반응 아이콘은 assets/icons 의 이미지 파일을 쓴다. */
.ui-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--red);
}

/* 상태/기관/콘텐츠/반응/장소/경고 아이콘: assets/icons/png/{category} 이미지(icon-manifest.json 참고).
   자체 색이 고정된 래스터 아이콘이라, 어두운 pill 배경(active) 위에서는
   .cat-icon--on-dark 로 흰색 반전 필터를 적용해 대비를 확보한다. */
.cat-icon {
  display: inline-block;
  flex-shrink: 0;
  object-fit: contain;
}
.cat-icon--pheno { width: calc(24px * var(--pheno-icon-scale, 1)); height: calc(24px * var(--pheno-icon-scale, 1)); }
.cat-icon--info { width: 20px; height: 20px; }
.cat-icon--count { width: 15px; height: 15px; }
.cat-icon--tag { width: 14px; height: 14px; }
.cat-icon--add { width: 16px; height: 16px; }
.cat-icon--reaction { width: 18px; height: 18px; }

/* ---------- Top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 12px;
  position: sticky;
  top: 0;
  background: #fff;
  z-index: 20;
}
.place-name {
  font-size: 19px;
  font-weight: 700;
  flex: 1;
  text-align: left;
  margin-left: 4px;
}
.topbar-actions { display: flex; gap: 4px; }
.icon-btn {
  width: 36px;
  height: 36px;
  border: none;
  background: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 50%;
  transition: background var(--transition-fast);
}
.icon-btn:hover { background: var(--gray-bg); }
.icon-btn:disabled { opacity: .4; cursor: wait; }
.icon-btn .ui-icon { width: 21px; height: 21px; }
#starBtn.active .ui-icon { fill: var(--red); }

/* ---------- Tabs (active class 전환, 페이지 이동 없음) ---------- */
.tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 64px;
  background: #fff;
  z-index: 19;
}
.tab {
  flex: 1;
  padding: 12px 0 10px;
  border: none;
  background: none;
  font-size: var(--fs-tab);
  color: var(--text-dim);
  cursor: pointer;
  position: relative;
  font-weight: var(--fw-tab);
  transition: color var(--transition-fast);
}
.tab.active {
  color: var(--text);
  font-weight: var(--fw-tab-active);
}
.tab.active::after {
  content: "";
  position: absolute;
  bottom: -1px;
  left: 30%;
  right: 30%;
  height: 2px;
  background: var(--text);
}

/* ---------- Content ---------- */
.content {
  flex: 1;
  overflow-y: auto;
  background: #fff;
}
.tab-panel { display: none; }
.tab-panel.active { display: block; }
.content.hub-mode .tab-panel.active { display: none; }
.phone.hub-active .tabs { display: none; }

/* ---------- 지역 리뷰 허브 (뒤로가기 도착 화면) ---------- */
.hub-view[hidden] { display: none; }
.hub-view { padding: 16px; }
.hub-search-row {
  position: relative;
  margin-bottom: 14px;
}
.hub-search-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--text-dim);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  pointer-events: none;
}
.hub-search-input {
  width: 100%;
  height: 46px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--gray-bg);
  padding: 0 14px 0 42px;
  font-size: 14px;
  color: var(--text);
}
.hub-search-input::placeholder { color: var(--text-dim); }
.hub-category-chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin-bottom: 16px;
  scrollbar-width: none;
}
.hub-category-chips::-webkit-scrollbar { display: none; }
.hub-chip {
  flex-shrink: 0;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}
.hub-chip.active {
  background: var(--red, #e0322f);
  border-color: var(--red, #e0322f);
  color: #fff;
}
.hub-chip.is-locked { color: var(--text-dim); cursor: default; }
.hub-list-empty {
  padding: 24px 0;
  text-align: center;
  color: var(--text-dim);
  font-size: 14px;
}
.hub-map {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--border);
  margin-bottom: 20px;
}
.hub-map-real { width: 100%; height: 280px; background: var(--gray-bg); }
/* OpenStreetMap 무료 타일 이용 조건상 저작권 표시는 완전히 지울 수 없어서,
   최대한 작고 눈에 덜 띄게만 줄인다. */
.hub-map-real .leaflet-control-attribution {
  font-size: 9px;
  padding: 0 4px;
  background: rgba(255,255,255,.6);
  line-height: 1.4;
}
/* +/- 확대·축소 버튼 - 일단 숨김 처리(요청 시 이 규칙만 지우면 다시 보인다).
   지도 자체의 스크롤/핀치 확대 기능은 그대로 동작한다. */
.hub-map-real .leaflet-control-zoom { display: none; }
/* Leaflet 마커(L.divIcon)의 내용물 - 위치 자체는 Leaflet이 iconAnchor로 잡아주므로
   여기서는 position/transform 없이 순수 표시 스타일만 담당한다. */
.hub-pin {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
}
.hub-pin-dot {
  width: 26px; height: 26px;
  border-radius: 50% 50% 50% 0;
  background: var(--red, #e02020);
  transform: rotate(-45deg);
  box-shadow: 0 2px 6px rgba(0,0,0,.25);
  margin-bottom: 4px;
  position: relative;
}
.hub-pin-dot::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: #fff;
}
.hub-pin-label {
  background: #fff;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  box-shadow: 0 1px 4px rgba(0,0,0,.2);
  white-space: nowrap;
}
/* Leaflet의 L.divIcon 기본 스타일(흰 배경+테두리 박스)을 지우고 우리 핀 모양만 보이게 한다. */
.hub-leaflet-marker { background: none; border: none; }
.hub-list-title { font-size: var(--fs-title); font-weight: var(--fw-title); margin: 0 0 10px; }
.hub-list-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.hub-list-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 14px;
  cursor: pointer;
  background: #fff;
  transition: background var(--transition-fast);
}
.hub-list-item:hover { background: var(--gray-bg); }
.hub-list-thumb { width: 56px; height: 56px; border-radius: 10px; object-fit: cover; flex-shrink: 0; background: var(--gray-bg); }
.hub-list-body { flex: 1; min-width: 0; }
.hub-list-name { font-size: 16px; font-weight: 700; margin: 0 0 2px; }
.hub-list-tags { font-size: 13px; color: var(--text-dim); margin: 0 0 6px; }
.hub-list-count { display: inline-block; font-size: 12px; color: var(--text-dim); background: var(--gray-bg); border-radius: 999px; padding: 3px 9px; }
.hub-list-chevron { width: 18px; height: 18px; color: var(--text-dim); flex-shrink: 0; }

.home-title {
  padding: 18px 16px 0;
  font-size: var(--fs-title);
  font-weight: var(--fw-title);
}

.subtitle-row {
  padding: 8px 16px 4px;
  color: var(--text-dim);
  font-size: var(--fs-meta);
  font-weight: var(--fw-meta);
}

.badge-row {
  display: flex;
  gap: 8px;
  padding: 10px 16px 14px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.badge-row::-webkit-scrollbar { display: none; }
.badge {
  padding: var(--pill-pad-y) var(--pill-pad-x);
  border-radius: var(--radius-pill);
  font-size: var(--fs-button);
  font-weight: var(--fw-button);
  white-space: nowrap;
  flex-shrink: 0;
}
.badge-light { background: var(--blue-light); color: var(--blue); }
.badge-solid { background: var(--blue); color: #fff; }
.badge-outline { border: 1px solid var(--border); color: var(--text); display: flex; align-items: center; gap: 6px; }
.stars { display: inline-flex; align-items: center; gap: 1px; }
.icon-star { width: 13px; height: 13px; fill: var(--red); stroke: none; }
.icon-star.star-half { opacity: .45; }

/* ---------- Photo placeholders (ImageCard 공통) ---------- */
.photo-slot {
  position: relative;
  background: linear-gradient(160deg, #3a3d42, #17181a);
  border-radius: var(--radius-card);
  overflow: hidden;
}
.photo-slot::before {
  content: attr(data-placeholder);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8px;
  color: rgba(255,255,255,.45);
  font-size: 11px;
  line-height: 1.5;
  pointer-events: none;
}
.photo-slot img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---------- Hero (ImageCard) ---------- */
.hero {
  margin: 0 16px 18px;
  aspect-ratio: 4/3;
}
.hero-warning {
  position: absolute;
  z-index: 2;
  top: 14px;
  left: 14px;
  width: fit-content;
  max-width: calc(100% - 28px);
  background: rgba(0,0,0,.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: calc(10px * var(--hero-ui-scale, 1));
  padding: calc(10px * var(--hero-ui-scale, 1)) calc(14px * var(--hero-ui-scale, 1));
  display: flex;
  align-items: center;
  gap: calc(8px * var(--hero-ui-scale, 1));
  white-space: nowrap;
}
/* place.heroWarningIconScale: 경고 아이콘만 따로 키우거나 줄인다. flex-shrink:0(.ui-icon 기본값)이라
   아이콘 크기는 항상 유지되고, 옆 텍스트가 남는 공간에 맞춰 줄어들어 겹치지 않는다. */
.hero-warning .ui-icon { width: calc(18px * var(--hero-ui-scale, 1) * var(--hero-warning-icon-scale, 1)); height: calc(18px * var(--hero-ui-scale, 1) * var(--hero-warning-icon-scale, 1)); color: var(--red); }
.hero-warning-text { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.hero-warning-text strong { color: var(--red); font-size: calc(13px * var(--hero-ui-scale, 1)); font-weight: 700; overflow: hidden; text-overflow: ellipsis; }
.hero-warning-text span { color: #d8d8d8; font-size: calc(11px * var(--hero-ui-scale, 1)); overflow: hidden; text-overflow: ellipsis; }
/* place.dangerColor: 경고 아이콘·제목 · 위험 통계(아이콘 포함) 강조색(빨강/노랑/초록). 부제(span)는 항상 회색 그대로 둔다. */
.hero.color-yellow .hero-warning .ui-icon,
.hero.color-yellow .hero-warning-text strong { color: var(--yellow); }
.hero.color-green .hero-warning .ui-icon,
.hero.color-green .hero-warning-text strong { color: var(--green); }
/* place.heroWarningFont: 경고 문구·위험 통계 전용 폰트 선택(기본/명조/모노/고딕-굵게).
   .hero-warning-text/.hero-stat에만 지정해서 자식(strong/span/b)에는 상속으로 전달된다. */
.hero.font-serif .hero-warning-text,
.hero.font-serif .hero-stat { font-family: "Nanum Myeongjo", "Noto Serif KR", Batang, serif; }
.hero.font-mono .hero-warning-text,
.hero.font-mono .hero-stat { font-family: Consolas, "D2Coding", "Courier New", monospace; }
.hero.font-bold .hero-warning-text,
.hero.font-bold .hero-stat { font-family: "Apple SD Gothic Neo", "Malgun Gothic", sans-serif; font-weight: 800; }

.hero-stats {
  position: absolute;
  z-index: 2;
  left: 10px;
  right: 10px;
  bottom: 12px;
  background: rgba(0,0,0, var(--hero-stats-bg-alpha, .7));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: calc(10px * var(--hero-ui-scale, 1));
  display: flex;
  padding: calc(10px * var(--hero-ui-scale, 1)) 0;
}
.hero-stat {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: calc(5px * var(--hero-ui-scale, 1));
  padding: 0 calc(3px * var(--hero-ui-scale, 1));
  border-right: 1px solid rgba(255,255,255,.15);
  color: var(--red);
}
.hero.color-yellow .hero-stat { color: var(--yellow); }
.hero.color-green .hero-stat { color: var(--green); }
.hero-stat:last-child { border-right: none; }
/* .ui-icon 기본 규칙이 color: var(--red)를 직접 지정하고 있어(상속이 아니라 자기 자신에게
   붙은 선언이라 상속보다 우선한다), 부모 .hero-stat의 색만 바꿔서는 아이콘까지 안 바뀐다.
   그래서 아이콘에도 명시적으로 같은 색을 지정해준다. */
/* place.heroStatsIconScale: 아이콘만 따로 키우거나 줄인다. flex-shrink:0(.ui-icon 기본값)이라
   아이콘 크기는 항상 유지되고, 옆 텍스트(.hero-stat div)가 남는 공간에 맞춰 줄어들어 겹치지 않는다. */
.hero-stat .ui-icon { width: calc(15px * var(--hero-ui-scale, 1) * var(--hero-stats-icon-scale, 1)); height: calc(15px * var(--hero-ui-scale, 1) * var(--hero-stats-icon-scale, 1)); color: var(--red); }
.hero.color-yellow .hero-stat .ui-icon { color: var(--yellow); }
.hero.color-green .hero-stat .ui-icon { color: var(--green); }
.hero-stat div { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; overflow: hidden; }
/* place.heroStatsFontWeight: 지정 시 라벨/값 둘 다 같은 두께로, 미지정 시(기본) 서로 다른 기존 두께 유지 */
.hero-stat b { font-size: calc(var(--fs-overlay-label) * var(--hero-ui-scale, 1)); font-weight: var(--hero-stats-font-weight, var(--fw-overlay-label)); white-space: nowrap; opacity: .85; overflow: hidden; text-overflow: ellipsis; }
.hero-stat span { font-size: calc(var(--fs-overlay-value) * var(--hero-ui-scale, 1)); font-weight: var(--hero-stats-font-weight, var(--fw-overlay-value)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* layout.heroStats.columns === 2 : 4개 항목을 2x2로 배치 */
.hero-stats.cols-2 { flex-wrap: wrap; }
.hero-stats.cols-2 .hero-stat {
  flex: 0 0 50%;
  padding-bottom: 8px;
  margin-bottom: 8px;
}
.hero-stats.cols-2 .hero-stat:nth-child(odd) { border-right: 1px solid rgba(255,255,255,.15); }
.hero-stats.cols-2 .hero-stat:nth-child(-n+2) { border-bottom: 1px solid rgba(255,255,255,.15); }

/* ---------- Section ---------- */
.section { padding: 6px 16px 20px; }
.section-title { font-size: var(--fs-heading); font-weight: var(--fw-heading); }
.section-head { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.info-btn {
  border: none;
  background: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.overview-text { color: var(--text-dim); font-size: 14px; line-height: 1.7; margin-top: 8px; white-space: pre-line; }

/* ---------- Review toggle (생환자/목격담 - 공포 전용 아이콘) ---------- */
.review-toggle {
  display: flex;
  gap: 10px;
  padding: 14px 16px;
}
.toggle-btn {
  flex: 1;
  height: 54px;
  padding: 0 12px;
  border-radius: 12px;
  border: none;
  background: var(--gray-bg);
  color: var(--text-dim);
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.toggle-icon {
  width: 21px;
  height: 21px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.toggle-btn.active {
  background: #15171a;
  color: #e03131;
}

/* ---------- Phenomena list (공포 전용 아이콘) ---------- */
.phenomena-count {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-dim);
  font-size: var(--fs-meta);
  margin-bottom: 12px;
}
.phenomena-count .ui-icon { width: 15px; height: 15px; color: var(--teal); }
.phenomena-count b { color: var(--teal); font-size: 14px; }

.phenomena-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.phenomena-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 10px;
  background: #f2f4f4;
  overflow: hidden;
  font-size: 14px;
}
.phenomena-item::before {
  content: "";
  position: absolute;
  inset: 0;
  width: var(--pct);
  background: linear-gradient(90deg, #bfe6e0, #d9eeeb);
  z-index: 0;
}

/* layout.poll.itemSpacing */
.phenomena-list.spacing-compact { gap: 4px; }
.phenomena-list.spacing-large { gap: 14px; }

/* layout.poll.style === 'compact' : 막대 그래프 배경 없이 간결한 목록으로 표시 */
.phenomena-list.style-compact .phenomena-item {
  background: #fff;
  border: 1px solid var(--border);
  padding: 9px 12px;
}
.phenomena-list.style-compact .phenomena-item::before { display: none; }
.pheno-icon {
  position: relative; z-index: 1;
  width: 42px; height: 42px;
  border-radius: 9px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.06);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
.pheno-text { position: relative; z-index: 1; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.pheno-count { position: relative; z-index: 1; color: var(--teal-dark); font-weight: 800; }

.expand-btn {
  width: 34px; height: 34px;
  margin: 14px auto 0;
  display: flex;
  border-radius: 50%;
  border: none;
  background: var(--gray-bg);
  color: var(--text-dim);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--transition-fast);
}
.expand-btn .ui-icon { width: 16px; height: 16px; color: var(--text-dim); }

/* ---------- Gallery (이상현상 기록: reviews[].photos에서 자동 수집한 이미지를
   그리드 + 페이지 넘김으로 보여준다. 가로 스크롤 캐러셀이 아니다) ---------- */
.gallery-grid-wrap { position: relative; }
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.gallery-grid-single { grid-template-columns: 1fr; }
.gallery-grid-single .gallery-photo { aspect-ratio: 16/9; }
/* 별도 업로드 데이터가 아니므로 photoSlot의 placeholder-path 방식을 쓰지 않고 직접 <img>로 그린다. */
.gallery-photo {
  display: block;
  width: 100%;
  aspect-ratio: 3/4;
  object-fit: cover;
  border-radius: var(--radius-card);
  background: #20242a;
}
.gallery-photo.is-broken { background: #20242a; object-fit: cover; }
.gallery-empty-note {
  color: var(--text-dim);
  font-size: 13.5px;
  padding: 16px;
  text-align: center;
  background: var(--gray-bg);
  border-radius: var(--radius-card);
}
.gallery-next {
  position: absolute;
  z-index: 3;
  top: 50%; right: -16px; transform: translateY(-50%);
  width: 34px; height: 34px;
  border: none;
  background: rgba(255,255,255,.9);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
  transition: background var(--transition-fast);
}
.gallery-next .ui-icon { width: 16px; height: 16px; }

/* ---------- Review feed (앱 리스트형: 프로필/닉네임/메타/팔로우 → 이미지2장 → 태그 → 본문 → 반응 → 날짜) ---------- */
.review-card {
  padding: 18px 16px;
  border-top: 8px solid var(--gray-bg);
}
/* layout.reviews.cardSpacing */
.review-card.spacing-compact { padding: 10px 16px; border-top-width: 4px; }
.review-card.spacing-large { padding: 26px 16px; border-top-width: 16px; }
.review-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.avatar {
  width: 46px; height: 46px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.avatar::before {
  content: "";
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='8.5' r='3.6' fill='rgba(255,255,255,.35)'/><path d='M4 20c1.2-4.2 4.6-6.4 8-6.4s6.8 2.2 8 6.4' fill='rgba(255,255,255,.35)'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 60%;
}
.avatar-icon { width: 22px; height: 22px; color: rgba(255,255,255,.4); stroke-width: 1.6; }
.review-user { flex: 1; display: flex; flex-direction: column; line-height: 1.4; }
.review-user b { font-size: 15px; }
.review-user span { font-size: 12.5px; color: var(--text-dim); }
.follow-btn {
  padding: var(--pill-pad-y) var(--pill-pad-x);
  border-radius: var(--radius-pill);
  border: none;
  background: var(--blue-light);
  color: var(--blue);
  font-size: var(--fs-button);
  font-weight: var(--fw-button);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.follow-btn.following { background: var(--gray-bg); color: var(--text-dim); }

/* ---------- 리뷰 카드 사진 캐러셀 ----------
 * 리뷰 카드 사진은 2x2로 펼치지 않고 가로로 넘기는 캐러셀이다(+N 배지 없음).
 * - is-single(1장): 카드 전체 너비, next 버튼 없음
 * - is-many(2장 이상): 한 화면에 2장씩 보이는 flex 트랙 + 오른쪽 원형 next 버튼 */
.review-photo-carousel {
  position: relative;
  width: 100%;
  margin-top: 12px;
  margin-bottom: 12px;
  overflow: hidden;
  border-radius: 14px;
}
.review-photo-track {
  display: flex;
  gap: 2px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}
.review-photo-track::-webkit-scrollbar { display: none; }

.review-photo {
  display: block;
  object-fit: cover;
  background: #20242a;
  scroll-snap-align: start;
}
.review-photo.is-broken { background: #20242a; object-fit: cover; }

.review-photo-carousel.is-single .review-photo {
  width: 100%;
  flex: 0 0 100%;
  height: 240px;
}
.review-photo-carousel.is-many .review-photo {
  width: calc((100% - 2px) / 2);
  flex: 0 0 calc((100% - 2px) / 2);
  height: 170px;
}

.photo-next {
  position: absolute;
  right: 12px;
  top: 50%;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgba(255,255,255,.94);
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,.14);
}
.photo-next .ui-icon { width: 16px; height: 16px; color: #666; }
.review-photo-carousel.is-single .photo-next { display: none; }

.tag-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.tag {
  padding: 6px 11px;
  background: var(--gray-bg);
  border-radius: var(--radius-pill);
  font-size: 12px;
  color: var(--text-dim);
  font-weight: 600;
}

.review-text {
  font-size: 14px;
  line-height: 1.75;
  color: #2a2b2d;
  margin-bottom: 12px;
  white-space: pre-line;
}

.reaction-tags { margin-bottom: 12px; }
.reaction-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px 12px;
  background: var(--gray-bg);
  border-radius: var(--radius-pill);
  font-size: 12.5px;
  line-height: 1;
  color: var(--text-dim);
  overflow: hidden;
}
.reaction-tag b { color: var(--text); }

.review-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.react-add {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: none;
  background: none;
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 6px 0;
  overflow: hidden;
  transition: color var(--transition-fast);
}
.visit-date { font-size: 12px; color: var(--text-dim); white-space: nowrap; }

.emoji-reactions {
  display: flex;
  align-items: center;
  gap: 4px;
  border: none;
  background: none;
  font-size: 13.5px;
  line-height: 1;
  color: var(--text);
  cursor: pointer;
  padding: 4px 0;
  overflow: hidden;
}
.cat-icon--reaction + .cat-icon--reaction { margin-left: -4px; }
.emoji-reactions b { margin-left: 4px; }
.emoji-reactions .ui-icon { width: 13px; height: 13px; color: var(--text-dim); }


/* ---------- Photo tab grid ---------- */
.photo-tab-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  padding: 3px;
}
.photo-tab-cell { aspect-ratio: 1/1; border-radius: 0; }

/* ---------- ReactionPanel (fixed overlay, 별도 화면처럼 동작) ---------- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-fast);
}
.modal-backdrop.open { opacity: 1; pointer-events: auto; }
.modal {
  width: 430px;
  max-width: 100%;
  max-height: 82vh;
  background: #fff;
  border-radius: 20px 20px 0 0;
  display: flex;
  flex-direction: column;
  transform: translateY(30px);
  transition: transform 160ms ease;
  overflow: hidden;
}
.modal-backdrop.open .modal { transform: translateY(0); }

/* ---------- 긴급 재난 문자 (layout.disasterAlert.enabled로 켜고 끔, 기본 꺼짐) ---------- */
.disaster-alert-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.55);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 120; /* 다른 오버레이(리뷰 작성 바텀시트 등)보다 항상 위에 떠 있어야 한다 */
  padding: 24px;
}
.disaster-alert-backdrop.open { display: flex; }
.disaster-alert-modal {
  width: 100%;
  max-width: 380px;
  background: #fff;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 20px 50px rgba(0,0,0,.35);
}
.disaster-alert-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 22px 22px 4px;
}
.disaster-alert-icon { width: 26px; height: 26px; flex-shrink: 0; }
.disaster-alert-header h2 { font-size: 18px; font-weight: 800; color: #16181c; }
.disaster-alert-body {
  padding: 14px 22px 22px;
  font-size: 14.5px;
  line-height: 1.6;
  color: #24262b;
  white-space: pre-line;
}
.disaster-alert-confirm {
  display: block;
  width: 100%;
  padding: 15px;
  border: none;
  border-top: 1px solid var(--border);
  background: #fff;
  color: #1a73e8;
  font-size: 15.5px;
  font-weight: 700;
  cursor: pointer;
}
.disaster-alert-confirm:hover { background: var(--gray-bg); }

/* ---------- 리뷰 작성 바텀시트 (layout.reviewComposer.enabled, CMS 캡처 전용) ---------- */
.review-composer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.5);
  display: none;
  align-items: flex-end;
  justify-content: center;
  z-index: 110; /* 긴급 재난 문자(z-index:120)보다는 항상 낮아야 한다 */
}
.review-composer-backdrop.open { display: flex; }
.review-composer-sheet {
  width: 430px;
  max-width: 100%;
  max-height: 85vh;
  background: #fff;
  border-radius: 20px 20px 0 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.review-composer-handle {
  width: 36px;
  height: 4px;
  border-radius: 999px;
  background: var(--border);
  margin: 10px auto 4px;
}
.review-composer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 18px 12px;
}
.review-composer-header h2 { font-size: 17px; font-weight: var(--fw-title); }
.review-composer-body { padding: 4px 18px 18px; overflow-y: auto; }
.review-composer-section { margin-bottom: 20px; }
.review-composer-label { display: block; font-size: 14px; font-weight: 700; margin-bottom: 10px; }
.review-composer-optional { font-weight: 400; color: var(--text-dim); }
.review-composer-photo-row { display: flex; gap: 10px; }
.review-composer-photo-add,
.review-composer-photo-slot {
  width: 72px;
  height: 72px;
  border-radius: 12px;
  border: 1.5px dashed var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.review-composer-photo-add {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 24px;
  font-weight: 300;
  background: var(--gray-bg);
}
.review-composer-photo-add img,
.review-composer-photo-slot img { width: 100%; height: 100%; object-fit: cover; border-radius: 10px; }
.review-composer-textarea {
  width: 100%;
  min-height: 96px;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  resize: vertical;
}
.review-composer-textarea::placeholder { color: var(--text-dim); }
.review-composer-counter { text-align: right; font-size: 12px; color: var(--text-dim); margin-top: 6px; }
.review-composer-submit {
  display: block;
  width: calc(100% - 36px);
  margin: 0 18px 18px;
  padding: 15px;
  border: none;
  border-radius: 12px;
  background: var(--red, #e02020);
  color: #fff;
  font-size: 15.5px;
  font-weight: 700;
  cursor: pointer;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 18px 12px;
}
.modal-header h2 { font-size: 17px; font-weight: var(--fw-title); }

.reaction-tabs-wrap {
  position: relative;
  min-width: 0;
}
.reaction-tabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  padding: 4px 16px 16px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;
  cursor: grab;
}
.reaction-tabs::-webkit-scrollbar { display: none; }
.reaction-tabs.dragging { cursor: grabbing; scroll-snap-type: none; }
/* 스크롤할 내용이 더 있다는 힌트: 오른쪽 fade. 끝까지 스크롤하면 JS가 .is-end를 붙여 숨긴다 */
.reaction-tabs-fade {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 16px;
  width: 40px;
  background: linear-gradient(to right, rgba(255,255,255,0), #fff 78%);
  pointer-events: none;
  transition: opacity var(--transition-fast);
}
.reaction-tabs-wrap.is-end .reaction-tabs-fade { opacity: 0; }
.reaction-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  height: 46px;
  padding: 0 18px;
  border-radius: 999px;
  border: none;
  background: var(--gray-bg);
  color: var(--text-dim);
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transform: none !important;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.reaction-chip-icon { width: 24px; height: 24px; flex-shrink: 0; object-fit: contain; }
.reaction-chip .count { font-weight: 700; color: var(--text-dim); }
.reaction-chip.active { background: #222529; color: #fff; }
.reaction-chip.active .count { color: #e03131; }

.reactor-list {
  list-style: none;
  overflow-y: auto;
  padding: 4px 16px 20px;
}
.reactor {
  display: flex;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid var(--border);
}
.reactor:first-child { border-top: none; }
.avatar.sm { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; }
.avatar.sm .avatar-icon { width: 24px; height: 24px; }
.reactor-body { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.reactor-name-row { display: flex; align-items: center; gap: 8px; }
.reactor-name-row b { font-size: 14.5px; }
.cat-icon--reactor { width: 16px; height: 16px; }
.reactor-stats { font-size: 12px; color: var(--text-dim); }
.reactor-comment { font-size: 13.5px; color: #2a2b2d; margin-top: 4px; line-height: 1.5; white-space: pre-line; }

.status-badge {
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 700;
}
.status-badge.alive { background: #e3f6ec; color: #1f9d5c; }
.status-badge.dead { background: #fbe6e5; color: var(--red); }
.status-badge.missing { background: #fdf2d8; color: #b8860a; }

/* ---------- 사진 확대 보기 (리뷰 탭/사진 탭 사진 클릭) ---------- */
.photo-lightbox-backdrop {
  position: fixed;
  inset: 0;
  z-index: 150; /* 재난 문자(120)/리뷰 작성(110)보다는 위, 치명적 로드 실패 안내(200)보다는 아래 */
  background: rgba(0,0,0,.9);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
}
.photo-lightbox-backdrop.open { display: flex; }
.photo-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 8px;
  object-fit: contain;
}
.photo-lightbox-close {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(255,255,255,.15);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.photo-lightbox-close:hover { background: rgba(255,255,255,.25); }
.photo-lightbox-close .ui-icon { width: 20px; height: 20px; }
/* 확대 가능한 사진에는 커서로 클릭 가능함을 알려준다. */
.review-photo, .photo-tab-cell img { cursor: pointer; }

/* ---------- 데이터 로드 실패 안내 ---------- */
.load-error {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0,0,0,.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.load-error[hidden] { display: none; }
.load-error-box {
  max-width: 420px;
  background: #fff;
  border-radius: 16px;
  padding: 24px;
  font-size: 14px;
  line-height: 1.7;
}
.load-error-box b { font-size: 16px; }
.load-error-box p { margin-top: 10px; color: var(--text-dim); }
.load-error-box code {
  background: var(--gray-bg);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12.5px;
}

/* ---------- Scrollbar niceties ---------- */
.content::-webkit-scrollbar, .reactor-list::-webkit-scrollbar { width: 0; }

/* =========================================================
 * 다크 모드 (layout.darkMode.enabled로 켜고 끔, 기본 꺼짐)
 * script.js가 .phone과 body 양쪽에 dark-mode 클래스를 붙였을 때만 적용된다(반응
 * 모달·긴급 재난 문자·로드 에러 안내가 DOM상 .phone의 자식이 아니라 body 바로 밑
 * 형제로 붙어있어서, .phone에만 클래스를 줘서는 그쪽까지 못 덮는다).
 * --text/--text-dim/--border/--gray-bg/--blue-light 커스텀 프로퍼티는 body에서
 * 다시 정의해야 .phone 안쪽과 저 형제 오버레이들 양쪽 다 상속으로 자동 반영된다.
 * 그 외 컴포넌트별로 직접 박아둔 색(#fff, #2a2b2d 등)만 따로 덮어써준다. */
body.dark-mode {
  --text: #f2f3f5;
  --text-dim: #9a9da4;
  --border: #303236;
  --gray-bg: #202226;
  --blue-light: #1c2c47;
}
.phone.dark-mode { background: #121214; }
.phone.dark-mode .topbar,
.phone.dark-mode .tabs,
.phone.dark-mode .content { background: #121214; }

.phone.dark-mode .phenomena-item { background: #1c1d20; }
.phone.dark-mode .phenomena-item::before { background: linear-gradient(90deg, #1d4d47, #163a35); }
.phone.dark-mode .phenomena-list.style-compact .phenomena-item { background: #121214; }
.phone.dark-mode .pheno-icon { background: #1c1d20; box-shadow: 0 1px 2px rgba(0,0,0,.4); }

.phone.dark-mode .hub-search-input { background: #1c1d20; border-color: #2a2c30; color: #f2f3f5; }
.phone.dark-mode .hub-chip { background: #1c1d20; border-color: #2a2c30; color: #f2f3f5; }
.phone.dark-mode .hub-chip.active { background: var(--red, #e0322f); border-color: var(--red, #e0322f); color: #fff; }
.phone.dark-mode .hub-map { border-color: #2a2c30; }
.phone.dark-mode .hub-pin-label { background: #1c1d20; color: #f2f3f5; }
.phone.dark-mode .hub-list-item { background: #121214; border-color: #2a2c30; }
.phone.dark-mode .hub-list-item:hover { background: #1c1d20; }
.phone.dark-mode .hub-list-thumb { background: #1c1d20; }
.phone.dark-mode .hub-list-count { background: #1c1d20; }

.phone.dark-mode .toggle-btn.active { background: #2a1414; color: #ff6b6b; }

.phone.dark-mode .review-card { border-top-color: #1a1b1e; }
.phone.dark-mode .review-text { color: #dcdde0; }

/* .status-badge는 리뷰 카드(.phone 안)와 반응 모달의 반응자 목록(.modal, body 형제) 양쪽에
 * 다 쓰이므로 두 스코프 모두에 적용해야 한다. */
.phone.dark-mode .status-badge.alive,
body.dark-mode .status-badge.alive { background: #113322; color: #4fd889; }
.phone.dark-mode .status-badge.dead,
body.dark-mode .status-badge.dead { background: #3a1717; color: #ff7a7a; }
.phone.dark-mode .status-badge.missing,
body.dark-mode .status-badge.missing { background: #3a2c0d; color: #e0b23e; }

/* 반응 모달/긴급 재난 문자/로드 에러 안내는 DOM상 .phone의 자식이 아니라 body 바로 아래
 * 형제로 붙어있는 오버레이라서(고정 위치 뒷배경), .phone.dark-mode가 아니라
 * body.dark-mode로 범위를 잡아야 실제로 적용된다. */
body.dark-mode .modal,
body.dark-mode .disaster-alert-modal { background: #1c1d20; }
body.dark-mode .reaction-tabs-fade { background: linear-gradient(to right, rgba(28,29,32,0), #1c1d20 78%); }
body.dark-mode .reaction-chip.active { background: #2a2d31; }
body.dark-mode .reactor-comment { color: #dcdde0; }
body.dark-mode .reactor { border-top-color: #2a2c30; }
body.dark-mode .modal-header h2,
body.dark-mode .reactor-name-row b { color: #f2f3f5; }
body.dark-mode .disaster-alert-header h2 { color: #f2f3f5; }
body.dark-mode .disaster-alert-body { color: #dcdde0; }
body.dark-mode .disaster-alert-confirm { background: #1c1d20; color: #6ea8ff; }
body.dark-mode .disaster-alert-confirm:hover { background: #202226; }

body.dark-mode .review-composer-sheet { background: #1c1d20; }
body.dark-mode .review-composer-handle { background: #3a3c40; }
body.dark-mode .review-composer-header h2 { color: #f2f3f5; }
body.dark-mode .review-composer-photo-add,
body.dark-mode .review-composer-photo-slot { border-color: #3a3c40; }
body.dark-mode .review-composer-photo-add { background: #202226; }
body.dark-mode .review-composer-textarea { background: #202226; border-color: #3a3c40; color: #f2f3f5; }

body.dark-mode .load-error-box { background: #1c1d20; color: #f2f3f5; }
body.dark-mode .load-error-box code { background: #202226; }

.phone.dark-mode .android-statusbar,
.phone.dark-mode .android-navbar { background: #121214; }
.phone.dark-mode .android-statusbar { color: #f2f3f5; }
.phone.dark-mode .android-status-icon { color: #f2f3f5; }
.phone.dark-mode .android-nav-icon svg { stroke: #d8d9db; }

@media (max-width: 480px) {
  body { padding: 0; }
  /* 실제 모바일에서는 기기 화면 자체가 곧 뷰포트라, 844px 고정 프레임 대신
     자연스러운 전체 페이지 스크롤로 되돌린다(데스크톱 데모 전용 박스형 스크롤 해제). */
  .phone { border-radius: 0; height: auto; max-height: none; min-height: 100vh; }
  /* .phone이 다시 문서 전체 스크롤을 따라 늘어나므로, .phone 기준
     position:absolute로는 스크롤 중 화면 밖으로 같이 밀려날 수 있다 -
     뷰포트 기준 position:fixed로 되돌린다(모바일 폭에서는 .phone이 max-width:430px
     안에서 거의 뷰포트 전체 폭을 채우므로 이 정렬이 그대로 맞는다). */
  .android-statusbar, .android-navbar {
    position: fixed;
    left: 0; right: 0;
    max-width: 430px;
    margin: 0 auto;
  }
  .android-statusbar, .android-navbar { border-radius: 0; }
  /* 안드로이드 상태바/내비바는 "PC에서 폰 목업으로 볼 때"만 보여주는 연출이다 -
     실제 모바일 기기에는 이미 진짜 상태바가 있어서 가짜 상태바를 겹쳐 보여주면
     어색하므로, CMS 설정(layout.androidChrome.enabled)과 무관하게 이 폭에서는
     항상 숨긴다. 단, CMS 미리보기 창(390/430px, 항상 이 폭 이하)은 실제 모바일이
     아니라 관리자가 캡처용으로 확인하는 화면이므로 .chrome-preview-force가 붙어
     있으면(isPreviewMode) 숨기지 않는다. */
  .phone.has-android-chrome:not(.chrome-preview-force) .android-statusbar,
  .phone.has-android-chrome:not(.chrome-preview-force) .android-navbar { display: none; }
  .phone.has-android-chrome:not(.chrome-preview-force) { padding-top: 0; }
  .phone.has-android-chrome:not(.chrome-preview-force) .content { padding-bottom: 0; }
}
