@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
/* 21차(성능): 정적 weight 나열 → 가변 폰트(wght 범위). 자세한 이유는 src/shell.ts GFONTS 주석 참고.
   이 URL 은 shell.ts 의 GFONTS / admin.css:2 와 '완전히 동일한 문자열'이어야 합니다. */
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@400..900&family=Playfair+Display:wght@700..800&display=swap');

:root {
  --ink: #12201C;
  --ink-2: #1E3530;
  --forest: #1F4A40;
  --paper: #F5F2EB;
  --card: #FFFFFF;
  --line: #E4DED2;
  --line-2: #EFEAE0;
  --mute: #7B7F78;
  --mute-2: #A6A79F;
  --brass: #B8893F;
  --brass-soft: #F3E8D3;
  --accent: #D4532B;
  --ok: #2F8A5F;
  --serif: 'Noto Serif KR', serif;
  --sans: 'Pretendard Variable', Pretendard, -apple-system, sans-serif;
  /* 21차(성능): JetBrains Mono 웹폰트(30.6KB) 대신 시스템 모노를 씁니다.
     JetBrains Mono 에는 한글 글리프가 없어 한글은 이미 monospace 로 폴백되고 있었으므로
     한글 렌더는 달라지지 않습니다. 숫자·영문(ID, 금액, 해시, 영문 eyebrow 라벨)만 글꼴이 바뀝니다.
     모두 고정폭이라 자릿수 정렬은 그대로 유지됩니다. */
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
  --logo: 'Playfair Display', 'Noto Serif KR', serif; /* 홈 상단 MGM. 로고와 같은 고대비 세리프 */
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* iOS 가로모드에서 글자를 임의로 키우지 않게 합니다(text inflation 차단). */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* 29차: 당겨서 새로고침(pull-to-refresh) 차단.
   분양현장 상세에서 물건정보를 보려고 아래로 길게 드래그하면, .scroll 이 맨 위에
   닿은 뒤 오버스크롤이 문서(document)로 체이닝되어 브라우저가 페이지를 새로고침했습니다.
   (이 앱은 화면 상태를 메모리에만 두므로 새로고침 = 홈으로 강제 복귀였습니다.)
   - html/body: none → 이 스크롤포트의 오버스크롤 동작 자체를 끕니다(새로고침 포함).
   - .scroll   : contain → 내부 스크롤이 끝에 닿아도 부모로 체이닝되지 않게 합니다.
   동작에는 영향이 없고(스크롤은 그대로 됨), 새로고침만 막습니다. */
html, body { margin: 0; height: 100%; background: #DCD6CA; font-family: var(--sans); color: var(--ink); overflow-x: hidden; overscroll-behavior-y: none; }
::selection { background: var(--brass-soft); }
body { display: flex; justify-content: center; }
/* 한국어는 단어 중간에서 끊기지 않게 합니다. */
h1, h2, h3, h4, b, p, dd, dt, small, label, button, span { word-break: keep-all; overflow-wrap: anywhere; }
button:focus-visible, input:focus-visible, select:focus-visible, a:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* 이미지가 없을 때 쓰는 자리표시자 */
.imgph { display: grid; place-items: center; background: repeating-linear-gradient(135deg, var(--line-2) 0 8px, #F7F5F0 8px 16px); }
.imgph i { width: 20px; height: 20px; border: 1.5px solid var(--mute-2); border-radius: 3px; position: relative; opacity: .6; }
.imgph i::after { content: ''; position: absolute; right: 2px; bottom: 2px; width: 8px; height: 5px; border: 1.5px solid var(--mute-2); border-left: 0; border-bottom: 0; }
button { font-family: inherit; color: inherit; border: 0; background: none; padding: 0; cursor: pointer; }
input, select, textarea { font-family: inherit; color: inherit; }
img { display: block; }

/* ① dvh 미지원 브라우저(iOS<15.4, Chrome<108)는 100vh 로 떨어집니다.
   dvh 한 줄만 있으면 이 선언이 무효가 되어 높이가 auto → .app(inset:0) 이 0으로 붕괴합니다.
   ② 가상 키보드가 올라오면 --kb 만큼 줄여 하단 고정 요소가 키보드에 가리지 않게 합니다.
   (dvh 는 소프트 키보드를 반영하지 않으므로 visualViewport 계산값이 필요합니다) */
#root { width: 100%; max-width: 440px; height: 100vh; height: calc(100dvh - var(--kb, 0px)); position: relative; background: var(--paper); overflow: hidden; box-shadow: 0 0 0 1px rgba(0,0,0,.04), 0 30px 80px rgba(18,32,28,.18); }

.app { position: absolute; inset: 0; display: flex; flex-direction: column; }
/* 29차: 내부 스크롤러가 끝에 닿아도 부모(문서)로 체이닝되지 않게 합니다.
   iOS Safari 는 루트가 아니라 이 요소에 걸어야 당겨서 새로고침 체이닝이 끊깁니다. */
.scroll { flex: 1; overflow-y: auto; overflow-x: hidden; scrollbar-width: none; overscroll-behavior-y: contain; }
.scroll::-webkit-scrollbar { display: none; }

/* Top bar */
/* 상단바는 노치·상태바 인셋을 높이에 더합니다(box-sizing:border-box 이므로 padding-top 만큼 내용은 그대로 56px). */
.topbar { height: calc(56px + env(safe-area-inset-top)); flex: none; display: flex; align-items: center; padding: 0 max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); padding-top: env(safe-area-inset-top); gap: 8px; background: var(--paper); position: relative; z-index: 5; }
.topbar.dark { background: var(--ink); color: var(--paper); }
.topbar.clear { position: absolute; top: 0; left: 0; right: 0; background: linear-gradient(rgba(0,0,0,.45), transparent); color: #fff; }
.topbar h1 { font-size: 17px; font-weight: 700; margin: 0; flex: 1; letter-spacing: -0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.icon-btn { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; margin: 0 -10px; flex: none; }
.icon-btn:active { background: rgba(0,0,0,.06); }

/* 54차: 현장 상세 히어로 위의 '뒤로가기'.
   종전에는 22px 화살표만 있어 뒤로가기인지 헷갈린다는 요청이 있었습니다.
   → 아이콘을 28px 로 키우고 '뒤로' 문구를 붙여 하나의 알약 버튼으로 묶었습니다.
   히어로 사진 위에 얹히므로 반투명 검정 바탕을 깔아 밝은 사진에서도 읽히게 했습니다.
   (터치 영역도 44px 높이를 유지해 기존 .icon-btn 과 같은 기준을 지킵니다.) */
.topbar.clear .nav-back { display: inline-flex; align-items: center; gap: 3px; height: 44px; padding: 0 14px 0 7px; margin-left: -8px; border-radius: 22px; flex: none; background: rgba(0, 0, 0, .34); color: #fff; font-size: 14px; font-weight: 700; letter-spacing: -.01em; transition: background .15s; }
.topbar.clear .nav-back:active { background: rgba(0, 0, 0, .54); }

.logo { display: flex; align-items: baseline; gap: 6px; flex: 1; }
.logo b { font-family: var(--serif); font-weight: 900; font-size: 22px; letter-spacing: -0.01em; }
.logo b i { font-style: normal; color: var(--brass); }
.logo span { font-size: 11px; font-weight: 600; color: var(--mute); letter-spacing: 0.02em; }

/* 홈 상단 — 로고를 정가운데에 놓고 아이콘은 양 끝에 붙입니다. */
.topbar.home-top { position: relative; justify-content: center; height: calc(88px + env(safe-area-inset-top)); padding: 0 8px; padding-top: env(safe-area-inset-top); background: var(--paper); flex: none; }
.topbar.home-top .logo { flex: none; display: flex; justify-content: center; align-items: center; height: 100%; }
.topbar.home-top .logo img { height: 52px; width: auto; display: block; }
.topbar.home-top .icon-btn.abs { position: absolute; top: 50%; transform: translateY(-50%); margin: 0; }
/* 53차: 인라인 style(left:8 / right:8) → 클래스. 값이 같아 모바일 렌더는 동일합니다.
   인라인이면 PC 미디어쿼리에서 여백을 넓힐 수 없어 옮겼습니다. */
.topbar.home-top .icon-btn.abs-l { left: 8px; }
.topbar.home-top .icon-btn.abs-r { right: 8px; }

/* Bottom tabs */
/* height 대신 min-height — border-box 에서 safe-area 패딩(≈34px)이 64px 안쪽을 먹어
   탭 라벨(22px 아이콘 + 4px + 11px)이 위아래로 넘치던 문제를 막습니다. */
.tabs { flex: none; min-height: 64px; display: grid; grid-template-columns: repeat(5, 1fr); background: var(--card); border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); }
.tab { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; font-size: 11px; font-weight: 600; color: #3E3B35; transition: color .15s; }
.tab.on { color: var(--ink); font-weight: 700; }
/* [48차 필수] 후손 결합자(svg)가 아니라 자식 결합자(> svg)여야 합니다.
   아이콘이 .tile 안으로 들어갔으므로 `.tab.on svg` 로 두면 타일 내부 svg 까지
   ink(검정)로 칠해져 금장이 사라집니다. */
.tab.on > svg { stroke: var(--ink); }
.tab:active { opacity: .6; }

/* 48차-B: 메인화면 메뉴 아이콘 — '입체 금장 베벨 프레임 + 글로시 먹타일' (icons-premium.js).
   사용자 제공 2번째 참고 이미지(두께감 있는 금장 테두리 + 유리 광택이 도는 먹색 표면 +
   금속 광택 아이콘)를 반영했습니다.
   1번째 참고 이미지대로 상단 헤더(검색·알림)는 타일 없이 금장 아이콘만 씁니다(PTile → PIco).

   [주의] `.tab.on > svg` 는 반드시 자식 결합자('>')입니다.
   아이콘이 .tile 안쪽에 들어갔으므로 후손 결합자로 두면 타일 내부 svg 까지 ink 로 칠해져
   금장 광택이 사라집니다. */
.tile {
  position: relative;
  display: grid; place-items: center; flex: none;
  border-radius: 14px;
  /* 2겹 배경 — 안쪽(padding-box)은 먹색 유리, 테두리 영역(border-box)은 금장 메탈 그라데이션.
     border 를 transparent 로 두고 두 배경을 겹쳐야 '금장 프레임'이 됩니다. */
  background:
    linear-gradient(162deg, #2B2724 0%, #16130F 46%, #100E0B 100%) padding-box,
    linear-gradient(146deg,
      #F7E6BE 0%, #D9B77C 14%, #A8823F 32%, #7E5C2C 48%,
      #C9A461 64%, #F0DCAE 79%, #9A7638 100%) border-box;
  border: 2px solid transparent;
  box-shadow:
    0 0 0 .5px rgba(60, 44, 20, .50),        /* 바깥 얇은 경계 — 프레임이 배경에 묻히지 않게 */
    0 3px 8px rgba(12, 16, 14, .30),         /* 바닥 그림자 */
    0 1px 2px rgba(12, 16, 14, .22),
    inset 0 1px 0 rgba(255, 255, 255, .15),  /* 윗면 하이라이트 */
    inset 0 -2px 4px rgba(0, 0, 0, .45),     /* 아랫면 음영 */
    inset 0 0 10px rgba(0, 0, 0, .35);
  transition: box-shadow .18s, transform .12s;
}
/* 유리 상판 광택 — 타일 위쪽 절반에만 밝은 띠를 얹습니다(참고 이미지의 유리질 표면). */
.tile::before {
  content: ''; position: absolute; inset: 1px 1px auto 1px; height: 46%;
  border-radius: 12px 12px 46% 46% / 12px 12px 22px 22px;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, .14) 0%, rgba(255, 255, 255, .045) 55%, rgba(255, 255, 255, 0) 100%);
  pointer-events: none;
}
.tile > svg { position: relative; z-index: 1; }
/* 참고 이미지 2는 활성/비활성 모두 아이콘이 같은 밝기의 금장입니다.
   구분은 프레임 밝기와 금빛 발광(.tile.on)이 담당하므로 아이콘은 흐리게 하지 않습니다. */
.tab:active .tile { transform: scale(.95); }

/* 활성 상태 — 프레임이 더 밝은 금장이 되고 테두리 안쪽에 금빛 링이 생깁니다. */
.tile.on {
  background:
    linear-gradient(162deg, #322C26 0%, #191510 46%, #13100C 100%) padding-box,
    linear-gradient(146deg,
      #FFF6DE 0%, #F1D8A4 13%, #CFA868 30%, #A07B3D 47%,
      #EBD3A2 63%, #FFF3D6 78%, #C79E58 100%) border-box;
  box-shadow:
    0 0 0 .5px rgba(120, 88, 38, .55),
    0 3px 12px rgba(12, 16, 14, .34),
    0 0 12px rgba(214, 176, 108, .34),       /* 금빛 발광 */
    inset 0 0 0 1px rgba(255, 240, 205, .20), /* 안쪽 금빛 링 */
    inset 0 1px 0 rgba(255, 255, 255, .22),
    inset 0 -2px 5px rgba(0, 0, 0, .45);
}
.tile.on > svg { opacity: 1; }

.pi { display: block; overflow: visible; }
/* 상단 헤더는 타일 없이 금장 아이콘만 — 밝은 종이 배경에서 형태가 묻히지 않게 살짝 띄웁니다. */
.topbar.home-top .icon-btn .pi { filter: drop-shadow(0 1px 1.5px rgba(122, 92, 42, .38)); }


/* Sections */
.sec { padding-top: 28px; padding-right: max(20px, env(safe-area-inset-right)); padding-bottom: 4px; padding-left: max(20px, env(safe-area-inset-left)); }
.sec-h { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 14px; }
.sec-h h2 { margin: 0; font-size: 19px; font-weight: 800; letter-spacing: -0.03em; }
.sec-h .eyebrow { font-family: var(--mono); font-size: 10px; color: var(--brass); letter-spacing: .12em; display: block; margin-bottom: 4px; font-weight: 700; }
.more { font-size: 13px; color: var(--mute); font-weight: 600; display: flex; align-items: center; gap: 2px; }

/* Banner */
/* 65차: 배너 박스 높이 고정(380px)을 없애고 사진 비율(3:2)에 맞춥니다.
   배경(프로덕션 실측, Playwright 로 잰 값):
     · 모바일 390px 화면 → 박스 358x380 = 비율 0.942 (세로형)
       → 3:2 사진의 **좌우 37.2%** 가 잘려 금색 제목 왼쪽이 소실됐습니다.
     · PC 1440px 화면 → 박스 1148x400 = 비율 2.870 (초와이드)
       → 3:2 사진의 **상하 47.7%** 가 잘렸습니다.
   height: 380px 이 첫 커밋(744453f)부터 고정값이라 화면 폭이 변해도 높이가 따라가지
   않았던 것이 원인입니다. 사진과 같은 3:2 로 두면 잘림이 0 이 됩니다.
   (PC 는 아래 @media(min-width:1024px) 에서 16:9 로 덮어씁니다.) */
.banner { position: relative; aspect-ratio: 3 / 2; height: auto; margin: 4px 16px 0; border-radius: 4px; overflow: hidden; background: var(--ink); color: #fff; }
.banner-track { display: flex; height: 100%; transition: transform .6s cubic-bezier(.6,.05,.2,1); }
.banner-slide { flex: none; width: 100%; height: 100%; position: relative; }
.banner-slide img { width: 100%; height: 100%; object-fit: cover; }
.banner-slide::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(18,32,28,.05) 30%, rgba(18,32,28,.88) 100%); }
.banner-cap { position: absolute; left: 20px; right: 20px; bottom: 44px; z-index: 2; }
.banner-tag { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; padding: 5px 9px; background: var(--brass); color: #fff; letter-spacing: .02em; }
.banner-cap h3 { font-family: var(--serif); font-weight: 700; font-size: 28px; line-height: 1.25; margin: 12px 0 8px; white-space: pre-line; letter-spacing: -0.02em; }
.banner-cap p { margin: 0; font-size: 13px; opacity: .82; }
.banner-dots { position: absolute; left: 20px; bottom: 20px; z-index: 3; display: flex; gap: 6px; align-items: center; }
.banner-dots i { width: 18px; height: 2px; background: rgba(255,255,255,.35); transition: all .3s; }
.banner-dots i.on { width: 32px; background: #fff; }
.banner-count { position: absolute; right: 20px; bottom: 14px; z-index: 3; font-family: var(--mono); font-size: 11px; opacity: .8; }

/* Quick menu */
/* 48차-B: 참고 이미지 2는 흰 카드/구분선 없이 타일이 배경에 떠 있는 형태입니다.
   그래서 카드 배경·테두리·세로 구분선을 걷어냈습니다. */
.quick { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin: 22px 10px 0; background: none; border: 0; border-radius: 0; }
.quick button { padding: 4px 2px 2px; display: flex; flex-direction: column; align-items: center; gap: 9px; font-size: 12.5px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); border-radius: 10px; }
.quick button + button { border-left: 0; }
.quick .qi { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; background: var(--paper); }

/* Site cards */
.hscroll { display: flex; gap: 12px; overflow-x: auto; padding: 0 20px 6px; margin: 0 -20px; scroll-snap-type: x mandatory; scroll-padding-left: 20px; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.hscroll::after { content: ''; flex: none; width: 4px; }

/* 관심물건 캐러셀 (22차)
   기존 .hscroll + inline width:180 은 390px 폭에서 20+180+12+180=392px 이 되어
   두 번째 카드가 2px 잘렸습니다. 카드 폭을 calc 로 계산해 '정확히 2개'만 보이게 하고,
   남은 물건은 우측 화살표(.fav-nav.next)로 한 페이지씩 넘깁니다. 손가락 드래그도 그대로 됩니다. */
.fav-wrap { position: relative; }
/* 106차: MY 관심물건 섹션에서 '분양현장' / 'MGM스튜디오' 두 줄을 구분하는 작은 라벨.
   두 목록은 저장 표가 달라(favorites / studio_favorites) 출처를 눈으로 구분할 필요가 있습니다.
   한쪽만 있어도 라벨은 붙습니다(그때는 사실상 제목 역할). */
.fav-group { font-size: 11.5px; font-weight: 700; letter-spacing: .02em; color: var(--mute);
  padding: 0 20px; margin: 0 0 8px; display: flex; align-items: center; gap: 6px; }
.fav-group::before { content: ''; width: 3px; height: 11px; border-radius: 1px;
  background: var(--brass); display: block; }
.fav-track {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding: 0 20px 6px;
  margin: 0 -20px;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 20px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.fav-track::-webkit-scrollbar { display: none; }
.fav-track::after { content: ''; flex: none; width: 8px; }
/* 카드 폭: (뷰포트 - 좌우 패딩 40 - 카드 사이 gap 12) / 2 → 정확히 2개.
   .fav-track 을 붙인 이유: 아래쪽 .site-card{width:240px} 보다 명시도를 높여야
   소스 순서와 무관하게 이 규칙이 적용됩니다(동일 명시도면 뒤에 선언된 쪽이 이김). */
.fav-track .fav-card { width: calc((100% - 12px) / 2); min-width: 0; scroll-snap-align: start; }
/* 108차: MY 관심물건 카드에서 바로 삭제할 수 있게 카드마다 X 버튼을 얹습니다.
   HTML 규칙상 <button> 안에 <button> 을 넣을 수 없어(브라우저가 안쪽 버튼을 밖으로
   끄집어내 레이아웃이 깨집니다) 카드와 삭제 버튼을 '형제'로 두고 래퍼로 감쌉니다.
   ⚠️ 폭 계산을 래퍼가 이어받아야 합니다 — .fav-track 의 flex 자식이 카드에서 래퍼로
   바뀌었으므로, 종전 .fav-card 의 width:calc(...) 를 그대로 두면 카드가 래퍼의
   50% 가 되어 카드가 절반 크기로 줄어듭니다. 그래서 아래에서 카드 폭을 100% 로 되돌립니다. */
.fav-track .fav-itemwrap {
  width: calc((100% - 12px) / 2);
  min-width: 0;
  flex: none;
  scroll-snap-align: start;
}
.fav-track .fav-itemwrap .fav-card { width: 100%; }
.fav-itemwrap { position: relative; }
/* 110차: 재생 버튼(.st-card .ph .play)과 같은 모양으로 맞춤.
   요청: "재생 버튼처럼 테두리만 흰 링 + 속은 비고 흰 X 를 원해"
   109차의 '꽉 찬 흰 원'은 사진 위에서 흰 딱지처럼 보였습니다.
   재생 버튼(studio.css 145행)이 이미 같은 문제를 풀어 둔 선례가 있어 그 값을 그대로 따릅니다.
     · 배경 거의 투명(10%) — 원판이 아니라 '테두리 원'으로 보이게
     · 테두리 흰색 1.5px(.92)
     · 바깥에 얇은 어두운 링 + 그림자 — 썸네일이 밝은 사진이어도 흰 테두리가 사라지지 않게
   X 는 재생 버튼의 삼각형과 같이 흰색입니다. 흰 사진에서 묻히지 않도록 drop-shadow 를 겁니다
   (box-shadow 는 SVG 사각 박스에 붙어 모양이 드러나지 않으므로 filter 를 씁니다).
   색은 CSS color 한 곳에서 정하고 아이콘은 currentColor 로 받습니다. */
.fav-del {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(18, 32, 28, .10);
  border: 1.5px solid rgba(255, 255, 255, .92);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .16), 0 2px 8px rgba(0, 0, 0, .26);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  color: #fff;
  transition: transform .16s, background .16s;
}
.fav-del svg { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .55)); }
.fav-del:hover { background: rgba(18, 32, 28, .22); }
.fav-del:active { transform: scale(.9); }
.fav-del:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
/* 터치 기기: 손가락에 가리지 않도록 터치 영역을 조금 넓힙니다. */
@media (pointer: coarse) {
  .fav-del { width: 34px; height: 34px; }
}
.fav-card .ph { aspect-ratio: 3 / 2; height: auto; }
.fav-card h4 { font-size: 14.5px; margin: 9px 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fav-card .meta { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fav-card .price { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 우측에 다음 물건이 더 있을 때 카드 위로 자연스럽게 얹히는 페이드 */
.fav-wrap.has-more::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 6px;
  width: 34px;
  pointer-events: none;
  background: linear-gradient(to right, rgba(245, 242, 235, 0), var(--paper) 78%);
  border-radius: 0 4px 4px 0;
}
/* 좌우 넘김 버튼 */
.fav-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(18, 32, 28, .74);
  border: 1px solid rgba(255, 255, 255, .22);
  box-shadow: 0 4px 14px rgba(18, 32, 28, .28);
  color: #fff;
  z-index: 2;
  transition: background .16s, opacity .16s;
}
.fav-nav:hover { background: rgba(18, 32, 28, .9); }
.fav-nav:active { background: rgba(18, 32, 28, 1); }
.fav-nav.next { right: 2px; }
.fav-nav.next svg { margin-left: 1px; }
.fav-nav.prev { left: 2px; }
.fav-nav.prev svg { transform: rotate(180deg); margin-right: 1px; }
/* 터치 기기에서 손가락이 버튼에 가리지 않도록 최소 터치 영역 확보 */
@media (pointer: coarse) {
  .fav-nav { width: 38px; height: 38px; }
}

/* 슬로우 마키 — 좌우 풀블리드로 흐르게 */
.marquee { overflow: hidden; margin: 0 -20px; padding: 2px 0 4px; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.marquee-track { display: flex; gap: 12px; padding-left: 20px; width: max-content; will-change: transform; }
.marquee .site-card { flex: none; width: 240px; scroll-snap-align: none; }
.marquee .site-card:last-child { margin-right: 20px; }
@media (prefers-reduced-motion: reduce) { .marquee-track { transform: none !important; } }
.hscroll::-webkit-scrollbar { display: none; }
.site-card { flex: none; width: 240px; scroll-snap-align: start; text-align: left; transition: transform .18s; }
.site-card:active { transform: scale(.985); }
.site-card .ph { aspect-ratio: 3 / 2; height: auto; border-radius: 4px; overflow: hidden; position: relative; background: var(--line); }
.site-card .ph img { width: 100%; height: 100%; object-fit: cover; }
.site-card h4 { margin: 10px 0 3px; font-size: 16px; font-weight: 700; letter-spacing: -0.03em; }
.site-card .meta { font-size: 12.5px; color: var(--mute); }
.site-card .price { font-size: 13px; font-weight: 700; margin-top: 4px; }

/* ── 59차: 배지(필) 재설계 ──────────────────────────────────────
   요청: "첨부한 이미지 대로 현장물건 들어가면 현장명 위에 뜨는 문구를 수정해줘.
          전체적인 디자인에 맞게 하려고 그러는거야."
   참고 이미지(https://www.genspark.ai/api/files/s/dV0mJHgu)는
   - 알약형(완전 둥근) 필 3개
   - 첫 번째(강조)는 흑갈색 그라데이션 + 아이보리 글자
   - 나머지는 크림 그라데이션 + 진한 갈색 글자
   - 셋 다 금장 베벨 테두리(안쪽 하이라이트 + 바깥 골드 링 + 아래쪽 그림자)
   기존 마크업/클래스 이름은 그대로 두고(StatusBadge 의 on/rest/half/done/soon,
   .badge.type/.badge.data/.badge.vip) 겉모양만 바꿉니다. */
.badge {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  height: 27px; padding: 0 13px; border-radius: 999px;
  font-family: var(--sans); font-size: 12.5px; font-weight: 600;
  letter-spacing: -0.02em; line-height: 1; white-space: nowrap;
  /* 기본값 = 서브 필(크림 + 금장 베벨) */
  background: linear-gradient(180deg, #FBF8F2 0%, #EFE8DC 100%);
  color: #2B231E;
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, .88),
    inset 0 -1px 1px rgba(110, 80, 50, .34),
    0 0 0 1px rgba(178, 142, 88, .55),
    0 2px 4px rgba(64, 44, 26, .16),
    0 1px 2px rgba(64, 44, 26, .10);
}
/* 강조 필 — 분양중. 흑갈색 그라데이션 + 아이보리 글자 + 금장 링 */
.badge.on {
  background: linear-gradient(180deg, #241F1B 0%, #11100E 100%);
  color: #F5EFE6;
  box-shadow:
    inset 0 1px 1px rgba(255, 246, 230, .26),
    inset 0 -1px 1px rgba(0, 0, 0, .62),
    0 0 0 1px rgba(198, 162, 104, .68),
    0 2px 4px rgba(0, 0, 0, .28),
    0 1px 2px rgba(0, 0, 0, .18);
}
/* 할인분양 — 같은 금장 계열이되 청동빛으로 구분 */
.badge.rest {
  background: linear-gradient(180deg, #B8893F 0%, #8E6527 100%);
  color: #FFF7E8;
  box-shadow:
    inset 0 1px 1px rgba(255, 246, 230, .42),
    inset 0 -1px 1px rgba(60, 38, 8, .46),
    0 0 0 1px rgba(214, 180, 122, .62),
    0 2px 4px rgba(72, 48, 14, .22),
    0 1px 2px rgba(72, 48, 14, .14);
}
/* 반값분양 — 진한 금장 */
.badge.half {
  background: linear-gradient(180deg, #D9B978 0%, #B8893F 100%);
  color: #3A2A08;
  box-shadow:
    inset 0 1px 1px rgba(255, 252, 240, .82),
    inset 0 -1px 1px rgba(96, 64, 18, .38),
    0 0 0 1px rgba(196, 160, 102, .7),
    0 2px 4px rgba(72, 48, 14, .2),
    0 1px 2px rgba(72, 48, 14, .12);
}
/* 분양예정 — 크림 베이스(기본값과 동일 계열이라 링만 살짝 약하게) */
.badge.soon {
  background: #FFFFFF;
  color: var(--ink);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, .9),
    inset 0 -1px 1px rgba(110, 80, 50, .2),
    0 0 0 1px rgba(190, 160, 112, .5),
    0 1px 3px rgba(64, 44, 26, .12);
}
/* 분양완료 — 채도를 뺀 회색 크림 */
.badge.done {
  background: linear-gradient(180deg, #F4F3F0 0%, #E7E6E1 100%);
  color: var(--mute);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, .8),
    inset 0 -1px 1px rgba(90, 90, 82, .18),
    0 0 0 1px rgba(170, 168, 158, .48),
    0 1px 3px rgba(40, 40, 34, .1);
}
/* 물건종류(아파트 등) — 크림 + 옅은 금장 */
.badge.type {
  background: linear-gradient(180deg, #FDFAF4 0%, #F1E9DA 100%);
  color: #6E4F1C;
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, .9),
    inset 0 -1px 1px rgba(120, 88, 40, .26),
    0 0 0 1px rgba(186, 152, 96, .52),
    0 1px 3px rgba(64, 44, 26, .12);
}
/* MGM 약정 체결 — 크림 + 금장 글자 */
.badge.data {
  background: linear-gradient(180deg, #FCF8F0 0%, #EFE5D2 100%);
  color: #7A5A22;
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, .9),
    inset 0 -1px 1px rgba(120, 88, 40, .3),
    0 0 0 1px rgba(190, 155, 94, .6),
    0 1px 3px rgba(64, 44, 26, .13);
}
/* VIP — 흑색 + 금색 글자 */
.badge.vip {
  background: linear-gradient(180deg, #1E1B18 0%, #0D0C0A 100%);
  color: #E9D3A6; letter-spacing: .06em; font-weight: 700;
  box-shadow:
    inset 0 1px 1px rgba(255, 246, 230, .24),
    inset 0 -1px 1px rgba(0, 0, 0, .6),
    0 0 0 1px rgba(198, 162, 104, .7),
    0 2px 4px rgba(0, 0, 0, .26);
}
.ph .badge.vip { left: auto; right: 10px; }
.ph:has(.fav-heart) .badge.vip { right: 52px; top: 14px; }
.fav-heart { position: absolute; top: 8px; right: 8px; z-index: 2; width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; background: rgba(18,32,28,.28); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); cursor: pointer; transition: transform .18s ease, background .18s; }
.fav-heart svg { filter: drop-shadow(0 1px 2px rgba(0,0,0,.25)); transition: transform .2s cubic-bezier(.3,1.6,.5,1); }
.fav-heart.on { background: rgba(255,255,255,.92); }
.fav-heart.on svg { filter: none; transform: scale(1.08); }
.fav-heart:active { transform: scale(.88); }
.fav-heart:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
/* 59차: 여기에 있던 `.badge.done` / `.badge.data` 옛 규칙(단색 배경)을 삭제했습니다.
   같은 선택자(명시도 동일)가 59차 금장 베벨 규칙보다 **뒤에** 있어서 그라데이션과
   금장 링을 통째로 덮어썼습니다(실측: .badge.data 의 background-image 가 none,
   color 가 #23405A 로 나와 베벨이 사라짐). 새 규칙은 위쪽 .badge.done(360행) /
   .badge.data(380행) 한 곳에만 둡니다. */
.ph .badge { position: absolute; left: 10px; top: 10px; }
.reward-chip { position: absolute; right: 10px; bottom: 10px; background: rgba(18,32,28,.82); color: #fff; font-size: 11px; font-weight: 700; padding: 4px 8px; border-radius: 2px; backdrop-filter: blur(4px); }

/* Counselor */
.cs-row { display: flex; align-items: center; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--line-2); }
.cs-row:last-child { border-bottom: 0; }
.avatar { width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; background: var(--forest); color: var(--brass-soft); font-family: var(--serif); font-weight: 700; font-size: 18px; position: relative; flex: none; }
.avatar.sm { width: 36px; height: 36px; font-size: 14px; }
.avatar .dot { position: absolute; right: 1px; bottom: 1px; width: 11px; height: 11px; border-radius: 50%; background: var(--ok); border: 2px solid var(--card); }
.cs-info { flex: 1; min-width: 0; }
.cs-info b { font-size: 15px; font-weight: 700; }
.cs-info small { display: block; font-size: 12px; color: var(--mute); margin-top: 2px; }
.pill-btn { height: 36px; padding: 0 14px; border-radius: 18px; border: 1px solid var(--line); font-size: 13px; font-weight: 700; background: var(--card); display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.pill-btn.dark { background: var(--ink); color: #fff; border-color: var(--ink); }

.card { background: var(--card); border: 1px solid var(--line); border-radius: 4px; padding: 4px 16px; }

/* News */
.news-row { display: flex; gap: 14px; padding: 17px 0; border-bottom: 1px solid var(--line-2); text-align: left; width: 100%; align-items: flex-start; }
.news-row:last-child { border-bottom: 0; }
.news-row .nt { flex: 1; min-width: 0; }
.news-row .cat { font-size: 11px; font-weight: 700; color: var(--brass); }
.news-row h4 { font-size: 15px; font-weight: 600; line-height: 1.5; margin: 5px 0 7px; letter-spacing: -0.03em; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.news-row.noimg h4 { font-size: 16px; -webkit-line-clamp: 3; }
.news-row .d { font-size: 12px; color: var(--mute-2); }
.news-row img, .news-row .imgph { width: 84px; height: 84px; object-fit: cover; border-radius: 3px; flex: none; }
.news-row .imgph i { width: 16px; height: 16px; }

/* Filters */
.chips { display: flex; gap: 6px; overflow-x: auto; padding: 0 20px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip { flex: none; height: 34px; padding: 0 14px; border-radius: 17px; border: 1px solid var(--line); background: var(--card); font-size: 13px; font-weight: 600; color: var(--ink-2); }
.chip.on { background: var(--ink); color: #fff; border-color: var(--ink); }

/* ── 49차: 세리프 제목 + 금장 밑줄 (분양현장 · 뉴스 상단 공용) ──
   제목 글자 폭에 맞춰 밑줄이 따라가도록 inline-block 으로 두고 ::after 로 긋습니다. */
.gold-title { position: relative; display: inline-block; padding-bottom: 8px; flex: none; }
.gold-title::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; border-radius: 1px;
  background: linear-gradient(90deg, #C2A05F 0%, #EBD3A0 28%, #B8893F 66%, #8E6B31 100%);
}

/* ── 49차: 분양현장 상단 ──
   참고 이미지처럼 제목은 세리프 + 금장 밑줄, 돋보기는 타일 없이 금장 아이콘만 씁니다. */
.topbar.sites-top { height: calc(66px + env(safe-area-inset-top)); }
.topbar.sites-top .ttl-wrap { flex: 1; min-width: 0; display: flex; align-items: center; }
.topbar.sites-top .sites-ttl { font-family: var(--serif); font-size: 25px; font-weight: 700; letter-spacing: -.035em; color: var(--ink); flex: none; }
.topbar.sites-top .icon-btn .pi { filter: drop-shadow(0 1px 1.5px rgba(122, 92, 42, .34)); }

/* ── 66차: 탭 화면 뒤로가기(<) ─────────────────────────────────
   하단 탭 · 홈 퀵메뉴로 들어간 분양현장 · 부동산뉴스 · MGM스튜디오 · 마이페이지에는
   뒤로가기 버튼이 없었습니다. 요청대로 '뒤로' 문구 없이 아이콘만 둡니다.

   [중요] 이 화면들은 app.js 의 nav.tab() 이 스택을 비우기 때문에(setStack([]))
   nav.back() 이 빈 배열을 자르는 무동작이 됩니다. 그래서 버튼은 nav.home() 을 씁니다.
   (탭 화면에서 '뒤로' = 홈으로 돌아가기)

   세로 여백 설계
   · .backrow 는 노치 인셋(safe-area-inset-top)을 직접 포함합니다.
   · 스튜디오(.st-topcard) · MY(.my-head) 카드는 원래 margin-top 에 같은 인셋을
     더하고 있어서, 그대로 두면 아이폰에서 위 여백이 두 배가 됩니다.
     → .backrow 바로 뒤에 오는 카드만 인셋을 빼고 10px 로 맞춥니다.
   · 뉴스(.nhead)는 인셋을 갖고 있지 않아, 앞에 .backrow 가 오면 위 여백만 줄입니다. */
/* 버튼 자체 — .backrow 안과 분양현장 상단바 안에서 같은 모양이어야 하므로
   .back-ico 를 독립 클래스로 둡니다(.backrow 하위 선택자로 묶지 않습니다). */
.back-ico {
  width: 44px; height: 44px; flex: none;
  margin-left: -10px;            /* 셰브런 잉크를 본문 20px 축에 광학 정렬 */
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--ink);
}
.back-ico:active { background: rgba(0, 0, 0, .06); }

.backrow {
  flex: none;
  display: flex; align-items: center;
  /* 좌우 여백은 각 화면이 정의한 --pad 를 그대로 씁니다.
     모바일에서는 --pad 가 없으므로 20px 로 떨어지고(기존 본문 축과 동일),
     PC(≥1024px)에서만 .nwrap(1000) · .studio-scroll(1000) · .my-scroll(900)
     이 --pad 를 정의해 본문 카드와 같은 세로축에 정렬됩니다.
     (고정 20px 로 두면 PC 에서 카드보다 왼쪽으로 크게 벗어납니다 — 실측 88~138px) */
  padding: calc(8px + env(safe-area-inset-top)) var(--pad, 20px) 0;
}

/* 카드가 인셋을 이미 갖고 있는 화면(스튜디오 · MY)은 위 여백이 두 번 더해지지 않게 줄입니다.
   뉴스(.nhead)는 인셋이 없어 26px → 10px 로만 줄입니다(아이콘이 위 여백 역할을 합니다). */
.backrow + .st-topcard,
.backrow + .my-head { margin-top: 10px; }
.backrow + .nhead { padding-top: 10px; }

/* ── 49차: 분양현장 전용 금테 필터 칩 ──
   .chip 은 구인구직 · 고객센터 · 스튜디오 · 검색이 함께 쓰므로,
   분양현장 마크업에만 붙인 'gold' 수정자 안에서만 다시 칠합니다. */
/* 5개가 한 줄에 들어오도록 간격·좌우 여백을 잡았습니다.
   390px 기준 실측 377px(여유 13px). 360px 소형 기기는 아래 미디어쿼리에서 더 좁힙니다. */
.chips.gold { gap: 6px; }
.chips.gold .chip {
  padding: 0 12.5px;
  border: 1px solid #D8BF8C; color: var(--ink);
  background: linear-gradient(180deg, #FCF7EC 0%, #F5EDDD 100%);
  box-shadow: 0 1px 1.5px rgba(120, 92, 42, .07), inset 0 1px 0 rgba(255, 255, 255, .8);
}
/* 360px 급에서 5칩이 잘리지 않게 — 실측 350px(여유 10px). */
@media (max-width: 374px) {
  .chips.gold { gap: 5px; }
  .chips.gold .chip { padding: 0 10px; }
}
.chips.gold .chip.on {
  color: #F8F1E1; border: 1px solid transparent;
  background:
    linear-gradient(180deg, #3B342B 0%, #241F18 50%, #15110C 100%) padding-box,
    linear-gradient(150deg, #F7E5BC 0%, #D6B377 32%, #A07B3C 64%, #EBD2A2 100%) border-box;
  box-shadow:
    0 2px 7px rgba(20, 22, 18, .28),
    0 0 0 .5px rgba(90, 68, 30, .45),
    inset 0 1px 0 rgba(255, 255, 255, .17),
    inset 0 -2px 4px rgba(0, 0, 0, .40);
}

/* Site list (vertical) */
/* 53차: 분양현장 목록 래퍼. 이전에는 인라인 스타일(padding:'0 20px')이었습니다.
   값을 그대로 클래스로 옮겼으므로 모바일 렌더 결과는 동일하고,
   PC 미디어쿼리(@media min-width:1024px)에서만 .sites-grid 가 3~4열 그리드가 됩니다. */
.sites-list { padding: 0 20px; }
.sites-count { font-size: 13px; color: var(--mute); margin-bottom: 12px; }
.sites-count b { color: var(--ink); }
/* .sites-grid 에는 기본 규칙을 두지 않습니다 —
   규칙이 없으면 그냥 블록 상자라 .site-row 가 이전처럼 세로 1열로 쌓입니다. */

.site-row { display: block; width: 100%; text-align: left; margin-bottom: 22px; }
.site-row .ph { aspect-ratio: 3 / 2; height: auto; border-radius: 4px; overflow: hidden; position: relative; }
.site-row .ph img { width: 100%; height: 100%; object-fit: cover; }
.site-row .ph .imgph { width: 100%; height: 100%; }
.site-row .ph .imgph i { width: 26px; height: 26px; }
.site-row .row-b { display: flex; justify-content: space-between; align-items: flex-start; margin-top: 12px; gap: 8px; }
.site-row h4 { font-size: 18px; margin: 0 0 4px; font-weight: 800; letter-spacing: -0.03em; }
.site-row .meta { font-size: 13px; color: var(--mute); }
.site-row .price { font-size: 14px; font-weight: 700; margin-top: 6px; }

/* Detail */
/* 26차: 히어로 이미지를 좌우로 드래그해 사진을 넘깁니다.
   touch-action: pan-y 로 세로 스크롤은 브라우저에 남기고 가로 제스처만 JS 가 받습니다.
   (이 값이 없으면 세로 스크롤 컨테이너가 가로 이동까지 가로채 스와이프가 먹히지 않습니다.) */
/* 65차-B: 히어로 박스 높이 고정(340px)을 없애고 사진 비율(3:2)에 맞춥니다.
   배너(65차)와 같은 원인이었습니다 — height 가 고정이라 화면 폭이 변해도
   높이가 따라가지 않아 박스가 세로형이 되고, object-fit: cover 가 좌우를 잘랐습니다.
   프로덕션 실측(Playwright):
     · 모바일 390px → 박스 390x340 = 1.147 → 3:2 사진 좌우 23.5% 잘림
     · PC 1440px   → 박스 430x432 = 0.995 → 좌우 33.7% 잘림
     · PC 1920px   → 박스 430x518 = 0.829 → 좌우 44.7% 잘림
   갤러리 사진 6장이 모두 3:2(1200x800 / 1128x752)라 3:2 로 두면 잘림이 0 이 됩니다.
   높이는 모바일 340 → 260px 로 낮아지지만 제목이 잘리지 않습니다.
   (PC 는 아래 @media(min-width:1024px) 에서 같은 3:2 를 다시 선언합니다.) */
.hero { position: relative; aspect-ratio: 3 / 2; height: auto; background: var(--ink); touch-action: pan-y; }
.hero img { width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.hero::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,.25), transparent 30%, transparent 55%, rgba(18,32,28,.7)); pointer-events: none; }
.hero-pg { position: absolute; right: 16px; bottom: 16px; z-index: 2; color: #fff; font-family: var(--mono); font-size: 11px; background: rgba(0,0,0,.4); padding: 4px 8px; border-radius: 2px; }
/* 51차: 상단 이미지의 'VR 현장 둘러보기' 버튼을 삭제해 .hero-vr 규칙도 함께 제거했습니다.
   (grep 으로 JS/TSX 참조 0건 확인. legacy 앱은 별도 스타일시트를 쓰므로 그대로 둡니다.) */
.dt-head { padding: 20px 20px 18px; background: var(--card); border-bottom: 1px solid var(--line); }
.dt-head h2 { font-family: var(--serif); font-size: 26px; font-weight: 700; margin: 10px 0 6px; letter-spacing: -0.02em; }
.dt-head .addr { font-size: 13px; color: var(--mute); }
.dt-head .price { font-size: 17px; font-weight: 800; margin-top: 12px; letter-spacing: -0.02em; }

/* 52차: 상세 상단 액션 4개를 참고 이미지(입체 금장 베벨 타일 + 금장 라벨)로 교체했습니다.
   타일 자체는 메인 퀵메뉴·하단탭과 같은 .tile / PTile 을 그대로 씁니다(같은 금장 세트).
   · 배경: 참고 이미지의 종이색 톤(var(--paper)). 카드(흰색)보다 한 단계 낮춰 타일이 떠 보이게 합니다.
   · 라벨: 타일 아래 12px. 활성(관심등록됨)만 금장색, 나머지는 잉크색 — 참고 이미지와 같은 대비입니다.
   · 좌우 여백: 4열이라 320px 에서도 라벨이 잘리지 않도록 padding 을 최소로 둡니다. */
.dt-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; background: var(--paper); border-bottom: 1px solid var(--line); padding: 16px 6px 14px; }
.dt-actions button { padding: 2px 0 0; display: flex; flex-direction: column; align-items: center; gap: 9px; background: none; border: 0; border-radius: 12px; }
.dt-actions button:active .tile { transform: scale(.95); }
.dt-lbl { font-size: 12px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); line-height: 1.25; text-align: center; }
.dt-actions button.on .dt-lbl { color: var(--brass); font-weight: 700; }

/* 70차: '귀로 듣는 현장정보'(TTS) 를 59차에 삭제하면서 마크업은 사라졌는데
   .tts-bar / .tts-play / .tts-line 규칙만 남아 있었습니다(참조 0건 확인 후 제거).
   .wave · @keyframes wv 는 admin.css 의 .vplaying 규칙이 함께 참조하고 있어 그대로 둡니다. */
.wave { display: flex; gap: 2px; align-items: center; height: 20px; margin-left: auto; }
.wave i { width: 2px; background: var(--brass); border-radius: 1px; height: 6px; }
.wave.play i { animation: wv 0.9s ease-in-out infinite; }
@keyframes wv { 0%,100% { height: 4px; } 50% { height: 18px; } }

.spec { display: grid; grid-template-columns: 84px 1fr; row-gap: 12px; font-size: 14px; }
.spec dt { color: var(--mute); }
.spec dd { margin: 0; font-weight: 600; }
.spec dd, .spec dt { word-break: keep-all; }
.points { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.points div { background: var(--card); border: 1px solid var(--line); padding: 14px 12px; font-size: 13.5px; font-weight: 600; letter-spacing: -0.02em; border-radius: 3px; display: flex; gap: 8px; align-items: flex-start; line-height: 1.45; }
.points div span { font-family: var(--mono); color: var(--brass); font-size: 11px; padding-top: 2px; flex: none; }

.reward-box { background: var(--brass-soft); border-radius: 4px; padding: 18px; display: flex; gap: 14px; align-items: center; }
.reward-box b { font-size: 15px; }
.reward-box p { font-size: 12.5px; margin: 4px 0 0; color: #6E5524; line-height: 1.5; }

.bottom-cta { flex: none; display: flex; gap: 8px; padding: 10px 16px; background: var(--card); border-top: 1px solid var(--line); padding-bottom: calc(10px + env(safe-area-inset-bottom)); }
.btn { height: 52px; border-radius: 4px; font-size: 15px; font-weight: 800; display: flex; align-items: center; justify-content: center; gap: 6px; letter-spacing: -0.02em; }
.btn.primary { background: var(--ink); color: #fff; flex: 1; }
.btn.accent { background: var(--accent); color: #fff; flex: 1; }
.btn.ghost { border: 1px solid var(--line); background: var(--card); padding: 0 16px; }
.btn:disabled { opacity: .35; }

/* VR */
.vr { position: absolute; inset: 0; background: #000; z-index: 50; touch-action: none; user-select: none; overflow: hidden; }
.vr-pano { position: absolute; inset: 0; background-repeat: repeat-x; background-size: auto 100%; cursor: grab; }
.vr-pano:active { cursor: grabbing; }
.vr-ui { position: absolute; left: 0; right: 0; top: 0; padding: calc(12px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 12px max(16px, env(safe-area-inset-left)); display: flex; align-items: center; gap: 10px; color: #fff; background: linear-gradient(rgba(0,0,0,.6), transparent); }
.vr-hint { position: absolute; left: 50%; bottom: 120px; transform: translateX(-50%); color: #fff; font-size: 13px; background: rgba(0,0,0,.5); padding: 8px 14px; border-radius: 18px; display: flex; gap: 8px; align-items: center; transition: opacity .4s; white-space: nowrap; }
.vr-spots { position: absolute; left: 0; right: 0; bottom: 0; padding: 16px; display: flex; gap: 8px; background: linear-gradient(transparent, rgba(0,0,0,.75)); overflow-x: auto; }
.vr-spots button { flex: none; height: 36px; padding: 0 14px; border-radius: 18px; background: rgba(255,255,255,.15); color: #fff; font-size: 13px; font-weight: 600; border: 1px solid rgba(255,255,255,.25); backdrop-filter: blur(6px); }
.vr-spots button.on { background: #fff; color: var(--ink); }
.rv-box { position: absolute; inset: 0; touch-action: auto; }
/* 90차: 인앱 카카오 로드뷰.
   .rv-host 는 카카오 SDK 가 파노라마 캔버스를 그려 넣는 컨테이너입니다.
   SDK 는 생성 시점의 컨테이너 크기를 기준으로 렌더링하므로 반드시 '실제 크기'가
   있어야 합니다(실측: width/height 가 0 이면 회색 빈 화면). 그래서 inset 으로
   .rv-box 를 가득 채웁니다. */
.rv-host { position: absolute; inset: 0; background: #0d1211; }
.rv-host > div { border-radius: 0 !important; }
/* 로드뷰 화면에서는 파노라마를 직접 만지므로 .vr 의 touch-action:none 을 풀어줍니다
   (걸려 있으면 카카오 로드뷰의 드래그 회전이 동작하지 않습니다). */
.rv { touch-action: auto; }
/* '현장까지 약 N m' — 시점을 어디에 맞췄는지 알려주는 근거 표시 */
.rv-meta { align-self: center; flex: none; color: rgba(255,255,255,.75); font-size: 12px; font-weight: 600; white-space: nowrap; padding: 0 4px; }

/* 91차: 로드뷰 화면의 미니 지도 (카카오 로드뷰와 같은 자리·같은 역할)
   - .rv-box 안 absolute 로 두어 파노라마 위에 떠 있게 합니다.
     .rv-box 자체가 inset:0 0 68px 이므로, bottom:14px 이면 하단 버튼줄 바로 위입니다.
   - pointer-events:none — 손가락 드래그가 지도에 먹히지 않고 파노라마로 전달됩니다.
     (지도 드래그도 껐으므로 조작할 것이 없습니다. 표시 전용입니다.) */
.rv-mini {
  position: absolute; left: 14px; bottom: 14px;
  width: 104px; height: 104px;
  border-radius: 10px; overflow: hidden;
  border: 1px solid rgba(255,255,255,.38);
  box-shadow: 0 4px 16px rgba(0,0,0,.45);
  background: #dfe4e0;
  pointer-events: none;
  z-index: 4;
}
.rv-mini > div { border-radius: 0 !important; }

/* 현장 점 — 92차: 빨강(주황)은 '로드뷰가 있는 자리'로 오해되기 쉬워 짙은 회색으로 바꿨습니다.
   이제 '로드뷰 위치'는 아래 .mm-rvicon(카메라 아이콘)이 맡습니다. */
.mm-site {
  width: 9px; height: 9px; border-radius: 50%;
  background: #43524C;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.45);
  box-sizing: border-box;
}

/* ── 92차: 로드뷰 아이콘 + 시야 부채꼴(반경) ───────────────────────
   파노라마(=지금 서 있는 자리)에 카메라 아이콘을 두고, 그 둘레에
   '지금 바라보는 방향'을 나타내는 부채꼴을 겁니다.
   드래그하면 m-detail 이 150ms 마다 pan 을 읽어 .mm-cone 을 회전시킵니다.

   [색을 짙게 바꾼 이유]
    91차에는 흰색 28% 부채꼴을 썼는데, 카카오 지도 배경(밝은 미색) 위에서
     사실상 보이지 않았습니다(실측). 그래서 짙은 청록 + 62% 로 대비를 확보했습니다. */
.mm-panowrap {
  position: relative;
  width: 100px; height: 100px;
  pointer-events: none;
}
/* 부채꼴 — 북쪽(위)을 0°로 그려 두고 transform 으로 회전합니다.
   카카오 지도는 항상 북쪽이 위이고 회전이 없으므로, 방위각(pan)을
   시계방향 회전각으로 그대로 쓰면 됩니다(별도 보정 불필요).
   회전축은 요소 중심 = SVG 좌표 (0,0) = 부채꼴의 꼭짓점입니다. */
.mm-cone {
  position: absolute; left: 0; top: 0;
  width: 100px; height: 100px;
  transform-origin: 50% 50%;
  transform: rotate(0deg);
  will-change: transform;
  transition: transform 90ms linear;
}
/* 로드뷰 카메라 아이콘 — 부채꼴 꼭짓점(중심)에 놓습니다. */
.mm-rvicon {
  position: absolute; left: 50%; top: 50%;
  width: 20px; height: 20px; margin: -10px 0 0 -10px;
  border-radius: 50%;
  background: #22302B;
  border: 1.5px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.5);
  display: grid; place-items: center;
  box-sizing: border-box;
}
.mm-rvicon > svg { display: block; }
/* 좁은 화면에서는 파노라마를 덜 가리도록 조금 줄입니다. */
@media (max-width: 420px) {
  .rv-mini { width: 88px; height: 88px; left: 10px; bottom: 10px; border-radius: 9px; }
}
.rv .vr-ui, .rv .vr-spots, .rv .rv-pan { z-index: 5; }
.rv .vr-ui { pointer-events: none; } .rv .vr-ui > * { pointer-events: auto; }
.rv-state { position: absolute; inset: 0; z-index: 3; background-size: cover; background-position: center; display: grid; place-items: center; padding: 90px 28px 110px; }
.rv-state::before { content: ''; position: absolute; inset: 0; background: rgba(12,20,18,.72); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.rv-state-in { position: relative; color: #fff; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 300px; }
.rv-state-in b { font-size: 15.5px; font-weight: 800; line-height: 1.45; text-wrap: pretty; }
.rv-state-in small { font-size: 12.5px; line-height: 1.6; opacity: .72; text-wrap: pretty; }
.rv-badge { width: 44px; height: 44px; border-radius: 11px; display: grid; place-items: center; font-weight: 900; font-size: 19px; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.25); }
.rv-state-acts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 8px; }
.rv-ghost { height: 38px; padding: 0 14px; border-radius: 19px; border: 1px solid rgba(255,255,255,.35); color: #fff; background: rgba(255,255,255,.08); font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; text-decoration: none; }
.rv-spin { display: block; width: 28px; height: 28px; border-radius: 50%; border: 2.5px solid rgba(255,255,255,.25); border-top-color: #fff; animation: vspin .8s linear infinite; }
.rv-pan { position: absolute; right: 14px; bottom: 84px; display: flex; gap: 6px; }
.rv-pan button { width: 40px; height: 40px; border-radius: 50%; background: rgba(0,0,0,.45); border: 1px solid rgba(255,255,255,.25); display: grid; place-items: center; backdrop-filter: blur(6px); }
.compass { position: absolute; right: max(16px, env(safe-area-inset-right)); top: calc(70px + env(safe-area-inset-top)); width: 48px; height: 48px; border-radius: 50%; border: 1px solid rgba(255,255,255,.4); color: #fff; display: grid; place-items: center; font-family: var(--mono); font-size: 10px; }
.compass i { position: absolute; top: 4px; left: 50%; width: 2px; height: 10px; background: var(--accent); margin-left: -1px; transform-origin: 1px 20px; }

/* Chat */
.chat-body { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; background: #EEEAE1; }
.msg { max-width: 78%; font-size: 14px; line-height: 1.55; padding: 10px 13px; border-radius: 14px; white-space: pre-wrap; letter-spacing: -0.01em; }
.msg.them { background: #fff; align-self: flex-start; border-top-left-radius: 3px; }
.msg.me { background: var(--ink); color: #fff; align-self: flex-end; border-top-right-radius: 3px; }
.msg-meta { font-size: 10.5px; color: var(--mute); margin-top: -4px; }
.msg-meta.me { align-self: flex-end; }
.typing { display: flex; gap: 4px; padding: 14px; }
.typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--mute-2); animation: ty 1s infinite; }
.typing i:nth-child(2) { animation-delay: .15s; } .typing i:nth-child(3) { animation-delay: .3s; }
@keyframes ty { 0%,100% { opacity: .3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }
/* 39차: 하단 safe-area 인셋을 더합니다. .tabs / .bottom-cta 와 같은 규칙입니다.
   #root 는 100dvh(viewport-fit=cover) 라 .app 의 바닥이 홈 인디케이터 영역까지 내려갑니다.
   패딩이 없으면 입력창·전송 버튼이 인디케이터에 가립니다. */
.chat-input { flex: none; display: flex; gap: 8px; padding: 10px 12px calc(10px + env(safe-area-inset-bottom)); background: var(--card); border-top: 1px solid var(--line); align-items: center; }
/* font-size 16px — iOS Safari 는 16px 미만 입력창에 포커스하면 화면을 강제 확대합니다. */
/* 39차: min-width:0 이 없으면 flex 자식의 기본 min-width:auto 가 input 을 콘텐츠 최소폭
   밑으로 줄지 못하게 막습니다. 그 결과 input(340) + gap(8) + send(44) + 좌우패딩(24) = 404px 로
   뷰포트(390)를 14px 넘어가 전송 버튼이 화면 밖으로 잘렸습니다(모바일 실측).
   .jsearch input / .search-box input 과 동일한 처리입니다. */
.chat-input input { flex: 1; min-width: 0; height: 44px; border-radius: 22px; border: 1px solid var(--line); padding: 0 16px; font-size: 16px; background: var(--paper); outline: none; }
.send { width: 44px; height: 44px; border-radius: 50%; background: var(--accent); display: grid; place-items: center; flex: none; }
.send:disabled { background: var(--mute-2); }
.quick-q { display: flex; gap: 6px; overflow-x: auto; padding: 8px 12px 0; background: var(--card); scrollbar-width: none; }
.quick-q::-webkit-scrollbar { display: none; }
.quick-q button { flex: none; font-size: 12.5px; padding: 7px 11px; border-radius: 16px; background: var(--paper); border: 1px solid var(--line); font-weight: 600; }

/* Forms */
.field { margin-bottom: 22px; }
.field > label { display: block; font-size: 13px; font-weight: 700; margin-bottom: 10px; color: var(--ink-2); }
.input { width: 100%; height: 50px; border: 1px solid var(--line); border-radius: 4px; padding: 0 14px; font-size: 16px; background: var(--card); outline: none; }
.input:focus { border-color: var(--ink); }
.seg { display: grid; gap: 6px; }
.seg button { height: 46px; border: 1px solid var(--line); background: var(--card); border-radius: 4px; font-size: 14px; font-weight: 600; }
.seg button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.seg button:disabled { color: var(--mute-2); background: var(--line-2); text-decoration: line-through; }
.days { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin: 0 -20px; padding: 0 20px; }
.days::-webkit-scrollbar { display: none; }
.days button { flex: none; width: 54px; height: 66px; border: 1px solid var(--line); background: var(--card); border-radius: 4px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }
.days button small { font-size: 11px; color: var(--mute); }
.days button b { font-size: 18px; font-weight: 800; font-family: var(--mono); }
.days button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.days button.on small { color: rgba(255,255,255,.6); }
.days button.sun small { color: var(--accent); }
.site-pick { display: flex; gap: 10px; align-items: center; padding: 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--card); width: 100%; text-align: left; margin-bottom: 6px; }
.site-pick.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.site-pick img { width: 52px; height: 52px; object-fit: cover; border-radius: 3px; }
.site-pick b { font-size: 14px; display: block; }
.site-pick small { font-size: 12px; color: var(--mute); }

/* 40차: 방문예약 현장 검색. 물건이 수백·수천 건이 되어도 상단에서 바로 찾을 수 있게 합니다.
   min-width:0 이 없으면 flex 자식의 기본 min-width:auto 때문에 input 이 콘텐츠 최소폭
   밑으로 줄지 못해 좁은 화면에서 가로로 넘칩니다. .jsearch input 과 같은 처리입니다. */
.site-search { display: flex; align-items: center; gap: 8px; height: 44px; border: 1px solid var(--line); border-radius: 4px; background: var(--card); padding: 0 13px; margin-bottom: 6px; }
.site-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; font-family: inherit; font-size: 16px; color: var(--ink); -webkit-appearance: none; appearance: none; }
.site-search input::placeholder { color: var(--mute-2); }
.site-search input::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
.site-search .clr { flex: none; width: 24px; height: 24px; border-radius: 50%; border: 0; background: var(--line-2); display: grid; place-items: center; padding: 0; }
.site-count { font-size: 12px; color: var(--mute); margin: 0 0 8px 2px; }

.check { width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid var(--line); flex: none; margin-left: auto; display: grid; place-items: center; }
.on > .check { background: var(--ink); border-color: var(--ink); }

/* Done ticket */
.ticket { margin: 20px; background: var(--card); border-radius: 6px; overflow: hidden; border: 1px solid var(--line); }
.ticket-top { background: var(--ink); color: #fff; padding: 22px 20px; }
.ticket-top small { font-family: var(--mono); font-size: 10px; letter-spacing: .14em; color: var(--brass); }
.ticket-top h3 { font-family: var(--serif); font-size: 22px; margin: 6px 0 0; }
.ticket-cut { height: 0; border-top: 2px dashed var(--line); margin: 0 14px; position: relative; }
.ticket-cut::before, .ticket-cut::after { content: ''; position: absolute; top: -11px; width: 20px; height: 20px; border-radius: 50%; background: var(--paper); }
.ticket-cut::before { left: -24px; } .ticket-cut::after { right: -24px; }
.ticket-body { padding: 20px; }
.qr { width: 148px; height: 148px; margin: 4px auto 10px; display: grid; grid-template-columns: repeat(21, 1fr); gap: 0; padding: 8px; border: 1px solid var(--line); }
.qr i { background: var(--ink); }
.qr i.o { background: transparent; }

/* 46차: 부동산계산기 삭제에 따라 .calc-tabs / .range / .calc-out / .lbl-row 규칙을 함께 제거했습니다.
   (계산기가 유일한 사용처였고, MGM스튜디오는 studio.css 를 씁니다.
    .seg 는 MY › 멤버십(m-account.js)에서 계속 쓰므로 그대로 둡니다.) */

/* My */
/* 50차: 참고 이미지 반영 — 화면 끝까지 채우던 먹색 띠를 '여백이 있는 둥근 카드'로 바꾸고,
   우상단에 금빛 앰비언트 글로우를 얹었습니다. MGM스튜디오 상단(.st-topcard)과 같은 문법입니다. */
.my-head {
  position: relative; overflow: hidden;
  margin: calc(10px + env(safe-area-inset-top)) 14px 0;
  padding: 20px 18px 18px;
  border-radius: 14px;
  color: var(--paper);
  background: linear-gradient(166deg, #2B2521 0%, #18140F 54%, #100D0A 100%);
  box-shadow: 0 8px 24px rgba(16, 13, 10, .22), inset 0 1px 0 rgba(255, 255, 255, .10);
}
.my-head::after {
  content: ''; position: absolute; top: -110px; right: -70px; width: 250px; height: 250px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle,
    rgba(228, 192, 126, .40) 0%, rgba(200, 158, 92, .17) 38%, rgba(184, 137, 63, 0) 70%);
}
.my-head > * { position: relative; z-index: 1; }
.my-head h2 { font-family: var(--serif); font-size: 24px; font-weight: 700; letter-spacing: -.03em;
  margin: 0 0 9px; color: #FBF5E7; }
.my-head small { opacity: .58; font-size: 12px; letter-spacing: -.01em; }
.my-id { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.my-id-txt { min-width: 0; }
.my-sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 등급 배지 — 참고 이미지처럼 '금테 아웃라인 알약'. 어두운 카드 위에서 등급과 무관하게 같은 톤으로 읽힙니다.
   (.my-head 안에서만 적용되므로 백오피스·시스템관리의 배지는 영향을 받지 않습니다.)
   주의: `.my-head .mbadge`(0,2,0) 로는 아래 `.mbadge.general`(0,2,0) 과 명시도가 같아
   소스 순서상 뒤에 오는 `.mbadge.*` 가 이깁니다(실측: 배경이 --line-2 크림색으로 덮였음).
   그래서 `.my-sub` 를 한 단계 더 물려 (0,3,0) 으로 올립니다. */
.my-head .my-sub .mbadge {
  background: rgba(255, 255, 255, .04);
  color: #EBD3A0;
  box-shadow: inset 0 0 0 1px rgba(206, 174, 116, .62);
  height: 20px; padding: 0 7px; font-size: 10.5px; letter-spacing: .05em;
}
.my-head .my-partner { background: transparent; border-color: rgba(206, 174, 116, .55);
  color: #EFDCB6; height: 32px; font-size: 12.5px; flex: none; }

/* 보유 리워드 — 금테 박스 */
.point-card {
  margin-top: 16px; padding: 13px 14px;
  border-radius: 10px;
  border: 1px solid rgba(206, 174, 116, .34);
  background: rgba(255, 255, 255, .035);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.pc-label { display: block; font-size: 11.5px; color: rgba(245, 242, 235, .55);
  letter-spacing: -.01em; margin-bottom: 2px; }
.point-card b { font-family: var(--serif); font-size: 26px; font-weight: 700;
  color: #E9CFA0; letter-spacing: -.02em; display: flex; align-items: baseline; gap: 4px; }
.point-card b i { font-style: normal; font-size: 15px; font-weight: 700; color: #E9CFA0; }
/* 22차: QR 인증 버튼 — 어두운 카드 위에서 .pill-btn 기본값(흰 배경 + --paper 글자)이
   겹쳐 '흰 바탕에 흰 글자'로 읽히지 않았습니다. 카드 톤에 맞춘 반투명 + 황동 테두리로 교체합니다. */
.point-card .pill-btn {
  background: rgba(184, 137, 63, .16);
  border-color: rgba(184, 137, 63, .55);
  color: var(--brass-soft);
  height: 34px;
  border-radius: 999px;
  font-weight: 700;
  letter-spacing: -0.01em;
  transition: background .16s, border-color .16s;
}
.point-card .pill-btn:hover { background: rgba(184, 137, 63, .26); border-color: rgba(184, 137, 63, .8); }
.point-card .pill-btn:active { background: rgba(184, 137, 63, .34); }
.point-card .pill-btn svg { color: var(--brass); }
/* 참고 이미지의 '방문예약 내역'처럼, MY 본문의 섹션 제목 아래에 금장 가는 줄을 긋습니다.
   (.my-head 뒤에 오는 .sec 에만 적용 — 다른 화면의 .sec-h 는 그대로입니다.) */
.my-head ~ .sec .sec-h { border-bottom: 1px solid rgba(194, 160, 95, .34); padding-bottom: 10px; }
.my-head ~ .sec .sec-h h2 { font-family: var(--serif); font-weight: 700; letter-spacing: -.03em; }
.list-btn { width: 100%; display: flex; align-items: center; gap: 12px; padding: 16px 0; border-bottom: 1px solid var(--line-2); font-size: 15px; font-weight: 600; text-align: left; }
.list-btn .cnt { margin-left: auto; font-size: 13px; color: var(--mute); font-weight: 600; display: flex; align-items: center; gap: 4px; }

/* Admin */
.admin { background: #F2F3F1; }
.adm-tabs { display: flex; background: var(--ink); padding: 0 12px; gap: 4px; flex: none; }
.adm-tabs button { color: rgba(255,255,255,.5); font-size: 14px; font-weight: 700; padding: 12px 10px 14px; border-bottom: 2px solid transparent; }
.adm-tabs button.on { color: #fff; border-color: var(--brass); }
.kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.kpi { background: #fff; border-radius: 4px; padding: 14px; border: 1px solid #E3E5E1; }
.kpi small { font-size: 12px; color: var(--mute); font-weight: 600; }
.kpi b { display: block; font-family: var(--mono); font-size: 22px; margin: 6px 0 2px; letter-spacing: -0.02em; }
.kpi .d { font-size: 11.5px; font-weight: 700; color: var(--ok); }
.kpi .d.neg { color: var(--accent); }
.panel { background: #fff; border: 1px solid #E3E5E1; border-radius: 4px; padding: 16px; margin-top: 10px; }
.panel h5 { margin: 0 0 14px; font-size: 14px; font-weight: 800; display: flex; justify-content: space-between; align-items: center; }
.panel h5 small { font-weight: 600; color: var(--mute); font-size: 11.5px; }
.bars { display: flex; align-items: flex-end; gap: 3px; height: 110px; }
.bars i { flex: 1; background: var(--forest); border-radius: 1px 1px 0 0; min-height: 2px; position: relative; }
.bars i.pk { background: var(--brass); }
.bars-x { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9.5px; color: var(--mute-2); margin-top: 6px; }
.hbar { display: grid; grid-template-columns: 110px 1fr 38px; align-items: center; gap: 10px; font-size: 12.5px; margin-bottom: 10px; }
.hbar .tr { height: 8px; background: #EEF0EC; border-radius: 4px; overflow: hidden; }
.hbar .tr i { display: block; height: 100%; background: var(--forest); border-radius: 4px; }
.hbar b { font-family: var(--mono); font-size: 12px; text-align: right; }
.sched { display: grid; grid-template-columns: 48px 1fr auto; gap: 10px; padding: 12px 0; border-bottom: 1px solid #EEF0EC; align-items: center; }
.sched:last-child { border: 0; }
.sched .t { font-family: var(--mono); font-size: 12.5px; font-weight: 700; }
.sched b { font-size: 13.5px; display: block; }
.sched small { font-size: 12px; color: var(--mute); }
.st { font-size: 11px; font-weight: 700; padding: 4px 8px; border-radius: 2px; }
.st.done { background: #E8F2EC; color: var(--ok); }
.st.ing { background: var(--brass-soft); color: #7A5A22; }
.st.plan { background: #EEF0EC; color: var(--mute); }
table.tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tbl th { text-align: left; color: var(--mute); font-weight: 600; padding: 0 0 8px; border-bottom: 1px solid #EEF0EC; }
.tbl td { padding: 10px 0; border-bottom: 1px solid #EEF0EC; }
.tbl td.n { font-family: var(--mono); text-align: right; }
.tbl th.n { text-align: right; }

.empty { text-align: center; padding: 60px 20px; color: var(--mute); font-size: 14px; }

.toast { position: absolute; left: 50%; bottom: 90px; transform: translateX(-50%); background: var(--ink); color: #fff; font-size: 13px; padding: 11px 16px; border-radius: 22px; z-index: 100; white-space: nowrap; animation: tin .25s ease-out; }
@keyframes tin { from { opacity: 0; transform: translate(-50%, 8px); } }

/* 정리(20차): .sheet-bg / .sheet 구(舊) 정의를 삭제했습니다.
   뒤쪽 .sheet-wrap / .sheet 정의가 두 규칙의 속성을 전부 덮어써 이미 죽은 코드였습니다.
   (.sheet-bg 는 JS·셸 어디에서도 사용되지 않았습니다)
   단, @keyframes fade 는 .lightbox(411행), @keyframes up 은 .mgm-seal(616행)이
   계속 사용하므로 keyframes 정의는 남깁니다. */
@keyframes fade { from { opacity: 0; } }
@keyframes up { from { transform: translateY(100%); } }
.rv-opt { width: 100%; display: flex; align-items: center; gap: 12px; padding: 14px; margin-bottom: 8px; border: 1px solid var(--line); border-radius: 8px; background: #fff; text-align: left; color: var(--ink); }
.rv-opt:active { background: var(--line); }
.rv-logo { width: 38px; height: 38px; border-radius: 9px; display: grid; place-items: center; font-weight: 900; font-size: 17px; flex: none; }
.rv-opt.kakao .rv-logo { background: #FEE500; color: #191600; }
.rv-opt.naver .rv-logo { background: #03C75A; color: #fff; }
.rv-opt.photo .rv-logo { background: var(--ink); }
.rv-t { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.rv-t b { font-size: 15px; font-weight: 800; }
.rv-t small { font-size: 12px; color: var(--mute); }
.rv-ext { font-size: 16px; color: var(--mute); }
.rv-note { margin-top: 6px; font-size: 11.5px; line-height: 1.55; color: var(--mute); }
.sheet .grab { width: 40px; height: 4px; background: var(--line); border-radius: 2px; margin: 0 auto 16px; }

/* 35차: min-width:0 이 없으면 flex 자식이 min-content(≈372px) 밑으로 줄지 못합니다.
   그러면 #root 에 가로 오버플로가 생기고, autofocus 된 input 을 보이게 하려고
   브라우저가 #root 를 가로로 스크롤해 화면 전체가 왼쪽으로 밀립니다(검색 화면 41px 틀어짐).
   flex 컨테이너/자식 양쪽에 min-width:0 을 둬서 실제 가용폭까지 줄어들게 합니다. */
.search-box { margin: 4px 16px 0; height: 48px; border-radius: 24px; background: var(--card); border: 1px solid var(--line); display: flex; align-items: center; padding: 0 16px; gap: 10px; min-width: 0; }
.search-box input { border: 0; outline: 0; background: none; flex: 1; min-width: 0; font-size: 16px; }

/* media grid */
.mediagrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.mediacell { position: relative; height: 116px; border-radius: 3px; overflow: hidden; border: 1px solid var(--line); background: var(--line-2); }
.mediacell.wide { grid-column: 1 / -1; height: 200px; }
.mediacell img { width: 100%; height: 100%; object-fit: cover; }
.mediacell .mtag { position: absolute; left: 0; bottom: 0; right: 0; padding: 18px 10px 8px; font-size: 12px; font-weight: 700; color: #fff; text-align: left; background: linear-gradient(transparent, rgba(18,32,28,.82)); }

/* 64차: 분양자료(PDF) 자료실 — 갤러리(.mediagrid)와 다른 목록형입니다.
   PDF 는 이미지가 아니라 파일이라 썸네일 대신 아이콘 + 파일명 + 크기로 보여줍니다. */
.doclist { display: grid; gap: 8px; }
.docitem { display: grid; grid-template-columns: 42px 1fr 22px; gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--line); border-radius: 5px; background: var(--card); text-decoration: none; color: inherit; }
.docitem:active { background: var(--line-2); }
.docitem .dicon { display: grid; place-items: center; height: 42px; border-radius: 4px; background: var(--brass-soft); color: #7A5A22; font-size: 10.5px; font-weight: 800; letter-spacing: .04em; }
.docitem .dinfo { min-width: 0; display: grid; gap: 2px; }
.docitem .dinfo b { font-size: 13.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.docitem .dinfo small { font-size: 11.5px; color: var(--mute); }
.docitem .dgo { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--brass-soft); color: #7A5A22; font-size: 11.5px; font-weight: 700; }

.lightbox { position: absolute; inset: 0; background: #101A17; z-index: 80; display: flex; flex-direction: column; animation: fade .2s; }
.lightbox .lb-top { flex: none; display: flex; align-items: center; gap: 8px; padding: 10px 8px 10px 18px; color: #fff; background: rgba(255,255,255,.06); }
.lightbox .lb-top b { flex: 1; font-size: 15px; text-align: left; }
.lightbox img { flex: 1; min-height: 0; width: 100%; object-fit: contain; padding: 14px; }
.lightbox .lb-bot { flex: none; text-align: center; color: rgba(255,255,255,.7); font-size: 13px; padding: 10px 20px 24px; }

/* 뉴스 카테고리 (앱 공용) */
.ncat { display: inline-flex; align-items: center; height: 21px; padding: 0 7px; font-size: 11px; font-weight: 800; border-radius: 2px; letter-spacing: -0.01em; white-space: nowrap; }
.ncat.cat1 { background: #E7F0F4; color: #23405A; }
.ncat.cat2 { background: var(--brass-soft); color: #7A5A22; }
.ncat.cat3 { background: #E7F2EB; color: #1F5F42; }
.ncat.cat4 { background: #EFEAF6; color: #4B3A73; }
.nlead { background: var(--line-2); border-radius: 4px; padding: 20px; }
.nlead b { display: block; font-size: 17px; font-weight: 700; line-height: 1.45; margin-top: 10px; letter-spacing: -0.02em; text-wrap: pretty; }
.leadcard { display: block; text-align: left; padding: 0 20px; width: 100%; transition: opacity .15s; }
.leadcard:active { opacity: .7; }
.leadcard .leadsum { font-size: 13.5px; color: var(--mute); line-height: 1.7; margin-bottom: 10px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-wrap: pretty; }
.leadcard .leadtitle { font-family: var(--serif); font-size: 20px; font-weight: 700; line-height: 1.42; margin: 6px 0 10px; letter-spacing: -0.02em; text-wrap: pretty; }
.leadcard .leadby { font-size: 12px; color: var(--mute-2); margin-top: 12px; }
.summ { background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--brass); border-radius: 3px; padding: 16px; }
.summ b { font-size: 12px; color: var(--brass); letter-spacing: .04em; }
.summ p { margin: 8px 0 0; font-size: 15px; line-height: 1.8; color: #2C3632; text-wrap: pretty; }

/* 품질 다듬기 — 그림자·여백·상태 */
.banner { box-shadow: 0 14px 36px rgba(18,32,28,.16); }
.quick button:active { background: var(--line-2); }
.card, .pcell, .chartwrap, .deals, .points div, .mediacell { transition: border-color .15s, box-shadow .15s; }
.pcell:hover, .chartwrap:hover { border-color: var(--line-2); }
.bottom-cta { box-shadow: 0 -6px 20px rgba(18,32,28,.05); }
.topbar { transition: background .2s; }
.sec-h h2 { line-height: 1.35; }
.article p:first-of-type::first-letter { font-size: 1.05em; }

/* 스크롤바 (데스크톱에서 앱을 볼 때) */
@media (min-width: 480px) {
  .scroll::-webkit-scrollbar { width: 6px; }
  .scroll::-webkit-scrollbar-thumb { background: rgba(18,32,28,.14); border-radius: 3px; }
  .scroll::-webkit-scrollbar-track { background: transparent; }
}

.foot { padding: 32px 20px 36px; font-size: 11.5px; color: var(--mute-2); line-height: 1.7; }
.foot b { font-family: var(--serif); color: var(--mute); font-size: 14px; }

.screen-enter { animation: sc .28s cubic-bezier(.2,.8,.2,1); }
@keyframes sc { from { opacity: 0; transform: translateX(16px); } }

.article h2 { font-family: var(--serif); font-size: 23px; line-height: 1.4; margin: 10px 0 10px; letter-spacing: -0.02em; text-wrap: pretty; }
.article p { font-size: 15.5px; line-height: 1.85; margin: 0 0 18px; color: #2C3632; letter-spacing: -0.01em; text-wrap: pretty; }

/* ── 멤버십 · 휴대폰 소액결제 ── */
.mono { font-family: var(--mono); }
.mbadge { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 11px; font-size: 11px; font-weight: 800; letter-spacing: .02em; }
.mbadge.general { background: var(--line-2); color: var(--mute); }
.mbadge.partner { background: var(--forest); color: #fff; }
.mbadge.gold { background: linear-gradient(135deg,#E9CF8A,#C9A04E); color: #3A2A08; }
.mbadge.ruby { background: linear-gradient(135deg,#B3264A,#7E1430); color: #fff; }
.mbadge.vip { background: #111; color: var(--brass); box-shadow: inset 0 0 0 1px var(--brass); }
/* 63차: core.js 의 MemberBadge 는 dark 프롭을 받으면 class 에 ' dark' 를 붙입니다
   (core.js:155 → 'mbadge ' + tier + (dark ? ' dark' : '')). 그런데 CSS 에는
   `.mbadge.general.dk` 밖에 없었습니다 — 'dk' 는 JS 어디에서도 만들지 않는 죽은 선택자였고,
   'dark' 는 스타일이 없어 아무 효과가 없었습니다.
   그래서 먹색 패널(.mb-now) 위에서도 크림색 general 배지가 그대로 떠 보였습니다.
   (실측: m-account.js:482 가 dark=${true} 로 넘기지만 계산된 배경이 --line-2 그대로)
   등급별 규칙(.mbadge.gold 등, 명시도 0,2,0)보다 뒤에 두어 dark 가 이기게 합니다. */
.mbadge.dark { background: rgba(255,255,255,.10); color: #EBD3A0; box-shadow: inset 0 0 0 1px rgba(206,174,116,.55); }
.mb-now { background: var(--ink); color: var(--paper); border-radius: 6px; padding: 18px; }
.mb-now small { font-size: 12px; opacity: .6; }
.mb-now b { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; }
.mb-now p { margin: 8px 0 0; font-size: 13px; line-height: 1.6; opacity: .72; }
.tier-card { width: 100%; text-align: left; background: var(--card); border: 1.5px solid var(--line); border-radius: 6px; padding: 16px; transition: border-color .15s, box-shadow .15s; }
.tier-card.on { border-color: var(--ink); box-shadow: 0 0 0 3px rgba(18,32,28,.06); }
.tier-card.vip.on { border-color: var(--brass); box-shadow: 0 0 0 3px rgba(184,137,63,.14); }
.tier-card.gold.on { border-color: #C9A04E; box-shadow: 0 0 0 3px rgba(201,160,78,.15); }
.tier-card.ruby.on { border-color: #9B1D3D; box-shadow: 0 0 0 3px rgba(155,29,61,.12); }
.tc-mgm { float: right; font-size: 11.5px; font-weight: 800; padding: 3px 8px; border-radius: 3px; background: var(--line-2); color: var(--mute); }
.tc-mgm.on { background: var(--ink); color: var(--brass-soft); }
.tc-h { display: flex; align-items: center; gap: 8px; }
.tc-mine { font-size: 11px; font-weight: 700; color: var(--ok, #2F8A5F); }
.tc-price { margin-left: auto; font-size: 13px; color: var(--mute); }
.tc-price b { font-family: var(--mono); font-size: 20px; color: var(--ink); }
.tc-q { margin-top: 12px; font-size: 14px; color: var(--ink-2); }
.tc-q b { font-weight: 800; }
.tier-card ul { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 5px; }
.tier-card li { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--mute); }
.tier-card li svg { color: var(--brass); flex: none; }
.mb-compare { margin-top: 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); overflow: hidden; }
.mb-compare .row { display: grid; grid-template-columns: 1.5fr repeat(5, 1fr); gap: 2px; padding: 11px 10px; border-top: 1px solid var(--line-2); font-size: 12.5px; text-align: center; color: var(--ink-2); }
.mb-compare .row span:first-child { text-align: left; color: var(--mute); }
.mb-compare .row.h { border-top: 0; background: var(--paper); font-weight: 800; font-size: 12px; }
.mb-compare p { margin: 0; padding: 10px 14px 12px; font-size: 11.5px; color: var(--mute-2); border-top: 1px solid var(--line-2); }
.kv-row { display: flex; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line-2); font-size: 13.5px; }
.kv-row:last-child { border-bottom: 0; }
.kv-row span { color: var(--mute); }
.sheet-wrap { position: absolute; inset: 0; z-index: 60; background: rgba(10,18,16,.5); display: flex; align-items: flex-end; animation: fadeIn .2s; }
/* overscroll-behavior: contain — 시트 스크롤이 끝에 닿아도 배경으로 체이닝(iOS 바운스)되지 않게 합니다. */
.sheet { width: 100%; max-height: 92%; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--paper); border-radius: 14px 14px 0 0; padding: 6px max(20px, env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); animation: sheetUp .28s cubic-bezier(.2,.8,.2,1); }
.sheet-h { display: flex; align-items: center; justify-content: space-between; height: 54px; }
.sheet-h b { font-size: 17px; font-weight: 800; }
.pay-sum { display: flex; justify-content: space-between; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: 6px; padding: 14px 16px; margin-bottom: 20px; font-size: 13.5px; color: var(--mute); }
.pay-sum b { font-family: var(--mono); font-size: 18px; color: var(--ink); }
.agree { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; font-size: 13.5px; font-weight: 600; padding: 4px 0 10px; }
.agree .box { width: 22px; height: 22px; border-radius: 4px; border: 1.5px solid var(--line); display: grid; place-items: center; flex: none; background: var(--card); }
.agree.on .box { background: var(--ink); border-color: var(--ink); }
.pay-note { font-size: 12px; color: var(--mute); line-height: 1.6; margin: 0 0 16px; }
.pay-done { text-align: center; padding: 10px 0 20px; }
.pay-done .ok { width: 56px; height: 56px; border-radius: 50%; background: var(--ok, #2F8A5F); display: inline-grid; place-items: center; }
.pay-done h3 { margin: 14px 0 6px; font-size: 19px; font-weight: 800; letter-spacing: -0.02em; }
.pay-done p { margin: 0; font-size: 14px; color: var(--mute); }
.btn.ghost { flex: none; }
a.btn.ghost { width: 100%; }
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* 시스템관리 연동 — 공지 띠 · 점검 화면 */
.notice-strip { flex: none; display: flex; align-items: center; gap: 8px; background: var(--ink); color: #fff; font-size: 12.5px; padding: 8px 16px; }
.notice-strip b { flex: none; font-size: 11px; font-weight: 800; color: var(--brass); letter-spacing: .04em; }
.notice-strip span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app.maint { align-items: center; justify-content: center; text-align: center; padding: 32px; background: var(--paper); }
.app.maint img { height: 56px; width: auto; margin-bottom: 28px; }
.app.maint h2 { margin: 0 0 10px; font-size: 22px; font-weight: 800; letter-spacing: -0.03em; }
.app.maint p { margin: 0 0 18px; font-size: 14px; line-height: 1.7; color: var(--mute); text-wrap: pretty; }
.app.maint .until { font-size: 13px; color: var(--mute); background: var(--card); border: 1px solid var(--line); border-radius: 4px; padding: 10px 14px; }
.app.maint .until b { font-family: var(--mono); color: var(--ink); margin-left: 6px; }
.app.maint small { margin-top: 22px; font-size: 12px; color: var(--mute-2); }

/* VIP 파트너 통계 · 상담관리 */
.list-btn.locked-row { color: var(--mute); }
.list-btn.locked-row .cnt { color: var(--brass); font-weight: 700; font-size: 12px; }
.desk-lock { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 32px 28px 60px; }
.desk-lock h3 { margin: 16px 0 8px; font-size: 19px; font-weight: 800; letter-spacing: -0.03em; }
.desk-lock p { margin: 0 0 24px; font-size: 14px; color: var(--mute); line-height: 1.65; text-wrap: pretty; }
.desk-notice { display: flex; gap: 8px; background: var(--brass-soft); color: #6E5524; font-size: 12.5px; line-height: 1.55; padding: 10px 12px; border-radius: 4px; margin-bottom: 12px; }
.desk-notice b { flex: none; font-weight: 800; color: #5A4419; }

/* 현장 상세 — 홍보영상 */
.promo { position: relative; aspect-ratio: 16 / 9; border-radius: 6px; overflow: hidden; background: #111; }
.promo video, .promo iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000; }
.promo-cover { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; }
.promo-cover img { width: 100%; height: 100%; object-fit: cover; }
.promo-cover::after { content: ''; position: absolute; inset: 0; background: linear-gradient(transparent 45%, rgba(0,0,0,.65)); }
.promo-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -60%); width: 58px; height: 58px; border-radius: 50%; background: rgba(255,255,255,.94); display: grid; place-items: center; z-index: 2; box-shadow: 0 6px 20px rgba(0,0,0,.3); padding-left: 3px; }
.promo-cap { position: absolute; left: 14px; right: 14px; bottom: 12px; z-index: 2; display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; color: #fff; text-align: left; }
.promo-cap b { font-size: 15px; font-weight: 800; letter-spacing: -0.02em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.promo-cap small { flex: none; font-family: var(--mono); font-size: 11.5px; background: rgba(0,0,0,.55); padding: 2px 6px; border-radius: 2px; }
.promo .noposter { display: block; width: 100%; height: 100%; background: repeating-linear-gradient(135deg, #2a302d 0 8px, #232825 8px 16px); }
.promo.empty-promo { aspect-ratio: auto; height: 120px; background: var(--card); border: 1px dashed var(--line); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; font-size: 13px; color: var(--mute); }
.promo-list { display: flex; gap: 10px; overflow-x: auto; margin-top: 10px; scrollbar-width: none; }
.promo-list::-webkit-scrollbar { display: none; }
.promo-item { flex: none; width: 140px; text-align: left; }
.promo-item .pt { position: relative; display: block; width: 140px; height: 79px; border-radius: 4px; overflow: hidden; background: #111; border: 2px solid transparent; }
.promo-item.on .pt { border-color: var(--brass); }
.promo-item .pt img { width: 100%; height: 100%; object-fit: cover; }
.promo-item .pt em { position: absolute; right: 4px; bottom: 4px; font-style: normal; font-family: var(--mono); font-size: 10px; color: #fff; background: rgba(0,0,0,.65); padding: 1px 4px; border-radius: 2px; }
.promo-item b { display: block; font-size: 12.5px; font-weight: 700; margin-top: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spin.light { display: block; width: 22px; height: 22px; border-radius: 50%; border: 2.5px solid rgba(0,0,0,.15); border-top-color: var(--ink); animation: vspin .8s linear infinite; }
@keyframes vspin { to { transform: rotate(360deg); } }

.yt-out { position: absolute; right: 8px; top: 8px; z-index: 3; font-size: 11px; font-weight: 700; color: #fff; background: rgba(0,0,0,.6); padding: 4px 8px; border-radius: 3px; text-decoration: none; opacity: 0; transition: opacity .2s; }
.promo:hover .yt-out, .vframe:hover .yt-out, .promo:focus-within .yt-out { opacity: 1; }
@media (hover: none) { .yt-out { opacity: .85; } }

/* ───────── MGM등록 (고객정보 전달) ───────── */
.dt-title { display: flex; align-items: flex-start; gap: 12px; }
.dt-title h2 { flex: 1; min-width: 0; }
.mgm-btn { flex: none; margin-top: 12px; height: 34px; padding: 0 12px 0 11px; border-radius: 3px; background: var(--ink); color: #fff; display: inline-flex; align-items: center; box-shadow: 0 0 0 1px var(--ink), inset 0 0 0 1px rgba(184,137,63,.55); transition: transform .15s; }
.mgm-btn:active { transform: scale(.96); }
.mgm-mark { display: inline-flex; align-items: baseline; gap: .28em; line-height: 1; white-space: nowrap; }
.mgm-mark b { font-family: var(--logo); font-weight: 800; letter-spacing: .01em; font-size: 1em; }
/* 115차: 서비스명 MGM → 인투인. 브랜드가 'MGM'(라틴) → '인투인'(한글) 이 되면서
   금장 마침표(b::after '.')는 '인투인.' 으로 읽혀 어색합니다. 표시하지 않습니다.
   (규칙은 지우지 않고 content 만 비워, 되돌릴 때 한 줄만 고치면 됩니다.) */
.mgm-mark b::after { content: none; }
.mgm-mark span { font-family: var(--serif); font-weight: 700; font-size: .78em; letter-spacing: .02em; }
.mgm-btn .mgm-mark span { color: var(--brass-soft); }

.mgm-sheet { padding-bottom: calc(22px + env(safe-area-inset-bottom)); }
.mgm-sh { display: flex; align-items: center; height: 40px; margin-bottom: 10px; }
.mgm-site { display: flex; gap: 12px; align-items: center; padding: 10px; background: var(--card); border: 1px solid var(--line); border-radius: 6px; margin-bottom: 16px; }
.mgm-site img, .mgm-site .imgph { width: 56px; height: 42px; object-fit: cover; border-radius: 3px; flex: none; }
.mgm-site b { display: block; font-size: 14.5px; font-weight: 800; letter-spacing: -.02em; }
.mgm-site small { font-size: 12px; color: var(--mute); }

.mgm-route { display: flex; align-items: center; gap: 8px; margin-bottom: 20px; padding: 12px 14px; border-radius: 6px; background: var(--ink); color: #fff; }
.mgm-node { flex: 1; display: flex; align-items: center; gap: 9px; min-width: 0; }
/* 자식 div 도 줄어들어야 320px 에서 텍스트가 카드 밖으로 넘치지 않습니다. */
.mgm-node > div { min-width: 0; flex: 1; }
.mgm-node .av { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: rgba(255,255,255,.12); font-family: var(--serif); font-weight: 700; font-size: 14px; flex: none; }
.mgm-node .av.vip { background: var(--brass); }
.mgm-node small { display: block; font-size: 10.5px; opacity: .6; }
/* 320~360px 에서 nowrap 때문에 시트에 가로 스크롤이 생기던 문제 — 말줄임으로 바꿉니다. */
.mgm-node b { display: block; font-size: 13.5px; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mgm-node b em { font-style: normal; font-family: var(--mono); font-size: 9.5px; color: var(--brass-soft); border: 1px solid rgba(243,232,211,.4); padding: 1px 4px; border-radius: 2px; margin-left: 3px; vertical-align: 2px; }
.mgm-arrow { flex: none; width: 26px; height: 1px; background: rgba(255,255,255,.4); position: relative; }
.mgm-arrow::after { content: ''; position: absolute; right: 0; top: -3px; width: 6px; height: 6px; border-top: 1px solid rgba(255,255,255,.6); border-right: 1px solid rgba(255,255,255,.6); transform: rotate(45deg); }

.mgm-sheet .field { margin-bottom: 16px; }
.mgm-sheet .field > label { margin-bottom: 8px; }
.mgm-sheet .field > label i { font-style: normal; color: var(--accent); }
.mgm-sheet .field > label span { font-weight: 500; color: var(--mute-2); font-size: 12px; margin-left: 4px; }
.mgm-sheet .input.mono { font-family: var(--mono); letter-spacing: .02em; }
.mgm-sheet .input.ta { height: 78px; padding: 12px 14px; resize: none; font-size: 16px; line-height: 1.55; }
.input.bad { border-color: var(--accent); }
.ferr { font-size: 12px; color: var(--accent); margin-top: 6px; }
.mgm-agree { width: 100%; display: flex; gap: 10px; align-items: flex-start; text-align: left; font-size: 12.5px; line-height: 1.55; color: var(--ink-2); padding: 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); margin-bottom: 14px; }
.mgm-agree.bad { border-color: var(--accent); }
.mgm-agree .cb { width: 20px; height: 20px; border-radius: 4px; border: 1.5px solid var(--mute-2); flex: none; display: grid; place-items: center; margin-top: 1px; }
.mgm-agree.on .cb { background: var(--ink); border-color: var(--ink); }
.mgm-dup { font-size: 12.5px; line-height: 1.6; color: #8A341A; background: #FBE9E2; border-radius: 6px; padding: 11px 13px; margin-bottom: 12px; }
.mgm-dup b { display: block; margin-bottom: 2px; }
.mgm-cta { width: 100%; height: 54px; border-radius: 6px; background: var(--ink); color: #fff; font-size: 16px; font-weight: 800; display: flex; align-items: center; justify-content: center; text-decoration: none; letter-spacing: -.01em; }
.mgm-cta:disabled { background: var(--mute-2); }
.mgm-sub { width: 100%; height: 46px; margin-top: 8px; font-size: 14px; font-weight: 700; color: var(--mute); }
.mgm-fine { font-size: 11.5px; color: var(--mute-2); text-align: center; margin-top: 10px; line-height: 1.5; }

.mgm-done { text-align: center; padding: 6px 0 0; }
.mgm-seal { width: 60px; height: 60px; border-radius: 50%; background: var(--forest); display: grid; place-items: center; margin: 0 auto 14px; box-shadow: 0 0 0 6px var(--brass-soft); animation: up .4s cubic-bezier(.3,1.5,.5,1); }
.mgm-done h3, .mgm-lock h3 { font-family: var(--serif); font-size: 21px; margin: 0 0 8px; letter-spacing: -.02em; }
.mgm-done > p, .mgm-lock p { font-size: 13.5px; color: var(--mute); line-height: 1.6; margin: 0 0 18px; text-wrap: pretty; }
.mgm-done > p b, .mgm-lock p b { color: var(--ink); }
.mgm-receipt { display: grid; grid-template-columns: auto 1fr; gap: 9px 14px; text-align: left; background: var(--card); border: 1px dashed var(--line); border-radius: 6px; padding: 14px 16px; font-size: 13px; margin: 0 0 14px; }
.mgm-receipt dt { color: var(--mute); }
.mgm-receipt dd { margin: 0; font-weight: 700; text-align: right; }
.mgm-next { text-align: left; margin-bottom: 18px; }
.mgm-next small { font-size: 11px; font-weight: 700; color: var(--mute-2); letter-spacing: .06em; }
.mgm-next ol { list-style: none; margin: 8px 0 0; padding: 0; display: flex; gap: 4px; }
.mgm-next li { flex: 1; text-align: center; font-size: 11px; font-weight: 700; color: var(--mute-2); padding-top: 9px; border-top: 3px solid var(--line); white-space: nowrap; }
.mgm-next li.on { color: var(--ink); border-color: var(--brass); }
.mgm-lock { text-align: center; padding: 10px 4px 0; }
.mgm-lockico { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; margin: 0 auto 14px; background: var(--brass-soft); color: #7A5A22; }

.mgm-my { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--line-2); }
.mgm-my:last-child { border-bottom: 0; }
.mgm-my > div { flex: 1; min-width: 0; }
.mgm-my b { font-size: 14px; display: block; }
.mgm-my small { font-size: 12px; color: var(--mute); }
.mgm-st { font-size: 11.5px; font-weight: 800; padding: 4px 8px; border-radius: 3px; background: var(--line-2); color: var(--ink-2); white-space: nowrap; }
.mgm-st.st-0 { background: #FBE9E2; color: #A23F1F; }
.mgm-st.st-1, .mgm-st.st-2 { background: var(--brass-soft); color: #7A5A22; }
.mgm-st.st-3, .mgm-st.st-4, .mgm-st.st-5 { background: #E3ECE8; color: var(--forest); }
.mgm-st.st-6 { background: var(--forest); color: #fff; }
.mgm-st.st-hold { background: #EEF0EC; color: var(--mute); }
/* ───────── 간편 회원가입 (네이버 · 카카오 · 구글) ───────── */
.au-wrap { z-index: 90; }
.au-sheet { padding-bottom: calc(24px + env(safe-area-inset-bottom)); }
.au-lead { padding: 4px 0 20px; }
.au-reason { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px; border-radius: 13px; background: var(--brass-soft); color: #7A5A22; font-size: 12px; font-weight: 800; margin-bottom: 12px; }
.au-lead h3 { margin: 0 0 8px; font-family: var(--serif); font-size: 23px; font-weight: 700; letter-spacing: -0.03em; }
.au-lead p { margin: 0; font-size: 13.5px; line-height: 1.65; color: var(--mute); }
.au-btns { display: grid; gap: 10px; }
.au-btn { position: relative; height: 54px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 15.5px; font-weight: 700; letter-spacing: -0.02em; transition: transform .12s, filter .12s; }
.au-btn > span:first-child { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); }
.au-btn:active { transform: scale(.985); }
.au-btn:disabled { filter: saturate(.6) opacity(.75); cursor: default; }
.au-btn.naver { background: #03C75A; color: #fff; }
.au-btn.kakao { background: #FEE500; color: rgba(0,0,0,.85); }
.au-btn.google { background: #fff; color: #1F1F1F; border: 1px solid #DADCE0; }
.sm-n { display: inline-grid; place-items: center; font-weight: 900; font-family: Arial, sans-serif; color: #fff; background: #03C75A; border-radius: 3px; line-height: 1; }
.au-btn.naver .sm-n { background: transparent; }
.sm-k { display: inline-grid; place-items: center; }
.sm-k i { width: 82%; height: 68%; background: #191919; border-radius: 50%; position: relative; }
.sm-k i::after { content: ''; position: absolute; left: 22%; bottom: -22%; border: 4px solid transparent; border-top: 5px solid #191919; border-left-width: 2px; transform: skewX(-12deg); }
.sm-g { display: inline-grid; place-items: center; font-family: Arial, sans-serif; font-weight: 900; line-height: 1; background: conic-gradient(from -45deg, #EA4335 0 25%, #4285F4 25% 50%, #34A853 50% 75%, #FBBC05 75%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.au-perk { margin-top: 20px; background: var(--card); border: 1px solid var(--line); border-radius: 6px; padding: 14px 16px; }
.au-perk small { font-size: 12px; color: var(--mute); }
.au-perk small b { color: var(--ink); }
.au-perk ul { list-style: none; margin: 8px 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; }
.au-perk li { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; }
.au-perk li svg { color: var(--ok); flex: none; }
.au-fine { font-size: 11.5px; color: var(--mute); line-height: 1.6; margin: 14px 0 0; text-align: center; }
.au-prov { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-radius: 6px; background: var(--card); border: 1px solid var(--line); margin-bottom: 18px; }
.au-prov > div { flex: 1; min-width: 0; }
.au-prov b { display: block; font-size: 14px; }
.au-prov small { font-size: 12.5px; color: var(--mute); }
.au-prov button { font-size: 12.5px; font-weight: 700; color: var(--mute); text-decoration: underline; text-underline-offset: 3px; }
.au-agree { border-top: 1px solid var(--line); margin: 4px 0 14px; padding-top: 12px; }
.au-agree .agree { font-weight: 500; font-size: 13px; padding: 5px 0; }
.au-agree .agree.all { font-weight: 800; font-size: 14.5px; padding: 2px 0 10px; border-bottom: 1px solid var(--line-2); margin-bottom: 6px; }
.au-exist { background: #E3ECE8; border-radius: 6px; padding: 14px 16px; margin-bottom: 16px; }
.au-exist b { font-size: 14px; color: var(--forest); }
.au-exist p { margin: 4px 0 0; font-size: 12.5px; color: var(--ink-2); line-height: 1.55; }
.au-exist.warn { background: #FBE9E2; }
.au-exist.warn b { color: #A23F1F; }
.mgm-dot { display: inline-grid; place-items: center; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px; background: var(--accent); color: #fff; font-size: 10.5px; font-weight: 800; margin-left: 4px; }

/* 23차: 현장 상세 홍보 영상 */
.videobox { border-radius: 6px; overflow: hidden; background: var(--ink); }
/* 59차: 홍보영상 최대 3개 — 세로로 쌓고, 2편 이상일 때만 '영상 N' 라벨을 붙입니다. */
.vidstack { display: grid; gap: 10px; }
.vidstack .videobox { position: relative; }
.vidstack .vtag { position: absolute; left: 8px; top: 8px; z-index: 2; height: 22px; padding: 0 9px; display: inline-flex; align-items: center; border-radius: 999px; font-size: 11px; font-weight: 600; letter-spacing: -0.01em; color: #F5EFE6; background: linear-gradient(180deg, rgba(36,31,27,.92) 0%, rgba(17,16,14,.92) 100%); box-shadow: inset 0 1px 1px rgba(255,246,230,.22), 0 0 0 1px rgba(198,162,104,.6); pointer-events: none; }
.vframe { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; background: #000; }

/* ── 뉴스 (38차) — 칼럼·정책·소식 3분류, 인쇄물 느낌의 고급 레이아웃 ── */
.nwrap { background: var(--paper); }

/* ── 49차: 뉴스 상단 — 세리프 제목 + 금장 밑줄, eyebrow 제거(참고 이미지에 없음) ── */
.nhead { padding: 26px 20px 18px; text-align: left; }
.nhead .ntitle { font-family: var(--serif); font-size: 27px; font-weight: 700; letter-spacing: -.03em; margin: 0 0 10px; color: var(--ink); }
.nhead .nsub { font-size: 12.5px; color: var(--mute); letter-spacing: -.01em; margin: 0; }

/* ── 49차: 뉴스 분류 카드 — 금테 + 크림 그라데이션 / 활성은 글로시 먹타일 ── */
.ntabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 0 20px 20px; }
.ntab { position: relative; text-align: left; padding: 14px 12px 18px; border-radius: 10px;
  background: linear-gradient(180deg, #FDFAF2 0%, #F6EEDE 100%);
  border: 1px solid #DDC79C;
  box-shadow: 0 1px 2px rgba(120, 92, 42, .07), inset 0 1px 0 rgba(255, 255, 255, .85);
  transition: all .18s ease; }
.ntab b { display: block; font-family: var(--serif); font-size: 16px; font-weight: 700; color: var(--ink-2); letter-spacing: -.02em; }
.ntab span { display: block; font-size: 10.5px; color: #8C8375; margin-top: 3px; letter-spacing: -.01em; }
.ntab i { position: absolute; top: 10px; right: 11px; font-style: normal; font-family: var(--mono);
  font-size: 10px; color: #BBA075; }
.ntab.on {
  border: 1px solid transparent;
  background:
    linear-gradient(168deg, #3A332A 0%, #241F18 48%, #14100C 100%) padding-box,
    linear-gradient(148deg, #FCF1D6 0%, #E2C48C 30%, #AC8544 62%, #F3DDB0 100%) border-box;
  box-shadow:
    0 4px 14px rgba(20, 22, 18, .26),
    0 0 0 .5px rgba(90, 68, 30, .40),
    inset 0 1px 0 rgba(255, 255, 255, .16),
    inset 0 -2px 5px rgba(0, 0, 0, .42);
}
.ntab.on b { color: #FBF5E7; }
.ntab.on span { color: rgba(250, 243, 228, .62); }
.ntab.on i { color: #DFBE85; }
.ntab.on::after { content: ''; position: absolute; left: 11px; right: 11px; bottom: 8px; height: 2px; border-radius: 1px;
  background: linear-gradient(90deg, #C9A463 0%, #EFD9A6 45%, #A87F3D 100%); }

.nloading { padding: 44px 20px; text-align: center; font-size: 13px; color: var(--mute-2); line-height: 1.8; }
.nloading small { font-size: 11.5px; color: var(--mute-2); }

.nlead-card { display: block; width: calc(100% - 40px); margin: 0 20px 6px; padding: 22px 20px 18px; text-align: left;
  background: var(--ink); border-radius: 3px; border-bottom: 3px solid var(--brass); transition: opacity .15s; }
.nlead-card:active { opacity: .86; }
.nlead-kicker { font-size: 10.5px; letter-spacing: .16em; color: var(--brass); text-transform: uppercase; font-weight: 700; }
.nlead-title { font-family: var(--serif); font-size: 20px; font-weight: 700; line-height: 1.46; color: #fff;
  margin: 12px 0 14px; letter-spacing: -.025em; text-wrap: pretty; }
.nlead-meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: rgba(255,255,255,.5); }
.nlead-meta b { color: rgba(255,255,255,.86); font-weight: 600; }
.nlead-meta span::before { content: '·'; margin-right: 8px; color: rgba(255,255,255,.28); }
.nlead-more { display: inline-flex; align-items: center; gap: 4px; margin-top: 16px; font-size: 11.5px;
  font-weight: 700; color: var(--brass); letter-spacing: .02em; }
.nlead-more i { font-style: normal; }

.nlist { list-style: none; margin: 0; padding: 4px 20px 0; }
.nrow { display: flex; align-items: flex-start; gap: 13px; width: 100%; text-align: left;
  padding: 16px 0; border-bottom: 1px solid var(--line); background: none; }
.nrow-no { font-family: var(--mono); font-size: 11px; color: var(--brass); padding-top: 3px; flex: none; width: 20px; }
.nrow-b { flex: 1; min-width: 0; }
.nrow-b strong { display: block; font-size: 14.5px; font-weight: 600; line-height: 1.55; color: var(--ink);
  letter-spacing: -.025em; text-wrap: pretty; }
.nrow-b small { display: block; margin-top: 6px; font-size: 11.5px; color: var(--mute-2); }
.nrow-ar { flex: none; font-size: 12px; color: var(--mute-2); padding-top: 2px; }

/* 80차: 뉴스 '이전 기사 더 보기'
   종전에는 limit=20 하드코딩으로 최신 20건만 볼 수 있었습니다.
   이제 남은 기사가 있으면 이 버튼으로 이어서 불러옵니다. */
.nmore-wrap { margin: 6px 20px 0; }
.nmore { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
  padding: 14px 16px; border-radius: 10px; cursor: pointer;
  font-family: var(--sans); font-size: 13.5px; font-weight: 700; letter-spacing: -.01em;
  color: #FBF5E7;
  background: linear-gradient(180deg, #3A332A 0%, #241F18 52%, #14100C 100%);
  border: 1px solid #AC8544;
  box-shadow: 0 2px 10px rgba(20, 22, 18, .18), inset 0 1px 0 rgba(255, 255, 255, .14);
  transition: opacity .15s ease; }
.nmore:active { opacity: .82; }
.nmore[disabled] { opacity: .6; cursor: default; }
.nmore-cnt { font-family: var(--mono); font-size: 11px; font-weight: 600; color: #DFBE85; letter-spacing: 0; }
.nmore-bar { position: relative; height: 2px; margin-top: 8px; border-radius: 1px; overflow: hidden;
  background: rgba(0, 0, 0, .07); }
.nmore-bar i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 1px;
  background: linear-gradient(90deg, #C9A463 0%, #EFD9A6 50%, #A87F3D 100%);
  transition: width .25s ease; }
.nmore-hint { margin: 9px 0 0; text-align: center; font-size: 10.5px; color: var(--mute-2);
  letter-spacing: .01em; }
.ndone { margin: 20px 20px 0; padding: 14px 0 0; text-align: center;
  font-size: 12px; color: var(--mute-2); letter-spacing: -.01em; }
.ndone b { color: var(--ink-2); font-weight: 700; }

.nfoot { margin: 22px 20px 30px; padding: 18px 0 0; border-top: 1px solid var(--line); }
.nfoot p { font-size: 11.5px; line-height: 1.75; color: var(--mute); margin: 0 0 6px; text-wrap: pretty; }
.nfoot p b { color: var(--ink-2); font-weight: 700; }
.nfoot .nfine { font-size: 10.5px; color: var(--mute-2); letter-spacing: .04em; }

/* 기사 상세 */
.nart-body { padding: 24px 20px 10px; }
.nart-cat { display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .14em;
  color: var(--brass); text-transform: uppercase; padding-bottom: 10px; }
.nart-title { font-family: var(--serif); font-size: 22px; font-weight: 700; line-height: 1.44;
  letter-spacing: -.03em; color: var(--ink); margin: 0 0 14px; text-wrap: pretty; }
.nart-by { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--mute);
  padding-bottom: 18px; border-bottom: 1px solid var(--line); margin-bottom: 20px; }
.nart-by b { color: var(--ink-2); font-weight: 700; }
.nart-by span::before { content: '·'; margin-right: 8px; color: var(--mute-2); }
.nart-p { font-family: var(--serif); font-size: 15px; line-height: 1.95; color: #2C3632;
  margin: 0 0 18px; letter-spacing: -.01em; text-wrap: pretty; }
.nart-note { margin: 22px 0 14px; padding: 15px 16px; background: var(--brass-soft);
  border-left: 2.5px solid var(--brass); border-radius: 2px;
  font-size: 11.5px; line-height: 1.75; color: #6B5324; text-wrap: pretty; }
.nart-note b { font-weight: 700; }
.nart-link { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 18px 0 8px; padding: 16px 18px; background: var(--ink); color: #fff;
  border-radius: 3px; font-size: 13.5px; font-weight: 700; letter-spacing: -.01em; }
.nart-link:active { opacity: .88; }
.nart-link i { font-style: normal; color: var(--brass); }

/* ── 41차: 고객센터 ─────────────────────────────────────────
   MY › 고객센터. 탭 3개(자주 묻는 질문 / 1:1 문의 / 연락처).
   검색 입력창은 .site-search 와 같은 이유로 min-width:0 을 넣습니다 —
   flex 자식의 기본 min-width:auto 가 input 을 콘텐츠 최소폭 밑으로 줄이지 못해
   좁은 화면에서 가로로 넘칩니다. font-size:16px 은 iOS 강제 확대 방지. */
.hc-tabs { flex: none; display: flex; gap: 6px; padding: 4px 20px 12px; }
.hc-tab { flex: 1; height: 38px; border: 1px solid var(--line); border-radius: 4px; background: var(--card); font-size: 12.5px; font-weight: 700; color: var(--ink-2); letter-spacing: -.02em; }
.hc-tab.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.hc-tab:active { opacity: .75; }

.hc-search { display: flex; align-items: center; gap: 8px; height: 44px; margin: 0 20px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--card); padding: 0 13px; }
.hc-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; font-family: inherit; font-size: 16px; color: var(--ink); -webkit-appearance: none; appearance: none; }
.hc-search input::placeholder { color: var(--mute-2); }
.hc-search input::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
.hc-search .clr { flex: none; width: 24px; height: 24px; border-radius: 50%; border: 0; background: var(--line-2); display: grid; place-items: center; padding: 0; }

.hc-count { font-size: 12px; color: var(--mute); margin: 0 0 10px 2px; }

.hc-list { border-top: 1px solid var(--line-2); }
.hc-item { border-bottom: 1px solid var(--line-2); }
.hc-q { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 15px 0; }
.hc-q:active { opacity: .7; }
/* 질문 텍스트는 한 줄 말줄임입니다. 접었을 때 목록이 길어지면
   수십 건을 훑기 어려워집니다. 펼치면 .hc-a 에 전체가 나옵니다. */
.hc-no { flex: none; font-family: var(--mono); font-size: 11px; color: var(--brass); font-weight: 700; width: 20px; }
.hc-qt { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; line-height: 1.5; letter-spacing: -.02em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hc-item.open .hc-qt { white-space: normal; }
.hc-chev { flex: none; display: grid; place-items: center; transition: transform .18s; }
.hc-item.open .hc-chev { transform: rotate(90deg); }

.hc-a { padding: 0 0 16px 30px; }
.hc-a p { margin: 0 0 6px; font-size: 12.5px; line-height: 1.8; color: var(--ink-2); }
.hc-a p:last-child { margin-bottom: 0; }
.hc-lbl { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; color: var(--mute-2); margin: 12px 0 6px; }
.hc-lbl span { font-weight: 600; letter-spacing: 0; color: var(--mute-2); }
.hc-reply { margin-top: 12px; padding: 12px 14px; background: var(--paper); border-left: 2px solid var(--brass); border-radius: 2px; }
.hc-reply .hc-lbl { margin-top: 0; }
.hc-wait { margin-top: 12px; padding: 11px 13px; background: var(--line-2); border-radius: 3px; font-size: 12px; line-height: 1.65; color: var(--mute); }

/* 상태 배지 — 접수 / 처리중 / 답변완료 */
.hc-badge { flex: none; font-size: 10px; font-weight: 800; letter-spacing: .02em; padding: 3px 7px; border-radius: 3px; background: var(--line-2); color: var(--mute); white-space: nowrap; }
.hc-badge.ing { background: var(--brass-soft); color: #7A5A22; }
.hc-badge.done { background: var(--ink); color: #fff; }

.hc-cats { display: flex; flex-wrap: wrap; gap: 6px; }
/* 입력창 안의 높이를 키웁니다. 기본 .input 은 height:50px 고정이라 textarea 에 쓰면
   글이 잘립니다. resize:none 은 모바일에서 핸들이 어색해서 끕니다. */
.hc-ta { height: auto; min-height: 120px; padding: 12px 14px; font-size: 16px; line-height: 1.65; resize: none; }
.hc-hint { margin-top: 6px; font-size: 11px; color: var(--mute-2); text-align: right; }

/* 연락처 카드 */
.hc-contact { background: var(--card); border: 1px solid var(--line); border-radius: 5px; padding: 22px 18px 18px; text-align: center; }
.hc-ct-l { font-size: 11.5px; font-weight: 700; color: var(--mute); letter-spacing: .04em; }
.hc-ct-n { font-family: var(--mono); font-size: 26px; font-weight: 800; letter-spacing: -.02em; margin: 6px 0 8px; }
.hc-ct-h { font-size: 11.5px; line-height: 1.75; color: var(--mute); }
.hc-ct-b { display: flex; gap: 8px; margin-top: 18px; }
.hc-ct-b .btn.primary { flex: 1; }
.hc-ci { width: 40px; height: 40px; border-radius: 50%; background: var(--paper); display: grid; place-items: center; flex: none; }

/* ══════════════════════════════════════════════════════════════════
   53차: PC(데스크톱) 반응형 확장 — 1단계
   ──────────────────────────────────────────────────────────────────
   원칙
   1) 모든 규칙은 @media (min-width: 1024px) 안에만 둡니다.
      → 모바일(<1024px)은 이 블록을 아예 읽지 않으므로 렌더가 100% 동일합니다.
   2) 구조를 바꾸지 않습니다. 마크업·API·데이터는 그대로이고
      CSS 와 '클래스 훅'만 추가했습니다.
   3) 톤은 기존 그대로 — 먹색(var(--ink)) · 금장(var(--brass)) · 세리프(var(--serif)).
      새 색을 만들지 않고 기존 변수만 씁니다.

   셸 구조
   · 탭 화면에서만 .app 에 'shell' 수정자가 붙습니다(app.js).
     스택 화면(상세·예약·채팅 등)은 .app 단독이라 이 블록의 영향을 받지 않습니다.
     (그래야 .bottom-cta 같은 flex 자식이 가로로 붙는 사고가 없습니다.)
   · .app.shell  → 가로 배치(row)
   · .tabs       → 좌측 세로 사이드바 (DOM 순서상 뒤에 있으므로 order:-1)
   · .scroll     → 우측 콘텐츠 영역

   가로 정렬
   · --pad = max(24px, (100% - 1160px) / 2)
     콘텐츠를 1160px 로 제한하면서 좌우를 자동으로 맞춥니다.
     퍼센트는 '그 요소의 컨테이너 폭' 기준이라 홈의 모든 자식이 같은 축에 정렬됩니다.
     (margin: auto + max-width 조합은 .banner 처럼 기존 margin 이 있는 요소와
      충돌하므로 padding/margin 값을 직접 계산하는 이 방식을 씁니다.)
   ══════════════════════════════════════════════════════════════════ */

/* 사이드바 브랜드 — 모바일에서는 감춥니다.
   (.tabs 가 repeat(5, 1fr) 그리드라 display:none 이어야 탭 5개 배치가 그대로 유지됩니다) */
.side-brand { display: none; }

@media (min-width: 1024px) {
  /* ── 1. 루트 · 셸 ───────────────────────────────────────────── */
  /* 440px 폰 프레임을 벗어나 화면 전체를 씁니다. */
  #root {
    max-width: none;
    box-shadow: none;          /* 풀폭에서는 프레임 그림자가 의미 없습니다 */
  }

  .app.shell { flex-direction: row; }
  /* 사이드바가 오른쪽에 붙지 않도록 DOM 순서를 뒤집습니다. */
  .app.shell > .tabs { order: -1; }
  /* 가로 flex 자식의 기본 min-width:auto 가 콘텐츠를 밀어내지 않게 합니다. */
  .app.shell > .scroll { min-width: 0; }

  /* ── 2. 하단 탭 → 좌측 사이드바 ─────────────────────────────── */
  .app.shell > .tabs {
    flex: none;
    order: -1;
    width: 244px;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 18px 12px 20px;
    border-top: 0;
    border-right: 1px solid var(--line);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
  }

  .side-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    /* .tabs 가 이미 좌우 12px 패딩을 갖고 있으므로 여기서는 4px 만 더합니다. */
    padding: 4px 4px 18px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--line-2);
    /* nav 의 마지막 자식이지만(DOM 순서 유지) 시각적으로는 맨 위로 올립니다. */
    order: -1;
  }
  .side-brand img { height: 34px; width: auto; display: block; }

  /* 세로 탭 = 가로 한 줄(타일 + 라벨) */
  .app.shell > .tabs .tab {
    flex: none;
    width: 100%;
    height: 52px;
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    padding: 0 12px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: #3E3B35;
    transition: background .15s, color .15s, box-shadow .15s;
  }
  /* 활성 탭 — 분양현장 금테 칩(.chips.gold .chip)과 같은 금장 어휘를 씁니다.
     타일은 이미 먹색+금테라, 활성 배경을 먹색으로 두면 타일이 묻힙니다. */
  .app.shell > .tabs .tab.on {
    background: linear-gradient(180deg, #FCF7EC 0%, #F5EDDD 100%);
    box-shadow: inset 0 0 0 1px #E2CDA2, 0 1px 2px rgba(120, 92, 42, .06);
    color: var(--ink);
    font-weight: 700;
  }
  .app.shell > .tabs .tab:hover:not(.on) { background: var(--line-2); }
  .app.shell > .tabs .tab:active { opacity: 1; }

  /* ── 3. 스택 화면 가드 ────────────────────────────────────────
     상세·예약·채팅 등은 .app 단독입니다. 폭 제한이 없으면 1440px 에서
     히어로 이미지와 본문이 화면 끝까지 늘어나 읽기 어려워집니다.
     position:absolute + left/right:0 + margin:auto 조합이라
     transform 없이 가운데 정렬됩니다(자식 absolute 기준점도 그대로 유지).

     [53차-3 실측 보정] 선택자를 `#root > .app` 로 한정했습니다.
     종전 `.app:not(.shell)` 은 '바깥 .app(app.js)' 과 '안쪽 .app(각 화면 컴포넌트)' 
     둘 다에 걸렸습니다. 그래서 바깥만 넓혀도 안쪽이 880 에 남아
     상세의 .bottom-cta 폭이 어긋나는 문제가 있었습니다(53차-2 에서 실측).
     바깥만 잡으면 안쪽은 position:absolute; inset:0 이라 부모를 그대로 채웁니다.
     → 화면별 폭은 아래에서 `#root > .app.stack-*` 로만 지정합니다. */
  #root > .app:not(.shell) { max-width: 880px; margin: 0 auto; }

  /* ── 4. 홈 ──────────────────────────────────────────────────── */
  .home-scroll { --pad: max(24px, calc((100% - 1160px) / 2)); }

  .home-scroll > .topbar.home-top { height: 96px; }
  .home-scroll > .topbar.home-top .logo img { height: 56px; }
  .home-scroll > .topbar.home-top .icon-btn.abs-l { left: var(--pad); }
  .home-scroll > .topbar.home-top .icon-btn.abs-r { right: var(--pad); }

  /* 65차: PC 배너는 16:9 로 고정합니다.
     이전에는 height: clamp(400px, 40vh, 560px) 이라 폭이 넓어질수록 박스가 초와이드가 됐고,
     실측 PC 1440px 에서 박스 1148x400 = 비율 2.870 → 3:2 사진의 상하 47.7% 가 잘렸습니다.
     16:9(1.778) 로 두면 3:2 사진(1.500)의 상하 잘림이 15.6% 로 줄고, PC 화면에서
     가장 흔한 영상형 비율이라 관리자가 올린 사진도 예측 가능한 구도로 보입니다. */
  .home-scroll > .banner { aspect-ratio: 16 / 9; height: auto; margin: 4px var(--pad) 0; }
  .home-scroll > .banner .banner-cap { left: 32px; right: 32px; bottom: 52px; }
  .home-scroll > .banner .banner-cap h3 { font-size: 42px; line-height: 1.22; margin: 14px 0 10px; }
  .home-scroll > .banner .banner-cap p { font-size: 14.5px; }
  .home-scroll > .banner .banner-dots { left: 32px; bottom: 24px; }
  .home-scroll > .banner .banner-count { right: 32px; bottom: 18px; font-size: 12px; }

  .home-scroll > .quick { margin: 30px var(--pad) 0; }
  .home-scroll > .quick button { font-size: 13.5px; gap: 11px; padding: 6px 2px 4px; }

  .home-scroll > .sec { padding-left: var(--pad); padding-right: var(--pad); padding-top: 36px; }
  .home-scroll > .sec .sec-h { margin-bottom: 18px; }
  .home-scroll > .sec .sec-h h2 { font-size: 23px; }
  .home-scroll > .sec .sec-h .eyebrow { font-size: 10.5px; }

  .home-scroll > .foot { padding-left: var(--pad); padding-right: var(--pad); }

  /* 홈 '지금 주목받는 분양현장' — PC 에서는 마키 대신 정지 그리드.
     (AutoMarquee 는 카드를 복제하기 때문에 CSS 로는 그리드가 불가능합니다.
      m-home.js 에서 desk 여부로 렌더 자체를 분기합니다.) */
  .site-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 24px;
  }
  /* .site-card 기본값(flex:none; width:240px)은 마키 전용이라 그리드에서 풀어줍니다. */
  .site-grid .site-card { flex: initial; width: auto; }
  .site-grid .site-card h4 { font-size: 17px; }
  .site-grid .site-card .meta { font-size: 13px; }
  .site-grid .site-card .price { font-size: 14px; }

  /* 추천 상담사는 폭이 넓어 행 여백만 넓힙니다. */
  .sec-counselor .card { padding: 8px 22px; }
  .sec-counselor .cs-row { padding: 16px 0; }

  /* ── 5. 분양현장 목록 ───────────────────────────────────────── */
  .sites-scroll { --pad: max(24px, calc((100% - 1160px) / 2)); }

  .sites-scroll > .topbar.sites-top { height: 84px; padding-left: var(--pad); padding-right: var(--pad); }
  .sites-scroll > .topbar.sites-top .sites-ttl { font-size: 31px; }
  .sites-scroll > .chips.gold { padding-left: var(--pad); padding-right: var(--pad); }
  .sites-scroll > .chips.gold .chip { height: 38px; padding: 0 18px; font-size: 13.5px; }

  .sites-scroll .sites-list { padding: 0 var(--pad); }
  .sites-scroll .sites-count { font-size: 13.5px; margin-bottom: 16px; }

  /* 목록 → 카드 그리드 (창 폭에 따라 2~4열) */
  .sites-scroll .sites-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 28px 26px;
    align-items: start;
  }
  /* 그리드에서는 카드 하단 여백을 gap 이 대신합니다. */
  .sites-scroll .sites-grid > .site-row { margin-bottom: 0; }
  .sites-scroll .sites-grid > .site-row h4 { font-size: 17.5px; }

  /* ── 6. 표시 계층 정리 ──────────────────────────────────────────
     .tabs 가 좌측으로 가면서 하단 safe-area 인셋을 쓸 일이 없어집니다. */
  .app.shell > .tabs { padding-bottom: 20px; }
}

/* ══════════════════════════════════════════════════════════════════
   53차-2: PC(데스크톱) 반응형 확장 — 2단계
   대상 — 분양현장 상세(2단) · 홈 뉴스(3열) · 뉴스 · 스튜디오 · MY

   원칙은 1단계와 같습니다.
     · 모든 규칙은 @media (min-width: 1024px) 안에만 둡니다.
       → 모바일(≤1023px)에는 이 블록의 어떤 선언도 닿지 않습니다.
     · 새 색·새 폰트를 만들지 않고 :root 토큰만 씁니다.
     · 새 클래스는 JS 에서 이미 붙여 둔 훅(.detail-app / .detail-scroll /
       .dt-aside / .dt-main / .home-news / .studio-scroll / .my-scroll /
       .my-listwrap)에만 걸립니다. 기존 선택자는 건드리지 않습니다.
   ══════════════════════════════════════════════════════════════════ */

/* MY 하단 메뉴 묶음 — 이전에는 인라인 style(padding:'18px 20px') 이었습니다.
   인라인은 미디어쿼리로 덮을 수 없어 클래스로 옮겼습니다.
   값이 같으므로 모바일 렌더 결과는 동일합니다. */
.my-listwrap { padding: 18px 20px; }

@media (min-width: 1024px) {
  /* ── 1. 스택 화면 폭 ─────────────────────────────────────────
     1단계에서는 모든 스택 화면을 880px 로 묶어 두었습니다(아래 .app:not(.shell)).
     상세만 2단이 되므로 '상세에 한해' 더 넓힙니다.

     [실측으로 잡은 함정 1] 안쪽 .detail-app 에만 1120px 을 걸어도 880px 로 남았습니다.
     .app:not(.shell) 의 880px 은 app.js 가 그리는 '바깥' .app 에 걸리고,
     m-detail.js 의 .app 은 그 안에 position:absolute; inset:0 으로 들어가
     부모 폭을 그대로 물려받기 때문입니다.

     [실측으로 잡은 함정 2] 바깥만 넓히면(1120) 안쪽 .app 은 여전히 880 이라
     .bottom-cta 폭이 880 으로 남아 좌우가 어긋났습니다(실측 ctaW=880).
     → 바깥(.app.stack-detail)과 안쪽(.app.detail-app) 둘 다 풀어야 합니다.
     두 선택자 모두 명시도 0,2,0 으로 .app:not(.shell) 과 같으므로
     소스 순서로 이깁니다 — 반드시 .app:not(.shell) 뒤에 둡니다. */
  #root > .app.stack-detail { max-width: 1120px; }
  .app.detail-app { max-width: none; }

  /* ── 2. 홈 · 부동산 뉴스 3열 ────────────────────────────────
     모바일은 .news-row 가 가로 1열 목록이고, PC 에서만 카드 3열이 됩니다.
     flex-direction: column-reverse 로 이미지를 위로 올립니다
     (마크업은 .nt → img 순서이므로 reverse 해야 이미지가 먼저 옵니다). */
  .home-news { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }

  .home-news .news-row {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: 0;
    padding: 0;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 4px;
    overflow: hidden;
    transition: box-shadow .18s, transform .18s;
  }
  .home-news .news-row:hover {
    box-shadow: 0 6px 18px rgba(18, 32, 28, .10);
    transform: translateY(-2px);
  }
  /* 목록용 84px 정사각 썸네일을 카드 상단 와이드 이미지로 바꿉니다. */
  .home-news .news-row img {
    width: 100%; height: 158px; border-radius: 0; object-fit: cover;
  }
  .home-news .news-row .nt { padding: 14px 15px 16px; }
  .home-news .news-row .cat { font-size: 10.5px; letter-spacing: .04em; }
  .home-news .news-row h4 { font-size: 15px; -webkit-line-clamp: 3; margin: 7px 0 9px; }
  .home-news .news-row .d { font-size: 11.5px; }

  /* ── 3. 분양현장 상세 — 2단 ───────────────────────────────────
     왼쪽 = 히어로(스크롤에 따라 고정), 오른쪽 = 본문.
     .detail-scroll 이 스크롤러이면서 그리드입니다.
     sticky 의 기준은 '가장 가까운 스크롤 조상'이므로 .dt-aside 에 그대로 걸립니다.
     (1단계에서 .app 전체를 row 로 바꾸지 않은 것과 같은 이유로,
      .app 은 세로 배치 그대로 두고 .scroll 안쪽만 2단으로 만듭니다.
      → .bottom-cta 는 여전히 .app 의 세로 flex 자식이라 아래에 붙습니다.) */
  .detail-scroll {
    display: grid;
    grid-template-columns: minmax(0, 430px) minmax(0, 1fr);
    gap: 0 40px;
    align-items: start;
    padding: 24px max(28px, calc((100% - 1040px) / 2)) 0;
  }

  .dt-aside { position: sticky; top: 24px; align-self: start; }

  /* 65차-B: PC 히어로도 3:2 로 고정합니다.
     이전 height: clamp(380px, 48vh, 560px) 은 폭(430px 고정)과 무관하게 높이만
     커져서, 화면이 높아질수록 박스가 더 세로형이 됐습니다(실측 PC 1440 → 430x432 = 0.995,
     PC 1920 → 430x518 = 0.829). 3:2 로 두면 갤러리 사진 6장 모두 잘림 0 이 됩니다.
     (모바일 .hero 규칙과 같은 값이며, 명시도를 위해 여기서 다시 선언합니다.) */
  .detail-scroll .hero {
    aspect-ratio: 3 / 2;
    height: auto;
    border-radius: 4px;
    overflow: hidden;
  }
  .detail-scroll .hero-pg { right: 14px; bottom: 14px; }

  /* 오른쪽 열 — 자식들이 각자 갖고 있던 좌우 20px 여백을 걷어내
     히어로와 '같은 세로축'에 맞춥니다. 세로 여백은 그대로 둡니다. */
  .detail-scroll .dt-main { min-width: 0; }

  .detail-scroll .dt-head {
    padding: 0 0 20px;
    background: transparent;
    border-bottom: 1px solid var(--line);
  }
  .detail-scroll .dt-head h2 { font-size: 32px; margin: 12px 0 8px; }
  .detail-scroll .dt-head .addr { font-size: 13.5px; }
  .detail-scroll .dt-head .price { font-size: 20px; margin-top: 14px; }

  .detail-scroll .dt-actions { padding: 18px 0 16px; }

  .detail-scroll .dt-main > .sec { padding-left: 0; padding-right: 0; padding-top: 32px; }
  .detail-scroll .dt-main > .sec .sec-h h2 { font-size: 20px; }

  /* 하단 CTA — .app 이 1120px 이라 그대로 두면 버튼이 화면 끝까지 늘어납니다.
     좌우 패딩을 본문 축에 맞춰 안쪽으로 당깁니다. */
  .app.detail-app > .bottom-cta {
    padding-left: max(16px, calc((100% - 1040px) / 2));
    padding-right: max(16px, calc((100% - 1040px) / 2));
  }

  /* ── 4. 뉴스 화면 ────────────────────────────────────────────
     머리기사 1건 + 목록. PC 에서는 목록을 2열로 나눠 세로 길이를 줄입니다. */
  .nwrap { --pad: max(24px, calc((100% - 1000px) / 2)); }

  .nwrap > .nhead { padding: 40px var(--pad) 22px; }
  .nwrap > .nhead .ntitle { font-size: 38px; }
  .nwrap > .nhead .nsub { font-size: 13.5px; }

  .nwrap > .ntabs { padding: 0 var(--pad) 24px; gap: 12px; }
  .nwrap > .ntabs .ntab { padding: 18px 16px 22px; }
  .nwrap > .ntabs .ntab b { font-size: 18px; }
  .nwrap > .ntabs .ntab span { font-size: 11.5px; }

  .nwrap > .nlead-card { width: calc(100% - var(--pad) * 2); margin: 0 var(--pad) 10px; padding: 32px 30px 26px; }
  .nwrap > .nlead-card .nlead-title { font-size: 27px; margin: 14px 0 16px; }
  .nwrap > .nlead-card .nlead-kicker { font-size: 11px; }

  .nwrap > .nlist {
    padding: 10px var(--pad) 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 40px;
    align-items: start;
  }
  .nwrap > .nlist .nrow { padding: 18px 0; }
  .nwrap > .nlist .nrow-b strong { font-size: 15px; }

  .nwrap > .nfoot { margin: 28px var(--pad) 44px; }

  /* 80차: PC 는 목록이 2단 그리드라 '더 보기'도 같은 여백으로 맞춥니다. */
  .nwrap > .nmore-wrap { margin: 18px var(--pad) 0; }
  .nwrap > .nmore-wrap .nmore { max-width: 420px; margin: 0 auto; padding: 16px 20px; font-size: 14px; }
  .nwrap > .ndone { margin: 24px var(--pad) 0; font-size: 12.5px; }

  /* ── 5. MGM스튜디오 ──────────────────────────────────────────
     상단 카드는 '떠 있는 카드' 문법 그대로 두고 여백만 넓힙니다. */
  .studio-scroll { --pad: max(24px, calc((100% - 1000px) / 2)); }

  .studio-scroll > .st-topcard { margin: 24px var(--pad) 0; }
  .studio-scroll > .st-topcard .st-hero { padding: 32px 32px 34px; }
  .studio-scroll > .st-topcard .st-hero h1 { font-size: 40px; margin: 12px 0 12px; }
  .studio-scroll > .st-topcard .st-hero p { font-size: 14px; max-width: 560px; line-height: 1.72; }
  .studio-scroll > .st-topcard .st-eyebrow { font-size: 10.5px; }
  .studio-scroll > .st-topcard .st-pipe { margin-top: 20px; gap: 8px; }
  .studio-scroll > .st-topcard .st-pipe span { font-size: 11.5px; padding: 5px 12px; }

  /* 검색창·모드탭은 카드 폭을 그대로 씁니다.
     99차: 탭·검색이 .st-topcard 밖(.st-bar)으로 나갔으므로 선택자를 옮겼습니다.
     예전 선택자(.st-topcard .st-modes)로 두면 PC 에서만 이 규칙이 죽어
     탭 높이가 46px 로 남습니다(모바일 값). */
  .studio-scroll > .st-bar .st-modes button { height: 52px; font-size: 14.5px; }
  .studio-scroll > .st-bar .st-searchwrap { padding: 14px 18px 16px; }
  .studio-scroll > .st-bar .st-search { height: 44px; }
  .studio-scroll > .st-bar .st-search input { font-size: 14px; }
  /* 카드 조각의 좌우 여백을 PC 본문 축에 맞춥니다(hero 카드와 같은 --pad). */
  .studio-scroll > .st-bar .st-barcard { margin: 0 var(--pad); }

  .studio-scroll > .st-bar .chips { padding-left: var(--pad); padding-right: var(--pad); }
  .studio-scroll > .st-bar .chips .chip { height: 38px; padding: 0 18px; font-size: 13.5px; }

  /* 물건 카드 — 1열 세로 목록을 폭에 따라 2~3열 그리드로. */
  .studio-scroll .st-list {
    padding: 20px var(--pad) 8px;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
  }

  /* '내 상담' 모드의 요약·안내 박스도 같은 축에 맞춥니다. */
  .studio-scroll .st-sum { margin: 0 var(--pad); }
  .studio-scroll .st-conn { margin: 20px var(--pad) 0; }
  .studio-scroll .st-lead { padding: 16px 0; }

  /* ── 6. MY ───────────────────────────────────────────────────
     .my-head 는 '떠 있는 먹색 카드' 문법 그대로, 여백만 넓힙니다. */
  .my-scroll { --pad: max(24px, calc((100% - 900px) / 2)); }

  .my-scroll > .my-head { margin: 24px var(--pad) 0; padding: 28px 26px 24px; }
  .my-scroll > .my-head h2 { font-size: 30px; }
  .my-scroll > .my-head small { font-size: 12.5px; }
  .my-scroll > .my-head .point-card { margin-top: 20px; padding: 15px 18px; }
  .my-scroll > .my-head .point-card b { font-size: 30px; }

  .my-scroll > .sec { padding-left: var(--pad); padding-right: var(--pad); padding-top: 34px; }
  .my-scroll > .sec .sec-h h2 { font-size: 21px; }
  .my-scroll > .sec .card { padding: 6px 20px; }
  .my-scroll > .sec .cs-row { padding: 16px 0; }

  .my-scroll > .my-listwrap { padding: 22px var(--pad) 18px; }
  .my-scroll > .my-listwrap .list-btn { padding: 17px 0; font-size: 15.5px; }
}

/* ══════════════════════════════════════════════════════════════════
   53차-3: PC(데스크톱) 반응형 확장 — 3단계
   대상 — 검색 · 방문예약 · 예약완료 · 채팅 · 게시판 · 고객센터 · 알림 · 기사

   ── 먼저: 기본값 복원 ─────────────────────────────────────────
   아래 클래스들은 원래 JSX 의 인라인 style 이었습니다. 인라인은
   미디어쿼리로 덮을 수 없어 클래스로 옮겼고, 모바일 렌더가 100% 같도록
   여기에 '원래 값 그대로' 기본 규칙을 먼저 둡니다.
   (값은 git diff 로 확인한 이전 인라인 값과 동일합니다)

     board-meta     ← padding: '16px 20px 0'
     board-list     ← padding: '4px 20px 0'
     edu-list       ← padding: '6px 20px 0'   (커뮤니티 목록만 top 6px)
     board-detail   ← padding: '4px 20px 0'
     board-hub      ← padding: '16px 20px 0'
     help-pad       ← padding: '0 20px'
     help-pad-top   ← padding: '16px 20px 0'
     reserve-scroll ← padding: '8px 20px 20px'
   ══════════════════════════════════════════════════════════════════ */
.board-meta { padding: 16px 20px 0; }
.board-list { padding: 4px 20px 0; }
.board-list.edu-list { padding: 6px 20px 0; }
.board-detail { padding: 4px 20px 0; }
.board-hub { padding: 16px 20px 0; }
.help-pad { padding: 0 20px; }
.help-pad-top { padding: 16px 20px 0; }
.reserve-scroll { padding: 8px 20px 20px; }

/* 좌우 여백만 갈아끼우는 헬퍼 — 세로 여백(위 값)은 건드리지 않습니다.
   각 화면의 콘텐츠 축을 한 값으로 맞추기 위한 것이고, PC 블록에서만 호출합니다. */
@media (min-width: 1024px) {
  /* ── 1. 스택 화면 폭 (화면별) ────────────────────────────────
     #root > .app:not(.shell) 의 880px 을 화면 성격에 따라 넓힙니다.
     모두 명시도 1,2,0 으로 같으므로 소스 순서로 이깁니다 — 이 블록이 뒤입니다. */
  #root > .app.stack-search { max-width: none; }   /* 지구본 — 화면 전체 */
  #root > .app.stack-form { max-width: 1080px; }   /* 예약·멤버십·스튜디오 상세 */
  #root > .app.stack-list { max-width: 1080px; }   /* 게시판 4종 + 허브 */
  #root > .app.stack-help { max-width: 1080px; }   /* 고객센터·알림 */
  #root > .app.stack-read { max-width: 1080px; }   /* 기사 본문 */
  #root > .app.stack-chat { max-width: 900px; }    /* 1:1 채팅 */

  /* ── 2. 검색 — 지구본은 화면 전체, UI 는 콘텐츠 축에 ───────── */
  .stack-search .search-page { --pad: max(20px, calc((100% - 1160px) / 2)); }

  /* 상단바·추천 검색어·캡션을 같은 축에 맞춥니다. */
  .stack-search .search-page .topbar {
    padding-left: max(16px, calc((100% - 1160px) / 2));
    padding-right: max(16px, calc((100% - 1160px) / 2));
  }
  .stack-search .search-chips { padding-left: var(--pad); padding-right: var(--pad); }
  /* 83차: 지구본 삭제 → 캡션 클래스명도 .map-cap 으로 바뀌었습니다.
     값은 종전과 동일합니다(지도 화면에서도 같은 자리에 놓입니다). */
  .stack-search .map-cap {
    left: max(20px, calc((100% - 1160px) / 2));
    right: auto;
    width: min(520px, calc(100% - 40px));
  }

  /* 결과 시트 — 화면 끝까지 늘리지 않고 가운데 카드로 띄웁니다.
     [주의] .search-sheet 는 @keyframes sheetUp 이 transform 을 쓰므로
     여기서 transform 으로 가운데 정렬하면 애니메이션과 충돌합니다.
     left/right 인셋만 씁니다. */
  .stack-search .search-sheet {
    left: max(0px, calc((100% - 860px) / 2));
    right: max(0px, calc((100% - 860px) / 2));
    max-height: 60%;
  }
  .stack-search .ss-h { padding: 16px 24px 10px; }
  .stack-search .ss-body { padding: 12px 24px 22px; }

  /* ── 3. 방문예약 — 가운데 폼 열 ───────────────────────────── */
  /* 720px 폼 축. .reserve-scroll 은 안쪽 .app 을 채우므로 100% = 1080px. */
  .stack-form .reserve-scroll {
    padding: 24px max(24px, calc((100% - 720px) / 2)) 28px;
  }
  /* 시간대 12칸 — 모바일 4열 그대로 두면 720px 에서 한 칸이 170px 라
     '09:00' 이 지나치게 헐렁합니다. 6열 × 2줄로 정리합니다. */
  .stack-form .chk-time { grid-template-columns: repeat(6, 1fr); }
  .stack-form .chk-date { grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); }
  .stack-form .chk-time .chk { min-height: 52px; }

  /* 하단 CTA 도 같은 축으로 — 좁은 폼 아래에서 버튼만 화면 끝까지 늘어나면 어색합니다. */
  .stack-form .bottom-cta {
    padding-left: max(16px, calc((100% - 720px) / 2));
    padding-right: max(16px, calc((100% - 720px) / 2));
  }
  /* 예약완료 티켓은 폼보다 좁게 — 종이 티켓 비례를 유지합니다. */
  .stack-form .ticket { max-width: 520px; margin: 28px auto; }

  /* ── 4. 채팅 ──────────────────────────────────────────────────
     말풍선 max-width 78% 는 880px 에서 587px 까지 늘어 읽기 나쁩니다.
     상한만 둡니다(모바일은 이 블록을 읽지 않으므로 영향 없음). */
  .stack-chat .msg { max-width: min(78%, 520px); }
  .stack-chat .chat-body { padding: 20px 24px; }
  .stack-chat .chat-input { padding: 14px 24px calc(14px + env(safe-area-inset-bottom)); }

  /* ── 5. 게시판 · 고객센터 · 알림 ─────────────────────────────
     목록은 글 중심이라 그리드보다 '읽기 좋은 단일 열'이 맞습니다.
     820px 축으로 모으고, 검색·칩·안내문도 같은 축에 맞춥니다. */
  .stack-list .board-meta,
  .stack-list .board-list,
  .stack-list .board-detail,
  .stack-list .board-hub,
  .stack-help .help-pad,
  .stack-help .help-pad-top {
    padding-left: max(20px, calc((100% - 820px) / 2));
    padding-right: max(20px, calc((100% - 820px) / 2));
  }
  .stack-list .chips,
  .stack-help .chips { padding-left: max(20px, calc((100% - 820px) / 2)); padding-right: max(20px, calc((100% - 820px) / 2)); }
  .stack-list .sec,
  .stack-help .sec { padding-left: max(20px, calc((100% - 820px) / 2)); padding-right: max(20px, calc((100% - 820px) / 2)); }
  .stack-help .hc-search { margin-left: max(20px, calc((100% - 820px) / 2)); margin-right: max(20px, calc((100% - 820px) / 2)); }
  .stack-help .hc-tabs { padding-left: max(20px, calc((100% - 820px) / 2)); padding-right: max(20px, calc((100% - 820px) / 2)); }
  .stack-help .hc-tabs .hc-tab { height: 42px; font-size: 13.5px; }

  /* 목록 카드 — 행간을 조금 넓혀 820px 폭에서 답답하지 않게. */
  .stack-list .jobcard { padding: 20px 0; gap: 16px; }
  .stack-list .jtitle { font-size: 16.5px; }
  .stack-list .lessoncard { padding: 20px 0; }
  .stack-list .boardcard { padding: 20px; }

  /* 질문 목록 — 펼친 답변의 행간을 넓힙니다. */
  .stack-help .hc-q { padding: 17px 0; }
  .stack-help .hc-qt { font-size: 14.5px; white-space: normal; }
  .stack-help .hc-a { padding: 0 0 18px 30px; }

  /* ── 6. 기사 본문 — 읽기 폭 ────────────────────────────────
     본문은 680px 를 넘으면 눈이 줄을 놓칩니다. 제목·발행정보·본문·고지
     모두 같은 축으로 모읍니다. (상단 히어로 이미지는 전체 폭 유지) */
  .stack-read .nart-body {
    padding: 32px max(24px, calc((100% - 680px) / 2)) 24px;
  }
  .stack-read .nart-title { font-size: 30px; line-height: 1.4; margin: 0 0 16px; }
  .stack-read .nart-p { font-size: 16.5px; line-height: 2.05; }
  .stack-read .nart-by { font-size: 12.5px; }
  .stack-read .nart-note { margin: 26px 0 16px; padding: 18px 20px; }

  /* ── 7. 공통 — 스택 화면 상단바 여백 ────────────────────────
     좁은 화면용 16px 은 넓은 화면에서 로고/제목이 화면 끝에 붙어 보입니다. */
  #root > .app.stack-form .topbar,
  #root > .app.stack-list .topbar,
  #root > .app.stack-help .topbar,
  #root > .app.stack-read .topbar,
  #root > .app.stack-chat .topbar {
    padding-left: max(20px, calc((100% - 1000px) / 2));
    padding-right: max(20px, calc((100% - 1000px) / 2));
    height: calc(64px + env(safe-area-inset-top));
  }
}

/* ── 58차: 단지 안내 사진 전체보기 (좌우 넘기기) ─────────────── */
/* 등록된 사진을 한 화면에서 넘겨 봅니다. 누른 사진부터 시작합니다. */
.lightbox .lb-stage { position: relative; flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
.lightbox .lb-stage img { flex: none; width: 100%; height: 100%; object-fit: contain; padding: 8px 4px; }
.lightbox .lb-count { font-size: 12.5px; font-weight: 700; color: rgba(255,255,255,.75); letter-spacing: .02em; }
.lightbox .lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.28);
  color: #fff; cursor: pointer; z-index: 2;
  -webkit-tap-highlight-color: transparent;
}
.lightbox .lb-nav:active { background: rgba(255,255,255,.3); }
.lightbox .lb-nav.prev { left: 8px; }
.lightbox .lb-nav.next { right: 8px; }
.lightbox .lb-desc { margin-bottom: 8px; }
.lightbox .lb-thumbs { display: flex; gap: 6px; overflow-x: auto; padding: 2px 0 4px; justify-content: flex-start; -webkit-overflow-scrolling: touch; }
.lightbox .lb-thumb {
  flex: none; width: 56px; height: 40px; padding: 0; border-radius: 3px;
  overflow: hidden; border: 2px solid transparent; background: #1b2723; opacity: .55; cursor: pointer;
}
.lightbox .lb-thumb.on { border-color: var(--brass, #C6A15B); opacity: 1; }
.lightbox .lb-thumb img { width: 100%; height: 100%; object-fit: cover; padding: 0; }
