/* =====================================================================
   부동산 매물관리 SaaS — 디자인 시스템 v3
   ---------------------------------------------------------------------
   v2 → v3 (2026-08-15): **대비를 올렸다.**
   v2 는 선이 너무 연해서 "여기부터 저기까지가 한 덩어리"가 눈에 안 들어왔다.
     · 경계선을 두 단계 진하게 (#e3e9e8 → #c2d0cd). 1px 로도 확실히 보이게
     · 흐린 회색 글씨(#78878f)를 본문에 쓸 수 있는 명도(#54666f)로 교정
     · 사이드바를 짙은 틸로 — 내비게이션과 작업 영역이 색으로 갈린다
     · 모든 영역(카드·패널·팝업)의 머리에 배경색 + 굵은 아래선을 넣어
       "무엇을 보는 곳인지"를 제목이 아니라 색으로 먼저 알게 한다
     · 앰버는 여전히 "지금 해야 할 일"에만 — 남발하면 다시 구분이 사라진다
   ===================================================================== */

:root {
  /* =====================================================================
     테마: 모노크롬 (2026-08-26)

     검정·흰색·회색만으로 뼈대를 세운다. 색은 <b>뜻이 있을 때만</b> 쓴다.

     ★ 완전한 흑백으로 만들지 않은 이유.
       이 화면에는 색이 곧 정보인 자리가 있다.
         · 일치 / 어긋남  — 목록을 훑을 때 글자를 읽지 않고 색으로 먼저 가른다
         · 매수·임차·매도·임대 — "임차"와 "임대"는 한 글자 차이인데 뜻이 정반대다
       이것들까지 회색으로 만들면 훑어보기가 불가능해지고, 그건 꾸미기가 아니라
       기능을 없애는 것이다. 그래서 <b>채도만 크게 낮춰</b> 남겼다.
       회색 화면 위에서는 옅은 색도 충분히 눈에 띈다.

     ★ 바꾼 것은 이 변수 값들뿐이다. 마크업·JS·기능은 한 줄도 손대지 않았다.
     ===================================================================== */

  /* ---------- 바탕: 흰 종이와 옅은 회색 ---------- */
  --canvas:      #f6f6f7;
  --surface:     #ffffff;
  --surface-2:   #fafafa;
  --surface-3:   #f0f0f1;

  /* 글자 — 순수 검정(#000)은 쓰지 않는다. 흰 바탕에서 눈이 부신다 */
  --ink:         #17171a;
  --ink-2:       #45454b;
  --ink-mute:    #78787f;

  --line:        #e6e6e8;
  --line-strong: #c9c9ce;

  /* ---------- 브랜드: 검정 ----------
     주 단추와 강조 요소가 전부 검정이 된다. 색이 아니라 <b>대비</b>로 눈길을 끈다. */
  --brand:       #1c1c1f;
  --brand-ink:   #000000;
  --brand-deep:  #000000;
  --brand-soft:  #dcdce0;
  --brand-tint:  #f2f2f3;

  /* 사이드바 — 거의 검정. 본문의 흰 종이와 가장 강하게 갈라진다 */
  --nav-bg:      #131316;
  --nav-ink:     #e7e7ea;
  --nav-ink-mute:#83838c;   /* 내비 묶음 이름. 메뉴보다 약해야 제목으로 읽힌다 */
  --nav-line:    #2a2a2f;

  /* ---------- 강조 (행동 유도 전용) ----------
     검정으로 하면 주 단추와 구분이 안 된다. 회색 화면에서 유일하게 튀는
     색 하나만 남긴다 — 눌러야 할 곳이 어디인지는 색으로 말해야 한다. */
  --accent:      #b45309;
  --accent-ink:  #8a3f07;
  --accent-soft: #f5e7d5;

  /* ---------- 의미색 (뜻이므로 남긴다. 채도만 낮췄다) ---------- */
  --ok:          #3f6d52;
  --ok-soft:     #e2ebe5;
  --warn:        #7a5f22;
  --warn-soft:   #f1e9d6;
  --danger:      #97463a;
  --danger-soft: #f2dfdc;
  --info:        #3f5a80;
  --info-soft:   #e2e8f1;
  /* ---------- 고객 유형 ----------
     임차와 임대는 한 글자 차이인데 뜻이 정반대라, 글자만으로는 목록을 훑을 때 반드시 헷갈린다.
     그래서 색으로 먼저 가른다. 기준은 "물건을 찾는 쪽(차가운 색) / 내놓는 쪽(따뜻한 색)" 이다.
     한 번 익히면 매수·임차가 손님, 매도·임대가 물건 주인이라는 것이 색으로 읽힌다.
     의미색(ok/warn/danger)을 빌려 쓰지 않는다 — 임대는 경고가 아니다. */
  --buyer:         #3f5a80;   /* 매수 — 남색 */
  --buyer-soft:    #e3e8f0;
  --tenant:        #5c5480;   /* 임차 — 보라 */
  --tenant-soft:   #e7e5ef;
  --seller:        #80495f;   /* 매도 — 자주 */
  --seller-soft:   #f0e2e7;
  --landlord:      #7d5f2b;   /* 임대 — 앰버 */
  --landlord-soft: #efe8d9;

  /* ---------- 정체성 색 (2026-09-13) ----------
     검정 뼈대 위에 <b>단 하나</b>의 색. 단추에는 쓰지 않는다 — 단추 색은 위의 --accent(행동)이 맡는다.
     이 색이 가는 곳: 내비 현재 표시 · 페이지 제목 밑줄 · 카드 제목 막대 · 로고 · 포커스 테두리.
     ★ 예전에는 같은 자리에 #4fd3c4 · #6fe3d3 · #2b5a54 · rgba(47,125,99) 가 제각각 박혀 있었다.
       서비스 이름과 브랜드 색이 정해지면 <b>아래 두 값만</b> 바꾸면 된다. */
  --identity:        #1a9c8a;   /* 흰 바탕 위 (진하게) */
  --identity-bright: #5fe0cf;   /* 검은 내비 위 (밝게) */
  --identity-soft:   #d9f1ed;

  /* ---------- 글자 위계 (2026-09-13) ----------
     화면마다 제목 크기가 조금씩 달랐다(17 · 16.5 · 15 · 14.5). 다섯 단으로 고정한다.
     JS 템플릿에 박힌 크기도 이 값을 쓴다. */
  --fs-h1:   25px;    /* 페이지 제목 */
  --fs-h2:   16px;    /* 카드·팝업 제목 */
  --fs-h3:   13.5px;  /* 카드 안 구역 제목 */
  --fs-body: 14px;
  --fs-sm:   12.5px;
  --fs-xs:   11.5px;

  /* 모서리를 키우면 같은 구조도 덜 딱딱해 보인다 */
  --r-sm: 10px;
  --r:    15px;
  --r-lg: 19px;
  --r-pill: 999px;

  /* 그림자도 회색이 아니라 따뜻한 갈색빛으로 — 종이 위에 얹힌 느낌 */
  --shadow-1: 0 1px 2px rgba(62, 50, 38, .07);
  --shadow-2: 0 2px 6px rgba(62, 50, 38, .07), 0 14px 30px -20px rgba(62, 50, 38, .35);
  --shadow-3: 0 28px 66px -26px rgba(48, 38, 28, .38);
  --shadow-brand: 0 6px 16px -8px rgba(28, 28, 31, .45);   /* 검은 단추의 그림자 — 단추 색과 같은 계열 */

  --nav-w: 238px;
}

/* =====================================================================
   글꼴 (2026-09-13)

   ★ 여태 아래 body 에 "Pretendard" 라고 적어만 두고 <b>불러오는 코드가 없었다.</b>
     컴퓨터에 설치돼 있지 않으면 맑은 고딕으로 떨어졌다 — "관리 프로그램 느낌"의 절반은 그 글꼴이었다.

   ★ 파일은 숏츠용으로 이미 war 안에 있던 것(2.7MB TTF)을 <b>한글·라틴만 남겨 WOFF2 로 줄인 것</b>이다
     (한 파일 630KB 안팎, 한 번 받으면 브라우저가 가지고 있는다). 한자·특수기호는 이 화면에 안 나온다.

   ★ 굵기는 셋뿐인데 CSS 에는 550·600·650·700·750·800 이 섞여 있다. 그래서 <b>구간</b>으로 잇는다 —
       ~580  → Regular   (550 은 "살짝 힘준 본문"이라 굵어지면 화면이 무거워진다)
     581~740 → Bold      (600·650·700)
     741~    → ExtraBold (750·800 — 제목)
   ===================================================================== */
@font-face {
  font-family: "Pretendard";
  src: url("/fonts/Pretendard-Regular.woff2") format("woff2");
  font-weight: 100 580;
  font-display: swap;
}
@font-face {
  font-family: "Pretendard";
  src: url("/fonts/Pretendard-Bold.woff2") format("woff2");
  font-weight: 581 740;
  font-display: swap;
}
@font-face {
  font-family: "Pretendard";
  src: url("/fonts/Pretendard-ExtraBold.woff2") format("woff2");
  font-weight: 741 900;
  font-display: swap;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
               "Malgun Gothic", "맑은 고딕", system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  word-break: keep-all;
}

h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -0.02em; line-height: 1.32; }
p { margin: 0; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--identity); outline-offset: 2px; border-radius: 5px; }

/* 텍스트 링크 — 버튼과 구분되게 색과 밑줄로만 표시 */
.link {
  color: var(--brand-ink);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  border-bottom: 1px solid transparent;
}
.link:hover { border-bottom-color: currentColor; }
/* 목록 안에서 버튼으로 만든 링크 (기본 버튼 모양을 지운다) */
button.link { background: none; border: none; padding: 0; font: inherit; line-height: inherit; }

/* ===================== 레이아웃 ===================== */

.app { display: flex; min-height: 100vh; }

/* 사이드바는 짙게 — 내비게이션과 작업 영역을 색으로 갈라 놓는다 */
.nav {
  width: var(--nav-w);
  flex: 0 0 var(--nav-w);
  background: var(--nav-bg);
  color: var(--nav-ink);
  border-right: 1px solid var(--nav-bg);
  padding: 20px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  position: sticky;
  top: 0;
  height: 100vh;
  /*
   * ★ 메뉴가 화면보다 길어질 수 있다 (2026-09-08).
   *   묶음 이름 세 줄이 늘었고, 개발 설정이 켜지면 [준비 과제]·[보완 과제] 가 더 붙는다.
   *   노트북처럼 세로가 짧은 화면에서 이게 없으면 <b>맨 아래 로그아웃이 잘려</b> 못 누른다.
   */
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 10px 18px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--nav-line);
  color: #fff;
}

.brand-mark {
  width: 34px; height: 34px;
  flex: 0 0 34px;
  border-radius: 11px;
  background: linear-gradient(145deg, var(--identity), #0f6a5d);
  color: #fff;
  display: grid; place-items: center;
  box-shadow: 0 6px 16px -8px rgba(26, 156, 138, .7);
}
.brand-mark svg { display: block; }

.brand-name { display: block; font-size: 15px; font-weight: 700; letter-spacing: -0.02em; }
.brand-sub { display: block; font-size: 11.5px; color: #a1a1a8; }

.nav-link {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  color: var(--nav-ink);
  text-decoration: none;
  font-size: 14px;
  font-weight: 550;
  transition: background .13s ease, color .13s ease;
}
.nav-link:hover { background: #232327; color: #fff; }

.nav-link[aria-current="page"] {
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  box-shadow: var(--shadow-brand);
}
.nav-link[aria-current="page"]::before {
  content: "";
  position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 22px;
  border-radius: 0 4px 4px 0;
  background: var(--identity-bright);
}
.nav-icon { width: 18px; display: grid; place-items: center; opacity: .95; }

/*
 * 메뉴 묶음 이름 (2026-09-08).
 *
 * ★ 누를 수 없는 <b>제목</b>이라는 것이 한눈에 보여야 한다. 그래서 메뉴보다
 *   작고 흐리게, 아이콘 자리도 비운다 — 아이콘이 붙으면 눌러 보게 된다.
 * ★ 위 여백을 아래보다 훨씬 크게 준다. 제목이 <b>앞 묶음이 아니라 뒤 묶음에</b>
 *   붙어 보여야 나누는 구실을 한다.
 */
.nav-group {
  margin: 15px 0 3px;
  padding: 0 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  color: var(--nav-ink-mute);
  user-select: none;
}

/* 설정을 앞 묶음에서 떼어 내는 선. 여백만으로는 "참고" 에 딸려 보인다 */
.nav-divider {
  height: 1px;
  background: var(--nav-line);
  margin: 12px 12px 9px;
}

.nav-foot { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--nav-line); }
.nav-user { padding: 4px 12px 12px; }
.nav-user strong { display: block; font-size: 13.5px; font-weight: 650; color: #fff; }
.nav-user span { font-size: 12px; color: #a1a1a8; }
.nav .btn {
  background: transparent; color: var(--nav-ink);
  border-color: var(--nav-line); box-shadow: none;
}
.nav .btn:hover { background: #232327; color: #fff; border-color: var(--identity); }

/*
  본문 최대 폭.
  1340px 은 넓은 화면에서 오른쪽이 크게 비었다. 표와 카드가 대부분이라
  줄이 길어져 읽기 어려워지는 문제도 적어 폭을 늘렸다.
  (읽는 글이 많은 화면은 각자 안에서 다시 좁힌다)
*/
.main { flex: 1; min-width: 0; padding: 26px 34px 76px; max-width: 1680px; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding-bottom: 16px; margin-bottom: 20px;
  border-bottom: 2px solid var(--line-strong);
  position: relative;
}
/* 헤더 밑줄에 브랜드 색 한 조각 — 페이지마다 같은 자리에 오는 정체성 표시 */
.page-head::after {
  content: "";
  position: absolute; left: 0; bottom: -2px;
  width: 64px; height: 3px;
  background: linear-gradient(90deg, var(--identity), var(--identity-bright));
  border-radius: 2px;
}
.page-head h1 { font-size: var(--fs-h1); font-weight: 750; }
.page-head .sub { color: var(--ink-mute); font-size: 13.5px; margin-top: 5px; max-width: 62ch; font-weight: 550; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ===================== 버튼 ===================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 36px;
  padding: 8px 15px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-size: 13.5px; font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: var(--shadow-1);
  transition: background .13s ease, border-color .13s ease, box-shadow .13s ease, transform .07s ease;
}
.btn:hover { background: var(--surface-2); border-color: var(--ink-mute); box-shadow: var(--shadow-2); }
.btn:active { transform: translateY(1px); box-shadow: var(--shadow-1); }
.btn:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

.btn-primary {
  background: var(--brand); border-color: var(--brand); color: #fff;
  box-shadow: var(--shadow-brand);
}
.btn-primary:hover { background: var(--brand-ink); border-color: var(--brand-ink); transform: translateY(-1px); }

/* 앰버 — "지금 이걸 눌러 보세요" 하나에만 */
.btn-accent { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-ink); border-color: var(--accent-ink); }

.btn-quiet { border-color: transparent; background: transparent; box-shadow: none; color: var(--ink-2); }
.btn-quiet:hover { background: var(--surface-3); border-color: var(--line-strong); box-shadow: none; }

.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 28%, var(--line)); }
.btn-danger:hover { background: var(--danger-soft); border-color: var(--danger); }

.btn-sm { min-height: 29px; padding: 4px 11px; font-size: 12.5px; }
.btn-block { width: 100%; }

/* ===================== 카드 / 패널 ===================== */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  /* 8월에 경계선을 진하게 올리면서 그림자를 거의 뺐더니 전부 한 평면에 붙어 보였다. 아주 얇게 띄운다 */
  box-shadow: var(--shadow-1), 0 10px 24px -22px rgba(62, 50, 38, .35);
  overflow: hidden;
}
/* 카드 머리에는 배경과 굵은 아래선 — 제목을 읽기 전에 영역이 먼저 보인다 */
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 18px;
  background: var(--surface-2);
  border-bottom: 2px solid var(--line);
}
.card-head h2 {
  font-size: var(--fs-h2); font-weight: 700;
  display: flex; align-items: center; gap: 8px;
}
/* 제목 앞 브랜드 색 막대 */
.card-head h2::before {
  content: "";
  width: 4px; height: 15px; border-radius: 2px;
  background: var(--identity);
  flex: 0 0 4px;
}
.card-head .hint { font-size: 12.5px; color: var(--ink-mute); font-weight: 550; }
.card-body { padding: 14px 18px 18px; }
.card-body.flush { padding: 0; }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-main { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }
/*
  대시보드 상자 배치.

  지금은 둘이다 — 할 일 / 정책·호재.
  ("최근 활동"은 뺐다. 고객 화면의 타임라인과 같은 내용을 한 번 더 보여 줄 뿐이었다.
   이 자리는 나중에 검색어 트렌드 카드가 들어온다 — 그때 세 칸으로 돌린다)

  호재를 조금 넓게 — 공고 제목이 가장 길다.
*/
.grid-dash { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }

/* ===================== 지표 타일 ===================== */

.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }

.stat {
  position: relative;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-lg);
  padding: 16px 18px 15px;
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
/* 타일마다 왼쪽에 색 띠 — 네 개가 나란히 있을 때 구분이 빨라진다 */
.stat::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 5px;
  background: var(--brand);
}
.stat:nth-child(2)::before { background: #6f88a8; }
.stat:nth-child(3)::before { background: #7a8ee0; }
.stat:nth-child(4)::before { background: var(--accent); }

.stat-label { font-size: 12.5px; color: var(--ink-mute); display: flex; align-items: center; gap: 6px; }
.stat-value {
  display: block; margin-top: 6px;
  font-size: 30px; font-weight: 750; letter-spacing: -0.035em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.stat-value .unit { font-size: 14px; font-weight: 550; color: var(--ink-mute); margin-left: 3px; letter-spacing: 0; }
.stat-foot { font-size: 12px; color: var(--ink-mute); margin-top: 3px; }

/* ===================== 배지 / 칩 ===================== */

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .01em;
  background: var(--surface-3); color: var(--ink-2);
  border: 1px solid var(--line-strong);
  white-space: nowrap;
  letter-spacing: -0.01em;
}
.badge[data-tone="ok"]     { background: var(--ok-soft);     color: var(--ok);     border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
.badge[data-tone="warn"]   { background: var(--warn-soft);   color: var(--warn);   border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.badge[data-tone="danger"] { background: var(--danger-soft); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.badge[data-tone="info"]   { background: var(--info-soft);   color: var(--info);   border-color: color-mix(in srgb, var(--info) 38%, transparent); }
/* ★ accent 는 "이건 눈에 띄어야 한다" 는 뜻이다 (예정·오늘·관심도 높음·필수).
     모노크롬 테마로 바꾸면서 brand(검정·회색)에 물려 있어 전부 회색으로 보였다 —
     강조하려고 만든 색이 강조가 안 되면 있으나 마나다 (2026-08-30). */
.badge[data-tone="accent"] { background: var(--accent-soft); color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 45%, transparent); font-weight: 750; }

/* ---- 고객 유형 ---- */
.badge[data-tone="buyer"]    { background: var(--buyer-soft);    color: var(--buyer);    border-color: color-mix(in srgb, var(--buyer) 38%, transparent); }
.badge[data-tone="tenant"]   { background: var(--tenant-soft);   color: var(--tenant);   border-color: color-mix(in srgb, var(--tenant) 38%, transparent); }
.badge[data-tone="seller"]   { background: var(--seller-soft);   color: var(--seller);   border-color: color-mix(in srgb, var(--seller) 38%, transparent); }
.badge[data-tone="landlord"] { background: var(--landlord-soft); color: var(--landlord); border-color: color-mix(in srgb, var(--landlord) 38%, transparent); }

/*
  색만으로 가르면 색각 이상이 있는 사용자에게는 네 배지가 거의 같아 보이고,
  흑백 출력에서도 구분이 사라진다. 그래서 "찾는 쪽 ●, 내놓는 쪽 ○" 표식을 함께 붙인다.
  글자 크기를 건드리지 않도록 점만 작게 둔다.
*/
.badge[data-tone="buyer"]::before,
.badge[data-tone="tenant"]::before   { content: "●"; font-size: 7px; line-height: 1; }
.badge[data-tone="seller"]::before,
.badge[data-tone="landlord"]::before { content: "○"; font-size: 7px; line-height: 1; }

/* 도움말 줄 안에 배지가 섞이면 밑선이 어긋난다 (고객 등록 폼의 유형 미리보기) */
.help .badge { vertical-align: -2px; }

.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  font-size: 12px; font-weight: 550;
  color: var(--ink-2);
}
.chips { display: flex; flex-wrap: wrap; gap: 5px; }

button.chip { cursor: pointer; transition: background .12s ease, border-color .12s ease; }
button.chip:hover { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-deep); }

/* ===================== 표 ===================== */

.table { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
.table th, .table td { padding: 12px 18px; text-align: left; border-bottom: 1px solid var(--line); }
.table th {
  font-size: var(--fs-xs); font-weight: 750; color: var(--ink-2);
  letter-spacing: .02em;
  background: var(--surface-3);
  border-bottom: 2px solid var(--line-strong);
  position: sticky; top: 0; z-index: 1;
}
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr.clickable { cursor: pointer; transition: background .12s ease; }
.table tbody tr.clickable:hover { background: var(--brand-tint); }
.table tbody tr.clickable:hover td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ===================== 목록 줄 ===================== */

.rows { list-style: none; margin: 0; padding: 0; }
.row-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--line);
  transition: background .12s ease;
}
.row-item:last-child { border-bottom: none; }

/* 누를 수 있는 줄만 손가락 커서 + 오른쪽 › 표시 */
.row-item[data-id], .row-item[data-href],
.row-item.is-clickable { cursor: pointer; }

/* 매물·고객이 지워진 안내 완료 줄. 지우지 않되 흐리게 — 기록은 남고 눈에는 덜 걸린다 */
.row-item.is-muted .row-title { color: var(--ink-mute); }
.row-item[data-id]::after, .row-item[data-href]::after, .row-item.is-clickable::after {
  content: "›";
  margin-left: 4px;
  color: var(--line-strong);
  font-size: 19px; line-height: 1;
  transition: color .12s ease, transform .12s ease;
}
.row-item[data-id]:hover, .row-item[data-href]:hover, .row-item.is-clickable:hover {
  background: var(--brand-tint);
}
.row-item[data-id]:hover::after, .row-item[data-href]:hover::after, .row-item.is-clickable:hover::after {
  color: var(--brand); transform: translateX(2px);
}

/*
  줄 번호. 목록이 길어지면 "몇 번째 것을 봤는지"가 기억의 손잡이가 된다.
  폭을 고정해 두 자리·세 자리에서 본문 시작점이 흔들리지 않게 한다.
*/
.row-no {
  flex: 0 0 auto; min-width: 26px;
  text-align: right;
  font-size: 12.5px; font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}

.row-main { min-width: 0; flex: 1; }
.row-title {
  font-size: 14px; font-weight: 650;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: flex; align-items: center; gap: 6px;
}
.row-sub { font-size: 12.5px; color: var(--ink-mute); margin-top: 2px; font-weight: 500; }
.row-side { text-align: right; flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.row-time {
  flex: 0 0 60px; text-align: center;
  font-size: 12.5px; color: var(--ink-mute); font-variant-numeric: tabular-nums;
  padding: 4px 0;
  border-right: 1px solid var(--line);
}

.empty {
  padding: 34px 20px 32px;
  text-align: center;
  color: var(--ink-mute);
  font-size: var(--fs-body); font-weight: 550;
  line-height: 1.6;
}
/*
  빈 화면에 작은 그림 하나 (2026-09-13). 글자 한 줄만 있으면 "고장 났나" 로 읽힌다.
  그림은 CSS 만으로 그린다 — 파일을 하나 더 내려받게 하지 않는다. 얇은 서류함 모양.
*/
.empty::before {
  content: "";
  display: block;
  width: 44px; height: 34px;
  margin: 0 auto 12px;
  border: 2px solid var(--line-strong);
  border-radius: 8px;
  background:
    linear-gradient(var(--line-strong), var(--line-strong)) center 60% / 22px 2px no-repeat,
    linear-gradient(var(--line-strong), var(--line-strong)) center 42% / 14px 2px no-repeat;
  opacity: .75;
}
.empty.is-slim { padding: 22px 16px 20px; }
.empty.is-slim::before { width: 34px; height: 26px; margin-bottom: 9px; }
.empty strong { display: block; color: var(--ink-2); font-weight: 750; margin-bottom: 3px; font-size: 14.5px; }

/* ===================== 매물 카드 ===================== */

.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }

.pcard {
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: box-shadow .17s ease, transform .17s ease, border-color .17s ease;
  display: flex; flex-direction: column;
}
.pcard:hover {
  box-shadow: var(--shadow-2);
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--brand) 35%, var(--line));
}

.pcard-thumb {
  aspect-ratio: 4 / 3;
  background: linear-gradient(160deg, var(--surface-3), #d4e0dd);
  border-bottom: 1px solid var(--line);
  display: grid; place-items: center;
  color: var(--ink-mute);
  font-size: 12.5px;
  position: relative;
  overflow: hidden;
}
.pcard-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pcard-thumb .badge {
  position: absolute; top: 9px; left: 9px;
  background: rgba(255, 255, 255, .93);
  box-shadow: var(--shadow-1);
}

.pcard-body { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
.pcard-price { font-size: 17px; font-weight: 700; letter-spacing: -0.03em; color: var(--brand-deep); }
.pcard-title {
  font-size: 13.5px; font-weight: 650; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pcard-meta { font-size: 12px; color: var(--ink-mute); font-weight: 550; }

/* ===================== 폼 ===================== */

.form { display: grid; gap: 14px; }
.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.form-row-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }

.field { display: grid; gap: 5px; min-width: 0; align-content: start; }
.field > label { font-size: 12.5px; font-weight: 700; color: var(--ink-2); }
.field .help, .help { font-size: 11.5px; color: var(--ink-mute); line-height: 1.55; font-weight: 550; }

.input, .select, .textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-size: 14px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-mute); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--identity);
  box-shadow: 0 0 0 3px var(--identity-soft);
}
.input::placeholder, .textarea::placeholder { color: #a9b4ba; }
.textarea { resize: vertical; min-height: 84px; line-height: 1.6; }

/* select 임을 알 수 있게 화살표를 그린다 */
.select {
  appearance: none;
  padding-right: 32px;
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-mute) 50%),
    linear-gradient(135deg, var(--ink-mute) 50%, transparent 50%);
  background-position: calc(100% - 17px) calc(50% + 1px), calc(100% - 12px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.field-inline { display: flex; align-items: center; gap: 8px; }
.field-inline input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--brand); cursor: pointer; }
.field-inline label { font-size: 13.5px; font-weight: 500; cursor: pointer; }

.fieldset {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 14px;
  background: var(--surface-2);
}
.fieldset > legend { font-size: 12.5px; font-weight: 650; color: var(--brand-deep); padding: 0 7px; }
.fieldset > summary { list-style: none; }
.fieldset > summary::-webkit-details-marker { display: none; }
.fieldset > summary::before { content: "▸ "; color: var(--brand); }
details[open].fieldset > summary::before { content: "▾ "; }

/* 검색·필터는 한 덩어리로 보이게 상자에 담는다 */
.toolbar {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin-bottom: 16px;
  padding: 11px 12px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
}
.toolbar .input, .toolbar .select { width: auto; }

/* 카드 머리처럼 좁은 자리에 들어가는 선택 상자 */
.select-sm {
  width: auto; min-height: 28px;
  padding: 3px 26px 3px 9px;
  font-size: 12px; font-weight: 600;
  background-position: right 7px center;
}
.toolbar .search { flex: 1; min-width: 200px; }

/* ===================== 모달 ===================== */

dialog.modal {
  width: min(720px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  padding: 0;
  border: none;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-3);
  color: var(--ink);
}
dialog.modal::backdrop { background: rgba(16, 28, 34, .42); backdrop-filter: blur(2px); }

.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 15px 20px;
  border-bottom: 3px solid var(--brand);
  position: sticky; top: 0; z-index: 2;
  background: linear-gradient(180deg, var(--brand-tint), var(--surface));
}
.modal-head h2 { font-size: var(--fs-h2); font-weight: 750; }

/*
  ★ 스크롤이 두 개 생기던 문제 (2026-08-31).

    예전에는 본문 높이를 calc(100vh - 212px) 로 <b>머리·바닥 높이를 숫자로 박아</b> 뒀다.
    그 숫자가 실제와 어긋나는 순간(줄이 하나 늘거나, 버튼이 두 줄로 접히거나)
    팝업 전체가 max-height 를 넘어 <b>바깥에도 스크롤바가 생긴다.</b>
    스크롤이 둘이면 어느 것을 굴려야 할지 매번 고르게 되고, 바닥 버튼이 가려진다.

    이제 팝업을 세로 flex 로 두고 본문이 <b>남는 만큼</b> 차지하게 한다.
    머리·바닥이 몇 픽셀이든 계산이 필요 없다.

  ★ display 는 반드시 [open] 일 때만 준다. dialog 는 닫혀 있을 때 display:none 인데
    그걸 flex 로 덮으면 <b>닫힌 팝업이 화면에 남는다.</b>
*/
dialog.modal[open] { display: flex; flex-direction: column; }
.modal-head { flex: none; }
.modal-body {
  padding: 18px 20px;
  overflow-y: auto;
  flex: 1 1 auto; min-height: 0;
}
.modal-foot {
  flex: none;
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 13px 20px;
  border-top: 2px solid var(--line);
  background: var(--surface-2);
}
.modal-close {
  border: none; background: transparent; cursor: pointer;
  font-size: 21px; line-height: 1; color: var(--ink-mute); padding: 4px 7px; border-radius: 7px;
}
.modal-close:hover { background: var(--surface-3); color: var(--ink); }

/* 확인 팝업 — 본문이 짧으므로 좁게 */
dialog.modal.confirm { width: min(430px, calc(100vw - 32px)); }
dialog.modal.confirm .modal-body { padding: 20px; }
.confirm-msg { font-size: 14.5px; font-weight: 550; line-height: 1.6; }

/* 팝업 안의 간단 폼 (대시보드 빠른 처리 등) */
.quick-section { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.quick-section > h3 {
  font-size: 12px; font-weight: 700; color: var(--brand-deep);
  letter-spacing: .03em; margin-bottom: 9px;
}

/* ===================== 상세 팝업 안의 구성 요소 ===================== */

.section { margin-top: 22px; }
.section:first-child { margin-top: 0; }
/* 섹션 제목은 색 띠를 두른 라벨처럼 — 팝업 안에서 구획이 확실히 갈린다 */
.section > h3 {
  font-size: 12px; font-weight: 800; color: var(--brand-deep);
  letter-spacing: .02em; margin-bottom: 11px;
  padding: 5px 10px;
  background: var(--brand-soft);
  border-left: 4px solid var(--brand);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

.dl { display: grid; grid-template-columns: 96px 1fr; gap: 8px 12px; font-size: 13.5px; }
.dl dt { color: var(--ink-mute); font-weight: 600; }
.dl dd { margin: 0; font-weight: 650; }

/* 항목별 일치 여부를 칠할 수 있는 표 (매물 상세의 기본 정보) */
.speclist { display: grid; gap: 3px; font-size: 13.5px; margin: 0; }
.speclist .spec {
  display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 12px;
  padding: 7px 10px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  background: var(--surface-2);
}
.speclist .spec dt { color: var(--ink-mute); font-weight: 600; }
.speclist .spec dd { margin: 0; font-weight: 650; }

.speclist .spec[data-hit="ok"] {
  background: var(--ok-soft);
  border-color: color-mix(in srgb, var(--ok) 35%, transparent);
}
.speclist .spec[data-hit="ok"] dt { color: var(--ok); }
.speclist .spec[data-hit="warn"] {
  background: var(--warn-soft);
  border-color: color-mix(in srgb, var(--warn) 38%, transparent);
}
.speclist .spec[data-hit="warn"] dt { color: var(--warn); }
.spec-note { display: block; font-size: 11.5px; font-weight: 650; margin-top: 2px; }
.spec[data-hit="ok"] .spec-note { color: var(--ok); }
.spec[data-hit="warn"] .spec-note { color: var(--warn); }

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.gallery figure { margin: 0; position: relative; border-radius: var(--r-sm); overflow: hidden; background: var(--surface-3); }
.gallery img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.gallery .thumb-actions {
  position: absolute; inset: auto 0 0 0;
  display: flex; gap: 4px; justify-content: center;
  padding: 5px; background: linear-gradient(transparent, rgba(0,0,0,.6));
  opacity: 0; transition: opacity .14s ease;
}
.gallery figure:hover .thumb-actions { opacity: 1; }
.thumb-btn {
  border: none; background: rgba(255,255,255,.95); color: var(--ink);
  border-radius: 6px; font-size: 11px; font-weight: 600; padding: 3px 8px; cursor: pointer;
}
.thumb-btn:hover { background: #fff; }
.gallery figure[data-cover="true"]::after {
  content: "대표"; position: absolute; top: 5px; left: 5px;
  background: var(--brand); color: #fff; font-size: 10.5px; font-weight: 700;
  padding: 2px 7px; border-radius: var(--r-pill);
}

.dropzone {
  border: 2px dashed var(--line-strong);
  border-radius: var(--r);
  padding: 18px; text-align: center;
  color: var(--ink-mute); font-size: 13px; font-weight: 550;
  cursor: pointer;
  transition: border-color .13s ease, background .13s ease, color .13s ease;
}
.dropzone:hover, .dropzone.over {
  border-color: var(--brand); background: var(--brand-soft); color: var(--brand-deep);
}

/* ===================== 추천(매칭) ===================== */

.match {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 13px 2px;
  border-bottom: 1px solid var(--line);
}
.match:last-child { border-bottom: none; }

/* 점수대별로 링 색을 바꾼다 — 숫자를 읽기 전에 "볼 만한가"가 먼저 보인다 */
.score[data-fit="mid"]  { color: var(--info); }
.score[data-fit="low"]  { color: var(--ink-mute); }
.score[data-fit="high"] { color: var(--brand-deep); }

/* 낮은 일치율 구간을 여는 구분선 — 지우지 않고 아래로 내린다 */
.match-divider {
  display: flex; align-items: center; gap: 9px;
  margin: 14px 0 4px;
  font-size: 11.5px; font-weight: 750; color: var(--ink-mute);
  text-transform: none;
}
.match-divider::before, .match-divider::after {
  content: ""; height: 1px; background: var(--line); flex: 1;
}
/*
  엑셀 가져오기 미리보기에서 "못 넣는 줄" (2026-09-24).
  붉게 칠하지 않고 바탕만 옅게 깐다 — 오류가 절반이면 화면이 통째로 붉어져 오히려 안 읽힌다.
*/
.table tbody tr.row-problem { background: var(--danger-soft); }
.table tbody tr.row-problem td { color: var(--ink-2); }

.match.is-low { opacity: .92; }
.match.is-low .match-title { color: var(--ink-2); }

/* 눌러서 팝업을 여는 추천 카드 */
.match[data-quick],
.match[data-match-customer],
.match[data-match-property] {
  padding: 13px 10px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background .12s ease;
}
.match[data-quick]:hover,
.match[data-match-customer]:hover,
.match[data-match-property]:hover { background: var(--brand-tint); }

.score {
  flex: 0 0 46px; width: 46px; height: 46px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13.5px; font-weight: 800;
  color: var(--brand-deep);
  background: conic-gradient(currentColor calc(var(--pct) * 1%), var(--surface-3) 0);
  position: relative;
  margin-bottom: 16px;          /* 아래 캡션 자리 */
}
.score::before { content: ""; position: absolute; inset: 3.5px; border-radius: 50%; background: var(--surface); }

/* 동그라미만 있으면 "저 숫자가 뭐지?" 가 된다. 무엇을 재는 값인지 밑에 적어 둔다. */
.score::after {
  content: "일치율";
  position: absolute; left: 50%; bottom: -15px; transform: translateX(-50%);
  font-size: 10px; font-weight: 750; letter-spacing: -.02em;
  color: var(--ink-mute); white-space: nowrap;
}
.score[data-fit="none"] { color: var(--line-strong); }
.score[data-fit="none"]::after { content: "점수 없음"; }
.score span { position: relative; }

.match-main { flex: 1; min-width: 0; }
.match-title { font-size: 13.5px; font-weight: 700; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.match-sub { font-size: 12.5px; color: var(--ink-mute); margin-top: 2px; font-weight: 550; }
.match-reasons { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
.match-reasons .chip {
  background: var(--ok-soft);
  border-color: color-mix(in srgb, var(--ok) 35%, transparent);
  color: var(--ok); font-weight: 650;
}

/* ===================== 타임라인 ===================== */

.timeline { list-style: none; margin: 0; padding: 0 0 0 16px; border-left: 2px solid var(--line); }
.timeline li { position: relative; padding: 0 0 16px 14px; }
.timeline li::before {
  content: ""; position: absolute; left: -21px; top: 6px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--brand);
}
.timeline li:last-child { padding-bottom: 0; }
.timeline time { font-size: 11.5px; color: var(--ink-mute); font-variant-numeric: tabular-nums; }
.timeline .tl-title { font-size: 13.5px; font-weight: 600; margin-top: 2px; display: flex; gap: 6px; align-items: center; }
.timeline .tl-body { font-size: 13px; color: var(--ink-2); margin-top: 3px; }

/* 수정·삭제는 평소엔 조용히 있다가 그 줄에 손이 갔을 때만 또렷해진다 */
.tl-actions { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.tl-actions .btn { opacity: .45; transition: opacity .12s ease; }
.timeline li:hover .tl-actions .btn,
.tl-actions .btn:focus-visible { opacity: 1; }

/*
  잠긴 기록. 버튼만 사라지면 고장으로 읽히므로 "확정됨"이라고 적는다 —
  못 고치는 것이 결함이 아니라 의도라는 사실이 보여야 한다.
*/
.tl-locked {
  font-size: 11px; font-weight: 700; color: var(--ink-mute);
  padding: 1px 7px; border-radius: var(--r-pill);
  background: var(--surface-3); border: 1px solid var(--line);
  cursor: help;
}

.tl-edit { display: grid; gap: 7px; margin-top: 5px; }
.tl-edit .textarea { min-height: 74px; }

/* ===================== 토스트 ===================== */

/*
  알림 상자.

  ★ popover 로 만든다 — <dialog>.showModal() 로 연 팝업은 브라우저의 맨 위 층에 그려져
    z-index 로는 절대 넘을 수 없다. 같은 층으로 올라가야 팝업 위에 보인다 (2026-08-30).

  ★ popover 의 기본 모양(가운데 정렬·테두리·흰 배경)을 전부 되돌려야 한다.
    안 그러면 화면 한가운데 빈 상자가 뜬다.
*/
.toasts {
  position: fixed; right: 18px; bottom: 18px; z-index: 999;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
}

.toasts[popover] {
  inset: auto; right: 18px; bottom: 18px;
  margin: 0; padding: 0; border: 0; background: transparent;
  overflow: visible;
  max-width: none; max-height: none; width: auto; height: auto;
}

/* 떠 있어도 그 뒤를 가리지 않는다 — 알림은 지나가는 안내지 화면을 막는 것이 아니다 */
.toasts[popover]::backdrop { background: transparent; }

/* popover 는 열리기 전까지 display:none 이라, 열렸을 때만 flex 로 되돌린다 */
.toasts[popover]:popover-open {
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
}
.toast {
  background: var(--ink); color: #fff;
  padding: 11px 16px; border-radius: var(--r);
  font-size: 13.5px; font-weight: 550;
  box-shadow: var(--shadow-3);
  max-width: min(400px, calc(100vw - 36px));
  animation: toast-in .2s cubic-bezier(.2,.8,.3,1);
}
.toast[data-tone="ok"]     { background: var(--brand-deep); }
.toast[data-tone="danger"] { background: #8f3223; }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ===================== 로딩 ===================== */

.skeleton {
  background: linear-gradient(90deg, var(--surface-3) 25%, #f1f5f4 37%, var(--surface-3) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease infinite;
  border-radius: var(--r-sm);
  height: 14px;
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

.spinner {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  opacity: .8;
  animation: spin .7s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ===================== 로그인 ===================== */

.auth {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 24px;
  background:
    radial-gradient(1200px 520px at 8% -10%, #dff2ee 0%, transparent 58%),
    radial-gradient(900px 460px at 108% 110%, #fbeee0 0%, transparent 52%),
    var(--canvas);
}
.auth-card {
  width: min(400px, 100%);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: 34px 30px 28px;
  box-shadow: var(--shadow-2);
}
.auth-brand { display: flex; align-items: center; gap: 11px; margin-bottom: 24px; }
.auth h1 { font-size: 22px; margin-bottom: 5px; }
.auth .sub { color: var(--ink-mute); font-size: 13.5px; margin-bottom: 22px; }
.auth-links {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 16px; font-size: 13px;
}

/* 인증번호 입력 줄 — 번호 옆에 [인증번호 받기]가 붙는다 */
.verify-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: end; }
.verify-state {
  font-size: 12px; font-weight: 650; margin-top: 6px;
  display: flex; align-items: center; gap: 6px;
}
.verify-state[data-state="sent"] { color: var(--accent-ink); }
.verify-state[data-state="done"] { color: var(--ok); }
.verify-state[data-state="error"] { color: var(--danger); }

.auth-hint {
  margin-top: 18px; padding: 12px 14px;
  background: var(--brand-tint); border: 1px solid var(--brand-soft);
  border-radius: var(--r-sm); font-size: 12.5px; color: var(--ink-2); line-height: 1.65;
}
.auth-hint code {
  background: var(--surface); padding: 1px 6px; border-radius: 5px;
  font-size: 12px; color: var(--brand-deep); font-weight: 650;
}

.alert {
  padding: 11px 14px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600;
  background: var(--danger-soft); color: var(--danger);
  border: 1.5px solid color-mix(in srgb, var(--danger) 40%, transparent);
}
.alert[data-tone="info"] {
  background: var(--brand-tint); color: var(--brand-deep);
  border-color: color-mix(in srgb, var(--brand) 40%, transparent); font-weight: 600;
}
/* "확인해 보세요" 는 오류가 아니다. 기본(붉은) 알림으로 띄우면 고장 난 것처럼 보인다. */
.alert[data-tone="warn"] {
  background: var(--warn-soft); color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 40%, transparent); font-weight: 600;
}

/* ===================== 공개 공유 페이지 ===================== */

.public-shell { max-width: 960px; margin: 0 auto; padding: 34px 20px 76px; }
.public-head { text-align: center; margin-bottom: 28px; }
.public-head h1 { font-size: 25px; }
.public-head .sub { color: var(--ink-mute); font-size: 13.5px; margin-top: 7px; }
.public-foot {
  margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--line);
  text-align: center; color: var(--ink-mute); font-size: 12.5px; line-height: 1.7;
}

.share-item {
  display: grid; grid-template-columns: 220px 1fr; gap: 18px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden; margin-bottom: 14px;
  box-shadow: var(--shadow-1);
}
.share-item .shot { background: var(--surface-3); aspect-ratio: 4/3; }
.share-item .shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.share-item .info { padding: 16px 18px 16px 0; display: flex; flex-direction: column; gap: 8px; }

/* ===================== 유틸 ===================== */

.muted { color: var(--ink-mute); }
.small { font-size: 12.5px; }
.strong { font-weight: 650; }
.nowrap { white-space: nowrap; }
.right { text-align: right; }
.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.stack { display: grid; gap: 16px; }
.inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hidden { display: none !important; }
.scroll-x { overflow-x: auto; }
.prose { font-size: 14px; line-height: 1.78; white-space: pre-wrap; color: var(--ink-2); }
.price-lg { font-size: 23px; font-weight: 700; letter-spacing: -0.03em; color: var(--brand-deep); }

/* ===================== 2단 작업 화면 (목록 + 오른쪽 패널) =====================
   왼쪽에서 고르고 오른쪽에서 판단한다. 목록 → 상세 → 뒤로가기를 반복하지 않는 것이
   이 화면의 전부이므로, 오른쪽 패널은 스크롤을 따라다닌다(sticky).
   ============================================================================ */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 396px;
  gap: 18px;
  align-items: start;
}

.split-side { position: sticky; top: 18px; }

/* 패널 자체가 화면보다 길어지면 패널 안에서만 스크롤한다 */
.side-panel { display: flex; flex-direction: column; max-height: calc(100vh - 46px); }
.side-panel .side-body { overflow-y: auto; padding: 0 18px 18px; }
/* 오른쪽 패널 머리 — 왼쪽 목록과 다른 영역임을 색으로 못박는다 */
.side-panel .side-head {
  padding: 13px 18px;
  border-bottom: 3px solid var(--brand);
  background: var(--brand-soft);
  color: var(--brand-deep);
}
.side-panel .side-head h2 { color: var(--brand-deep); font-weight: 750; }
.side-panel .side-foot {
  margin-top: auto;
  padding: 11px 14px;
  border-top: 2px solid var(--line);
  background: var(--surface-2);
  display: flex; gap: 7px; flex-wrap: wrap;
}

/* 패널 머리의 선택된 매물/고객 요약 */
.side-summary { display: flex; gap: 11px; align-items: flex-start; min-width: 0; }
.side-summary .shot {
  flex: 0 0 66px; width: 66px; height: 52px;
  border-radius: var(--r-sm); overflow: hidden;
  background: var(--surface-3);
  display: grid; place-items: center;
  font-size: 10.5px; color: var(--ink-mute);
}
.side-summary .shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.side-summary .who { min-width: 0; flex: 1; }
.side-summary .who h2 {
  font-size: 14.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.side-summary .who .price { font-size: 15px; font-weight: 700; color: var(--brand-deep); letter-spacing: -.02em; }
.side-summary .who .sub { font-size: 12px; color: var(--ink-mute); margin-top: 2px; }

/* 아무것도 고르지 않았을 때 */
.side-idle {
  padding: 46px 22px;
  text-align: center;
  color: var(--ink-mute);
  font-size: 13px;
  line-height: 1.7;
}
.side-idle .mark {
  width: 42px; height: 42px; margin: 0 auto 12px;
  border-radius: 13px;
  background: var(--brand-soft); color: var(--brand-deep);
  display: grid; place-items: center; font-size: 19px;
}
.side-idle strong { display: block; color: var(--ink-2); font-size: 14px; margin-bottom: 5px; }

/* 목록 쪽에서 지금 보고 있는 항목 */
.pcard.is-active {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft), var(--shadow-2);
}
.pcard.is-active .pcard-body { background: var(--brand-tint); }
.row-item.is-active {
  background: var(--brand-tint);
  box-shadow: inset 4px 0 0 var(--brand);
}

/* 2단 화면 안에서는 카드가 좁아지므로 더 촘촘하게 */
.split .cards { grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 13px; }
.split .pcard-price { font-size: 15.5px; }

/* 추천 근거 중 "걸리는 점"은 색을 달리한다 — 좋은 근거와 섞이면 둘 다 안 읽힌다 */
.match-reasons .chip[data-tone="warn"] {
  background: var(--warn-soft); color: var(--warn); border-color: transparent;
}
.match-empty { padding: 26px 4px; text-align: center; color: var(--ink-mute); font-size: 13px; line-height: 1.7; }

/* 보기 전환 (매물별 / 건물별) */
/*
  상자 안의 작은 선택기 (2026-09-13). 대시보드 추천 탭에서 "안내할 것 / 안내 완료" 를 가른다.

  ★ 위의 .segmented(탭)보다 <b>한 단계 약하게</b> 그린다 — 밑줄만.
    탭과 같은 무게로 그리면 탭이 두 줄로 보이고, 애초에 탭을 하나로 줄인 이유가 사라진다.
*/
.subseg {
  display: flex;
  gap: 2px;
  padding: 6px 14px 0;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.subseg-btn {
  appearance: none;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  padding: 7px 10px 8px;
  margin-bottom: -1px;
  font-size: 12.5px; font-weight: 600;
  color: var(--ink-mute);
  cursor: pointer;
  transition: color .12s ease, border-color .12s ease;
}
.subseg-btn b { font-weight: 700; opacity: .75; }
.subseg-btn:hover { color: var(--ink); }
.subseg-btn[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--identity); }

.segmented {
  display: inline-flex;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface);
}
.segmented .seg {
  border: none; background: transparent; cursor: pointer;
  padding: 7px 14px;
  font-size: 13px; font-weight: 700; color: var(--ink-2);
}
.segmented .seg + .seg { border-left: 1.5px solid var(--line-strong); }
.segmented .seg:hover { background: var(--surface-2); }
.segmented .seg[aria-pressed="true"] { background: var(--brand); color: #fff; }

/* 건물 묶음 카드 */
.bcard {
  display: flex; align-items: center; gap: 14px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  padding: 14px 16px;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: border-color .13s ease, box-shadow .13s ease;
}
.bcard:hover { border-color: var(--brand); box-shadow: var(--shadow-2); }
.bcard-count {
  flex: 0 0 58px; text-align: center;
  border-right: 1px solid var(--line);
  padding-right: 12px;
}
.bcard-count strong { display: block; font-size: 22px; font-weight: 800; letter-spacing: -.03em; }
.bcard-count span { font-size: 11px; color: var(--ink-mute); font-weight: 650; }
.bcard-main { min-width: 0; flex: 1; }
.bcard-title { font-size: 15px; font-weight: 750; }
.bcard-sub { font-size: 12.5px; color: var(--ink-mute); margin-top: 2px; font-weight: 550; }
.bcard-mix { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 7px; }

/* ===================== 중앙 상세 팝업 ===================== */

dialog.modal.modal-xl { width: min(1140px, calc(100vw - 36px)); }
dialog.modal.modal-xl .modal-body { padding: 0; max-height: calc(100vh - 196px); }

.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  align-items: stretch;
}
.detail-main { padding: 18px 22px 26px; min-width: 0; }
.detail-side {
  padding: 18px 22px 26px;
  border-left: 2px solid var(--line);
  background: var(--surface-2);
  min-width: 0;
  display: flex; flex-direction: column;
}
.detail-side .section:first-child { margin-top: 0; }

/* 사진을 크게 볼 때 — 왼쪽을 넓히되 브리핑은 계속 보이게 둔다 */
.detail-grid.is-photo { grid-template-columns: minmax(0, 2.35fr) minmax(0, 1fr); }

/* ---------- 이 매물이 그 고객과 어디가 맞는가 ---------- */

.fitcard {
  border: 2px solid var(--brand);
  border-radius: var(--r);
  background: var(--brand-tint);
  padding: 13px 15px;
  display: flex; gap: 14px; align-items: flex-start;
}
.fitcard .score { flex: 0 0 54px; width: 54px; height: 54px; font-size: 15px; }
.fitcard .score::before { background: var(--brand-tint); }
.fitcard-main { min-width: 0; flex: 1; }
.fitcard-title { font-size: 14px; font-weight: 750; color: var(--brand-deep); }
.fitcard-sub { font-size: 12px; color: var(--ink-2); margin-top: 1px; font-weight: 550; }

.fitlist { display: grid; gap: 5px; margin-top: 10px; }
.fitline {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 6px 10px;
  border-radius: var(--r-sm);
  font-size: 12.5px; font-weight: 600;
  background: var(--surface);
  border: 1px solid var(--line);
}
.fitline .mark {
  flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 800; color: #fff;
}
.fitline .fitfield { font-weight: 750; }
.fitline[data-hit="ok"]   { background: var(--ok-soft);   border-color: color-mix(in srgb, var(--ok) 35%, transparent);   color: var(--ok); }
.fitline[data-hit="ok"] .mark   { background: var(--ok); }
.fitline[data-hit="warn"] { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 38%, transparent); color: var(--warn); }
.fitline[data-hit="warn"] .mark { background: var(--warn); }

/* ---------- 사진 뷰어 ---------- */

.viewer { display: grid; gap: 9px; }
.viewer-stage {
  position: relative;
  background: #0d1a21;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r);
  overflow: hidden;
  aspect-ratio: 16 / 10;
  display: grid; place-items: center;
}
.viewer-stage img { width: 100%; height: 100%; object-fit: contain; display: block; }
.viewer-stage .viewer-empty { color: #7f9a96; font-size: 13px; }

.viewer-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border-radius: 50%;
  border: none; cursor: pointer;
  background: rgba(255, 255, 255, .92); color: var(--ink);
  font-size: 19px; font-weight: 700; line-height: 1;
  display: grid; place-items: center;
  box-shadow: var(--shadow-2);
}
.viewer-nav:hover { background: #fff; }
.viewer-nav[data-dir="prev"] { left: 10px; }
.viewer-nav[data-dir="next"] { right: 10px; }

.viewer-tools {
  position: absolute; right: 10px; top: 10px;
  display: flex; gap: 6px;
}
.viewer-count {
  position: absolute; left: 12px; bottom: 10px;
  background: rgba(13, 26, 33, .78); color: #fff;
  font-size: 11.5px; font-weight: 700;
  padding: 3px 9px; border-radius: var(--r-pill);
}

.viewer-strip { display: flex; gap: 7px; overflow-x: auto; padding-bottom: 3px; }
.viewer-thumb {
  flex: 0 0 74px; width: 74px; height: 56px;
  border-radius: var(--r-sm); overflow: hidden;
  border: 2px solid var(--line);
  background: var(--surface-3);
  cursor: pointer; padding: 0;
  position: relative;
}
.viewer-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.viewer-thumb.is-active { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-soft); }
.viewer-thumb[data-cover="true"]::after {
  content: "대표"; position: absolute; left: 3px; top: 3px;
  background: var(--brand); color: #fff;
  font-size: 9.5px; font-weight: 800; padding: 1px 5px; border-radius: var(--r-pill);
}

/* 브리핑 편집기 — 팝업 오른쪽의 주인공이라 넉넉하게 준다 */
.brief-editor { display: flex; flex-direction: column; gap: 9px; }

/*
  브리핑 글상자.

  ★ 예전에는 min-height: 300px + flex:1 이었다. 그래서 한 줄만 적어도 상자가
    화면을 가득 채웠고, 그 아래 있던 [초안 자동 작성] 이 스크롤 밖으로 밀려났다 —
    <b>글이 없을 때 가장 필요한 단추인데 그때 손이 제일 멀었다.</b>

  이제 높이는 내용에 맞춰 JS 가 정한다(autoGrow). 사용자가 직접 끌어 늘리는 것은 그대로 둔다.
*/
.brief-editor .textarea {
  min-height: 0;
  resize: vertical;
  /*
    ★ 안쪽 스크롤바를 두지 않는다.
      높이를 내용에 맞춰 늘리는데 스크롤바까지 있으면, 팝업 스크롤과 겹쳐
      "무엇이 움직이는 건지" 헷갈린다. 길어지면 팝업이 통째로 스크롤되면 된다.
  */
  overflow-y: hidden;
  background: var(--surface);
  font-size: 13.5px; line-height: 1.75;
}

/* 공유 화면에 나가는 중개사 메모 */
.brief-public {
  margin-top: 10px; padding: 11px 13px;
  background: var(--brand-tint);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-sm);
}
.brief-public h4 {
  margin: 0 0 5px; font-size: 12px; font-weight: 700; color: var(--brand-deep);
}
.brief-public p {
  margin: 0; font-size: 13px; line-height: 1.7; color: var(--ink-2);
  white-space: pre-wrap;      /* 줄바꿈을 살려야 목록이 목록으로 읽힌다 */
}
.brief-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.brief-bar .state { font-size: 12px; color: var(--ink-mute); margin-left: auto; }
.brief-bar .state[data-dirty="true"] { color: var(--accent-ink); font-weight: 650; }

/* ===================== 월간 달력 ===================== */

.cal {
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-1);
}
.cal-weekdays {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--surface-3);
  border-bottom: 2px solid var(--line-strong);
}
.cal-weekdays span {
  padding: 9px 0; text-align: center;
  font-size: 12px; font-weight: 750; color: var(--ink-2);
}
.cal-weekdays span:first-child { color: var(--danger); }
.cal-weekdays span:last-child { color: var(--info); }

.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-cell {
  min-height: 112px;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
  padding: 6px 6px 8px;
  display: flex; flex-direction: column; gap: 3px;
  cursor: pointer;
  transition: background .12s ease;
}
.cal-cell:nth-child(7n + 1) { border-left: none; }
.cal-cell:hover { background: var(--brand-tint); }
.cal-cell.is-other { background: var(--surface-3); }
.cal-cell.is-other .cal-date { color: var(--ink-mute); opacity: .7; }
.cal-cell.is-today { background: #fff8ec; }
.cal-cell.is-selected { background: var(--brand-tint); box-shadow: inset 0 0 0 3px var(--brand); }

.cal-date {
  align-self: flex-start;
  min-width: 23px; height: 23px; padding: 0 6px;
  border-radius: var(--r-pill);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.cal-cell.is-sun .cal-date { color: var(--danger); }
.cal-cell.is-sat .cal-date { color: var(--info); }
.cal-cell.is-today .cal-date { background: var(--accent); color: #fff; box-shadow: var(--shadow-1); }

.cal-ev {
  font-size: 11.5px; line-height: 1.55; font-weight: 650;
  padding: 2px 7px;
  border-radius: 5px;
  background: var(--brand-soft); color: var(--brand-deep);
  border-left: 4px solid var(--brand);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: pointer;
}
.cal-ev:hover { filter: brightness(.95); }
.cal-ev[data-kind="CONTRACT"], .cal-ev[data-kind="BALANCE"] {
  background: var(--accent-soft); color: var(--accent-ink); border-left-color: var(--accent);
}
/* 갈래마다 색을 가른다 — 달력을 훑을 때 무슨 일인지 글자를 안 읽고도 알아야 한다 */
.cal-ev[data-kind="INTERIM"] { background: var(--warn-soft); color: var(--warn); border-left-color: #b08a2e; }
.cal-ev[data-kind="MOVE_IN"] { background: var(--ok-soft); color: var(--ok); border-left-color: #4d7a5f; }
.cal-ev[data-kind="CALL"] { background: var(--info-soft); color: var(--info); border-left-color: #6f88a8; }
.cal-ev.is-done { opacity: .5; text-decoration: line-through; }
.cal-more { font-size: 11px; color: var(--ink-mute); padding-left: 3px; }

/* ===================== 챙길 고객 (일정 화면 오른쪽) ===================== */

/* 달력 아래 "다가오는 일정" — 스크롤을 내리면 나오는 목록 */
.upcoming-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 22px 0 10px;
}
.upcoming-head h2 { font-size: 16px; display: flex; align-items: center; gap: 8px; }
.upcoming-head h2::before {
  content: ""; width: 4px; height: 16px; border-radius: 2px; background: var(--brand);
}
/* 날짜 머리 — 목록을 훑을 때 "여기서 날이 바뀐다" 가 한눈에 보여야 한다.
   회색 띠는 배경에 묻혀 그 역할을 못 했다 (2026-08-30). */
.upcoming-day {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 18px 9px 15px;
  background: linear-gradient(90deg, var(--accent-soft), var(--surface) 62%);
  border-left: 3px solid var(--accent);
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
  font-size: 12.5px; font-weight: 750; color: var(--ink);
  letter-spacing: -.1px;
  position: sticky; top: 0; z-index: 1;
}
.upcoming-day:first-child { border-top: none; }

.todo-why {
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 700;
  padding: 1px 8px; border-radius: var(--r-pill);
  background: var(--surface-3); color: var(--ink-2);
}
.todo-why[data-urgency="now"]  { background: var(--danger-soft); color: var(--danger); }
.todo-why[data-urgency="soon"] { background: var(--accent-soft); color: var(--accent-ink); }
.todo-why[data-urgency="cold"] { background: var(--warn-soft);   color: var(--warn); }

/* ===================== 공동중개 마켓 =====================
   마켓의 값어치는 "매물이 많다"가 아니라 "내 고객에게 맞는 매물이 있다"에서 나온다.
   그래서 고객 맞춤 바(.pickbar)가 필터보다 위, 목록보다 먼저 온다.
   ======================================================== */

.pickbar {
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-1);
  margin-bottom: 12px;
  overflow: hidden;
}

/* 아직 고객을 안 고른 상태 — 권유는 하되 시끄럽지 않게 */
.pickbar-idle {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 16px;
}
.pickbar-mark {
  flex: 0 0 36px; width: 36px; height: 36px;
  border-radius: 11px;
  background: var(--brand-soft); color: var(--brand-deep);
  display: grid; place-items: center; font-size: 17px;
}
.pickbar-copy { flex: 1; min-width: 0; font-size: 12.5px; color: var(--ink-mute); line-height: 1.6; font-weight: 550; }
.pickbar-copy strong { display: block; font-size: 14px; color: var(--ink); font-weight: 700; margin-bottom: 2px; }
.pickbar-copy b { color: var(--brand-deep); font-weight: 700; }

/* 고객을 고른 상태 — 지금 무엇을 기준으로 보고 있는지가 항상 눈에 있어야 한다 */
.pickbar-on {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--brand-soft);
  border-left: 4px solid var(--brand);
}
.pickbar-who { display: flex; align-items: center; gap: 12px; min-width: 0; }
.pickbar-avatar {
  flex: 0 0 38px; width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--brand); color: #fff;
  display: grid; place-items: center;
  font-size: 15px; font-weight: 750;
}
.pickbar-name {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 14.5px; font-weight: 750; color: var(--brand-deep);
}
.pickbar-conds { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.pickbar-conds .chip { background: var(--surface); border-color: var(--line-strong); font-weight: 600; }
.pickbar-actions { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-left: auto; }

/* 탭 옆 건수 배지 */
.seg-count {
  display: inline-block; margin-left: 5px;
  padding: 1px 6px; border-radius: 9px;
  background: var(--surface-3); color: var(--ink-mute);
  font-size: 11px; font-weight: 750; font-variant-numeric: tabular-nums;
}
.seg[aria-pressed="true"] .seg-count { background: rgba(255, 255, 255, .26); color: #fff; }

/* 카드 안의 일치율 — 목록 훑는 눈이 숫자와 근거를 한 번에 받게 한다 */
.pcard-fit {
  display: flex; gap: 11px; align-items: flex-start;
  margin-top: 9px; padding-top: 10px;
  border-top: 1px dashed var(--line-strong);
}
.pcard-fit .score {
  flex: 0 0 40px; width: 40px; height: 40px;
  font-size: 12.5px; margin-bottom: 15px;
}
.pcard-fit .match-reasons { margin-top: 0; flex: 1; min-width: 0; }
.pcard-fit .match-reasons .chip { font-size: 10.5px; padding: 2px 7px; }

/* 상세의 "이 매물에 맞는 내 고객" */
.fitcust {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 11px 2px;
  border-bottom: 1px solid var(--line);
}
.fitcust:last-child { border-bottom: none; }
.fitcust .score { flex: 0 0 40px; width: 40px; height: 40px; font-size: 12.5px; margin-bottom: 15px; }
.fitcust-main { flex: 1; min-width: 0; }
.fitcust-name { font-size: 13.5px; font-weight: 700; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fitcust-sub { font-size: 12px; color: var(--ink-mute); margin-top: 2px; font-weight: 550; }

/* 조건 줄 앞의 묶음 이름 — "어디" 와 "무엇" 을 눈으로 가른다 */
.toolbar-tag {
  flex: 0 0 auto;
  padding: 3px 9px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand-deep);
  font-size: 11.5px; font-weight: 800; letter-spacing: -.02em;
}
/*
  고른 지역 칩 (2026-09-10).

  ★ 시·군·구를 여러 곳 고를 수 있게 되면서 생긴 줄이다.
    고른 것을 선택 상자 안에만 두면 <b>상자를 열어 봐야</b> 무엇이 걸렸는지 안다.
  ★ 하나도 없으면 :empty 로 자리를 없앤다. 빈 줄이 늘 떠 있으면 목록이 그만큼 밀린다.
*/
.region-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }
.region-chips:empty { display: none; }

.region-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--brand-soft);
  border-radius: var(--r-pill);
  background: var(--brand-tint);
  color: var(--ink);
  font-size: 12.5px; font-weight: 650;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.region-chip span { color: var(--ink-mute); font-size: 13px; line-height: 1; }
.region-chip:hover { background: var(--brand-soft); border-color: var(--line-strong); }
.region-chip:hover span { color: var(--ink); }

/* "전부 빼기" 는 지역이 아니라 도구다. 색을 빼서 칩들과 구별한다 */
.region-chip.is-clear {
  background: transparent;
  border-style: dashed;
  border-color: var(--line-strong);
  color: var(--ink-mute);
  font-weight: 600;
}
.region-chip.is-clear:hover { background: var(--surface-3); color: var(--ink); }

.toolbar-where { background: var(--surface-2); }
.toolbar-where .select { min-width: 150px; }

/* 내 매물 — 노출 여부를 줄마다 못박는다 */
.mine-state { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.row-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; flex: 0 0 auto; }
.row-item.is-blocked { background: var(--warn-soft); }

/* 방금 공유를 켜거나 끈 줄. 목록에서 사라지지 않으므로 어디가 바뀌었는지 표시해 준다 */
.row-item.is-just-changed {
  background: var(--brand-tint);
  box-shadow: inset 4px 0 0 var(--brand);
}

.mb-1 { margin-bottom: 8px; }
.mb-2 { margin-bottom: 16px; }

/* ===================== 고객에게 보내기 (공유 링크) =====================
   이 화면은 "무엇을 하는 곳인가" 부터 설명해야 한다. 손님은 계정이 없고,
   매물 여러 건을 보여 줄 방법이 이것뿐이라는 사실이 화면에 드러나야 한다.
   ======================================================================== */

/* 세 걸음 안내 */
.howto {
  list-style: none; margin: 0 0 4px; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px;
}
.howto li {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 15px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  position: relative;
}
/* 걸음 사이의 화살표 — 순서가 있다는 것을 눈이 먼저 안다 */
.howto li + li::before {
  content: "›";
  position: absolute; left: -9px; top: 50%; transform: translateY(-50%);
  color: var(--line-strong); font-size: 18px; line-height: 1;
}
.howto-no {
  flex: 0 0 24px; width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--brand); color: #fff;
  display: grid; place-items: center;
  font-size: 12.5px; font-weight: 800;
}
.howto strong { display: block; font-size: 13.5px; font-weight: 700; margin-bottom: 2px; }
.howto div { font-size: 12px; color: var(--ink-mute); font-weight: 550; line-height: 1.5; }

/* 보이는 것 / 안 보이는 것 */
.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.checklist li {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 13px; font-weight: 550; color: var(--ink-2);
}
.checklist li::before {
  flex: 0 0 auto;
  font-size: 12px; font-weight: 800; line-height: 1.5;
}
.checklist li[data-ok="yes"]::before { content: "✓"; color: var(--ok); }
.checklist li[data-ok="no"]::before  { content: "✕"; color: var(--danger); }
.checklist li[data-ok="no"] { color: var(--ink-mute); }

/* 만든 링크 한 장. 주소와 [복사]가 주인공이라 표에서 카드로 바꿨다 */
.sharecard {
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 15px 17px;
  margin-bottom: 12px;
}
.sharecard[data-dead="yes"] { background: var(--surface-2); }
.sharecard[data-dead="yes"] .sharecard-url { opacity: .55; }
.sharecard-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 10px; }
.sharecard-title { font-size: 15px; font-weight: 750; min-width: 0; }

.sharecard-url {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 11px;
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.sharecard-url code {
  flex: 1; min-width: 0;
  font-size: 12.5px; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.sharecard-meta {
  display: flex; gap: 14px; flex-wrap: wrap;
  margin-top: 10px;
  font-size: 12.5px; color: var(--ink-mute); font-weight: 550;
}
.sharecard-meta b { color: var(--ink-2); font-weight: 700; }
.sharecard-foot { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 11px; }

/* 아직 아무것도 안 만든 사람에게 보여 줄 큰 안내 */
.share-blank {
  background: var(--surface);
  border: 2px dashed var(--line-strong);
  border-radius: var(--r-lg);
  padding: 34px 24px; text-align: center;
}
.share-blank strong { display: block; font-size: 16px; margin-bottom: 6px; }
.share-blank p { font-size: 13px; color: var(--ink-mute); line-height: 1.75; font-weight: 550; }

.req, .opt {
  display: inline-block; margin-left: 5px;
  padding: 1px 6px; border-radius: 999px;
  font-size: 10.5px; font-weight: 800;
}
.req { background: var(--accent-soft); color: var(--accent-ink); }
.opt { background: var(--surface-3); color: var(--ink-mute); }

/* ===================== 남은 크레딧 (내비 하단 · 모든 화면) =====================
   자리를 내비로 잡은 이유: 화면마다 위치가 달라지면 눈이 매번 다시 찾는다.
   평소에는 조용하고, 잔액이 적을 때만 색이 올라온다.
   ============================================================================= */

.nav-credit {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 8px 11px; margin-bottom: 9px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .10);
  text-decoration: none;
  transition: background .13s ease, border-color .13s ease;
}
.nav-credit:hover { background: rgba(255, 255, 255, .13); border-color: rgba(255, 255, 255, .2); }
.nav-credit-label { font-size: 11px; font-weight: 650; color: rgba(255, 255, 255, .62); }
.nav-credit-value {
  font-size: 14.5px; font-weight: 800; color: #fff;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
/* 잔액이 적을 때만 눈에 들어오게. 평소에 붉으면 아무도 안 본다 */
.nav-credit[data-level="low"]   .nav-credit-value { color: #ffcf8e; }
.nav-credit[data-level="empty"] .nav-credit-value { color: #ff9d8a; }
.nav-credit[data-level="empty"] { border-color: rgba(255, 157, 138, .45); }

/* ===================== 준비 중 표시 =====================
   "아직 실물 연동 전"임을 화면이 스스로 밝힌다.

   눈에 띄어야 하지만 시끄러우면 안 된다 — 매일 보는 화면이라 붉은 경고를 상시로 띄우면
   사흘 만에 아무도 안 읽는다. 그래서 왼쪽 굵은 띠 + 사선 무늬로 "공사 중" 느낌만 주고,
   색은 앰버(주의)까지만 쓴다. 진짜 위험한 것(개발 설정)만 붉게 올린다.
   ======================================================== */

.pending {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 15px;
  margin-bottom: 12px;
  border-radius: var(--r);
  background: var(--warn-soft);
  border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  border-left: 5px solid var(--warn);
  /* 아주 옅은 사선 — 배너가 아니라 "공사 중 구역"으로 읽히게 한다 */
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0 10px,
    color-mix(in srgb, var(--warn) 6%, transparent) 10px 20px
  );
}

.pending-tag {
  flex: 0 0 auto;
  padding: 3px 9px; border-radius: var(--r-pill);
  background: var(--warn); color: #fff;
  font-size: 11px; font-weight: 800; letter-spacing: -.02em;
  white-space: nowrap;
}

.pending-body { min-width: 0; display: grid; gap: 3px; }
.pending-body strong { font-size: 13.5px; font-weight: 700; color: var(--warn); line-height: 1.5; }
.pending-body span { font-size: 12.5px; color: var(--ink-2); font-weight: 550; line-height: 1.6; }

/* 개발 설정 경고 — 켜진 채로 배포하면 안 되는 것들. 이건 붉게 */
.pending[data-level="danger"] {
  background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 30%, transparent);
  border-left-color: var(--danger);
  background-image: repeating-linear-gradient(
    -45deg, transparent 0 10px,
    color-mix(in srgb, var(--danger) 7%, transparent) 10px 20px);
}
.pending[data-level="danger"] .pending-tag { background: var(--danger); }
.pending[data-level="danger"] .pending-body strong { color: var(--danger); }

/* 메뉴에 찍는 점 — 어느 화면이 아직인지 목록에서 바로 보인다 */
.nav-pending {
  width: 6px; height: 6px; border-radius: 50%;
  background: #cf9a45;
  margin-left: auto; flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgba(240, 185, 94, .18);
}

/* 버튼 하나가 준비 중일 때 (예: 크레딧 충전) */
.btn[data-pending] { position: relative; }
.btn[data-pending]::after {
  content: "준비 중";
  margin-left: 6px;
  padding: 1px 6px; border-radius: var(--r-pill);
  background: var(--warn-soft); color: var(--warn);
  font-size: 10px; font-weight: 800;
}

/* ===================== 마켓 상세 조건 ===================== */

.filter-more { background: var(--surface); margin-bottom: 16px; }
.filter-more > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 6px;
  color: var(--ink-2);
}
.filter-more > summary::-webkit-details-marker { display: none; }
.filter-more > summary::before { content: "▸ "; color: var(--brand); }
details[open].filter-more > summary::before { content: "▾ "; }
/* 접어 둔 채로 조건이 걸려 있으면 "왜 안 나오지"가 된다. 테두리로 표를 낸다 */
.filter-more.is-active { border-color: var(--brand); background: var(--brand-tint); }

.filter-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 13px;
}
.filter-switches {
  display: flex; flex-wrap: wrap; gap: 8px 18px;
  padding-top: 12px; border-top: 1px solid var(--line);
}

/* 작은 상태 배지 (목록 줄에서 여러 개가 붙는다) */
.badge-xs { font-size: 10.5px; padding: 1px 6px; }

/* 공개 범위 선택지 */
.vis-option {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 12px 14px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.vis-option:hover { border-color: var(--brand); background: var(--brand-tint); }
.vis-option input { width: 17px; height: 17px; accent-color: var(--brand); margin-top: 2px; flex: 0 0 auto; }
.vis-option strong { display: block; font-size: 13.5px; font-weight: 700; margin-bottom: 3px; }
.vis-option span { font-size: 12px; color: var(--ink-mute); line-height: 1.6; font-weight: 550; }

/* ===================== 반응형 ===================== */

@media (max-width: 1280px) {
  .split { grid-template-columns: minmax(0, 1fr) 340px; }
}

@media (max-width: 1080px) {
  .grid-main, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-dash { grid-template-columns: minmax(0, 1fr); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* 좁은 화면에서는 위아래로 쌓는다. 붙박이(sticky)를 유지하면 패널이 화면을 다 먹는다. */
  .split { grid-template-columns: minmax(0, 1fr); }
  .split-side { position: static; }
  .side-panel { max-height: none; }
  .detail-grid { grid-template-columns: minmax(0, 1fr); }
  .detail-side { border-left: none; border-top: 1px solid var(--line); }
  .brief-editor .textarea { min-height: 200px; }
  .cal-cell { min-height: 86px; }
}

@media (max-width: 880px) {
  .app { flex-direction: column; }
  .nav {
    width: 100%; flex: none; height: auto; position: sticky; top: 0; z-index: 20;
    flex-direction: row; align-items: center; gap: 2px;
    padding: 9px 12px; overflow-x: auto;
    border-right: none; border-bottom: 1px solid var(--line);
  }
  .brand { border: none; padding: 0 12px 0 2px; margin: 0; flex: 0 0 auto; }
  .brand-sub { display: none; }
  .nav-link { padding: 8px 12px; white-space: nowrap; }
  .nav-link[aria-current="page"]::before { display: none; }
  /*
   * 좁은 화면에서는 내비가 <b>가로 막대</b>가 된다.
   * 거기서 묶음 이름은 메뉴와 메뉴 사이에 끼어, 나누기는커녕 누를 수 없는 글자만
   * 하나 더 늘린다. 세로로 쌓일 때만 구실을 하므로 여기서는 감춘다.
   */
  .nav-group, .nav-divider { display: none; }
  .nav-foot, .nav-user { display: none; }
  .main { padding: 20px 16px 68px; }
  .grid-2, .grid-3, .grid-main, .grid-4, .form-row, .form-row-3 { grid-template-columns: 1fr; }
  .share-item { grid-template-columns: 1fr; }
  .share-item .info { padding: 0 18px 18px; }
  /* 좁은 화면에서 고객 맞춤 바는 버튼이 다음 줄로 내려간다 (잘리는 것보다 낫다) */
  .pickbar-idle { flex-wrap: wrap; }
  .pickbar-idle .btn { width: 100%; }
  .pickbar-actions { margin-left: 0; width: 100%; }
  /* 세 걸음이 세로로 쌓이면 사이의 화살표는 방향이 틀린 안내가 된다 */
  .howto { grid-template-columns: 1fr; }
  .howto li + li::before { display: none; }
  .toolbar-where .select { min-width: 0; flex: 1 1 140px; }
  .row-actions { width: 100%; justify-content: flex-end; }
}

@media (max-width: 560px) {
  .stats { grid-template-columns: 1fr 1fr; }
  .table th, .table td { padding: 10px 12px; }
  .toasts { left: 14px; right: 14px; align-items: stretch; }
  .page-head h1 { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* =====================================================================
   대시보드 — 상자 높이를 내용이 아니라 페이지가 정한다

   글이 늘 때마다 상자가 길어지면 대시보드가 매일 다른 모양이 되고,
   그러면 "어디에 무엇이 있었는지"를 눈이 기억하지 못한다.
   ===================================================================== */

/*
  한 페이지에 다섯 줄. 모자라면 빈 줄(row-filler)로 채워 높이를 지킨다.

  줄 높이를 변수로 둔 이유: 상자마다 한 줄에 담기는 양이 다르다.
  호재는 제목이 두 줄까지 가고 태그 줄이 하나 더 붙어 더 높다.
  빈 줄도 같은 변수를 쓰므로 페이지를 넘겨도 상자 높이가 그대로다.
*/
.fixed-rows { --row-h: 62px; }
.fixed-rows .row-item, .fixed-rows .row-filler { min-height: var(--row-h); }
.row-filler { border-bottom: 1px solid var(--line); }
.row-filler:last-child { border-bottom: none; }

/*
  호재 줄은 제목 2줄 + 요약 1줄로 잘라 둔다.
  자르지 않으면 긴 공고 하나가 상자를 혼자 늘려, 페이지를 넘길 때마다
  아래 카드가 위아래로 튄다.
*/
#news-list { --row-h: 98px; }
#news-list .row-title {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; white-space: normal;
}
#news-list .row-sub {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* 모아 보기(/policies)는 상자가 아니라 목록이라 제목을 접지 않는다 */
.policy-row .row-title { white-space: normal; }

/* 비었을 때는 짧게. 빈 자리가 세로를 잡아먹으면 아래 카드가 밀려난다 */
.empty.is-slim { padding: 18px 20px; }

.card-foot {
  padding: 9px 18px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}

/* 탭 옆 건수. 탭 이름보다 약하게 — 이름을 밀어내면 무엇을 고르는 자리인지 흐려진다 */
.segmented .seg b { margin-left: 3px; font-size: 12px; opacity: .65; }
.segmented .seg[aria-pressed="true"] b { opacity: .9; }
/* 좁은 칸에서 탭 두 개 + "전체 보기"가 한 줄에 안 들어가면 잘리는 대신 줄을 바꾼다 */
.grid-dash .card-head { flex-wrap: wrap; row-gap: 8px; }
.grid-dash .segmented .seg { padding: 7px 11px; }

/*
  줄 오른쪽 끝의 매물명.
  칸이 넓어져 가운데가 비는데, 부제에 이어 붙이면 긴 줄에 밀려 먼저 잘린다.
  폭을 묶어 두 줄이 되지 않게 하고, 넘치면 말줄임으로 끝낸다.
*/
#todo-list .row-side {
  max-width: 34%;
  font-size: 12.5px; font-weight: 600; color: var(--ink-mute);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* 카드 머리 아래 붙는 선택 줄 (지역·정렬·기간) */
.card-tools {
  display: flex; flex-wrap: wrap; gap: 7px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

.pager { display: flex; align-items: center; gap: 8px; }
.pager-btn {
  min-width: 28px; height: 26px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink-2);
  font-size: 14px; line-height: 1; cursor: pointer;
}
.pager-btn:hover:not(:disabled) { border-color: var(--brand); color: var(--brand-ink); }
.pager-btn:disabled { opacity: .4; cursor: default; }
.pager-at { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.pager-total { margin-left: auto; font-size: 11.5px; color: var(--ink-mute); }

/* 추천 줄의 작은 점수 동그라미 (일정의 시간 자리와 폭을 맞춘다) */
.score.score-sm {
  width: 38px; height: 38px; flex: 0 0 38px;
  font-size: 12px; margin-bottom: 0;
}

/* =====================================================================
   매물 목록 표 (dtable)

   카드에서 표로 바꾼 이유 — 중개사가 하루에 하는 일은 한 건을 감상하는 것이 아니라
   여러 건을 나란히 놓고 비교하는 것이다. 금액·면적·방 수가 같은 세로줄에 있어야
   눈이 훑으며 비교할 수 있다.
   ===================================================================== */

/*
  가로가 모자라면 <b>자르지 말고 밀어 낸다.</b>
  overflow:hidden 으로 두면 맨 오른쪽 [상세보기] 가 소리 없이 잘려 나가는데,
  버튼이 사라진 것을 사용자는 "기능이 없다"로 읽는다.
*/
.table-wrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow-x: auto;
  overflow-y: visible;
  box-shadow: var(--shadow-1);
}

.dtable {
  width: 100%;
  min-width: 780px;          /* 이보다 좁아지면 줄이지 말고 가로 스크롤 */
  border-collapse: collapse;
  font-size: 13.5px;
}

/*
  머리글을 sticky 로 붙이지 않는다.
  가로 스크롤(overflow-x:auto)을 켜면 세로 overflow 도 auto 로 계산되어
  sticky 의 기준이 페이지가 아니라 이 상자가 된다 — 상자에 높이 제한이 없으니
  "붙는 것처럼 보이지만 실제로는 안 붙는" 어정쩡한 상태가 된다.
  한 번에 20건씩 끊어 보여 주므로 없어도 불편하지 않다.
*/
.dtable thead th {
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  padding: 9px 10px;
  font-size: 11.5px; font-weight: 700;
  color: var(--ink-mute);
  letter-spacing: .02em;
  white-space: nowrap;
}

.dtable td {
  padding: 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.dtable tbody tr:last-child td { border-bottom: none; }

/*
  ★ 정렬 기본값을 <b>가운데</b>로 두고, 읽는 글(제목·주소)만 왼쪽으로 뺀다.
    th 와 td 를 같은 규칙에 묶어 두는 것이 핵심이다 —
    예전에는 `.dtable thead th { text-align:left }` 가 특정도에서 이겨
    머리글만 왼쪽에 남았고, 그래서 값과 어긋나 보였다.
    아래처럼 th·td 를 한 선택자에 담아 두면 한쪽만 바뀌는 일이 생길 수 없다.
*/
.dtable th, .dtable td { text-align: center; }

/* 읽는 글은 왼쪽에서 시작해야 눈이 따라간다 */
.dtable th.cell-main, .dtable td.cell-main { text-align: left; }

/* 숫자는 자릿수가 세로로 맞아야 비교가 된다 */
.dtable th.col-price, .dtable td.col-price,
.dtable th.col-area,  .dtable td.col-area,
.dtable th.col-room,  .dtable td.col-room {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.dtable-row { cursor: pointer; transition: background .12s ease; }
.dtable-row:hover { background: var(--brand-tint); }

/* 선택된 줄은 왼쪽 굵은 선으로 — 배경만 바꾸면 hover 와 구분이 안 된다 */
.dtable-row.is-active { background: var(--brand-tint); box-shadow: inset 3px 0 0 var(--brand); }

/* 본문 칸만 남는 폭을 다 쓰고, 나머지는 내용에 딱 맞춘다 */
.dtable th.cell-main, .dtable td.cell-main { width: auto; min-width: 200px; }
.cell-title {
  font-weight: 650; color: var(--ink);
  display: flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cell-sub {
  margin-top: 2px; font-size: 12px; color: var(--ink-mute);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cell-price { font-weight: 700; color: var(--brand-ink); }

/*
  본문 칸(cell-main)만 남는 폭을 가져가고 나머지는 내용에 딱 맞춘다.
  ★ 폭을 안 정한 칸이 하나라도 있으면 그 칸이 본문 칸과 남는 공간을 나눠 가져
    제목이 이유 없이 좁아진다 — 금액 칸이 그랬다.
*/
.dtable th.col-status, .dtable td.col-status,
.dtable th.col-deal,   .dtable td.col-deal,
.dtable th.col-type,   .dtable td.col-type,
.dtable th.col-price,  .dtable td.col-price,
.dtable th.col-area,   .dtable td.col-area,
.dtable th.col-room,   .dtable td.col-room,
.dtable th.col-act,    .dtable td.col-act { width: 1%; white-space: nowrap; }

/*
  단추는 눌리는 크기를 지키되 칸은 최소로.
  ★ 좌우 여백을 다르게 주지 않는다 — 한쪽만 넓히면 가운데 정렬이 그만큼 어긋난다.
  ★ 폭을 하나로 고정한다. 글자 수("공유중" 3자 / "추천 고객 12" 7자)에 따라
    단추가 제각각 넓어지면 줄마다 위치가 어긋나 목록이 들쭉날쭉해 보인다.
*/
.dtable td.col-act .btn {
  padding: 3px 9px;
  min-height: 27px;
  min-width: 88px;
  font-size: 12px;
  justify-content: center;
}

/* 좁은 화면에서는 덜 중요한 칸부터 접는다 */
@media (max-width: 1500px) { .col-room { display: none; } }
@media (max-width: 1280px) { .col-area { display: none; } }

.input-num { width: 92px; }
.input-date { width: 150px; }

/* =====================================================================
   계약 화면
   ===================================================================== */

.dtable th.col-date, .dtable td.col-date {
  width: 1%; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/*
  중개보수 수령 여부.
  금액만 적어 두면 "계약은 했는데 돈은 안 들어온" 건이 묻힌다.
  미수령을 앰버로 세워 두는 이유는 그것이 <b>지금 해야 할 일</b>이기 때문이다.
*/
.fee-state {
  margin-top: 2px;
  font-size: 11px; font-weight: 700;
}
.fee-state.is-paid   { color: var(--ok); }
.fee-state.is-unpaid { color: var(--accent-ink); }

/* 못 받은 보수가 있으면 요약 상자가 스스로 눈에 띈다 */
.stat.is-warn { border-color: var(--accent); background: #faf7f2; }
.stat.is-warn .stat-value { color: var(--accent-ink); }



/* =====================================================================
   조건 대조 — 맞는 것은 노란색, 어긋나는 것은 흐리게

   맞는 조건과 어긋나는 조건이 같은 회색 칩으로 나열되면 눈이 구분하지 못한다.
   "무엇이 겹치는가"가 이 화면의 핵심 정보이므로 색으로 먼저 가른다.
   ===================================================================== */

.cond {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 4px 9px; border-radius: var(--r-sm);
  font-size: 12px; line-height: 1.45;
  border: 1px solid transparent;
}

/* 맞는 조건 — 앰버. 이 화면에서 가장 먼저 눈에 들어와야 하는 정보다 */
.cond.is-hit {
  background: #f2eee4;
  border-color: #ddd6c4;
  color: #6a5a34;
}
.cond.is-hit .cond-mark { color: var(--accent-ink); font-weight: 800; }

/* 어긋나는 조건 — 지우지 않는다. 왜 점수가 낮은지가 판단의 재료다 */
.cond.is-miss {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--ink-mute);
}
.cond.is-miss .cond-mark { color: var(--line-strong); font-weight: 800; }

/* 목록 안에서는 항목 이름만 (자세한 내용은 팝업의 표에서) */
.cond.is-mini { padding: 2px 7px; font-size: 11.5px; }

.cond-line { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }

/* =====================================================================
   추천 고객 서랍 (오른쪽에서 밀려 나온다)

   오른쪽 고정 패널을 대신한다. 패널은 늘 자리를 차지하면서 매물을 고르기 전에는
   비어 있었고, 그 폭 때문에 정작 중요한 표가 눌렸다.
   서랍은 필요할 때만 나오므로 표가 화면을 다 쓸 수 있다.
   ===================================================================== */

/*
  ① 무엇을 보고 있는가 — 매물.
  바탕색을 달리해 아래 목록과 확실히 갈라 둔다. 선 하나로는 눈이 안 멈춘다.
*/
.fit-subject {
  display: flex; gap: 15px;
  padding: 17px 22px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.subject-shot {
  flex: 0 0 88px; height: 66px; border-radius: var(--r-sm);
  background: var(--surface-3); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--ink-mute);
}
.subject-shot img { width: 100%; height: 100%; object-fit: cover; }
.subject-main { min-width: 0; flex: 1; }
.subject-price { font-size: 15px; font-weight: 800; color: var(--brand-ink); }
.subject-title {
  font-size: 13.5px; font-weight: 650; color: var(--ink); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.subject-sub {
  font-size: 12px; color: var(--ink-mute); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ② 여기서부터 고객 — 굵은 띠로 확실히 가른다 */
.fit-split {
  padding: 11px 22px;
  background: var(--brand-deep);
}
.fit-split-title {
  margin: 0; font-size: 12px; font-weight: 700;
  color: var(--brand-tint); letter-spacing: .02em;
}

/*
  목록 안 필터.
  점수는 "조건이 얼마나 맞느냐"이고 "지금 누구에게 전화할까"는 다른 문제다.
  순위를 바꾸지 않고 <b>무엇을 볼지</b>만 좁힌다.
*/
/* 목록은 팝업 안에서 스크롤한다 (머리·발은 고정) */
.fit-body { padding: 0; max-height: min(46vh, 420px); overflow-y: auto; }

/*
  팝업 안에서는 여백을 넉넉히.
  .match 의 기본 좌우 여백은 2px 이다 — 좁은 사이드 패널에 맞춘 값이라
  팝업에 그대로 쓰면 글자가 가장자리에 붙어 답답하다.
*/
.fit-body .match {
  padding: 16px 24px 16px 28px;   /* 점수 동그라미가 왼쪽 벽에 붙지 않게 */
  gap: 18px;
  align-items: center;
}
.fit-body .match-sub { margin-top: 4px; }
.fit-body .hit-preview { margin-top: 7px; }
.fit-body .match-divider { margin: 6px 28px; }
.fit-body .match-empty { padding: 34px 28px; }

/* 점수 동그라미 아래 여백은 캡션이 있을 때만 필요하다. 여기서는 줄만 두껍게 만든다 */
.fit-body .match .score { margin-bottom: 0; }

/* [추천 근거] 는 줄 오른쪽에서 세로 가운데 */
.fit-body .match > .btn { flex: 0 0 auto; align-self: center; }

/*
  ③ 맞은 조건 미리 보기 — 작은 글씨로 이름 아래.
  칩으로 만들면 줄이 두꺼워져 한 화면에 몇 명 못 본다.
  훑을 때는 "무엇이 맞았는지" 낱말만 보이면 충분하다.
*/
.hit-preview {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 7px;
  margin-top: 4px;
  font-size: 11.5px; line-height: 1.5;
}
.hit-lead {
  font-weight: 800; color: var(--accent-ink);
  padding: 0 5px; border-radius: var(--r-pill);
  background: var(--accent-soft);
}
/* 노란 글씨 — 이 화면에서 가장 먼저 읽혀야 하는 정보다 */
.hit-word { color: var(--accent-ink); font-weight: 650; }
.hit-word + .hit-word::before { content: '·'; margin-right: 6px; color: var(--line-strong); }
.hit-more { color: var(--ink-mute); }

/* 근거 팝업 안의 매물 요약 */
.why-subject {
  display: flex; gap: 14px; align-items: center;
  margin-top: 14px; padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  border-bottom: none;
}

/*
  매물의 어느 항목이 맞았는지 — 값 옆에 바로 붙인다.
  조건 칩을 따로 나열하면 "그래서 이 매물의 무엇이 맞았다는 거지?" 를
  머릿속에서 맞춰 봐야 한다.
*/
.fit-table {
  width: 100%; border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  overflow: hidden;
  font-size: 12.5px;
}
.fit-table th, .fit-table td {
  padding: 9px 12px;
  border-top: 1px solid var(--line);
  text-align: left; vertical-align: middle;
}
.fit-table tr:first-child th, .fit-table tr:first-child td { border-top: none; }

.fit-table th {
  width: 1%; white-space: nowrap;
  color: var(--ink-mute); font-weight: 650;
}
.fit-table td { color: var(--ink); font-weight: 600; }

/* 맞은 줄은 노란 바탕 — 이 화면에서 가장 먼저 읽혀야 하는 정보다 */
  /* (낡은 규칙 6줄을 지웠다 — 줄 배경과 글씨색은 아래 "줄 배경으로 결과를 먼저 말한다" 절이 정본이다) */

.fit-mark { width: 1%; white-space: nowrap; }
.fit-o { color: var(--accent-ink); font-weight: 800; }
.fit-x { color: var(--ink-mute); font-weight: 700; }
.fit-na { color: var(--line-strong); }

.fit-note { color: var(--ink-mute); font-weight: 500; font-size: 11.5px; }

/* 목록 안의 단추 세 개 */
.row-acts { display: inline-flex; gap: 6px; justify-content: flex-end; }
.row-acts .btn b { font-weight: 800; }

/* 매물 화면에서 [공동중개]로 넘어왔을 때 그 줄을 잠깐 짚어 준다 */
.row-item.is-focused {
  animation: focus-flash 2.4s ease-out;
  box-shadow: inset 3px 0 0 var(--accent);
}
@keyframes focus-flash {
  0%, 40% { background: var(--accent-soft); }
  100%    { background: transparent; }
}

/* =====================================================================
   고객 팝업
   ===================================================================== */

/*
  ★ dialog.modal 이 width 를 정하므로 특정도를 맞춰야 한다.
    `.modal-wide` 만으로는 (0,1,0) 이라 (0,1,1) 인 dialog.modal 에 밀려 무시됐다.
*/
dialog.modal.modal-wide { width: min(820px, calc(100vw - 32px)); }

/* =====================================================================
   "왜 추천되었나" — 고객 팝업의 첫 화면

   점수만 보여 주면 "숫자를 믿으라"는 말이 된다.
   무엇이 맞아서 그 점수인지가 먼저, 크게 보여야 중개사가 고객에게 설명할 수 있다.
   ===================================================================== */

.why {
  margin: 0 0 6px;
  padding: 18px 20px;
  background: var(--brand-tint);
  border: 1px solid var(--brand-soft);
  border-radius: var(--r);
}

.why-head { display: flex; align-items: center; gap: 16px; }
.why-headline h4 { margin: 0; font-size: 15px; color: var(--brand-deep); }
.why-headline p { margin: 5px 0 0; font-size: 13px; color: var(--ink-2); line-height: 1.6; }

.why-block { margin-top: 18px; }

.why-label {
  display: inline-block; margin-bottom: 8px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .02em;
}
.why-label.is-hit  { color: var(--accent-ink); }
.why-label.is-miss { color: var(--ink-mute); }

/* 목록에서 "외 N건" */
.cond-more { align-self: center; font-size: 11.5px; color: var(--ink-mute); }

/* 근거가 아예 없을 때 — 빈칸으로 두면 고장으로 읽힌다 */
.cond-none { font-size: 11.5px; color: var(--ink-mute); font-style: italic; }

.cust-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding-bottom: 14px; border-bottom: 1px solid var(--line);
}
.cust-name { margin: 0; font-size: 18px; display: flex; align-items: center; gap: 7px; }

.cust-section { margin-top: 22px; }
.cust-section > h4 {
  margin: 0 0 10px; font-size: 13px; font-weight: 700; color: var(--ink-mute);
  padding-bottom: 6px; border-bottom: 1px solid var(--line);
  text-transform: none; letter-spacing: .01em;
}

/* 희망조건 표 */
.kv {
  display: grid; grid-template-columns: max-content 1fr;
  gap: 9px 20px; margin: 0;
  font-size: 13px; line-height: 1.55;
}
.kv dt { color: var(--ink-mute); }
.kv dd { margin: 0; color: var(--ink); font-weight: 600; }

/* =====================================================================
   정책 · 호재 — 회색 일변도를 걷어낸다

   기사 목록이 전부 같은 회색이면 "무엇이 중요한지"가 보이지 않는다.
   지역 태그와 중요도에 색을 주어 훑는 눈이 걸리게 한다.
   ===================================================================== */

.tag {
  display: inline-block; padding: 2px 9px; border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
  border: 1px solid transparent;
}
/* 전국 — 모든 중개사가 알아야 하는 것. 브랜드색으로 가장 강하게 */
.tag[data-kind="nation"] { background: var(--brand); color: #fff; }
/* 지역 — 우리 동네 소식 */
.tag[data-kind="region"] { background: var(--info-soft); color: var(--info); border-color: #ccd3dd; }
/* 분류 */
.tag[data-kind="cat"]    { background: var(--surface-3); color: var(--ink-2); border-color: var(--line); }
/* 예시(목업) — 진짜가 아니라는 표시라 눈에 띄어야 한다 */
.tag[data-kind="sample"] { background: var(--warn-soft); color: var(--warn); border-color: #d6cfbd; }
/*
  제목만 확인 — "이 설명을 어디까지 믿어도 되나"를 말하는 표시.
  [예시] 만큼 위험하진 않지만(내용 자체는 진짜다) 근거가 제목 한 줄뿐이라는 사실은
  반드시 보여야 한다. 그래서 같은 계열의 옅은 색을 쓰되 한 단계 약하게 둔다.
*/
.tag[data-kind="titleonly"] {
  background: #f4efe3; color: #7a5f22; border-color: #e0d6c0;
  border-style: dashed;   /* "덜 채워진 것" 이 모양으로도 읽히게 */
}

/*
  날짜 · 출처.
  예전에는 제목 아래 회색 글자로만 흘러가 어디까지가 날짜이고 어디부터가 출처인지
  경계가 없었다. 태그로 감싸 덩어리로 보이게 한다.
  다만 색은 옅게 — 여기는 "무엇인지" 를 말할 뿐 "중요한지" 를 말하지 않는다.
*/
.tag[data-kind="date"] {
  background: var(--surface); color: var(--ink-2);
  border-color: var(--line-strong); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tag[data-kind="src"] {
  background: #eef3fb; color: #3f5a80; border-color: #ccdaee; font-weight: 600;
}

/*
  중요도.
  제목 옆에 두면 긴 제목에 밀려 잘렸다. 태그 줄 맨 앞으로 내려 늘 같은 자리에 둔다.
*/
.tag[data-kind="impact"][data-impact="HIGH"] {
  background: var(--accent); color: #fff;
}
.tag[data-kind="impact"][data-impact="MID"] {
  background: var(--brand-tint); color: var(--brand-ink); border-color: #bcd0ea;
}
.tag[data-kind="impact"][data-impact="LOW"] {
  background: var(--surface-3); color: var(--ink-mute); border-color: var(--line);
}

/* 중요도에 따라 줄 왼쪽에 색 띠를 둔다 — 목록을 훑을 때 먼저 걸리는 신호 */
.policy-row { border-left: 3px solid transparent; }
.policy-row[data-impact="HIGH"] { border-left-color: var(--accent); background: #faf7f2; }
.policy-row[data-impact="MID"]  { border-left-color: var(--brand); }
.policy-row[data-impact="LOW"]  { border-left-color: var(--line-strong); }
.policy-row:hover { background: var(--brand-tint); }

/* (제목 줄바꿈·자르기는 위쪽 "대시보드 — 상자 높이" 절에서 함께 다룬다) */

/* 태그 줄 */
.tag-line { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }

@media print {
  .nav, .page-actions, .toolbar, .modal-foot, .side-foot, .toasts { display: none !important; }
  body { background: #fff; }
  .card, .stat { box-shadow: none; }
}

/* =====================================================================
   인쇄물 — 광고 전단 · 브리핑 자료 (2026-09-25 신설)

   ★ 화면에 보이는 A4 판이 <b>그대로</b> 종이로 나간다.
     미리보기 화면과 인쇄물을 따로 만들면 언젠가 서로 달라지고, 그러면
     미리보기를 믿을 수 없게 된다. 그래서 같은 판을 화면에서는 회색 바탕 위에
     그림자를 두르고, 인쇄에서는 그림자와 여백만 걷어 낸다.

   ★ mm 로 적는다. 화면 전용 화면은 px 로 짜도 되지만 종이는 실제 크기가 있다.
     A4 는 210×297mm 이고, 가장자리 10mm 는 프린터가 못 찍는 영역(무인쇄 여백)을
     피하려고 둔 것이다 — 0 으로 두면 기종에 따라 글씨가 잘린다.
   ===================================================================== */

.print-body {
  background: var(--surface-2, #f1f1ef);
  margin: 0;
}

/* 위쪽 막대 — 인쇄에는 안 나온다 */
.print-bar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 16px;
  background: var(--surface-1, #fff);
  border-bottom: 1px solid var(--line, #e3e3e0);
}
.print-bar-main { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.print-bar-actions { display: flex; align-items: center; gap: 8px; }
.print-layout { display: flex; align-items: center; gap: 6px; }

.print-note { padding: 10px 16px 0; }
.print-note:empty { display: none; }

/* ---- A4 한 장 ---- */
.sheet {
  width: 210mm;
  min-height: 297mm;
  margin: 12mm auto;
  padding: 10mm;
  background: #fff;
  color: #111;
  box-shadow: 0 2px 14px rgba(0, 0, 0, .18);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  /* 위쪽 막대가 붙어 있어서, 장으로 스크롤할 때 머리글이 가리지 않게 띄운다 */
  scroll-margin-top: 64px;
}

/* 매물 하나가 차지하는 칸 */
.slot { display: flex; flex-direction: column; min-width: 0; }
.slot-photo {
  width: 100%;
  background: #f4f4f2;
  border: 1px solid #e0e0dc;
  object-fit: cover;
  display: block;
}
.slot-photo-empty {
  display: flex; align-items: center; justify-content: center;
  color: #9a9a95; font-size: 12pt;
}
.slot-heading { font-size: 20pt; font-weight: 800; line-height: 1.2; margin: 6mm 0 2mm; }
.slot-price   { font-size: 26pt; font-weight: 800; line-height: 1.1; color: #111; }
.slot-sub     { font-size: 11pt; color: #555; margin-top: 2mm; }

/* 조건표 — 종이에서는 선이 얇아야 깔끔하다 */
.slot-facts { width: 100%; border-collapse: collapse; margin-top: 4mm; }
.slot-facts th, .slot-facts td {
  border: 1px solid #ddd; padding: 2mm 3mm; font-size: 10.5pt; text-align: left;
}
.slot-facts th { background: #f7f7f5; font-weight: 600; width: 22mm; color: #444; }

.slot-briefing {
  margin-top: 4mm; padding: 4mm;
  background: #f7f7f5; border-left: 3px solid #999;
  font-size: 11pt; line-height: 1.6; white-space: pre-wrap;
}

/* 한 장에 1건 */
.sheet-one .slot-photo { height: 110mm; }

/* 한 장에 4건 — 2×2 */
.sheet-four .grid4 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8mm;
  flex: 1; align-content: start;
}
.sheet-four .slot-photo { height: 52mm; }
.sheet-four .slot-heading { font-size: 13pt; margin: 3mm 0 1mm; }
.sheet-four .slot-price { font-size: 16pt; }
.sheet-four .slot-sub { font-size: 9pt; }
.sheet-four .slot-facts th,
.sheet-four .slot-facts td { font-size: 8.5pt; padding: 1.2mm 2mm; }
.sheet-four .slot-facts th { width: 16mm; }

/*
   유리창 전단의 큰 연락처.

   ★ 아래 사무소 정보만으로는 <b>유리 밖에서 안 읽힌다.</b> 전단을 붙이는 목적은
     지나가던 사람이 전화를 거는 것인데, 10pt 글씨는 한 걸음 떨어지면 안 보인다.
     그래서 한 장에 1건일 때만 크게 한 번 더 적는다 (4건 틀은 자리가 없다).
*/
.ad-cta {
  margin-top: 6mm; padding: 5mm 6mm;
  border: 2px solid #111; border-radius: 2mm;
  display: flex; align-items: baseline; gap: 5mm;
}
.ad-cta .cta-label { font-size: 12pt; color: #444; white-space: nowrap; }
.ad-cta .cta-phone { font-size: 30pt; font-weight: 800; letter-spacing: -0.5pt; }
.ad-cta .cta-name  { font-size: 11pt; color: #555; margin-left: auto; text-align: right; }

/*
   광고 문구 한 줄 — "가격 협의 가능" · "급매".

   ★ 미리보기에서 <b>그 자리에서</b> 고쳐 쓴다. 따로 수정 화면으로 보내면
     "지금 보고 있는 이 종이" 와 "고치는 화면" 이 떨어져서, 고친 뒤 다시 확인해야 한다.
   ★ 화면에서는 고칠 수 있다는 것이 보이게 점선을 두르고, 인쇄에서는 점선을 걷어 낸다.
*/
.ad-note {
  margin-top: 4mm; padding: 3mm 4mm;
  background: #fdf4e3; border-left: 4px solid #c8861a;
  font-size: 14pt; font-weight: 700; color: #7a4f06;
  min-height: 8mm;
}
.ad-note:empty::before {
  content: '여기를 눌러 광고 문구를 적으세요 (예: 가격 협의 가능)';
  color: #b09a76; font-weight: 400; font-size: 11pt;
}
.ad-note[contenteditable="true"] { outline: 1px dashed #c8861a; outline-offset: 2px; }
.ad-note[contenteditable="true"]:focus { outline: 2px solid #c8861a; background: #fff8ec; }

/* 자주 쓰는 문구 단추 — 인쇄에는 안 나온다 */
.ad-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2mm; }
.ad-chips .chip { font-size: 10pt; }

/* 장 아래 사무소 정보 — 광고에 반드시 들어가야 하는 칸 */
.sheet-foot {
  margin-top: auto; padding-top: 4mm;
  border-top: 2px solid #111;
  font-size: 10pt; line-height: 1.6;
}
.sheet-foot b { font-size: 12pt; }
.sheet-foot .foot-line { color: #333; }
.sheet-foot .foot-warn { color: #a33; font-weight: 700; }

/* 비교표 (브리핑 자료 마지막 장) */
.compare { width: 100%; border-collapse: collapse; }
.compare th, .compare td {
  border: 1px solid #ddd; padding: 2.5mm 3mm; font-size: 10pt; text-align: left;
}
.compare thead th { background: #f0f0ed; font-weight: 700; }
.compare tbody th { background: #f7f7f5; font-weight: 600; white-space: nowrap; }
.sheet-title { font-size: 18pt; font-weight: 800; margin-bottom: 5mm; }

@page { size: A4; margin: 0; }

@media print {
  .print-bar, .print-note, .ad-chips { display: none !important; }
  /* 고칠 수 있다는 표시(점선)는 종이에 나오면 안 된다 */
  .ad-note[contenteditable="true"] { outline: none !important; }
  .ad-note:empty { display: none !important; }
  .print-body { background: #fff; }
  .sheet {
    margin: 0;
    box-shadow: none;
    /* ★ 장마다 새 종이로. 이 한 줄이 없으면 두 장이 한 장에 겹쳐 나온다 */
    page-break-after: always;
    break-after: page;
  }
  .sheet:last-child { page-break-after: auto; break-after: auto; }
  /* 사진·배경색을 프린터가 빼먹지 않게 한다 (기본값은 "배경 안 찍음") */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* =====================================================================
   시험 계정 안내 (로그인 화면 우측 상단)

   ★ 일부러 눈에 띄게 만들었다. 개발 편의 기능은 예뻐 보이면 안 된다 —
     예뻐 보이면 "이대로 나가도 되겠네" 하고 남는다.
     주황 경고색 + "시험 단계" 딱지로 임시라는 것을 계속 알린다.
   ★ 설정을 끄면 서버가 빈 목록을 주므로 이 상자는 아예 그려지지 않는다.
   ===================================================================== */

.dev-accounts {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 40;
  width: 290px;
  max-width: calc(100vw - 36px);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 12px;
  box-shadow: 0 6px 22px rgba(12, 26, 33, .13);
  overflow: hidden;
}

.dev-accounts-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--accent);
}

.dev-badge {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  color: #fff;
  background: var(--accent);
  border-radius: 999px;
  padding: 3px 8px;
}

.dev-accounts-title { font-size: 13px; font-weight: 600; color: var(--accent-ink); }

.dev-accounts-list { list-style: none; margin: 0; padding: 6px; }

.dev-account {
  display: block;
  width: 100%;
  text-align: left;
  padding: 9px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  cursor: pointer;
  font: inherit;
}

.dev-account:hover,
.dev-account:focus-visible {
  background: var(--brand-tint);
  border-color: var(--brand-soft);
  outline: none;
}

.dev-account-label { display: block; font-size: 13px; font-weight: 600; color: var(--ink); }

/* 이메일/비밀번호는 고정폭으로 — 눈으로 옮겨 적는 일이 실제로 있다 */
.dev-account-cred {
  display: block;
  margin-top: 3px;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 12px;
  color: var(--brand-ink);
  word-break: break-all;
}

.dev-account-note { display: block; margin-top: 2px; font-size: 11.5px; color: var(--ink-mute); }

.dev-accounts-foot {
  padding: 8px 12px 10px;
  border-top: 1px solid var(--line);
  font-size: 11.5px;
  color: var(--ink-mute);
  line-height: 1.5;
}

/* 좁은 화면에서는 고정을 풀어 로그인 상자를 가리지 않게 한다 */
@media (max-width: 720px) {
  .dev-accounts { position: static; width: auto; margin: 14px auto 0; max-width: 380px; }
}
/* =====================================================================
   아직 못 하는 기능 안내 + 준비 과제 화면
   ★ 실서비스 전환 시 app.readiness.show-page 를 끄면 화면은 사라진다.
     이 CSS 는 남아도 무해하지만, 정리할 때 함께 지우면 된다.
   ===================================================================== */

/* ---- 두 줄 알림 (toastRich) ---- */
.toast-rich {
  display: grid;
  gap: 4px;
  max-width: 420px;
  white-space: normal;
  cursor: pointer;
  line-height: 1.55;
}
.toast-rich strong { font-size: 13.5px; font-weight: 700; }
.toast-rich span   { font-size: 12.5px; opacity: .92; }
.toast[data-tone="warn"] { background: #5c4f2e; }
.toast[data-tone="info"] { background: #3d4a5c; }

/* ---- 막힌 버튼 표시 — 누르기 전에도 알 수 있게 ---- */
[data-blocked][data-blocked-on] {
  position: relative;
  opacity: .82;
}
[data-blocked][data-blocked-on]::after {
  content: '';
  position: absolute;
  top: 3px; right: 3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---- 내비의 준비 과제 메뉴 ---- */
.nav-readiness { margin-top: 6px; border-top: 1px dashed var(--nav-line); padding-top: 12px; }
.nav-count {
  margin-left: auto;
  min-width: 19px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
}

/* ---- 준비 과제 화면 ---- */
.temp-badge {
  display: inline-block;
  padding: 5px 11px;
  border: 1px dashed var(--accent);
  border-radius: 999px;
  color: var(--accent-ink);
  background: var(--accent-soft);
  font-size: 12px;
  font-weight: 700;
}

.card-note { margin: 0 0 12px; font-size: 12.5px; color: var(--ink-mute); line-height: 1.65; }

.ready-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.ready-item {
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: 9px;
  background: var(--surface);
}
.ready-item[data-tone="danger"] { border-left-color: var(--danger); }
.ready-item[data-tone="warn"]   { border-left-color: var(--warn); }
.ready-item[data-tone="info"]   { border-left-color: var(--info); }
.ready-item[data-tone="ok"]     { border-left-color: var(--ok); }

.ready-head { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-bottom: 7px; }
.ready-name { font-size: 14px; font-weight: 700; color: var(--ink); }

.chip {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
}
.chip-danger { background: var(--danger-soft); color: var(--danger); }
.chip-warn   { background: var(--warn-soft);   color: var(--warn); }
.chip-info   { background: var(--info-soft);   color: var(--info); }
.chip-ok     { background: var(--ok-soft);     color: var(--ok); }
.chip-quiet  { background: var(--canvas);      color: var(--ink-mute); }

.ready-why, .ready-todo {
  margin: 0 0 5px;
  font-size: 12.8px;
  color: var(--ink);
  line-height: 1.65;
}
.ready-label {
  display: inline-block;
  min-width: 108px;
  margin-right: 6px;
  color: var(--ink-mute);
  font-weight: 700;
  font-size: 11.5px;
}
.ready-link a { font-size: 12px; color: var(--brand-ink); word-break: break-all; }
.ready-key {
  margin: 9px 0 0;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 11.5px;
  color: var(--ink-mute);
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}
.ready-key code { font-size: 11.5px; }
/* =====================================================================
   고객 맞춤 브리핑 (고객 화면 오른쪽 패널)
   ===================================================================== */

.match-side { display: grid; gap: 6px; justify-items: end; align-content: start; }

/* 체크는 눈에 띄되 점수를 가리지 않아야 한다 */
.pick {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--ink-mute);
  cursor: pointer;
  white-space: nowrap;
  background: var(--surface);
}
.pick:hover { border-color: var(--brand); color: var(--brand-ink); }
.pick input { accent-color: var(--brand); margin: 0; }
.pick:has(input:checked) {
  border-color: var(--brand);
  background: var(--brand-tint);
  color: var(--brand-ink);
  font-weight: 700;
}

.brief-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 9px 14px;
  border-top: 1px solid var(--line);
  background: var(--brand-tint);
  font-size: 12.5px;
  color: var(--brand-ink);
}
.brief-count b { font-size: 14px; }

/* "저장 안 됨"을 눈에 띄게 — 저장한 줄 알고 나가면 손님은 아무것도 못 받는다 */
.brief-dirty {
  margin-left: 7px;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}
.brief-link {
  margin-left: auto;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 11.5px;
  color: var(--ink-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.side-foot-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  width: 100%;
  margin-top: 7px;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
}

/* ---- 보낼 내용 확인 ---- */
.brief-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.brief-item {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface);
}
.brief-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 6px; }
.brief-head strong { font-size: 13.5px; }
.brief-head .muted { font-size: 12px; }
.brief-note {
  margin: 0;
  font-size: 12.8px;
  line-height: 1.7;
  color: var(--ink);
  white-space: pre-wrap;
}
.brief-note.is-empty { color: var(--warn); font-weight: 600; }
/* =====================================================================
   화면 다듬기 (2026-08-26)
   ① 팝업 목록의 행 구분을 또렷하게
   ② 일치/어긋남을 태그로
   ③ "지금 보던 매물" 표시
   ===================================================================== */

/*
  ① 행 구분.
  얇은 선 하나로만 나누면 줄이 길어질수록 어디서 끊기는지 눈이 놓친다.
  카드처럼 띄우고 짝수 줄에 옅은 바탕을 깔아 덩어리로 읽히게 한다.
*/
.fit-body .rows > .row-item,
.fit-body .match {
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-bottom: 8px;
  padding: 11px 13px;
  background: var(--surface);
  transition: border-color .12s, box-shadow .12s, background .12s;
}
.fit-body .rows > .row-item:nth-child(even),
.fit-body .match:nth-child(even) { background: #fafafa; }

/*
  줄에 마우스를 올렸을 때 배경까지 초록으로 채우니, 정작 눌러야 할 단추가 묻혔다.
  줄은 테두리만 살짝 바꾸고, 색은 단추가 가져간다.
  ★ :has() — 단추 위에 있을 때는 줄 강조를 아예 끈다. 불이 두 군데 들어오면 어디를
    누르는 것인지 알 수 없다.
*/
.fit-body .rows > .row-item:hover,
.fit-body .match:hover {
  border-color: var(--line-strong);
  box-shadow: 0 1px 5px rgba(12, 26, 33, .06);
}
.fit-body .rows > .row-item:hover:has(.btn:hover),
.fit-body .match:hover:has(.btn:hover) {
  border-color: var(--line);
  box-shadow: none;
}
.fit-body .rows > .row-item:last-child,
.fit-body .match:last-child { margin-bottom: 0; }

/* 구분선은 이제 카드 테두리가 대신한다 */
.fit-body .rows > .row-item + .row-item { border-top: 1px solid var(--line); }

/* ② 일치 / 어긋남 / 미지정 — 태그로 */
.fit-tag {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.6;
  white-space: nowrap;
}
.fit-tag.is-o  { background: var(--ok-soft);     color: var(--ok); }
.fit-tag.is-x  { background: var(--accent-soft); color: var(--accent-ink); }
.fit-tag.is-na { background: var(--canvas);      color: var(--ink-mute); font-weight: 600; }

/* 표 자체도 줄이 구분되게 — 항목이 많아 눈이 미끄러진다 */
.fit-table tr + tr th,
.fit-table tr + tr td { border-top: 1px solid var(--line); }


/* ③ 지금 보던 매물 — 어느 것이 방금 그 매물인지 모르면 비교가 안 된다 */
.rows > .row-item.is-current {
  border-color: var(--brand);
  box-shadow: inset 3px 0 0 var(--brand);
}
.now-tag {
  display: inline-block;
  margin-right: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  vertical-align: middle;
}

/* 고객 팝업의 머리말 — 매물 화면의 fit-subject 와 같은 자리에 들어간다 */
/* 아래쪽 "매물 바구니" 절에서 가로 배치를 다시 정한다 (거기가 최종이다) */
#cust-fit-modal .side-summary h2 { font-size: 16px; margin: 0; }
#cust-fit-modal .side-summary .sub { font-size: 12.5px; color: var(--ink-mute); margin-top: 3px; }
#cust-fit-modal .modal-foot { flex-wrap: wrap; }
/* =====================================================================
   매물 바구니 (2026-08-26 개편)
   담기 버튼 하나 · 목록 위의 바구니 줄 · 담은 목록 팝업
   ===================================================================== */

/* ---- 행의 담기 버튼 (하나뿐이다) ---- */
.basket-btn { white-space: nowrap; }
.basket-btn.is-in {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  font-weight: 700;
}
.basket-btn.is-in:hover { background: var(--brand-ink); border-color: var(--brand-ink); }

/* ---- 바구니 — 고객 정보 행의 오른쪽 (줄을 따로 쓰지 않는다) ---- */
/*
  ★ .fit-subject 가 display:flex 라, 그 안의 .side-summary 는 <b>내용 너비만큼만</b>
    차지한다. 그래서 justify-content: space-between 을 걸어도 아무 일도 일어나지 않고
    바구니가 이름 바로 옆에 붙어 있었다.
    flex:1 로 가로를 다 쓰게 만들어야 오른쪽 끝으로 밀린다.
*/
#cust-fit-modal .side-summary {
  display: flex;
  align-items: center;
  gap: 14px;
  justify-content: space-between;
  flex: 1;
  width: 100%;
  min-width: 0;
}
#cust-fit-modal .side-summary .who { min-width: 0; flex: 1; }

/* 머리말 전체도 가로를 다 쓴다 */
#cust-fit-modal .fit-subject { align-items: center; }

/*
  흐름 띠 — 팝업이 세 겹으로 이어지는 자리에서 "지금 몇 번째인가" 를 말한다 (2026-09-09).

  ★ 팝업 안에 들어가므로 <b>얇아야 한다.</b> shares.jsp 의 .howto 는 카드 세 장짜리라
    한 화면을 통째로 쓰는 안내용이고, 여기서는 목록이 밀려 쓸 수 없다.
    같은 뜻을 한 줄로 줄인 것이 이 띠다.
  ★ 누를 수 없다. 걸음을 눌러 건너뛰게 하면 "고르지도 않고 보내기" 가 열린다 —
    순서 자체가 실수를 막는 장치다. 그래서 커서도 바뀌지 않는다.
*/
.flow {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 11px 18px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  color: var(--ink-mute);
  user-select: none;
  overflow-x: auto;
}
.flow li {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
/* 걸음 사이의 화살표 — 순서가 있다는 것을 눈이 먼저 안다 */
.flow li + li::before {
  content: "›";
  margin: 0 4px 0 0;
  color: var(--line-strong);
  font-size: 15px;
  line-height: 1;
}
.flow-no {
  display: grid;
  place-items: center;
  width: 17px; height: 17px;
  flex: 0 0 17px;
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--ink-mute);
  font-size: 10.5px;
  font-weight: 700;
}
/* 지금 있는 걸음만 진하다. 지나온 걸음은 옅게 두어 "여기까지 왔다" 만 남긴다 */
.flow li.is-now { color: var(--ink); font-weight: 700; }
.flow li.is-now .flow-no { background: var(--identity); color: #fff; }
.flow li.is-done .flow-no { background: var(--brand-soft); color: var(--ink-2); }

/* 담은 매물 한 줄의 오른쪽 단추들 */
.basket-acts { display: flex; align-items: center; gap: 6px; flex: none; }

.head-basket {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

/* 바구니는 요소 하나 — 숫자 자체가 단추다 */
.basket-btn-main {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-size: 12.5px;
  font-family: inherit;
  color: var(--ink-mute);
  white-space: nowrap;
  cursor: pointer;
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.basket-btn-main:disabled { cursor: default; opacity: .75; }
.basket-btn-main.is-on {
  border-color: var(--brand);
  background: var(--brand);
  color: #fff;
  font-weight: 700;
}
.basket-btn-main.is-on:hover {
  background: var(--brand-ink);
  border-color: var(--brand-ink);
  box-shadow: 0 0 0 3px var(--brand-soft);
}
.basket-icon { font-size: 15px; line-height: 1; }
.basket-btn-main b { font-size: 14px; font-weight: 800; }

/*
  추천 근거 단추 — 줄에 마우스를 올리면 줄 배경이 옅은 초록으로 바뀐다.
  그때 단추가 배경에 묻혀 "누를 수 있는 것"으로 안 보였다.
  단추 위에서는 배경을 흰색으로 되돌리고 테두리에 불을 켠다.
*/
/* 기본 상태 — 줄 배경이 무엇이든 단추는 흰 바탕에 또렷하게 */
.fit-body .match .btn,
.fit-body .rows > .row-item .btn {
  background: var(--surface);
  border-color: var(--line-strong);
  color: var(--ink);
  transition: all .12s;
}

/* 마우스를 올리면 진한 초록으로 채운다 — 여기만 불이 들어온다 */
.fit-body .match .btn:hover,
.fit-body .rows > .row-item .btn:hover {
  background: var(--brand-ink);
  border-color: var(--brand-ink);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 0 0 3px var(--brand-soft);
}

/*
  ★ 담긴 단추(.is-in)는 규칙 순서상 위의 .fit-body .match .btn 에 덮여
    흰 배경 + 흰 글씨가 되어 <b>글씨가 통째로 사라져 보였다.</b>
    같은 구체성으로 다시 못박는다.
*/
.fit-body .match .basket-btn.is-in,
.fit-body .rows > .row-item .basket-btn.is-in {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  font-weight: 700;
}
.fit-body .match .basket-btn.is-in:hover,
.fit-body .rows > .row-item .basket-btn.is-in:hover {
  background: var(--brand-deep);
  border-color: var(--brand-deep);
  color: #fff;
}

@media (max-width: 720px) {
  #cust-fit-modal .side-summary { flex-wrap: wrap; }
  .head-basket { width: 100%; justify-content: flex-end; }
}

/* ---- 담은 목록 팝업 ---- */
.basket-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 9px; }
.basket-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
}
.basket-item:nth-child(even) { background: #fafafa; }
.basket-main { min-width: 0; flex: 1; }
.basket-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 5px; }
.basket-head strong { font-size: 13.5px; }
.basket-head .muted { font-size: 12px; }
.basket-item .btn { flex: none; }
/* =====================================================================
   매물 목록의 "기다리는 고객 수" 알약 (2026-08-26)

   ★ 단추 안에 넣지 않는다. 단추 글씨 길이가 매물마다 달라져 오른쪽 끝이
     들쭉날쭉해지고, 무엇보다 누르기 전에는 안 보이는 숫자가 된다.
     제목 옆이 원래 비어 있던 자리라 줄을 더 쓰지 않는다.
   ===================================================================== */

.fit-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: 7px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 11px;
  font-weight: 700;
  vertical-align: middle;
  white-space: nowrap;
}
.fit-pill b { font-size: 12.5px; font-weight: 800; }

/* 0명은 알려 주되 눈길을 끌 이유가 없다 — 회색으로 가라앉힌다 */
.fit-pill.is-zero {
  background: var(--canvas);
  color: var(--ink-mute);
  font-weight: 600;
}
/* =====================================================================
   대시보드 두 카드의 키 맞추기 (2026-08-26)

   왼쪽(일정·추천)은 한 줄이 짧고 오른쪽(정책 브리핑)은 요약문이 붙어 훨씬 높다.
   같은 건수를 보여 주면 왼쪽 아래에 빈 공간이 크게 남는다.

   ★ 두 가지를 함께 쓴다.
     ① 상자마다 보여 줄 건수를 다르게 (dashboard.js 의 PAGE_SIZE)
     ② 그래도 남는 차이는 목록 영역이 늘어나 메운다 (아래 규칙)
     ①만으로는 데이터 양이 바뀔 때마다 어긋나고, ②만으로는 빈 줄이 늘어져 보인다.
   ===================================================================== */

.grid-dash > .card {
  display: flex;
  flex-direction: column;
}

/* 목록이 남는 높이를 가져간다 — 페이지 표시는 늘 바닥에 붙는다 */
.grid-dash > .card > .card-body { flex: 1 1 auto; min-height: 0; }
.grid-dash > .card > .card-foot { margin-top: auto; }
/* 준비 과제 숫자 — 켜진 개발 설정이 있으면 붉게 (화면마다 띄우던 붉은 띠를 대신한다) */
.nav-count.is-risky { background: #b4443a; }
/* =====================================================================
   추천 근거 팝업 — 손님이 원한 것 ↔ 이 매물 (2026-08-20 개편)

   표를 둘에서 하나로 합쳤다. 같은 항목을 위아래로 나눠 적으면
   눈이 오가며 맞춰 봐야 하고, 팝업이 길어져 정작 어긋난 곳이 아래로 밀린다.
   ===================================================================== */

.fit-table { width: 100%; border-collapse: collapse; margin-top: 12px; }

.fit-table thead th {
  padding: 6px 10px;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-mute);
  text-align: left;
  border-bottom: 1px solid var(--line);
}
/*
  칸 비율.
  ★ 표시(체크) 칸을 34px 로 잡았더니 남는 자리를 앞의 두 칸이 나눠 갖지 못하고
    체크만 오른쪽 끝에 덩그러니 붙었다. 고정폭 대신 비율로 정한다.
  ★ 머리글은 그 칸 글씨의 가운데에 오도록 가운데 정렬한다 —
    왼쪽에 다 붙어 있으면 어느 칸의 이름인지 눈이 한 번 더 찾는다.
*/
.fit-table thead th:nth-child(1) { width: 38%; }
.fit-table thead th:nth-child(2) { width: 52%; }
.fit-table thead th:nth-child(3) { width: 10%; }

/*
  ★ 머리글을 가운데 정렬했다가 되돌렸다 (2026-08-20).

    내용은 왼쪽에서 시작하는데 머리글만 칸 한가운데에 있으니
    "고객 요구 조건" 이 아래 값보다 한참 오른쪽에 떠 있어 서로 다른 줄처럼 보였다.
    머리글과 그 아래 값은 <b>같은 세로선에서 시작</b>해야 한 덩이로 읽힌다.
    들여쓰기(padding)도 아래 칸과 똑같이 맞춘다.
*/
.fit-table thead th { text-align: left; padding-left: 10px; padding-right: 10px; }
.fit-table thead th:nth-child(1) { padding-left: 22px; }

.fit-table tbody th,
.fit-table tbody td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  font-size: 13px;
}

/*
  왼쪽 칸 — 항목 이름 위, 고객이 원한 값 아래.

  ★ 표 왼쪽 벽에 딱 붙어 있어 답답했다. 안쪽으로 들여 숨 쉴 자리를 준다.
  ★ 값의 글씨색을 오른쪽(매물 정보)과 같은 진한 검정으로 맞춘다.
    한쪽만 흐리면 "왼쪽은 참고, 오른쪽이 본문"처럼 보이는데, 이 표는 둘을
    나란히 놓고 비교하라는 표다. 무게가 같아야 한다.
*/
.fit-table tbody th { text-align: left; font-weight: 700; padding-left: 22px; }
.fit-table tbody th span {
  display: block;
  margin-top: 3px;
  font-weight: 600;
  font-size: 13px;
  color: var(--ink);
}

.fit-table tbody td { color: var(--ink); font-weight: 600; }

/* 어긋난 이유를 값 아래에 적던 규칙은 지웠다 — 왼쪽 요구조건과 같은 말이 두 번 나왔다 */

/* ---- 표시 ----
   ★ 어긋남에 붉은색을 쓰지 않는다. 붉은색은 "고장·위험"이라는 뜻이라 매번 놀라게 된다.
     조건이 조금 어긋나는 것은 사고가 아니라 감안할 점이다. 그래서 노란 계열. */
/*
  표시는 <b>결과</b>일 뿐이라 끝에 가볍게 놓는다.
  앞에 두었더니 그 칸이 가운데를 크게 차지하고 정작 값이 오른쪽으로 밀려 줄바꿈이 났다.
*/
.fit-table td.fit-mark { text-align: center; padding-left: 4px; padding-right: 4px; }

.fit-mark-o, .fit-mark-x, .fit-mark-na {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px; height: 19px;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
}
.fit-mark-o  { background: var(--ok-soft);   color: var(--ok); }
.fit-mark-x  { background: #f7dcd9; color: #97463a; }
.fit-mark-na { background: var(--surface-3); color: var(--ink-mute); font-weight: 600; }

/*
  줄 배경으로 결과를 먼저 말한다. 세 가지뿐이라 색만 봐도 훑어진다.
    맞음        연두   — 이 조건은 됐다
    조건 없음    흰색   — 고객이 안 적어서 판단할 수 없다
    어긋남      연한 빨강 — 감안하고 말해야 한다
*/
.fit-table tr.is-hit  { background: #eef7e8; }
.fit-table tr.is-na   { background: var(--surface); }
.fit-table tr.is-miss { background: #fcefee; }

/* 조건을 안 적은 줄은 글씨도 가라앉힌다 — 판단 근거가 아니라 "빈 자리"라는 뜻 */

/* 고객 한 줄 요약 */
.cust-line {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-bottom: 11px;
  margin-bottom: 3px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.cust-line strong { font-size: 15px; }
.cust-line .muted { font-size: 12.5px; margin-left: auto; }
/*
  줄바꿈.
  keep-all 은 낱말을 안 쪼개는 대신, 칸이 좁으면 <b>낱말마다 줄을 바꿔</b> 세로로 길어진다.
  실제로 주소가 "두정 / 대우푸르지오 / 충청남도 / 천안시 …" 처럼 여섯 줄이 됐다.
  칸을 넓히고 보통 방식으로 되돌린다.
*/
.fit-table tbody td,
.fit-table tbody th span { word-break: normal; overflow-wrap: break-word; line-height: 1.6; }
/*
  추천 근거 팝업만 넓게.
  기본 modal-wide(820px)로는 세 칸짜리 대조표가 들어가지 않아 글씨가 계속 접혔다.
  같은 이유로 dialog.modal 과 같은 구체성(0,1,1)으로 써야 밀리지 않는다.
*/
dialog.modal#customer-modal { width: min(1040px, calc(100vw - 32px)); }
/*
  ★ 표 안의 글씨는 전부 같은 검정이다 (2026-08-20).

    예전 규칙이 남아 어긋난 줄과 조건 없는 줄의 글씨를 회색으로 만들고 있었다.
    "역세권, 학원가" 처럼 엄연히 있는 값이 흐리게 나와, 값이 없는 줄과 구분이 안 됐다.

    상태는 <b>배경색과 표시(체크·느낌표·점)</b>가 말한다. 글씨 농도까지 상태를 나르면
    같은 것을 세 번 말하면서 정작 내용을 읽기 어려워진다.
*/
/* 값(오른쪽 칸)과 고객이 원한 값(왼쪽 칸 아랫줄) — 줄 상태와 무관하게 같은 검정 */
.fit-table tbody td,
.fit-table tbody th span,
.fit-table tr.is-na td,
.fit-table tr.is-na th span,
.fit-table tr.is-miss td,
.fit-table tr.is-miss th span { color: var(--ink); }

/*
  항목 이름(유형·금액·지역…)만 한 단계 옅게.
  이름과 값이 같은 농도면 어느 쪽이 값인지 눈이 한 번 더 가른다.
  줄 상태와 상관없이 늘 같은 색이다.
*/
.fit-table tbody th,
.fit-table tr.is-na th,
.fit-table tr.is-miss th { color: var(--ink-2); }

/* =====================================================================
   검색어 표시 (2026-08-20)

   목록이 스무 줄이면 "왜 이 매물이 걸렸지"를 눈으로 찾아야 한다.
   걸린 자리를 칠해 주면 그 수고가 사라진다.

   ★ 모노크롬 화면이라 노란 형광은 유난히 튄다. 그래서 옅게 깔고 글씨는 그대로 둔다 —
     표시는 "여기다"라고 가리키는 것이지, 그 글자를 더 중요하게 만드는 것이 아니다.
   ===================================================================== */

mark.hit {
  background: #fdf0c4;
  color: inherit;
  border-radius: 3px;
  padding: 0 2px;
  margin: 0 -1px;
  font-weight: 700;
}

/* 부제(주소)에서는 한 단계 더 옅게 — 제목이 먼저 읽혀야 한다 */
.cell-sub mark.hit { background: #fbf3d9; font-weight: 600; }

/* 선택된 줄 위에서도 표시가 보이도록 */
.dtable-row.is-active mark.hit { background: #f7e39a; }

/* =====================================================================
   고객 등록 — 입주 시기 고르기 (2026-08-20)
   ===================================================================== */

/* 즉시 입주 / 날짜 지정 중 하나. 라디오를 알약처럼 보이게 한다 */
.choice-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}

.choice {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 13px;
  cursor: pointer;
  user-select: none;
  transition: background .12s, border-color .12s;
}

.choice:hover { background: var(--brand-tint); }

.choice input { margin: 0; cursor: pointer; }

/* 고른 쪽을 눈에 띄게. 배경과 글자색을 한 규칙에서 같이 정한다
   (따로 두었다가 흰 배경에 흰 글씨가 된 적이 있다)

   ★ 검정으로 칠했다가 되돌렸다 (2026-08-20). 입력하는 칸이 새까맣게 변하면
     "고른 것"이 아니라 "잠긴 것"처럼 보인다. 강조는 앰버로 하고 글자는 검게 둔다. */
.choice:has(input:checked) {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--ink);
  font-weight: 600;
}

/* 못 불러왔을 때. "지역 없음"과 구분되어야 한다 */
.alert-inline {
  display: inline-block;
  padding: 6px 10px;
  border: 1px solid var(--danger);
  border-radius: 8px;
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 12px;
}

/* 직원 목록에 없는 이름을 적었을 때 */
.input.is-invalid {
  border-color: var(--danger);
  background: var(--danger-soft);
}

.text-warn { color: var(--accent-ink); }

/* =====================================================================
   계약 화면 — 일정과 알림을 한 줄에서 (2026-08-29)
   ===================================================================== */

.alarm-grid {
  display: flex; flex-direction: column; gap: 10px;
}

/* [이름] [날짜] [알림 체크] [며칠 전] 을 한 줄로 */
.alarm-row {
  display: grid;
  grid-template-columns: 84px 168px auto 1fr;
  align-items: center;
  gap: 10px;
}

.alarm-name {
  font-size: 13px; font-weight: 600; color: var(--ink);
}

/* 날짜를 안 적은 줄은 알림을 켤 수 없다 — 흐리게 해서 먼저 알린다 */
.alarm-row.is-off .alarm-name,
.alarm-row.is-off .alarm-toggle { color: var(--ink-mute); }

.alarm-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 13px;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: background .12s, border-color .12s;
}

.alarm-toggle:hover { background: var(--brand-tint); }

.alarm-row.is-off .alarm-toggle { cursor: default; background: var(--canvas); }
.alarm-row.is-off .alarm-toggle:hover { background: var(--canvas); }

.alarm-toggle input { margin: 0; cursor: pointer; }
.alarm-row.is-off .alarm-toggle input { cursor: default; }

/* 켜진 줄만 앰버로. 배경과 글자색을 한 규칙에서 같이 정한다 */
.alarm-toggle:has(input:checked) {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--ink);
  font-weight: 600;
}

.alarm-days { max-width: 140px; }

/* 지금 알림이 어디까지 가는지. 문자가 연결되면 문구가 저절로 바뀐다 */
.alarm-note {
  margin: 10px 0 0;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--canvas);
  color: var(--ink-mute);
  font-size: 12px;
  line-height: 1.6;
}

/* 좁은 화면에서는 줄을 접는다 (칸이 눌려 날짜가 안 보이는 것을 막는다) */
@media (max-width: 720px) {
  .alarm-row { grid-template-columns: 1fr 1fr; }
  .alarm-name { grid-column: 1 / -1; }
}
/* 칸 이름 옆의 단위 표시 — "매매가 (만원)" (2026-08-30)
   묶음 제목에만 적으면 칸을 볼 때는 눈에 안 들어와, 0 을 네 개 더 적는 사고가 난다 */
.unit {
  font-weight: 400;
  color: var(--ink-mute);
  font-size: 12px;
}
/* 직접 추가한 알림 줄 — [제목] [날짜] [며칠 전] [삭제] (2026-08-30) */
.alarm-row.is-custom {
  grid-template-columns: 1fr 168px 140px auto;
  margin-top: 8px;
}

/* 좁은 화면에서는 제목이 한 줄을 차지한다 (칸이 눌려 못 읽는 것을 막는다) */
@media (max-width: 720px) {
  .alarm-row.is-custom { grid-template-columns: 1fr 1fr; }
  .alarm-row.is-custom [data-c-title] { grid-column: 1 / -1; }
}

/* 날짜 칸 + 버튼을 한 줄에 */
.inline-fill {
  display: flex; align-items: center; gap: 8px;
}
.inline-fill .input { flex: 1; min-width: 0; }
/* 공유 링크 — 이미 나간 매물 (2026-08-30)
   감추지 않고 흐리게 표시한다. 감추면 손님은 "봤던 집이 왜 없어졌지" 를 겪는다 */
.share-item.is-gone { opacity: .62; }
.share-item.is-gone .shot { filter: grayscale(1); }
/* =====================================================================
   보완 과제 (/gaps) — 코드로 해결해야 하는 것들 (2026-08-30)

   ★ 줄을 낮게 유지한다. 항목마다 큰 카드를 만들면 다섯 개만 넘어가도 스크롤이 길어져
     "무엇이 남았는지 한눈에 본다"는 목적을 잃는다. 자세한 내용은 눌러서 편다.
   ★ 실서비스 전에 없앨 화면이다 — 지울 때 이 묶음도 함께 지운다.
   ===================================================================== */

.gap-intro {
  margin: 0 0 14px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: var(--canvas);
  color: var(--ink-mute);
  font-size: 12.5px;
  line-height: 1.65;
}

.gap-list {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.gap-item { border-bottom: 1px solid var(--line); }
.gap-item:last-child { border-bottom: 0; }

/* 한 줄 = 40px 남짓. 배지 둘 + 제목 + 오른쪽 끝에 구분·기간 */
.gap-item > summary {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 13px;
  cursor: pointer;
  list-style: none;
  transition: background .12s;
}
.gap-item > summary::-webkit-details-marker { display: none; }
.gap-item > summary:hover { background: var(--brand-tint); }
.gap-item[open] > summary { background: var(--brand-tint); }

.gap-title {
  flex: 1; min-width: 0;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.gap-meta {
  flex: none;
  font-size: 11.5px; color: var(--ink-mute);
  white-space: nowrap;
}

/* 펼친 내용 — 배지 폭만큼 들여써 제목 줄과 나란히 읽힌다 */
.gap-detail {
  padding: 2px 13px 13px 13px;
  background: var(--canvas);
  border-top: 1px solid var(--line);
}

.gap-line {
  display: grid; grid-template-columns: 62px 1fr; gap: 10px;
  padding: 7px 0;
}
.gap-line + .gap-line { border-top: 1px dashed var(--line); }
.gap-line > span {
  font-size: 11.5px; font-weight: 700; color: var(--ink-mute);
  padding-top: 1px;
}
.gap-line > p {
  margin: 0;
  font-size: 12.5px; line-height: 1.7; color: var(--ink);
}

/* 페이지 이동 */
.pager {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin-top: 16px;
}
.pager-now {
  font-size: 12.5px; color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  min-width: 56px; text-align: center;
}

@media (max-width: 640px) {
  .gap-meta { display: none; }       /* 좁으면 제목이 우선이다 */
  .gap-line { grid-template-columns: 1fr; gap: 2px; }
}

/* =====================================================================
   일정 화면 오른쪽 — 고른 날의 일정만 (2026-08-30)

   ★ "먼저 챙길 고객" 묶음을 걷어냈다. 이 칸은 이제 한 가지만 답한다 —
     "내가 방금 누른 날에 무엇이 잡혀 있나".

   ★ 지난번 문제: 줄이 왼쪽으로 삐져나오고 첫 줄만 두꺼운 검은 선으로 시작했다.
     목록에 음수 여백(margin:0 -18px)을 줘서 패널 밖으로 끌어낸 데다,
     급한 정도 띠가 그 줄에만 짙게 들어가 혼자 튀었다.
     이제 여백을 패널에 맞추고, 띠는 <b>모든 줄에 같은 두께</b>로 넣는다.
   ===================================================================== */

/* 목록을 패널 안쪽 선에 맞춘다 — 밖으로 끌어내지 않는다 */
#day-list .rows {
  margin: 0 -18px;
  border-top: 1px solid var(--line);
}

#day-list .row-item {
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-left: 3px solid transparent;   /* 갈래 색이 들어갈 자리. 모든 줄이 같은 두께다 */
}
#day-list .row-item + .row-item { border-top: 1px solid var(--line); }

/* 시각 — 목록에서 가장 먼저 보는 값이라 폭을 고정해 세로로 줄을 맞춘다 */
#day-list .row-time {
  flex: none; width: 44px;
  font-size: 12.5px; font-weight: 750; color: var(--ink);
  font-variant-numeric: tabular-nums;
}

#day-list .row-main { min-width: 0; }
#day-list .row-title {
  font-size: 13.5px; font-weight: 650;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#day-list .row-sub {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* 갈래마다 왼쪽 띠 색 — 달력의 일정 색과 같게 맞춘다 */
#day-list .row-item:has(.badge[data-tone="accent"]) { border-left-color: var(--accent); }

/* 빈 날은 조용하게. 큰 글씨로 "없음"을 외칠 일이 아니다 */
#day-list .empty { padding: 26px 0; }

/* =====================================================================
   계약 목록 — 보수 칸 · 관리 칸 (2026-08-31)
   ===================================================================== */

/* =====================================================================
   만기 알림 팝업 — 작게, 딱 필요한 크기로

   ★ 계약 팝업처럼 크면 방금 끝낸 일 위에 또 큰 창이 덮여 "아직 안 끝났나" 싶어진다.
     여기서 묻는 것은 두 가지뿐이다 — 언제 끝나나, 며칠 전에 알릴까.
   ===================================================================== */

dialog.modal.modal-slim {
  width: min(430px, calc(100vw - 32px));
}
.modal-slim .modal-body { padding: 15px 18px; max-height: calc(100vh - 260px); }
.modal-slim .modal-head { padding: 12px 18px; }
.modal-slim .modal-foot { padding: 11px 18px; }

/* 무엇에 대한 만기인지 — 팝업이 작아 제목만으로는 어느 계약인지 알 수 없다 */
.expiry-lead {
  margin: 0 0 13px;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: var(--canvas);
  font-size: 12.5px; line-height: 1.65; color: var(--ink);
}

/* 만기 알림 줄 — 이름칸을 좁혀 좁은 팝업에 맞춘다 */
.alarm-row.is-expiry { grid-template-columns: 66px auto 1fr; }

@media (max-width: 480px) {
  .alarm-row.is-expiry { grid-template-columns: 1fr 1fr; }
  .alarm-row.is-expiry .alarm-name { grid-column: 1 / -1; }
}

/* 확인 팝업의 설명 — 문구 안의 줄바꿈(\n)을 그대로 그린다 (2026-08-31)
   태그를 못 쓰는 자리라(전부 글자로 그린다) 줄바꿈은 이 방식뿐이다 */
.confirm-detail { white-space: pre-line; }


/* =====================================================================
   진행현황 팝업 바닥 — 버튼을 한 줄에 (2026-08-31)

   ★ 줄을 늘리면 팝업이 길어져 스크롤이 두 개가 된다.
     어느 것을 굴려야 할지 매번 고르게 되고 바닥 버튼이 가려진다.

   왼쪽부터  [삭제] [중도금 완료] [보수 수령 완료] … 여백 … [거래완료] [취소][저장]

   ★ 되돌릴 수 있는 일은 왼쪽에, <b>되돌릴 수 없는 일은 오른쪽 끝</b>에 모은다 (2026-09-01).
     [거래완료]는 누르는 순간 거래조건이 잠기므로 [저장] 곁에 두어 "마지막 동작"으로 보이게 하고,
     [중도금 완료]·[보수 수령 완료]는 취소할 수 있으므로 멀리 둔다.
   ===================================================================== */

.step-acts   { display: flex; gap: 8px; }
.fee-acts    { display: flex; gap: 8px; }
.finish-acts { display: flex; gap: 8px; margin-right: 6px; }
.step-acts:empty, .fee-acts:empty, .finish-acts:empty { display: none; }

/*
  ★ 여백은 <b>오른쪽 묶음이 스스로 밀어낸다</b> (margin-left:auto).

    왼쪽 묶음에 걸면 안 된다 — 보수가 0원이면 fee-acts 가 :empty 로 사라지고
    그때 여백까지 함께 사라져 [중도금 완료]가 [거래완료]에 달라붙는다.
    실제로 그렇게 붙으면 되돌릴 수 있는 버튼과 되돌릴 수 없는 버튼이 나란히 서게 된다.
*/
.modal-foot #btn-delete  { margin-right: auto; }
.modal-foot .finish-acts { margin-left: auto; }

/*
  진행 버튼은 <b>평소에 흰 버튼</b>이다 — 색은 [거래완료] 하나만 가진다.
  되돌릴 수 있는 일과 되돌릴 수 없는 일이 같은 무게로 보이면, 급할 때 잘못 누른다.
  대신 마우스를 올렸을 때 색이 들어와 "누를 수 있는 곳"임을 알린다.
*/
.modal-foot .btn.is-act:hover:not(:disabled) {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* 좁은 화면에서는 접히되 순서(진행 → 보수 → 끝내기 → 저장)는 그대로 둔다 */
@media (max-width: 700px) {
  .modal-foot { flex-wrap: wrap; }
  .modal-foot #btn-delete { margin-right: 0; }
  .modal-foot .finish-acts { margin-left: 0; width: 100%; }
  .finish-acts .btn { width: 100%; }
}

/* 저장 전이라 아직 누를 수 없는 단계 — 무엇을 하면 되는지만 알린다 (2026-08-31) */
.step-hint {
  display: inline-flex; align-items: center;
  font-size: 12px; color: var(--ink-mute);
  padding: 0 4px;
}

/* =====================================================================
   정책 · 호재 화면의 바탕 (2026-08-20)

   ★ 바꾼 것은 <b>배경뿐</b>이다. 줄(게시글) 구조·글자 크기·태그는 그대로다.

   왜 이 화면만인가.
     다른 화면은 매물·고객처럼 <b>내가 넣은 자료</b>를 다루는 곳이라
     회색 종이 위에서 색이 곧 정보로 읽혀야 한다(일치/어긋남, 매수/임대…).
     정책 브리핑은 <b>바깥에서 받아 온 읽을거리</b>다. 성격이 다르니 바탕도 다르게 두어
     "여기는 내 자료가 아니다" 가 화면 자체로 읽히게 한다.

   ★ 전부 .policies-page 안쪽에만 적는다. 이 클래스는 policies.jsp 의 <main> 에만 있다.
     바깥에 적으면 대시보드의 브리핑 카드까지 함께 바뀐다.
   ===================================================================== */

.policies-page {
  background:
    radial-gradient(900px 380px at 6% -8%,  #e5edf9 0%, rgba(229,237,249,0) 62%),
    radial-gradient(720px 330px at 97% 0%,  #f8ecdc 0%, rgba(248,236,220,0) 60%),
    linear-gradient(180deg, #fbfcfe 0%, #f3f6fb 46%, #eef2f8 100%);
}

/* 머리 밑줄도 함께 — 회색 선 하나가 남으면 그 부분만 옛 화면으로 보인다 */
.policies-page .page-head { border-bottom-color: #cdd7e6; }

/* 고르는 줄은 종이 위에 얹힌 흰 판으로. 반투명이라 뒤의 바탕색이 비친다 */
.policies-page .toolbar {
  background: rgba(255, 255, 255, .88);
  border-color: #dde4ef;
  box-shadow: 0 1px 2px rgba(38, 50, 72, .05),
              0 12px 26px -20px rgba(38, 50, 72, .5);
}

/*
  목록 전체를 한 장의 판으로 묶는다.
  줄이 바탕 위에 그냥 얹혀 있으면 어디까지가 목록인지 경계가 없다.
*/
.policies-page #policy-list {
  background: var(--surface);
  border: 1.5px solid #dde4ef;
  border-radius: var(--r);
  box-shadow: 0 1px 2px rgba(38, 50, 72, .05),
              0 16px 34px -24px rgba(38, 50, 72, .55);
  overflow: hidden;   /* 첫 줄·마지막 줄이 둥근 모서리 밖으로 삐져나오지 않게 */
}

/*
  ★ 줄 사이 선 (2026-08-20 진하게).

    처음에는 옅게 뒀는데(#edf0f6) 한 줄이 제목·요약·태그·날짜로 <b>네 줄</b>이라
    어디서 한 건이 끝나는지가 보이지 않았다. 목록에서 경계는 꾸밈이 아니라 기능이다.

  ★ 왼쪽 색 띠는 뺐다.
    중요도는 제목 옆 [영향 큼] 배지가 이미 말하고 있어서, 띠는 <b>같은 말을 두 번</b>
    하면서 목록 왼쪽에 검은/갈색 세로줄만 남겼다. 영향이 큰 줄은 바탕색으로 띄운다.
*/
.policies-page .policy-row {
  border-bottom-color: #ccd6e6;
  border-left: 0;
}

/* 영향이 큰 것만 따뜻한 종이색으로 — 훑을 때 먼저 걸려야 하는 줄이다 */
.policies-page .policy-row[data-impact="HIGH"] { background: #fdf7ee; }
.policies-page .policy-row:hover               { background: #e9f0fb; }
.policies-page .policy-row[data-impact="HIGH"]:hover { background: #f5efe5; }

/* 비었을 때·오류도 같은 판 위에 있어야 한다 */
.policies-page .empty {
  background: rgba(255, 255, 255, .9);
  border-color: #dde4ef;
}

/* 정렬 상자는 기간 버튼과 같은 높이로 — 혼자 작으면 딸린 것처럼 보인다 */
.sort-select { min-width: 108px; }

/*
  줄 맨 오른쪽에 홀로 떨어뜨리고 싶을 때 쓰는 표시.
  (정책 화면의 [초기화] 는 2026-08-20에 정렬 바로 옆으로 되돌렸다 — 끝까지 밀어 두니
   눈이 한 번 더 건너가야 했다. 규칙은 다른 곳에서 쓸 수 있게 남겨 둔다)
*/
.toolbar-end { margin-left: auto; }
@media (max-width: 760px) { .toolbar-end { margin-left: 0; } }
/* ===================================================================
   숏츠 만들기 (/shorts)

   장면 카드는 왼쪽 세로 썸네일 + 오른쪽 입력칸의 두 칸 구조다.
   썸네일을 9:16 로 두는 이유는 결과물이 세로 영상이기 때문이다 —
   가로 썸네일로 보여 주면 실제로 어떻게 잘리는지 알 수 없다.
   =================================================================== */
.shorts-scenes { display: grid; gap: 2px; }

/*
  ★ 장면 칸은 오른쪽 좁은 칸에 들어간다 (2026-08-20 옮김).
    예전에는 넓은 왼쪽 칸을 통째로 써서 <b>가로 여백만 넓고 세로로는 끝없이 길었다.</b>
    폭이 좁아진 만큼 썸네일과 간격을 함께 줄인다 — 안 줄이면 글자칸이 짜부라진다.
*/
.shorts-scene {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 12px;
  padding: 13px 0;
  border-top: 1px solid var(--line, #e5e8ee);
}
.shorts-scene:first-child { border-top: 0; padding-top: 2px; }

.shorts-thumb-col { display: grid; gap: 5px; align-content: start; }

.shorts-thumb {
  width: 104px;
  height: 185px;                 /* 9:16 */
  border: 1px solid var(--line, #e5e8ee);
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
}
.shorts-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.shorts-thumb.is-busy::after {
  content: "만드는 중…";
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .86);
  font-size: 12px;
  font-weight: 700; color: var(--accent-ink);
  /* 멈춰 있는 글자만 있으면 "멈춘 건가?" 가 된다. 숨쉬듯 깜빡여 살아 있음을 보인다 */
  animation: shorts-breathe 1.1s ease-in-out infinite;
}
@keyframes shorts-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* 아직 아무것도 없는 칸 — "고장" 이 아니라 "여기에 들어올 것" 으로 보여야 한다 */
.shorts-thumb.is-empty {
  border-style: dashed;
  color: var(--ink-mute);
  font-size: 12px;
  text-align: center;
  padding: 0 10px;
}

/* 그림 만들기가 실패한 칸. 조용히 비워 두면 "안 눌렸나?" 로만 보인다 */
.shorts-thumb.is-error {
  border-color: var(--danger);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 11.5px; font-weight: 700;
  text-align: center; padding: 0 8px;
}

/*
  ★ 고른 것이 보여야 한다 (2026-08-20).

    chips 는 누르면 .is-on 이 붙는데 <b>그 클래스에 아무 모양도 없었다.</b>
    그래서 스타일·템플릿·품질을 아무리 눌러도 화면은 그대로였고,
    무엇을 고른 상태인지 알 길이 없었다.

    ★ 색만으로 표시하지 않는다. 색약이거나 화면이 어두우면 구분이 안 되므로
      글자 굵기와 테두리 두께까지 함께 바꾼다.
*/
.chips button.chip.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 750;
  box-shadow: var(--shadow-1);
}
.chips button.chip.is-on:hover {
  background: var(--accent-ink);
  border-color: var(--accent-ink);
  color: #fff;
}
/* 못 쓰는 선택지(내 사진 모드의 그림 스타일 등)는 눌리지 않는다는 게 보여야 한다 */
.chips button.chip:disabled {
  opacity: .4;
  cursor: not-allowed;
  background: var(--surface-3);
  border-color: var(--line);
  color: var(--ink-mute);
  box-shadow: none;
}
.chips button.chip:disabled:hover { background: var(--surface-3); border-color: var(--line); }

/*
  지금 무엇이 골라져 있는지 한 줄로 다시 말해 준다.
  칩이 여러 줄로 흩어져 있으면 "그래서 지금 뭐지" 가 안 잡힌다.
*/
.shorts-picked {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline;
  padding: 10px 12px; margin-top: 4px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  font-size: 12.5px; color: var(--accent-ink);
}
.shorts-picked b { font-weight: 750; }
.shorts-picked .sep { opacity: .45; }

/* 장면 카드 위의 안내 — 장면 수가 줄었거나 그림이 실패했을 때 여기에 뜬다 */
.shorts-note { margin-bottom: 12px; }

/* =====================================================================
   진행 표시줄 (2026-08-20)

   ★ 화면 위에 붙여 따라다니게 한다. 장면이 5개면 목록이 길어 아래쪽 진행률이
     화면 밖으로 나가는데, 그러면 눌러 놓고 <b>아무 반응이 없는 것처럼</b> 보인다.
   ===================================================================== */
/*
  ★ sticky 가 아니라 <b>fixed</b> 다 (2026-08-20 고침).

    처음에는 본문 위에 sticky 로 붙였는데, 스크롤할 때마다 자리를 다시 잡느라
    <b>화면에서 덜덜 떨리듯 움직였다.</b> 진행 표시는 "지금 돌고 있다"만 조용히
    알려 주면 되는 것이라, 스크롤과 아예 무관한 자리에 못박는다.

    오른쪽 아래는 알림(.toasts)이 쓰므로 <b>왼쪽 아래</b>에 둔다 — 서로 가리지 않는다.
*/
.shorts-run {
  position: fixed; left: calc(var(--nav-w) + 18px); bottom: 18px; z-index: 900;
  width: min(340px, calc(100vw - var(--nav-w) - 36px));
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "dot text" "bar bar";
  align-items: center; gap: 8px 10px;
  padding: 12px 15px;
  background: var(--surface);
  border: 1.5px solid var(--accent);
  border-radius: var(--r);
  box-shadow: var(--shadow-3);
  color: var(--accent-ink);
}
.shorts-run-text { grid-area: text; display: grid; gap: 1px; min-width: 0; }
.shorts-run-text b { font-size: 13px; font-weight: 750; line-height: 1.35; }
.shorts-run-bar { grid-area: bar; background: var(--surface-3); }

@media (max-width: 900px) {
  .shorts-run { left: 18px; width: min(340px, calc(100vw - 36px)); }
}

/*
  진행률을 <b>모르는 단계</b>는 줄무늬가 흐른다.
  가짜 퍼센트를 채워 두면 "80%인데 왜 그대로지" 가 된다 — 모르면 모른다고 보인다.
*/
.shorts-run-bar.is-vague { position: relative; overflow: hidden; }
.shorts-run-bar.is-vague > i {
  width: 38%;
  background: var(--accent);
  animation: shorts-slide 1.4s ease-in-out infinite;
  transition: none;
}
@keyframes shorts-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}

/* 도는 표시. 글자만 있으면 멈춘 것처럼 보인다 */
.shorts-run-dot {
  grid-area: dot;
  width: 15px; height: 15px; border-radius: 50%;
  border: 2.5px solid rgba(180, 83, 9, .28);
  border-top-color: var(--accent);
  animation: shorts-spin .8s linear infinite;
}
@keyframes shorts-spin { to { transform: rotate(360deg); } }

/* 끌어다 놓기 — 어디에 떨어지는지 보여야 한다 */
.shorts-scenes.is-drop-on { outline: 2px dashed var(--accent); outline-offset: 6px; border-radius: var(--r-sm); }
.shorts-scene.is-drop { background: var(--accent-soft); border-radius: var(--r-sm); }
.shorts-scene.is-drop .shorts-thumb { border-color: var(--accent); border-style: dashed; }

.shorts-fields { display: grid; gap: 4px; min-width: 0; align-content: start; }
.shorts-fields label { margin-top: 2px; }
.shorts-fields .textarea { min-height: 0; padding: 7px 10px; font-size: 13px; line-height: 1.45; }
.shorts-thumb-col .btn { padding: 5px 8px; min-height: 28px; font-size: 11.5px; }

/*
  ★ 장면 카드의 동작 버튼을 <b>목록 위로</b> 올렸다 (2026-08-20).

    아래에 두면 장면이 5개일 때 [그림 만들기] 가 한참 스크롤해야 나온다 —
    누르려고 매번 내려가야 하는 버튼은 없는 것과 비슷하다.

    ★ 색도 바꿨다. 검정(btn-primary)은 이 화면에서 <b>혼자 붕 떠 보였다</b> —
      주변이 전부 흰 카드와 옅은 선인데 검은 덩어리 하나만 무겁게 앉아 있었다.
      강조색(btn-accent)은 "눌러야 할 곳" 이라는 뜻이 있고 화면 전체와 어울린다.
*/
.shorts-scene-acts {
  border-top: 0;
  border-bottom: 1px solid var(--line);
  padding: 0 0 12px;
  margin-bottom: 4px;
  background: transparent;
}

.shorts-bar {
  height: 9px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--surface-2);
}
.shorts-bar > i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent, #ffb020);
  transition: width .3s;
}

/*
  "4. 영상 만들기" 안의 진행 줄.
  버튼 · 게이지 · 문구가 서로 달라붙어 한 덩어리로 보였다 — 셋은 다른 것이므로 띄운다.
*/
#box-build .shorts-bar { margin: 14px 0 8px; }
#box-build #progress-note { margin: 0; }

/*
  ★ 오른쪽 "지난 작업" 상자가 왼쪽 칸 높이만큼 늘어나던 문제 (2026-08-20).

    grid 는 칸을 같은 높이로 맞춘다(stretch). 그래서 왼쪽에 장면이 5개 쌓이면
    오른쪽 상자도 <b>내용과 상관없이</b> 그만큼 길어져 아래가 텅 비었다.
    start 로 두면 제 내용만큼만 차지한다.
*/
.shorts-side { align-self: start; }

/*
  숏츠 화면의 좌우 나눔.
  왼쪽은 대사·설정(한 번 정하면 끝), 오른쪽은 장면(계속 손대는 곳)이라 거의 반반으로 둔다.
*/
.grid-shorts { grid-template-columns: minmax(0, 1fr) minmax(0, 1.04fr); }
@media (max-width: 1100px) { .grid-shorts { grid-template-columns: minmax(0, 1fr); } }

/* =====================================================================
   오류 페이지 (404 · 500) — 2026-08-20

   ★ 내비게이션이 없다. 로그인 전에도 떠야 하고, 오류 화면을 그리다 또 오류가 나면
     아무것도 안 보인다. 오류 화면은 무슨 일이 있어도 뜨는 것이 첫째다.
   ===================================================================== */
.errpage {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: var(--canvas);
}
.errpage-box {
  max-width: 520px; width: 100%;
  padding: 40px 36px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  text-align: center;
}
.errpage-code {
  margin: 0 0 6px;
  font-size: 54px; font-weight: 800; line-height: 1;
  color: var(--line-strong);
  font-variant-numeric: tabular-nums;
}
.errpage-code-bad { color: var(--danger); }
.errpage-box h1 { margin: 0 0 12px; font-size: 21px; font-weight: 750; }
.errpage-msg { margin: 0; color: var(--ink-mute); font-size: 14px; line-height: 1.7; }
.errpage-ref {
  margin: 16px 0 0; padding: 9px 12px;
  background: var(--surface-3); border-radius: var(--r-sm);
  font-size: 13px; color: var(--ink-2);
}
.errpage-ref b { font-family: ui-monospace, Menlo, Consolas, monospace; letter-spacing: .5px; }
.errpage-acts { display: flex; gap: 8px; justify-content: center; margin-top: 22px; flex-wrap: wrap; }

/* =====================================================================
   사진 순서 바꾸기 — 썸네일 끌어 옮기기 (2026-08-20)

   ★ 끌 수 있다는 것이 보여야 한다. 아무 표시가 없으면 아무도 시도하지 않아
     기능이 있어도 없는 것과 같다.
   ===================================================================== */
.viewer-thumb[draggable="true"] { cursor: grab; }
.viewer-thumb[draggable="true"]:active { cursor: grabbing; }

/* 끌고 있는 것 — 손에 들려 있다는 느낌 */
.viewer-thumb.is-dragging { opacity: .4; }

/* 놓을 자리 — 여기로 들어간다 */
.viewer-thumb.is-drop {
  outline: 2.5px solid var(--accent);
  outline-offset: 2px;
  transform: translateY(-3px);
}

/* 세로 영상이라 폭을 좁게 고정한다. 가로로 늘리면 위아래가 잘려 보인다 */
.shorts-player {
  width: 304px;
  max-width: 100%;
  margin-top: 16px;
  border-radius: 14px;
  background: #000;
  display: block;
}
