/*
 * 점주 포털 전용 스타일.
 *
 * 디자인 토큰(색·라운드·그림자·폰트)과 공통 컴포넌트(.btn .card .badge .input .table .toast ...)는
 * 관리자와 같은 /cms/assets/css/ops.css 를 그대로 쓴다. 여기에는 그 위에 얹는
 * "점주 화면의 껍데기와 전용 컴포넌트" 만 둔다 — 두 벌로 나뉘면 반드시 어긋난다.
 *
 * 기준은 모바일이다. 점주는 대부분 휴대폰으로 들어온다.
 * --accent 는 레이아웃이 <html> 인라인으로 테넌트 포인트 컬러를 덮어쓴다.
 *
 * ## `prefers-reduced-motion` 은 보지 않는다 (2026-09-17 결정)
 *
 * 예전에는 기기의 "동작 줄이기" 설정을 보고 연출(돋보기 스캔·제목 타이핑·카드 등장·숫자 세기)을 껐다.
 * 그런데 그 설정을 켜 둔 폰에서 진단 화면이 **다른 화면처럼** 보였고(돋보기가 멈추고 타이핑이 안 나온다),
 * 사장님 요청이 "기기 설정과 상관없이 똑같이 보였으면" 이라 **포털 전체에서 걷어냈다.**
 *
 * CSS 의 `@media (prefers-reduced-motion: reduce)` 블록 9개와 JS 쪽 검사 3곳(`typing.js`,
 * `diagnosis/result.php`, `order_ver/new.php`)을 같이 지웠다 — **한쪽만 지우면 그 폰에서 타이핑이 여전히 안 나온다.**
 * 접근성 관례라며 되살리지 말 것. 되살리려면 먼저 사장님과 이야기한다.
 */

/*
 * ## 글자 계층 (2026-09-21 — 피그마 `Typography` 259:463)
 *
 * 디자이너가 정한 눈금이다. **이 일곱 단계 밖의 크기를 새로 만들지 않는다** —
 * 12.5·13.5·14.5px 같은 값이 섞이면서 같은 자리의 글자가 화면마다 달라 보였다.
 *
 *   Title-1   28 / 36   Bold 700      화면 제목(홈 인사 · 진단 제목)
 *   Title-2   24 / 32   Bold 700      카드 안 큰 제목
 *   H1        20 / 28   SemiBold 600  구역 제목
 *   Body-1    18 / 26   SemiBold 600  (Regular 은 18 / 28)
 *   Body-2    16 / 24   SemiBold 600  본문 · 버튼
 *   Body-3    14 / 22   700/600/400   목록 · 칩 · 설명
 *   Body-4    12 / 20   700/600/500/400  배지 · 보조 설명
 *
 * 굵기는 400·500·600·700 넷뿐이다(550·620·650 같은 중간값을 쓰지 않는다).
 * 자간은 -3%(`-.03em`). 큰 제목(`.dg-hero`)만 -1% 로 푼다 — 2026-09-16 "글자 사이 여백" 요청이다.
 *
 * 눈금 밖으로 남겨 둔 것: 표시용 숫자(진단 점수 52px · 금액 34~40px · 수량 입력 34px)와
 * 차트 축 라벨(8·9.5px). 글이 아니라 그림에 가까운 자리라 계층을 따르지 않는다.
 *
 * 여백은 4px 눈금이다(2·4·6·8·10·12·14·16·20·24·28·32…). 7·11·13px 같은 홀수를 쓰지 않는다.
 */

/* ─────────────────────────────  셸  ───────────────────────────── */
body.ads {
  background: var(--bg);
  /* 하단 탭바를 걷어냈다(2026-09-18) — 홈 인디케이터 영역만 띄운다. */
  padding-bottom: env(safe-area-inset-bottom);
}

.ads-header {
  position: sticky; top: 0; z-index: 40;
  background: rgba(255, 255, 255, .82);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border);
}
.ads-header__inner {
  max-width: 980px; margin: 0 auto;
  height: 56px; padding: 0 16px;
  display: flex; align-items: center; gap: 12px;
}

/*
 * 브랜드 자리 — 로고 이미지 **하나뿐**이다(브랜드명 글자는 인사말이 가져갔다).
 * 로고가 없는 테넌트는 첫 글자로 만든 사각 마크가 그 자리에 선다.
 */
.ads-brand { flex-shrink: 0; display: flex; align-items: center; color: var(--text); font-weight: 650; }
.ads-brand:hover { text-decoration: none; }
/*
 * 워드마크(가로로 긴 로고)가 대부분이라 폭을 고정하지 않는다.
 * 좁은 화면에서는 인사말과 자리를 다투므로 상한을 더 줄인다.
 */
.ads-brand__logo { height: 26px; width: auto; max-width: 112px; object-fit: contain; display: block; }
.ads-brand__mark {
  width: 28px; height: 28px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; font-size: 14px; font-weight: 700;
}

/*
 * 인사말 — `안녕하세요, 센트럴시티점 점주님`.
 *
 * DOM 에는 메뉴와 로그아웃 사이 **한 자리**뿐이고, 폭에 따라 서는 곳이 달라진다.
 *   좁은 화면  메뉴가 없으므로 브랜드 바로 옆(예전 브랜드명 자리)
 *   넓은 화면  메뉴가 남는 폭을 먹으므로 자연히 로그아웃 왼쪽
 *
 * 길면 말줄임한다 — 매장명이 긴 지점에서 로그아웃 버튼을 밀어내면 안 된다.
 */
.ads-greet {
  flex: 1; min-width: 0; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16px; font-weight: 600; letter-spacing: -.03em; color: var(--text);
}

.ads-nav { display: none; flex: 1; gap: 2px; margin-left: 12px; }
.ads-nav__link {
  padding: 6px 12px; border-radius: var(--radius-full);
  font-size: 14px; font-weight: 600; color: var(--text-2);
  transition: background .18s var(--ease), color .18s var(--ease);
}
.ads-nav__link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.ads-nav__link.active { background: var(--accent-tint); color: var(--accent); font-weight: 650; }

/* 로그아웃 — 넓은 화면에만 선다. 폰에서는 햄버거가 여는 시트 아래쪽에 있다. */
.ads-logout--wide { display: none; }
@media (min-width: 861px) { .ads-logout--wide { display: inline-flex; } }

/*
 * 진단 셸 헤더(`.ads-header--space`)는 좁은 화면에서 인사말의 `안녕하세요,` 를 접는다.
 * 옛 `점주공간` 버튼(`.ads-space`)과 `<details>` 드롭다운(`.ads-menu`)은 전체 메뉴 시트로
 * 대체돼 규칙을 지웠다(2026-09-18).
 */

.ads-main { max-width: 980px; margin: 0 auto; padding: 20px 16px 32px; }

/* ─────────────────────────  전체 메뉴 시트(모바일)  ─────────────────────────
 *
 * 하단 탭바를 대신한다(2026-09-18). 점주공간 시트(`.ow-sheet`)와 치수·전환이 같고,
 * 다른 점은 **패널이 테넌트 포인트 색**이라는 것과 안이 **좌우로 나뉜다**는 것이다.
 * 왼쪽 레일이 점주공간으로 나가는 길, 오른쪽이 이 포털 메뉴다.
 */
.ads-burger {
  flex: none;
  width: 34px; height: 34px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid var(--border-strong); border-radius: var(--radius-full);
  background: var(--surface); color: var(--text);
  cursor: pointer;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.ads-burger:hover { color: var(--accent); border-color: var(--accent); }
.ads-burger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ads-burger .icon { width: 17px; height: 17px; }

.ads-sheet { position: fixed; inset: 0; z-index: 60; }
.ads-sheet[hidden] { display: none; }

.ads-sheet__scrim {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, .36);
  opacity: 0;
  transition: opacity .24s var(--ease);
}
.ads-sheet.is-open .ads-sheet__scrim { opacity: 1; }

.ads-sheet__panel {
  position: absolute; top: 0; bottom: 0; right: 0;
  width: min(84vw, 320px);
  display: flex;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--accent); color: #fff;
  box-shadow: var(--shadow-3);
  transform: translateX(100%);
  transition: transform .26s var(--ease);
}
.ads-sheet.is-open .ads-sheet__panel { transform: translateX(0); }
/* 열 때 초점을 받는 자리라 테두리를 그리지 않는다(ads.js 가 여기로 초점을 준다). */
.ads-sheet__panel:focus { outline: none; }

/* 왼쪽 레일 — 한 칸뿐이라 세로 가운데에 세운다. 같은 색을 한 단계 눌러 면을 가른다. */
.ads-rail {
  flex: none; width: 74px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 14px 6px;
  border-right: 1px solid rgba(255, 255, 255, .24);
  background: rgba(0, 0, 0, .12);
  color: #fff; text-align: center;
}
.ads-rail:hover { background: rgba(0, 0, 0, .2); color: #fff; text-decoration: none; }
.ads-rail:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }
.ads-rail__ico {
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: var(--radius-full); background: rgba(255, 255, 255, .18);
}
.ads-rail__ico .icon { width: 18px; height: 18px; }
.ads-rail__label { font-size: 12px; font-weight: 700; line-height: 20px; letter-spacing: -.01em; }

.ads-sheet__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* 머리 — 헤더와 같은 56px 라 열리는 순간 줄이 맞는다. */
.ads-sheet__head {
  flex: none;
  display: flex; align-items: center; gap: 8px;
  height: 56px; padding: 0 6px 0 14px;
  border-bottom: 1px solid rgba(255, 255, 255, .22);
}
.ads-sheet__title {
  flex: 1; min-width: 0; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16px; font-weight: 700; letter-spacing: -.03em; color: #fff;
}
.ads-sheet__close {
  flex: none;
  width: 40px; height: 40px; padding: 0;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-full);
  background: transparent; color: rgba(255, 255, 255, .86); cursor: pointer;
}
.ads-sheet__close:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.ads-sheet__close:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.ads-sheet__close .icon { width: 18px; height: 18px; }

/* 목록 — 길어지면 이 칸만 스크롤한다(머리·아래쪽은 제자리). */
.ads-sheet__body {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 8px 10px 14px;
}
.ads-sheet__list { margin: 0; padding: 0; list-style: none; }
.ads-sheet__link,
.ads-sheet__exit {
  display: flex; align-items: center; gap: 10px;
  min-height: 46px; padding: 0 12px;
  border-radius: var(--radius-sm);
  font-size: 16px; font-weight: 600; color: #fff; text-decoration: none;
}
.ads-sheet__link:hover,
.ads-sheet__exit:hover { background: rgba(255, 255, 255, .12); color: #fff; text-decoration: none; }
.ads-sheet__link:focus-visible,
.ads-sheet__exit:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.ads-sheet__ico { flex: none; width: 19px; height: 19px; opacity: .88; }

/* 지금 있는 화면 — 패널이 이미 색이라 흰색 반투명 면으로 든다. */
.ads-sheet__link.is-active { background: rgba(255, 255, 255, .18); }

.ads-sheet__foot {
  flex: none;
  padding: 8px 10px 12px;
  border-top: 1px solid rgba(255, 255, 255, .22);
}
.ads-sheet__exit { font-weight: 550; color: rgba(255, 255, 255, .86); }

/* 시트가 열려 있는 동안 뒤 화면이 스크롤되지 않게(ads.js 가 html 에 건다). */
html.ads-locked, html.ads-locked body { overflow: hidden; }

@media (min-width: 861px) {
  body.ads { padding-bottom: 0; }
  .ads-nav { display: flex; }
  .ads-burger,
  .ads-sheet { display: none !important; }
  html.ads-locked, html.ads-locked body { overflow: visible; }

  /* 넓은 화면에서는 메뉴가 주인공이다. 인사말은 로그아웃 옆에 **작게** 붙는다. */
  .ads-greet {
    flex: 0 1 auto; max-width: 280px;
    font-size: 14px; font-weight: 500; color: var(--text-2);
  }
}

/* 좁은 화면 — 로고·인사말·로그아웃이 자리를 다툰다. 여백과 로고 상한부터 줄인다. */
@media (max-width: 400px) {
  .ads-header__inner { gap: 8px; padding: 0 12px; }
  .ads-brand__logo { max-width: 84px; }
  .ads-greet { font-size: 14px; }
}

/*
 * 그래도 안 들어가는 화면(320px 급 구형 기기)에서만 뒤의 `안녕하세요!` 를 접는다.
 *
 * 실측: 인사말 전체가 188px, 340px 화면에서 쓸 수 있는 폭이 200px —
 * 그 아래에서만 말줄임이 시작된다. 잘려야 한다면 **잘릴 것은 인사지 매장명이 아니다.**
 * (매장명이 아주 긴 지점은 넓은 화면에서도 말줄임이 걸린다. 그때도 앞쪽 = 이름이 남는다)
 */
@media (max-width: 340px) {
  .ads-greet__hi { display: none; }
}

.hide-sm { display: none; }
@media (min-width: 561px) { .hide-sm { display: inline; } }

/* ─────────────────────────────  페이지 머리  ───────────────────────────── */
.ads-page-head { margin-bottom: 18px; }
.ads-page-head h1 { font-size: 20px; letter-spacing: -.03em; }
.ads-page-head p { margin-top: 4px; font-size: 14px; color: var(--text-2); }

/* ─────────────────────────────  요약 카드  ───────────────────────────── */
.ads-stats { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 861px) { .ads-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; } }

/*
 * 카드는 링크가 아니라 상자다. 다음 행동은 안에 있는 버튼 하나가 맡는다 —
 * 카드 전체를 <a> 로 두면 버튼을 넣는 순간 링크 안 링크가 된다.
 *
 * 버튼은 **오른쪽 위 한 자리에 고정**한다. 카드마다 내용 길이가 달라
 * 흐름대로 두면 버튼 높이가 제각각이 되고, 그때부터 줄이 지저분해 보인다.
 */
.ads-stat {
  position: relative;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 14px 16px;
  box-shadow: var(--shadow-1);
}
.ads-stat__label { font-size: 12px; color: var(--text-2); font-weight: 600; }
.ads-stat__value {
  margin-top: 4px; font-size: 20px; font-weight: 700;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.ads-stat__meta { margin-top: 2px; font-size: 12px; color: var(--text-3); }
.ads-stat__action { position: absolute; top: 12px; right: 12px; }
/* 버튼이 값 위에 겹치지 않게 오른쪽을 비워 둔다. */
.ads-stat:has(.ads-stat__action) .ads-stat__label,
.ads-stat:has(.ads-stat__action) .ads-stat__value { padding-right: 76px; }
.ads-stat--accent .ads-stat__value { color: var(--accent); }
.ads-stat--warning .ads-stat__value { color: var(--warning); }

/* ─────────────────────────────  본사 브랜드 성과(/hq)  ───────────────────────────── */
/*
 * 접두는 `.hq-` 다 — 이 파일의 화면별 접두 관행(`.hm-` 홈 · `.gd-` 이용안내 · `.of-` 접수).
 *
 * 홈의 순위 어법(`▲/▼` + `.is-up`/`.is-down`)과 **같은 모양이지만 클래스는 새로 둔다.**
 * 저쪽 `.hm-*` 는 `.hm` 이 정의하는 스코프 변수에 묶여 있어서, 그걸 쓰려면 조상에 `.hm` 을
 * 달아야 하고 그러면 화면이 584px 로 좁아진다. 본사 화면은 담당자가 PC 로 보는 곳이라
 * `.ads-main`(980px)을 그대로 쓴다.
 */
.hq-perf { margin-bottom: 18px; }

/* 잰 적이 없을 때. 숫자가 아니라 문장이 들어오므로 크기를 줄여 값 자리와 균형을 맞춘다. */
.hq-perf__none { font-size: 18px; color: var(--text-2); }

/*
 * 증감 뱃지. 값 옆에 붙는 작은 글자라 `.ads-stat__value` 의 큰 크기·굵기를 되돌린다
 * (안 되돌리면 22px/680 을 물려받아 증감이 값만큼 커진다).
 */
.hq-diff {
  margin-left: 6px;
  font-size: 12px; font-weight: 600; letter-spacing: 0;
  white-space: nowrap;
}
.hq-diff.is-up { color: var(--success); }
.hq-diff.is-down { color: var(--danger); }

/* 오른 지점 · 내린 지점 두 칸. 좁은 화면에서는 세로로 쌓인다. */
.hq-movers {
  display: grid; gap: 10px; margin-top: 10px;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 641px) {
  .hq-movers { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
}
.hq-movers__col {
  padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1);
}
.hq-movers__title { font-size: 12px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }

/*
 * 한 줄 = 지점 하나. 이름은 늘어나고 숫자 두 개는 고정 —
 * 지점명이 길어도 오른쪽 숫자가 밀리지 않아야 여러 줄을 눈으로 훑을 수 있다.
 */
.hq-mover {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0;
  font-size: 14px; color: var(--text);
}
.hq-mover + .hq-mover { border-top: 1px solid var(--border); }
.hq-mover:hover { text-decoration: none; }
.hq-mover:hover .hq-mover__name { color: var(--accent); }
.hq-mover__name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hq-mover__rate {
  flex: none; color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.hq-mover .hq-diff { flex: none; margin-left: 0; min-width: 52px; text-align: right; }

/* ─────────────────────────────  상품 선택(P-04)  ───────────────────────────── */
.ads-products { display: grid; gap: 10px; }
@media (min-width: 761px) { .ads-products { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.ads-product {
  position: relative; display: block; cursor: pointer;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-lg); padding: 16px;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease);
}
.ads-product input { position: absolute; opacity: 0; pointer-events: none; }
.ads-product:hover { border-color: var(--border-strong); }
.ads-product__name { font-size: 14px; font-weight: 700; letter-spacing: -.03em; }
.ads-product__desc { margin-top: 6px; font-size: 12px; color: var(--text-2); line-height: 20px; }
.ads-product__price { margin-top: 10px; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.ads-product__badge {
  position: absolute; top: 12px; right: 12px;
  height: 20px; padding: 0 8px; border-radius: var(--radius-full);
  display: inline-flex; align-items: center;
  background: var(--accent-soft); color: var(--accent);
  font-size: 12px; font-weight: 700;
}
.ads-product.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ─────────────────────────────  키워드 태그  ───────────────────────────── */
.ads-tags {
  display: flex; flex-wrap: wrap; gap: 6px;
  min-height: 38px; padding: 6px 10px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}
.ads-tags:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ads-tags__input {
  flex: 1; min-width: 120px; border: 0; outline: none;
  background: transparent; font-family: inherit; font-size: 14px; color: var(--text);
}
.ads-tag {
  display: inline-flex; align-items: center; gap: 4px;
  height: 24px; padding: 0 6px 0 10px; border-radius: var(--radius-full);
  background: var(--accent-soft); color: var(--accent);
  font-size: 12px; font-weight: 600;
}
.ads-tag button {
  width: 16px; height: 16px; border: 0; border-radius: 50%; padding: 0;
  background: rgba(0, 0, 0, .08); color: inherit;
  font-size: 12px; line-height: 1; cursor: pointer;
}
.ads-tag button:hover { background: rgba(0, 0, 0, .16); }

/*
 * 태그 안의 월 검색량.
 *
 * 키워드 옆에 붙여야 "이 키워드가 그만큼 검색된다" 로 읽힌다 — 표로 따로 빼면
 * 어느 줄이 어느 키워드인지 눈이 한 번 더 왔다 갔다 한다.
 */
.ads-tag__vol { font-weight: 500; font-size: 12px; opacity: .75; font-variant-numeric: tabular-nums; }
/* 검색량이 기준 아래인 키워드. 막지는 않고 색으로만 알린다. */
.ads-tag.is-low { background: var(--warning-soft); color: #a76500; }

/* 태그 안의 검색량도 늦게 붙는다. 자리를 비워 두면 태그 폭이 뛰어 줄바꿈이 통째로 바뀐다. */
.ads-tag__vol.is-pending {
  display: inline-block; width: 42px; height: 9px; border-radius: 4px;
  background: currentColor; opacity: .22; animation: ads-pulse 1.3s var(--ease) infinite;
}
@keyframes ads-pulse { 0%, 100% { opacity: .16; } 50% { opacity: .36; } }



/* ─────────────────────────────  수량 슬라이더  ───────────────────────────── */
.ads-range { display: flex; align-items: center; gap: 12px; }
.ads-range input[type="range"] {
  flex: 1; appearance: none; height: 4px; border-radius: 2px;
  background: var(--border-strong); outline: none;
}
.ads-range input[type="range"]::-webkit-slider-thumb {
  appearance: none; width: 22px; height: 22px; border-radius: 50%;
  background: #fff; border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-2); cursor: pointer;
}
.ads-range input[type="range"]::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: #fff; border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-2); cursor: pointer;
}
.ads-range__value { width: 108px; }
.ads-range__value .input { text-align: right; font-variant-numeric: tabular-nums; }

.ads-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.ads-chip {
  height: 30px; padding: 0 12px; border-radius: var(--radius-full);
  border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text-2); font-family: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; transition: all .16s var(--ease);
}
.ads-chip:hover { background: var(--surface-2); color: var(--text); }
.ads-chip.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }

/* ─────────────────────────────  금액 패널  ───────────────────────────── */
.ads-amount {
  position: sticky; bottom: calc(12px + env(safe-area-inset-bottom)); z-index: 20;
  margin-top: 18px; padding: 16px 18px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
}
@media (min-width: 861px) { .ads-amount { bottom: 16px; } }

.ads-amount__row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.ads-amount__label { font-size: 12px; color: var(--text-2); }
.ads-amount__total {
  font-size: 24px; font-weight: 700; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.ads-amount__meta { margin-top: 4px; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.ads-amount__after { color: var(--text-2); }
.ads-amount__shortage { color: var(--danger); font-weight: 600; }
.ads-amount .btn { margin-top: 14px; height: 46px; font-size: 14px; }

/* ─────────────────────────────  목록 필터 줄  ───────────────────────────── */
/*
 * `.toolbar` 자체는 `ops.css` 것이라 **고치지 않는다**(관리자 화면까지 흔들린다).
 * 여기서 점주 화면(`body.ads`)에만 덮는다.
 *
 * 좁은 화면에서 찌그러지던 이유 — `.toolbar .input/.select` 가 `width:auto` 에
 * `min-width:150px` 이다. 360px 기기에서 카드 안에 쓸 수 있는 폭이 286px 이라
 * `150 + 8 + 150 = 308` 이 안 들어가 **한 줄에 하나씩** 내려가는데, 각 칸은 150px 로
 * 남아 오른쪽 136px 이 빈 채 계단처럼 어긋난다. 줄바꿈이 문제가 아니라 **폭이 안 차는 것**이 문제다.
 *
 * 그래서 좁은 화면에서는 flex 를 버리고 **두 칸 격자**로 세운다 —
 * 셀렉트는 한 줄씩 꽉, 기간은 한 줄 안에서 반씩, 조회 버튼은 다시 한 줄 꽉.
 */
.ads .toolbar__range { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0; }
.ads .toolbar__range .input { min-width: 0; }
.ads .toolbar__tilde { flex: none; color: var(--text-3); font-size: 14px; }

/* 카드 밖에서 쓰는 줄(임시저장 탭) — 머리줄용 여백·테두리를 벗긴다. */
.ads .toolbar--bare { padding: 0 0 12px; border-bottom: 0; }

@media (max-width: 640px) {
  .ads .toolbar {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: 8px; padding: 14px 16px;
  }
  /* 상태·상품은 글자가 길어 한 줄을 다 쓴다. */
  .ads .toolbar > .select,
  .ads .toolbar > .btn,
  .ads .toolbar__range { grid-column: 1 / -1; }
  /*
   * `height:34px` 와 `min-height:38px` 가 부딪혀 실제로는 38px 이 되던 것을 못 박는다.
   * 손가락으로 누르는 화면이라 낮추지 않고 40px 로 맞춘다.
   */
  .ads .toolbar .input,
  .ads .toolbar .select {
    width: 100%; min-width: 0;
    height: 40px; min-height: 40px;
  }
  .ads .toolbar .btn { height: 40px; }
  .ads .toolbar--bare { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 0 0 12px; }
  .ads .toolbar--bare .btn { grid-column: auto; }
}

/* 쪽 번호가 좁은 화면에서 눌리지 않게. `ops.css` 에는 `flex-wrap` 이 없다. */
.ads .pagination { flex-wrap: wrap; }

/* ─────────────────────────────  주문 카드(모바일 목록)  ───────────────────────────── */
.ads-list { display: grid; gap: 10px; }
.ads-item {
  display: block; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1);
  transition: transform .14s var(--ease), box-shadow .18s var(--ease);
}
a.ads-item:hover { text-decoration: none; transform: translateY(-1px); box-shadow: var(--shadow-2); }
.ads-item__top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ads-item__title { flex: 1; min-width: 140px; font-size: 16px; font-weight: 700; letter-spacing: -.03em; }
a.ads-item__title { color: var(--text); }
a.ads-item__title:hover { color: var(--accent); text-decoration: none; }

/* 본문은 보조 정보가 아니라 **읽히는 값**이다. 흐릿한 회색 작은 글씨로 두지 않는다. */
.ads-item__meta { margin-top: 6px; font-size: 14px; color: var(--text); line-height: 22px; }
.ads-item__meta svg { width: 14px; height: 14px; vertical-align: -2px; color: var(--text-3); }

/*
 * 키워드 배지 — 몇 개를 걸었는지가 세지 않아도 보여야 한다.
 *
 * 이름이 `ads-item__kw` 인 이유: 예전엔 `.ads-kw` 였는데 접수 화면의 **추천 목록 컨테이너**가
 * 같은 이름을 쓰고 있었다. 이 규칙이 파일 뒤쪽이라 컨테이너를 덮어써 목록이 겹쳤다.
 * 배지는 `.ads-item` 카드 안의 것이므로 그 이름 아래로 넣어 전역 이름을 비운다.
 */
.ads-item__keywords { display: flex; gap: 4px; flex-wrap: wrap; margin: 6px 0; }
.ads-item__kw {
  display: inline-flex; align-items: center; height: 24px; padding: 0 10px;
  border-radius: var(--radius-full); border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text);
  font-size: 12px; font-weight: 600; letter-spacing: -.01em;
}
.ads-item__amount {
  font-size: 16px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* 진행률 — 승인 전에는 그리지 않는다(0% 막대는 "안 되고 있다" 로 읽힌다). */
.ads-item__progress { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.ads-item__progress .ads-progress { flex: 1; }
.ads-item__progress .small { flex-shrink: 0; font-size: 12px; color: var(--text-2); font-variant-numeric: tabular-nums; }

/* 관리 버튼 — 금액과 같은 줄, 좁으면 아래로 접힌다. */
.ads-item__foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border);
}
.ads-item__foot .spacer { flex: 1; }
.ads-item__actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* ─────────────────────────────  진행률  ───────────────────────────── */
.ads-progress { height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.ads-progress__bar { height: 100%; border-radius: 3px; background: var(--accent); transition: width .4s var(--ease); }

.ads-metrics { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 641px) { .ads-metrics { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.ads-metric { text-align: center; padding: 14px 8px; background: var(--surface-2); border-radius: var(--radius); }
.ads-metric__value { font-size: 20px; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.ads-metric__label { margin-top: 2px; font-size: 12px; color: var(--text-2); }

/* 정의 목록(주문 상세) */
.ads-dl { display: grid; gap: 0; }
.ads-dl > div {
  display: flex; gap: 12px; justify-content: space-between;
  padding: 10px 0; border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.ads-dl > div:last-child { border-bottom: 0; }
.ads-dl dt { color: var(--text-2); flex-shrink: 0; }
.ads-dl dd { text-align: right; font-weight: 550; word-break: break-all; }
.ads-dl dd.num { font-variant-numeric: tabular-nums; }

/* ─────────────────────────────  빈 상태  ───────────────────────────── */
.ads-empty { padding: 48px 20px; text-align: center; }
.ads-empty__icon {
  width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.ads-empty__icon svg { width: 24px; height: 24px; }
.ads-empty p { font-size: 14px; color: var(--text-2); }
.ads-empty .btn { margin-top: 16px; }

/* ─────────────────────────────  인증 화면(P-01 · P-02)  ───────────────────────────── */
.ads-auth {
  min-height: 100vh; min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 20px calc(24px + env(safe-area-inset-bottom));
  background: var(--bg);
}
.ads-auth__card {
  width: 100%; max-width: 380px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 22px; padding: 34px 26px;
  box-shadow: var(--shadow-3);
}
.ads-auth__brand { text-align: center; margin-bottom: 22px; }
.ads-auth__logo { max-height: 40px; max-width: 180px; object-fit: contain; }
.ads-auth__mark {
  width: 52px; height: 52px; margin: 0 auto; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; font-size: 20px; font-weight: 700;
}
.ads-auth__title { margin-top: 14px; font-size: 18px; font-weight: 700; letter-spacing: -.03em; }
.ads-auth__sub { margin-top: 4px; font-size: 14px; color: var(--text-2); line-height: 22px; }
.ads-auth .btn { height: 46px; font-size: 14px; }
.ads-auth__foot {
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border);
  text-align: center; font-size: 12px; color: var(--text-3); line-height: 20px;
}

/* 체크박스(약관) */
.ads-check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-2); cursor: pointer; }
.ads-check input { width: 17px; height: 17px; accent-color: var(--accent); }

.num { font-variant-numeric: tabular-nums; }

/* 폰에서는 토스트를 좌우로 편다. 바닥 여백은 홈 인디케이터 몫만(탭바는 2026-09-18 에 걷어냈다). */
body.ads .toast-stack {
  left: 16px; right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom));
}
body.ads .toast { min-width: 0; max-width: none; }
@media (min-width: 861px) {
  body.ads .toast-stack { left: auto; right: 20px; bottom: 20px; }
  body.ads .toast { min-width: 260px; max-width: 400px; }
}

/* 카드 제목 옆 아이콘 */
.card__head .card__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; margin-right: 8px; flex-shrink: 0;
  border-radius: 8px; background: var(--accent-soft); color: var(--accent);
}
.card__head .card__icon svg { width: 15px; height: 15px; }

/* ─────────────────────────────  내 플레이스 위젯  ─────────────────────────────
 * 네이버에서 읽어 온 값이라 "언제 기준인가" 가 항상 붙어야 한다.
 * 숫자만 크게 띄우면 점주는 그것이 실시간이라고 믿는다.
 */
.np-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.np-head__name { font-size: 16px; font-weight: 700; letter-spacing: -.03em; }
.np-head__cat { font-size: 12px; color: var(--text-3); }

.np-metrics {
  display: grid; gap: 8px; margin-top: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
/* 지표가 5칸이 되면서 고정 4열로는 마지막 칸만 혼자 남는다 — 폭에 맞춰 접히게 둔다. */
@media (min-width: 641px) { .np-metrics { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); } }

.np-metric {
  padding: 12px 12px; border-radius: var(--radius);
  background: var(--surface-2); border: 1px solid var(--border);
}
.np-metric__label {
  display: flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--text-2); font-weight: 600;
}
.np-metric__label svg { width: 13px; height: 13px; color: var(--text-3); }
.np-metric__value {
  margin-top: 6px; font-size: 20px; font-weight: 700; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.np-metric__diff { margin-top: 2px; font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text-3); }
.np-metric__diff.is-up { color: var(--success); font-weight: 620; }
.np-metric__diff.is-down { color: var(--danger); font-weight: 620; }
.np-metric--star .np-metric__value { color: var(--warning); }

/* 순위 목록 */
.np-ranks { display: grid; gap: 8px; margin-top: 16px; }
.np-rank {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--surface);
}
.np-rank__keyword { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; word-break: break-all; }

/* 광고 중인 키워드 표시 — 기본 키워드와 한 줄에 섞이므로 이게 없으면 왜 있는지 알 수 없다. */
.np-rank__tag {
  display: inline-block; margin-left: 4px; padding: 2px 6px; border-radius: 999px;
  background: var(--accent); color: #fff;
  font-size: 12px; font-weight: 700; line-height: 20px; vertical-align: 1px;
  word-break: keep-all;
}
.np-rank__badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 42px; height: 28px; padding: 0 8px; border-radius: 999px;
  font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--surface-2); color: var(--text-2);
}
/* 상위 3위는 눈에 띄게 — 광고가 실제로 먹히고 있다는 신호다. */
.np-rank__badge.is-top { background: var(--accent-soft); color: var(--accent); }
.np-rank__badge.is-out { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-3); font-weight: 550; }
.np-rank__diff { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 44px; text-align: right; }
.np-rank__diff.is-up { color: var(--success); }
.np-rank__diff.is-down { color: var(--danger); }
.np-rank__diff.is-same { color: var(--text-3); font-weight: 500; }
.np-rank.is-loading .np-rank__badge { opacity: .45; }

/* 갱신 시각 · 출처 */
.np-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
  font-size: 12px; color: var(--text-3);
}
.np-foot svg { width: 13px; height: 13px; }
.np-foot__spacer { flex: 1; }

/* 로딩 점 세 개 */
.np-dots::after {
  content: '·'; animation: npDots 1.2s steps(3, end) infinite;
}
@keyframes npDots {
  0% { content: '·'; } 33% { content: '··'; } 66% { content: '···'; }
}

/* ─────────────────────────────  내 플레이스 — 헤더·사진·경쟁사  ───────────────────────────── */

/* 매장 선택 탭. 매장이 둘 이상일 때만 그린다. */
.np-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.np-tab {
  padding: 6px 12px; border-radius: 999px; font-size: 12px; font-weight: 600;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
}
.np-tab:hover { text-decoration: none; border-color: var(--border-strong); color: var(--text); }
.np-tab.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 680; }

/* 업체 헤더 — 사진 한 장 + 이름·업종·주소·전화 */
.np-profile { display: flex; gap: 14px; align-items: flex-start; }
.np-profile__thumb {
  width: 78px; height: 78px; flex-shrink: 0; border-radius: var(--radius);
  object-fit: cover; background: var(--surface-2); border: 1px solid var(--border);
}
.np-profile__body { flex: 1; min-width: 0; }
.np-profile__title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.np-profile__name { font-size: 16px; font-weight: 700; letter-spacing: -.03em; }
.np-profile__meta { margin-top: 6px; font-size: 12px; color: var(--text-2); line-height: 20px; }
.np-profile__meta div { display: flex; align-items: flex-start; gap: 6px; }
.np-profile__meta svg { width: 13px; height: 13px; flex-shrink: 0; margin-top: 2px; color: var(--text-3); }

/* 사진 스트립 — 가로 스크롤. 세로로 쌓으면 위젯이 화면을 다 먹는다. */
.np-photos {
  display: flex; gap: 8px; margin-top: 14px;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.np-photos::-webkit-scrollbar { display: none; }
.np-photos img {
  width: 104px; height: 78px; flex-shrink: 0; border-radius: var(--radius);
  object-fit: cover; background: var(--surface-2); border: 1px solid var(--border);
}
.np-photos a { flex-shrink: 0; line-height: 0; }
.np-photos a:hover { text-decoration: none; }

/* ─────────────────  사진 · 클립  ─────────────────
 * 탭으로 갈라 두지 않는다 — 둘 다 "내 플레이스에 걸려 있는 그림" 이라 한 줄로 이어 붙인다.
 */
.np-media { margin-top: 14px; }
.np-media .np-photos { margin-top: 10px; }

/*
 * 가로 넘기기.
 *
 * 외부 스와이퍼 라이브러리를 붙이지 않는다(CDN 금지). 스크롤 스냅 + 좌우 버튼이면 같은 일을 한다.
 * 버튼은 넘칠 때만 JS 가 켠다 — 항상 보이면 더 있는 줄 알고 누르게 된다.
 */
.np-strip { position: relative; }
.np-strip .np-photos { scroll-snap-type: x proximity; scroll-behavior: smooth; }
.np-strip .np-photos > a { scroll-snap-align: start; }
.np-strip__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 28px; height: 28px; padding: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  font-family: inherit; font-size: 18px; line-height: 1; cursor: pointer;
  box-shadow: var(--shadow-2);
}
.np-strip__nav:hover { border-color: var(--accent); color: var(--accent); }
.np-strip__nav--prev { left: -6px; }
.np-strip__nav--next { right: -6px; }
.np-strip__nav[hidden] { display: none; }

/* 클립은 사진과 같은 스트립을 쓰되 재생 표시를 얹는다. 재생은 네이버에서 한다. */
.np-clip { position: relative; display: block; }
.np-clip__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .55); color: #fff; font-size: 12px; line-height: 1;
}
/* 사진과 같은 줄에 서므로 글자로 한 번 더 말해 준다 — 재생 버튼만으로는 놓친다. */
.np-clip__tag {
  position: absolute; left: 5px; top: 5px;
  padding: 2px 6px; border-radius: 999px;
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; line-height: 20px;
}
.np-clip__count {
  position: absolute; right: 5px; bottom: 5px;
  padding: 2px 6px; border-radius: 999px;
  background: rgba(0, 0, 0, .6); color: #fff; font-size: 12px; font-weight: 600;
}

/* 메뉴 — 이름·설명·가격 한 줄. 가격은 "변동"·"시가" 처럼 글자로 오기도 한다.
 * 대시보드에서는 메뉴 목록을 빼둔 상태다(수집·저장은 계속 한다). 다시 뿌릴 때를 위해 남겨 둔다. */
.np-menus { display: grid; gap: 8px; margin-top: 10px; max-height: 320px; overflow-y: auto; }
.np-menu {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--radius);
  background: var(--surface-2); border: 1px solid var(--border);
}
.np-menu img {
  width: 44px; height: 44px; flex-shrink: 0; border-radius: 8px;
  object-fit: cover; background: var(--surface); border: 1px solid var(--border);
}
.np-menu__body { flex: 1; min-width: 0; }
.np-menu__name { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; }
.np-menu__desc {
  margin-top: 2px; font-size: 12px; color: var(--text-3); line-height: 20px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-menu__price {
  flex-shrink: 0; font-size: 12px; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--text-2);
}

/* 업체 소개 한 줄 · 바로가기 링크 */
.np-intro { margin-top: 6px; font-size: 12px; color: var(--text-2); line-height: 20px; }
.np-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.np-links a { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; }
.np-links svg { width: 13px; height: 13px; }

/* 편의·시설·결제 — 원고를 쓸 때 실제로 쓰이는 재료라 라벨을 붙여 나눈다. */
.np-facts { display: grid; gap: 8px; margin-top: 14px; }
.np-fact { display: flex; align-items: flex-start; gap: 10px; }
.np-fact__label {
  width: 62px; flex-shrink: 0; padding-top: 2px;
  font-size: 12px; font-weight: 600; color: var(--text-3);
}
.np-fact__chips { display: flex; flex-wrap: wrap; gap: 4px; }
.np-chip {
  padding: 2px 8px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; color: var(--text-2);
}

/* 블로그 리뷰 — 제목과 링크만. 본문은 남의 글이라 뿌리지 않는다. */
.np-blog {
  display: block; padding: 8px 2px;
  border-bottom: 1px solid var(--border);
}
.np-blog:last-child { border-bottom: 0; }
.np-blog:hover { text-decoration: none; }
.np-blog__title {
  display: block; font-size: 12px; color: var(--text); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-blog:hover .np-blog__title { color: var(--accent); }
.np-blog__meta { display: block; margin-top: 2px; font-size: 12px; color: var(--text-3); }

/* 경쟁사 비교 막대 */
.np-versus { display: grid; gap: 16px; margin-top: 12px; }
.np-versus__title { display: flex; align-items: baseline; gap: 8px; font-size: 14px; font-weight: 600; }
.np-versus__title .dim { font-weight: 400; }
.np-bar { display: flex; align-items: center; gap: 10px; margin-top: 6px; font-size: 12px; }
.np-bar__label { width: 76px; flex-shrink: 0; color: var(--text-2); }
.np-bar__track { flex: 1; height: 10px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.np-bar__fill { height: 100%; border-radius: 999px; background: var(--border-strong); transition: width .5s var(--ease); }
.np-bar--mine .np-bar__fill { background: var(--accent); }
.np-bar--mine .np-bar__label { color: var(--text); font-weight: 620; }
.np-bar__value { width: 74px; flex-shrink: 0; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }

.np-verdict {
  display: flex; align-items: flex-start; gap: 8px; margin-top: 10px;
  padding: 10px 12px; border-radius: var(--radius);
  font-size: 12px; line-height: 20px;
}
.np-verdict svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; }
.np-verdict.is-good { background: var(--success-soft, rgba(22,163,74,.08)); color: var(--success); }
.np-verdict.is-bad { background: var(--danger-soft); color: #c9241a; }
.np-verdict b { font-weight: 700; }

/* 두 칸 배치 — 순위 / 경쟁사 */
.np-split { display: grid; gap: 16px; margin-top: 18px; }
@media (min-width: 861px) { .np-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.np-split__head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.np-split__head span:first-child { font-size: 14px; font-weight: 700; }

/* ─────────────────────────────  사진첩  ─────────────────────────────
 * 본사 관리 화면과 접수 선택 화면이 같은 마크업을 쓴다(page/partial/photo_album.php).
 */

/* 드롭존 — 폰에는 드래그가 없으므로 눌러도 파일 선택이 열린다. */
.ph-drop {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; margin-bottom: 12px;
  border: 1.5px dashed var(--border-strong); border-radius: var(--radius-lg);
  background: var(--surface-2); cursor: pointer;
  transition: border-color .16s var(--ease), background .16s var(--ease);
}
.ph-drop:hover, .ph-drop.is-over { border-color: var(--accent); background: var(--accent-soft); }
.ph-drop__icon {
  width: 38px; height: 38px; flex-shrink: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.ph-drop__icon svg { width: 18px; height: 18px; }
.ph-drop__text { display: grid; gap: 2px; font-size: 14px; }
.ph-drop__text .dim { font-size: 12px; }

/* 업로드 전 확인 패널 — 413 대신 사람이 읽을 수 있는 말을 보여 주는 유일한 장치다. */
.ph-plan {
  padding: 14px 16px; margin-bottom: 12px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface);
}
.ph-plan__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14px; }
.ph-plan__head .spacer { flex: 1; }
.ph-plan__note { margin-top: 6px; }

/* 선택바 */
.ph-selbar {
  position: sticky; top: 64px; z-index: 10;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; margin-bottom: 10px;
  border-radius: var(--radius-full);
  background: var(--accent-soft); color: var(--accent);
  font-size: 14px; font-weight: 600;
}
.ph-selbar .spacer { flex: 1; }
.ph-selbar__main { font-weight: 500; }

/*
 * 대표 이미지.
 *
 * 고른 사진에만 뜬다 — 안 고른 사진에 대표 버튼이 있으면 무엇이 나가는지 헷갈린다.
 * 지정된 한 장은 배지가 채워져 한눈에 구분된다.
 */
.ph-item__main {
  position: absolute; left: 6px; bottom: 34px; z-index: 2;
  display: none; padding: 2px 8px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .7); background: rgba(0, 0, 0, .55);
  color: #fff; font-family: inherit; font-size: 12px; font-weight: 700;
  line-height: 20px; cursor: pointer;
}
.ph-item.is-on .ph-item__main { display: inline-block; }
.ph-item.is-main .ph-item__main { display: inline-block; background: var(--accent); border-color: var(--accent); }
.ph-item.is-main { box-shadow: 0 0 0 2px var(--accent); }

.ph-album__empty { margin-bottom: 12px; }

/*
 * `[hidden]` 을 실제로 숨긴다.
 *
 * UA 기본 `[hidden]{display:none}` 은 **요소 선택자 규칙에 진다.** `.notice{display:flex}` 나
 * `.ph-selbar{display:flex}` 가 있으면 hidden 을 붙여도 그대로 보인다 —
 * 서버가 숨겨 보낸 것이 화면에 뜨는, 눈치채기 어려운 종류의 버그다.
 */
.ph-album [hidden] { display: none !important; }

/* ── 칸(소분류) ──────────────────────────────────────────
 * "원고에 쓸 사진" 한 덩어리만 보면 점주는 무엇을 몇 장 올려야 하는지 모른다.
 * 칸마다 이름·설명·최소 장수를 적어 두면 그 질문이 화면에서 끝난다.
 */
.ph-group + .ph-group {
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border);
}
.ph-group__head {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px;
}
.ph-group__title { flex: 1; min-width: 0; display: grid; gap: 2px; }
.ph-group__title strong { font-size: 14px; font-weight: 700; letter-spacing: -.03em; }
.ph-group__hint { font-size: 12px; color: var(--text-2); line-height: 20px; }

/* 개수는 **고른 장수** 다 — 100장 올려 두고 3장만 골랐는데 "채움" 이라고 하면 거짓말이 된다. */
.ph-group__count {
  flex-shrink: 0; padding: 2px 10px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; font-weight: 700; color: var(--text-2); white-space: nowrap;
}
/* 색은 뱃지(.badge--success/--warning)와 같은 조합을 쓴다 — 화면마다 다른 초록을 만들지 않는다. */
.ph-group__count.is-ok { background: var(--success-soft); border-color: transparent; color: #1d8a3a; }
.ph-group__count.is-short { background: var(--warning-soft); border-color: transparent; color: #a76500; }

.ph-group__note {
  display: flex; align-items: flex-start; gap: 6px;
  padding: 8px 10px; margin-bottom: 10px; border-radius: var(--radius);
  background: var(--accent-soft); color: var(--accent);
  font-size: 12px; line-height: 20px;
}
.ph-group__note svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; }

/* 카드 안의 분류 드롭다운 — 잘못 넣은 사진을 지웠다 다시 올리지 않아도 되게 한다. */
.ph-item__move {
  flex: 1; min-width: 0; max-width: 100%;
  border: 1px solid var(--border); border-radius: 6px; background: var(--surface-2);
  color: var(--text-2); font-family: inherit; font-size: 12px; line-height: 20px;
  padding: 2px 4px; cursor: pointer;
}
.ph-item__move:focus { outline: 2px solid var(--accent-soft); outline-offset: 1px; }

.ph-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.ph-item {
  position: relative; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
}
.ph-item img { display: block; width: 100%; height: 110px; object-fit: cover; }
.ph-item__bar {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; font-size: 12px; color: var(--text-2);
  background: var(--surface); border-top: 1px solid var(--border);
}
.ph-item__caption { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ph-item__del {
  border: 0; background: transparent; color: var(--text-3); cursor: pointer;
  /* 아이콘이 아니라 × 글자다 — line-height:0 이면 글자가 잘린다. */
  width: 18px; height: 18px; flex-shrink: 0; padding: 0; border-radius: 4px;
  font-size: 16px; line-height: 1; font-family: inherit;
}
.ph-item__del:hover { color: var(--danger); background: var(--danger-soft); }
.ph-item__badge {
  position: absolute; top: 6px; left: 6px;
  padding: 2px 6px; border-radius: 999px; font-size: 12px; font-weight: 700;
  background: rgba(0,0,0,.6); color: #fff;
}

/* 접수 화면의 사진 선택 */
.ph-pick { position: relative; cursor: pointer; }
.ph-pick input { position: absolute; opacity: 0; pointer-events: none; }
.ph-pick.is-on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.ph-pick__check {
  position: absolute; top: 6px; right: 6px;
  width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.85); border: 1px solid var(--border);
  color: transparent;
}
.ph-pick.is-on .ph-pick__check { background: var(--accent); border-color: var(--accent); color: #fff; }
.ph-pick__check svg { width: 13px; height: 13px; }

/* 본사 가이드 — 점주 화면에서는 읽기 전용 */
/*
 * 줄바꿈은 살리되 **템플릿 들여쓰기는 살리지 않는다.**
 *
 * 상자 자체에 `pre-wrap` 을 걸면 PHP 를 예쁘게 들여쓴 공백까지 화면에 나온다
 * (첫 줄 앞이 크게 비어 보였다). 본문만 `__body` 로 감싸 거기에만 건다.
 */
.guide-box {
  padding: 12px 14px; border-radius: var(--radius);
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 14px; line-height: 22px; color: var(--text-2);
  word-break: break-word;
}
.guide-box__body { white-space: pre-wrap; }
.guide-box + .guide-box { margin-top: 10px; }
.guide-box__head {
  display: flex; align-items: center; gap: 6px; margin-bottom: 6px;
  font-size: 12px; font-weight: 700; color: var(--text);
}
.guide-box__head svg { width: 14px; height: 14px; color: var(--text-3); }

/* ─────────────────────────────  경쟁사 목록  ─────────────────────────────
 * "경쟁사 평균"만 보여 주면 그 숫자가 어디서 왔는지 알 수 없다.
 * 평균에 실제로 들어간 업체를 **펼쳐서** 함께 둔다 —
 * 접어 두면 대부분 열어 보지 않고, 근거가 없는 숫자로 남는다.
 */
/*
 * 접히는 묶음 — 지금은 블로그 리뷰(감춰 둔 상태)만 쓴다.
 * 경쟁사 목록은 여기서 빠졌다. 근거가 되는 목록은 접지 않는다.
 */
.np-fold > summary {
  cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--text-2);
}
.np-fold > summary::-webkit-details-marker { display: none; }
.np-fold > summary:hover { color: var(--text); }
.np-fold > summary svg { width: 13px; height: 13px; transition: transform .18s var(--ease); }
.np-fold[open] > summary svg { transform: rotate(180deg); }

.np-rivals { margin-top: 12px; }
.np-rivals__head {
  display: flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--text-2);
}
.np-rivals__head svg { width: 13px; height: 13px; flex-shrink: 0; }
.np-rivals__list { margin-top: 4px; }

.np-rival {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 2px; font-size: 12px;
  border-bottom: 1px solid var(--border);
}
.np-rival:last-child { border-bottom: 0; }
.np-rival__rank {
  width: 24px; flex-shrink: 0; text-align: center;
  font-size: 12px; font-weight: 700; color: var(--text-3); font-variant-numeric: tabular-nums;
}
.np-rival__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-rival__num {
  flex-shrink: 0; font-size: 12px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* 기본 키워드 안내 배지 */
.np-fallback {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; color: var(--text-2); font-weight: 600;
}

/* 순위 항목을 누르면 그 키워드의 경쟁사 비교로 바뀐다. */
.np-rank { cursor: pointer; transition: border-color .15s var(--ease), background .15s var(--ease); }
.np-rank:hover { border-color: var(--border-strong); }
.np-rank.is-picked { border-color: var(--accent); background: var(--accent-soft); }
.np-rank.is-picked .np-rank__keyword { font-weight: 680; color: var(--accent); }
/* 비교할 자료가 없는 항목은 눌러도 바뀌지 않는다 — 눌리는 것처럼 보이지 않게. */
.np-rank.is-flat { cursor: default; }
.np-rank.is-flat:hover { border-color: var(--border); }

/* ═════════════════════  점주 홈 (/ads/main)  ═════════════════════
 *
 * 2026-09 개편분. 피그마 시안(node 135:335, 폭 616 = 584 + 좌우 16)의 수치를 그대로 옮겼다.
 *
 * 이름을 `hm-`(home) 으로 완전히 갈라 둔 이유가 있다 —
 * 옛 홈이 쓰던 `.ads-stat*` · `.np-*` 는 `/ads/main/legacy` 가 아직 쓰고 있어 손대면 안 되고,
 * 예전에 `.ads-kw` 를 두 컴포넌트가 나눠 쓰다 뒤 규칙이 앞을 덮어써 레이아웃이 겹쳐 깨진 적이 있다.
 *
 * 색은 되도록 ops.css 토큰을 쓴다(다크 모드가 저절로 따라온다).
 * 토큰과 정확히 맞아떨어진 것: `--text`(#1d1d1f) · `--text-2`(#6e6e73) ·
 * `--accent-soft`(#e8f2fe) · `--danger-soft`(#ffecea) · `--success-soft`(#e7f8ec).
 * 나머지 시안 고유색만 아래 스코프 변수로 둔다.
 */
/*
 * `.hm` 은 새 시안 화면들의 **공통 껍데기**다(홈 `/ads/main` · 이용안내 `/ads/guide`).
 * 폭·그림자·선 색·자간이 같은 시안에서 나온 값이라, 화면마다 따로 두면 조금씩 어긋난다.
 * 화면 고유의 것은 각자 접두어로 둔다 — 홈은 `.hm-*`, 이용안내는 `.gd-*`.
 */
.hm {
  /* 시안 본문 폭. `.ads-main` 은 980 이라 이 화면만 좁혀 가운데 세운다(2열은 만들지 않는다). */
  max-width: 584px; margin: 0 auto;
  /* 시안의 tracking 은 크기와 무관하게 전부 -3% 였다 — 요소마다 적지 않고 한 줄로 상속시킨다. */
  letter-spacing: -.03em;

  --hm-ink: #5f626b;          /* 표·목록 본문 회색(시안 고유) */
  --hm-dim: #92959d;          /* 더 흐린 보조 글자 */
  --hm-line: #ededf1;         /* 표 선 */
  --hm-bad: #c9241a;          /* 부족 */
  --hm-good: #16a34a;         /* 충분 */
  --hm-good-text: #3fcb63;    /* 초록 배지 안 글자(시안이 본문보다 밝게 썼다) */
  --hm-track: rgba(217, 217, 217, .7);

  /*
   * 순위 펼침의 **연출 시간표**. 목록 → 그래프 → 판정 → 조언이 이 값들로 이어진다.
   * JS(`playVerdict`)가 이 변수를 그대로 읽어 타이핑 속도를 맞추므로 **여기가 유일한 정답**이다.
   */
  --hm-step: 100ms;        /* 줄 하나가 다음 줄에 밀리는 간격(`--i` 에 곱한다) */
  --hm-bar-start: 520ms;   /* 목록이 다 나타난 뒤 막대가 자라기 시작할 때까지 */
  --hm-bar-run: 1500ms;    /* 막대가 다 자라는 데 걸리는 시간 = 판정 타이핑 시간 */
  --hm-advice-lead: 400ms; /* 조언이 그래프보다 얼마나 먼저 올라오는가 */
  /*
   * 카드 그림자 — 사방으로 퍼지는 옅은 **테넌트 포인트색** 기(2026-10-02 요청, AI 도우미 버튼 그림자처럼).
   *
   * 예전에는 시안 그대로 고정 파랑(rgba(22,119,255,.05))이라 붉은 브랜드에서도 카드가 파랗게 떴다.
   * `--accent` 는 레이아웃이 `<html style>` 에 테넌트 색으로 덮으므로 여기서 섞기만 하면 브랜드마다 따라간다.
   * 진하기는 예전 파랑과 비슷하게(8%) — 포인트색이 진한 브랜드에서도 카드가 물들어 보이지 않게.
   * `color-mix` 를 모르는 브라우저는 아래 `@supports` 를 건너뛰고 이 옅은 회색을 쓴다
   * (변수 안에서는 잘못된 값이 앞 선언으로 되돌아가지 않아 `@supports` 로 가른다).
   */
  --hm-shadow:
    0 4px 12px rgba(0, 0, 0, .04), 0 -4px 12px rgba(0, 0, 0, .04),
    4px 0 12px rgba(0, 0, 0, .04), -4px 0 12px rgba(0, 0, 0, .04);
}
@supports (color: color-mix(in srgb, red 50%, transparent)) {
  .hm {
    --hm-shadow-tint: color-mix(in srgb, var(--accent) 8%, transparent);
    --hm-shadow:
      0 4px 12px var(--hm-shadow-tint), 0 -4px 12px var(--hm-shadow-tint),
      4px 0 12px var(--hm-shadow-tint), -4px 0 12px var(--hm-shadow-tint);
  }
}

@media (prefers-color-scheme: dark) {
  .hm {
    --hm-ink: #a8abb3; --hm-dim: #8e8e93; --hm-line: #38383a;
    --hm-bad: #ff6b60; --hm-good: #4ade80; --hm-good-text: #4ade80;
    --hm-track: rgba(120, 120, 128, .4);
    --hm-shadow: var(--shadow-2);
  }
}

/*
 * `[hidden]` 을 실제로 숨긴다.
 * UA 기본 `[hidden]{display:none}` 은 **클래스 규칙에 진다.** 사진 넘김 버튼이 `display:flex` 라
 * 이 줄이 없으면 서버가 `hidden` 으로 내려도 그대로 보인다. 사진첩(`.ph-album`)이 한 번 걸렸던 자리다.
 */
.hm [hidden] { display: none !important; }

/* 인사 — 시안 28px Bold. 좁은 화면에서는 두 줄이 되지 않게 줄인다. */
.hm-greet {
  margin-bottom: 20px;
  font-size: clamp(24px, 5.6vw, 28px); font-weight: 700; line-height: 1.3; color: var(--text);
}

.hm-card {
  /* `relative` 는 설명 말풍선(`.hm-tip`)이 이 카드 안에서 떠 있기 위한 기준이다. */
  position: relative;
  margin-bottom: 16px; padding: 32px 24px;
  background: var(--surface); border-radius: var(--radius-sm); box-shadow: var(--hm-shadow);
}

/* 매장이 없거나 플레이스가 안 붙은 경우 — 이 화면은 전부 플레이스 자료라 보여 줄 것이 없다. */
.hm-empty { padding: 40px 24px; text-align: center; color: var(--text-2); font-size: 14px; line-height: 22px; }
.hm-empty svg { width: 28px; height: 28px; margin-bottom: 10px; color: var(--text-3); }

/* ── 매장 ─────────────────────────────────────────── */
.hm-store__name { display: inline-block; font-size: 24px; font-weight: 700; line-height: 32px; color: var(--text); }
a.hm-store__name:hover { color: var(--accent); text-decoration: none; }

.hm-store__meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; font-size: 16px; color: #424242; }
.hm-store__meta span + span::before { content: "·"; margin-right: 6px; color: #c9c9c9; }

.hm-store__rating { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 16px; color: #424242; }
.hm-store__ratingLabel { font-weight: 600; }

/*
 * 별점 — 회색 별 위에 노란 별을 겹치고 **위층을 점수 비율(`--score`)만큼만** 보여 준다.
 * 반 칸짜리 아이콘을 따로 만들 필요가 없고, 4.4 와 4.6 이 다르게 보인다.
 * 시안 크기: 별 17px 다섯 개(약 106px).
 */
.hm-stars { position: relative; display: inline-block; line-height: 0; }
.hm-stars__row { display: flex; gap: 1.4px; }
/* 시안 실측: 별 5개가 106px 안에 거의 붙어 선다(20px + 1.5px). 색은 노랑이 아니라 빨강 계열. */
.hm-stars__row svg { width: 20px; height: 20px; color: #ef4444; }
/* 못 채운 별은 **회색 채움이 아니라 외곽선만**이다 — 여기가 시안과 가장 달랐던 곳. */
.hm-stars__row:not(.hm-stars__row--on) svg { fill: none; stroke: currentColor; stroke-width: 1.6; }
.hm-stars__row--on {
  position: absolute; inset: 0;
  width: var(--score, 0%); overflow: hidden;
}
.hm-stars__row--on svg { flex-shrink: 0; fill: currentColor; stroke: none; }

@media (prefers-color-scheme: dark) { .hm-store__meta, .hm-store__rating { color: var(--text-2); } }

/* ── 사진 ─────────────────────────────────────────── */
.hm-photos { position: relative; margin-top: 16px; }
.hm-photos__track {
  display: flex; gap: 8px; overflow-x: auto;
  scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none;
}
.hm-photos__track::-webkit-scrollbar { display: none; }
/* 시안 210×210, radius 12, 어두운 바탕(사진이 뜨기 전에도 자리가 비어 보이지 않게). */
.hm-photo {
  flex: 0 0 auto; width: 210px; height: 210px; scroll-snap-align: start;
  border-radius: var(--radius); overflow: hidden; background: #020202;
}
.hm-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* 넘칠 때만 켠다(JS 가 폭을 잰다). 눌러도 안 움직이는 버튼을 두지 않는다. */
.hm-photos__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, .92);
  box-shadow: var(--shadow-2); color: var(--text-2); cursor: pointer;
}
.hm-photos__nav:hover { color: var(--text); }
.hm-photos__nav--prev { left: 4px; }
.hm-photos__nav--next { right: 4px; }
.hm-photos__nav svg { width: 20px; height: 20px; }
/* 아래를 가리키는 chevron 하나로 좌·우를 만든다(아이콘을 늘리지 않는다). */
.hm-photos__nav--prev svg { transform: rotate(90deg); }
.hm-photos__nav--next svg { transform: rotate(-90deg); }

/* ── 리뷰 현황 ────────────────────────────────────── */
.hm-panel { margin-top: 24px; padding: 16px; background: #f7f7f7; border-radius: var(--radius-sm); }
.hm-panel__title { font-size: 20px; font-weight: 700; line-height: 28px; color: var(--text); }

@media (prefers-color-scheme: dark) { .hm-panel { background: var(--surface-2); } }

.hm-reviews { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.hm-review {
  display: flex; flex-direction: column; align-items: center;
  min-height: 128px; padding: 18px 8px 8px; text-align: center;
  background: var(--surface); border-radius: var(--radius-sm);
  box-shadow: 0 4px 12px rgba(0, 0, 0, .03), 0 -4px 12px rgba(0, 0, 0, .03),
              4px 0 12px rgba(0, 0, 0, .03), -4px 0 12px rgba(0, 0, 0, .03);
}
.hm-review__label {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  font-size: 14px; font-weight: 600; color: var(--text-2);
}
.hm-review__label svg { width: 18px; height: 18px; }
.hm-review__value {
  margin-top: 4px; font-size: 32px; font-weight: 700; line-height: 32px;
  color: var(--text); font-variant-numeric: tabular-nums;
}
/* 숫자 색이 곧 판단이다. 비교 자료가 없으면 색을 주지 않는다(중립). */
.hm-review.is-good .hm-review__value { color: var(--hm-good); }
.hm-review.is-bad .hm-review__value { color: var(--hm-bad); }
/* 판정 배지는 카드 바닥에 붙는다. */
.hm-review .hm-verdict { margin-top: auto; width: 100%; }

.hm-verdict {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 28px; padding: 4px 8px; border-radius: 4px;
  font-size: 14px; font-weight: 500; line-height: 22px;
}
.hm-verdict svg { width: 20px; height: 20px; flex-shrink: 0; }
.hm-verdict.is-good { background: var(--success-soft); color: var(--hm-good-text); }
.hm-verdict.is-bad { background: var(--danger-soft); color: var(--hm-bad); }
/*
 * 한 자씩 찍히는 문구.
 *
 * 글자가 늘어나는 동안 아이콘이 좌우로 밀리지 않게 **최종 길이만큼 자리를 미리 잡아 둔다**
 * (`--len` 은 JS 가 글자 수를 넣는다). 배지 자체는 폭이 고정이라 높이는 흔들리지 않는다.
 */
/*
 * `min()` 으로 상한을 둔다 — 자리를 잡아 두는 건 좋지만, 좁은 화면에서는 이 최소 너비가
 * 배지 → 비교 블록 → 순위 줄로 전파되어 **카드를 통째로 밀어낸다**(375px 에서 71px 넘쳤다).
 * 부모보다 넓어지지 않게 잘라 두면 자리 잡기와 폭 안전을 같이 얻는다.
 */
.hm-verdict__text {
  display: inline-block; text-align: left;
  min-width: min(calc(var(--len, 0) * 1ch), 100%);
}

/*
 * 재는 중 → 판정, 두 단계.
 *
 * 재는 동안에는 색을 주지 않는다(중립 회색) — 판정이 나오기 전에 초록/빨강이 보이면
 * 결과를 미리 알려 주는 셈이라 재는 시늉이 거짓말이 된다.
 * 스크립트가 없으면 `is-thinking` 이 아예 안 붙어 결론이 처음부터 보인다.
 */
.hm-verdict__think { display: none; align-items: center; gap: 2px; }
.hm-verdict.is-thinking { background: var(--surface-2); color: var(--hm-dim); }
.hm-verdict.is-thinking .hm-verdict__think { display: inline-flex; }
.hm-verdict.is-thinking > svg,
.hm-verdict.is-thinking .hm-verdict__text { display: none; }

/* 생각하는 점 셋. 순서대로 밝아진다. */
.hm-verdict__think i {
  width: 3px; height: 3px; margin-top: 6px; border-radius: 50%;
  background: currentColor; animation: hm-dots 1.1s var(--ease) infinite;
}
.hm-verdict__think i:nth-child(1) { margin-left: 4px; }
.hm-verdict__think i:nth-child(2) { animation-delay: .15s; }
.hm-verdict__think i:nth-child(3) { animation-delay: .3s; }
@keyframes hm-dots { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }

/* 판정이 나오는 순간 아이콘이 먼저 톡 뜨고, 글자가 이어서 찍힌다. */
.hm-verdict:not(.is-thinking) > svg { animation: hm-pop .32s var(--ease) both; }
@keyframes hm-pop {
  from { opacity: 0; transform: scale(.4); }
  60% { transform: scale(1.12); }
  to { opacity: 1; transform: none; }
}

/* ── 검색 순위 ────────────────────────────────────── */
.hm-ranks__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 24px;
}
.hm-ranks__title { display: flex; align-items: center; gap: 8px; }
.hm-ranks__tools { display: flex; align-items: center; gap: 12px; }
.hm-help {
  display: flex; width: 16px; height: 16px; padding: 0;
  border: 0; background: transparent; color: var(--hm-ink); cursor: pointer;
}
.hm-help svg { width: 16px; height: 16px; }
.hm-refresh {
  display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; padding: 0;
  border: 0; background: transparent; color: var(--hm-ink);
  font-family: inherit; font-size: 14px; font-weight: 500; letter-spacing: inherit; cursor: pointer;
}
.hm-refresh:hover { color: var(--text); }
.hm-refresh svg { width: 18px; height: 18px; }
/*
 * 처리 중 — 아이콘이 돈다. `ADS.withBusy()` 는 글자를 갈아 끼우느라 이 SVG 를 지워 버려서 안 쓴다.
 * 끝나면 클래스만 빠지고 아이콘은 그대로 남는다.
 */
.hm-refresh.is-busy { color: var(--accent); cursor: default; }
.hm-refresh.is-busy svg { animation: hm-spin .9s linear infinite; }
@keyframes hm-spin { to { transform: rotate(360deg); } }
.hm-when { font-size: 14px; color: var(--hm-dim); font-variant-numeric: tabular-nums; }
.hm-note { margin-bottom: 16px; font-size: 14px; color: var(--hm-dim); line-height: 22px; }

.hm-rank-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
/* `더보기` 전까지 감춰 두는 줄. 홈이 순위 목록만으로 길어지지 않게. */
.hm-rank.is-folded { display: none; }

/*
 * `min-width: 0` 사슬.
 *
 * grid·flex 자식은 기본이 `min-width: auto` 라 **안쪽에서 제일 긴 것만큼 늘어난다.**
 * 판정 배지 하나가 넓으면 그것이 비교 블록 → 패널 → 줄 → 목록으로 전파되어
 * 좁은 화면에서 카드 밖으로 밀려 나간다(375px 에서 71px 넘쳤다). 각 단계에서 끊는다.
 */
.hm-rank, .hm-rank__box, .hm-rank__row, .hm-rank__panel,
.hm-versus, .hm-verdict, .hm-rivals, .hm-rival,
.hm-advice, .hm-advice__steps, .hm-advice__step, .hm-advice__body { min-width: 0; }

/* 줄 하나가 곧 테두리 상자다. 펼치면 그 상자가 그대로 커지며 내용을 감싼다. */
.hm-rank__box {
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); overflow: hidden;
  background: var(--surface); transition: border-color .18s var(--ease);
}
.hm-rank.is-open .hm-rank__box { border-color: rgba(0, 113, 227, .4); }

/*
 * 접힌 줄은 **표의 한 행**이다 — 키워드 / 순위 / 변동 / 펼침.
 * 칸 폭을 고정해야 줄마다 순위 숫자가 같은 세로선에 선다(시안 280 / 128 / 96 / 32).
 */
.hm-rank__row {
  display: grid; grid-template-columns: minmax(0, 1fr) 128px 96px 32px;
  align-items: center; width: 100%; min-height: 48px; padding: 0;
  border: 0; background: transparent; text-align: left;
  font-family: inherit; color: inherit; cursor: pointer;
}
/* 비교 자료가 없는 줄은 펼칠 것이 없다 — 눌리는 것처럼 보이지 않게 한다. */
.hm-rank__row[disabled] { cursor: default; }
.hm-rank.is-open .hm-rank__row { background: var(--accent-soft); }

.hm-rank__cell { display: flex; align-items: center; min-width: 0; }
.hm-rank__cell--kw { gap: 8px; padding: 0 8px 0 18px; }
.hm-rank__cell--rank { justify-content: center; }
.hm-rank__cell--diff { justify-content: center; gap: 4px; }
.hm-rank__cell--chev { justify-content: center; color: var(--hm-ink); }
.hm-rank__cell--chev svg { width: 20px; height: 20px; transition: transform .18s var(--ease); }
.hm-rank.is-open .hm-rank__cell--chev svg { transform: rotate(180deg); }

.hm-rank__kw {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16px; font-weight: 600; color: var(--hm-ink);
}
/* 광고 배지는 시안대로 **채운 알약**이다. 테넌트 포인트 컬러를 따른다. */
.hm-rank__ad {
  flex-shrink: 0; padding: 4px 12px; border-radius: var(--radius-full);
  background: var(--accent); color: #fff; font-size: 16px; font-weight: 600; line-height: 24px;
}
.hm-rank__badge { font-size: 16px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
/* 순위를 못 잡았거나 재는 중 — 숫자가 아니므로 강조하지 않는다. */
.hm-rank__badge.is-dim { font-size: 14px; font-weight: 600; color: var(--hm-dim); }
/*
 * 다시 재는 중. 줄 하나가 몇 초씩 걸리므로 **어디까지 왔는지가 보여야** 기다릴 수 있다.
 * 배지는 깜박이고 줄 전체에 옅은 빛이 지나간다.
 */
.hm-rank.is-loading .hm-rank__badge { animation: hm-blink 1.1s var(--ease) infinite; }
.hm-rank.is-loading .hm-rank__box { position: relative; overflow: hidden; }
.hm-rank.is-loading .hm-rank__box::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--accent-soft), transparent);
  opacity: .7; animation: hm-sweep 1.3s var(--ease) infinite;
}
@keyframes hm-blink { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes hm-sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.hm-rank__diff { font-size: 14px; font-weight: 600; color: var(--hm-dim); font-variant-numeric: tabular-nums; }
.hm-rank__diff.is-up { color: var(--hm-good); }
.hm-rank__diff.is-down { color: #ef4444; }

/* ── 펼친 패널 ────────────────────────────────────── */
.hm-rank__panel { padding: 10px 20px 20px 18px; }

/*
 * 설명 말풍선 — 시안대로 **꼬리 없는 흰 카드가 위에 떠 있다**(328×90, 카드 가로 가운데, 위에서 66px).
 *
 * `absolute` 라 아래 목록을 밀어내지 않는다 — 열고 닫을 때 순위 줄들이 위아래로 출렁이지 않는다.
 * 흰 배경 위 흰 카드라 경계는 옅은 사방 그림자가 만든다(시안 값 그대로).
 */
/*
 * 가운데 정렬을 `transform` 이 아니라 `left/right/margin` 으로 한다 —
 * 등장 애니메이션이 `transform` 을 쓰기 때문에, 그걸로 가운데를 잡으면 애니메이션이 끝나는 순간
 * `transform: none` 이 덮어써서 말풍선이 오른쪽으로 밀린다.
 */
.hm-tip {
  position: absolute; top: 66px; left: 0; right: 0; margin: 0 auto; z-index: 5;
  width: 328px; max-width: calc(100% - 24px); min-height: 90px;
  display: flex; align-items: center;
  padding: 12px 44px 12px 12px;
  background: var(--surface); border-radius: var(--radius-sm);
  box-shadow: -4px 0 12px rgba(0, 0, 0, .03), 4px 0 12px rgba(0, 0, 0, .03),
              0 -4px 12px rgba(0, 0, 0, .03), 0 4px 12px rgba(0, 0, 0, .03);
  font-size: 14px; line-height: 22px; color: var(--hm-ink);
  /*
   * 페이드만 준다 — `transform` 을 쓰는 애니메이션이면 그 값이 위치 계산에 섞여,
   * 애니메이션이 늦게 도는 상황(백그라운드 탭 등)에서 말풍선이 어긋난 자리에 멈춘다.
   */
  animation: hm-fade .18s var(--ease) both;
}
@keyframes hm-fade { from { opacity: 0; } to { opacity: 1; } }
/* 어두운 배경에서는 그림자만으로 카드가 안 떠 보인다 — 그때만 선을 준다. */
@media (prefers-color-scheme: dark) { .hm-tip { border: 1px solid var(--hm-line); } }
.hm-tip p { margin: 0; }
.hm-tip__close {
  position: absolute; top: 12px; right: 12px;
  display: flex; width: 20px; height: 20px; padding: 0;
  border: 0; background: transparent; color: var(--hm-ink); cursor: pointer;
}
.hm-tip__close svg { width: 20px; height: 20px; }

.hm-rivals { margin: 0 0 12px; padding: 0; list-style: none; }
.hm-rival {
  display: flex; align-items: center; gap: 20px;
  min-height: 42px; padding: 10px 12px;
  border-bottom: 1px solid var(--hm-line); font-size: 14px; color: var(--hm-ink);
  /*
   * **1위부터 차례로 나타난다.** `--i` 는 뷰가 심은 등장 순서다.
   * 열 때마다 다시 재생되어야 하는데, `hidden` 이 풀리면(display 가 돌아오면)
   * CSS 애니메이션은 저절로 처음부터 다시 돈다 — JS 로 클래스를 붙였다 뗄 필요가 없다.
   */
  animation: hm-rise .8s var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--hm-step));
}
@keyframes hm-rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.hm-rival:last-child { border-bottom: 0; }
.hm-rival__rank { flex-shrink: 0; min-width: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.hm-rival__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hm-rival__num {
  flex-shrink: 0; margin-left: auto; font-size: 12px; color: rgba(95, 98, 107, .7);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/*
 * 내 매장 줄.
 *
 * 시안은 굵기만 바꾸는데, 열 곳이 비슷한 이름으로 늘어선 목록에서 굵기 하나로는 잘 안 잡힌다.
 * 몇 위인지 보러 온 화면이라 **이 줄이 먼저 눈에 들어와야** 해서 옅은 배경을 얹었다
 * (테넌트 포인트 컬러를 따라간다).
 */
.hm-rival.is-mine {
  border-bottom: 0; font-weight: 700;
  background: var(--accent-soft); border-radius: var(--radius-sm);
}
.hm-rival.is-mine .hm-rival__num { color: var(--hm-ink); font-weight: 500; }

@media (prefers-color-scheme: dark) { .hm-rival__num { color: var(--text-3); } }

/*
 * 비교 블록 — 판정 색을 아주 옅게(3%) 깐 카드.
 * 라벨 / 막대 / 숫자를 **격자로 고정**해야 두 줄의 막대가 같은 지점에서 시작한다.
 */
.hm-versus {
  padding: 10px 20px 20px 18px; border-radius: var(--radius-sm);
  /* 목록이 다 나타난 뒤 이어서 올라온다. */
  animation: hm-rise .8s var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--hm-step));
}
.hm-versus + .hm-versus { margin-top: 8px; }
.hm-versus.is-good { background: rgba(22, 163, 74, .03); border: 1px solid rgba(22, 163, 74, .03); }
.hm-versus.is-bad { background: rgba(201, 36, 26, .03); border: 1px solid rgba(201, 36, 26, .03); }
.hm-versus__title { font-size: 14px; font-weight: 700; line-height: 22px; color: var(--text); }

.hm-bar {
  display: grid; grid-template-columns: 78px minmax(0, 1fr) 78px;
  align-items: center; margin-top: 10px;
}
.hm-bar__label { font-size: 12px; font-weight: 500; color: var(--text); }
.hm-bar__track { height: 8px; border-radius: var(--radius-full); background: transparent; }
/*
 * 막대는 **왼쪽에서 자란다.**
 *
 * 폭(`width`)은 서버가 인라인으로 박아 둔 실제 비율이고, 애니메이션은 `scaleX` 로만 준다 —
 * 폭 자체를 0에서 키우면 두 막대의 최종 길이가 애니메이션 값에 얽혀 비교가 흔들린다.
 * 목록이 다 나타난 뒤(`--i`)에 이어서 자라 "순위 → 그래프" 순으로 읽히게 한다.
 */
.hm-bar__fill {
  display: block; height: 100%; border-radius: var(--radius-full); background: var(--hm-track);
  transform-origin: left center;
  animation: hm-grow var(--hm-bar-run) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--hm-step) + var(--hm-bar-start));
}
@keyframes hm-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* 내 막대 색이 판단을 따른다 — 앞서면 초록, 부족하면 빨강. */
.hm-versus.is-good .hm-bar--mine .hm-bar__fill { background: var(--hm-good); }
.hm-versus.is-bad .hm-bar--mine .hm-bar__fill { background: var(--hm-bad); }
.hm-bar__value {
  text-align: right; font-size: 12px; font-weight: 700;
  color: var(--text); font-variant-numeric: tabular-nums;
}

/* 판정 배지는 리뷰 현황 카드의 것과 **같은 모양**이다 — 같은 말을 하는 자리라 모양이 달라질 이유가 없다. */
.hm-versus .hm-verdict { margin-top: 12px; }

/* ── 조언 ─────────────────────────────────────────
 * 펼침의 마지막 자리. 위가 "지금 어떤 상태인가" 라면 여기는 "그래서 무엇을 하는가" 다.
 *
 * 비교 블록(3% 배경)보다 **한 단계 진하게** 깐다 — 같은 톤으로 두면 그래프의 연장으로 읽혀
 * 결론이라는 것이 드러나지 않는다. 대신 카드처럼 테두리를 두르지는 않는다(펼침 안이라 선이 겹친다).
 */
.hm-advice {
  margin-top: 12px; padding: 14px 16px 16px; border-radius: var(--radius-sm);
  background: var(--accent-soft);
  /*
   * 결론이라 그래프·판정이 끝날 즈음 올라온다.
   * `--hm-advice-lead` 만큼 겹치게 둔 것은, 완전히 끝난 뒤에 시작하면
   * 그 사이 화면이 한 번 멈춘 것처럼 보이기 때문이다.
   */
  animation: hm-rise .8s var(--ease) both;
  animation-delay: calc(
    var(--i, 0) * var(--hm-step) + var(--hm-bar-start) + var(--hm-bar-run) - var(--hm-advice-lead)
  );
}
/* 1위 칭찬은 판정 배지와 같은 초록을 쓴다 — 같은 뜻의 말이 색까지 같아야 한 몸으로 읽힌다. */
.hm-advice.is-praise { background: var(--success-soft); }

.hm-advice__head {
  display: flex; align-items: center; gap: 6px;
  font-size: 14px; font-weight: 700; line-height: 22px; color: var(--text);
}
.hm-advice__head svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--accent); }
.hm-advice.is-praise .hm-advice__head svg { color: var(--hm-good); }

.hm-advice__steps { margin: 0; padding: 0; list-style: none; }
.hm-advice__step { display: flex; gap: 10px; margin-top: 12px; }
/* 아이콘은 첫 줄 글자 높이(13.5px x 1.6 ≈ 21px)에 맞춰 살짝 내려 붙인다. */
.hm-advice__icon { flex-shrink: 0; padding-top: 2px; color: var(--accent); }
.hm-advice__icon svg { width: 18px; height: 18px; display: block; }

/* 조언은 두 줄 넘어가는 문장이라 본문 회색이 아니라 **본문색**으로 둔다 — 읽으라고 쓴 글이다. */
.hm-advice__body { min-width: 0; }
.hm-advice__text { margin: 0; font-size: 14px; line-height: 22px; color: var(--text); }

/*
 * 접수로 넘어가는 버튼.
 *
 * 화면 맨 아래 `.hm-cta` 처럼 꽉 찬 버튼으로 만들지 않는다 — 홈에서 제일 큰 버튼은 하나여야 하고,
 * 여기 것은 "이 키워드 때문에" 누르는 좁은 문이라 문장 바로 아래 인라인으로 붙는 편이 맞다.
 */
.hm-advice__cta {
  display: inline-flex; align-items: center; gap: 2px;
  margin-top: 8px; padding: 8px 10px 8px 12px; border: 0; border-radius: var(--radius-full);
  background: var(--accent); color: #fff;
  font-family: inherit; font-size: 14px; font-weight: 600; line-height: 22px;
  letter-spacing: inherit; text-decoration: none; cursor: pointer;
  transition: opacity .18s var(--ease);
}
.hm-advice__cta:hover { opacity: .88; text-decoration: none; color: #fff; }
/* 오른쪽을 가리키는 화살표가 없어 `chevron`(아래 방향)을 90도 돌려 쓴다. */
.hm-advice__cta svg { width: 15px; height: 15px; transform: rotate(-90deg); flex: none; }
/*
 * 글자가 **키워드를 품게 되면서**(2026-09-17 "{키워드} 순위 올리기") 길이가 들쭉날쭉해졌다.
 * 키워드는 최대 50자라 짧은 고정 문구 전제였던 이 알약이 카드 밖으로 넘칠 수 있다.
 * 넘치면 키워드 쪽만 줄이고 화살표는 끝에 남긴다 — 화살표가 밀려나면 버튼으로 안 보인다.
 */
.hm-advice__cta { max-width: 100%; }
.hm-advice__cta__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/*
 * 아직 못 파는 상품.
 *
 * **모양은 같고 색만 죽인다** — 자리가 달라지면 "이건 다른 종류의 버튼" 으로 읽히고,
 * 열리는 날 눈이 다시 적응해야 한다. 회색 = 지금은 안 되는 것.
 *
 * 눌리기는 눌린다(눌러야 이유를 말해 준다). 그래서 `cursor` 는 `pointer` 그대로다 —
 * `not-allowed` 로 두면 "눌러도 아무 일 없다" 는 뜻이 되어 안내 팝업을 안 열어 보게 된다.
 */
.hm-advice__cta.is-soon { background: var(--hm-track); color: var(--hm-dim); }
.hm-advice__cta.is-soon:hover { opacity: 1; background: var(--hm-line); color: var(--hm-ink); }

/* 안내 팝업의 동그란 아이콘 자리. 충전 화면의 세금 안내와 같은 모양이다. */
.hm-soon__icon {
  width: 56px; height: 56px; margin: 0 auto 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--hm-dim);
}
.hm-soon__icon svg { width: 26px; height: 26px; }

.hm-more {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; padding: 14px; margin-top: 8px;
  border: 0; background: transparent; color: var(--hm-ink);
  font-family: inherit; font-size: 14px; font-weight: 500; letter-spacing: inherit; cursor: pointer;
}
.hm-more:hover { color: var(--text); }
.hm-more svg { width: 16px; height: 16px; }

/* ── 다음 행동 ────────────────────────────────────── */
.hm-cta { height: 56px; margin-top: 8px; font-size: 16px; font-weight: 600; }

/*
 * 좁은 화면 — 시안은 616px 한 장뿐이라 그 아래는 여기서 정한다.
 * 순위 표의 고정 칸(128/96)이 그대로면 키워드가 몇 글자 못 보이므로 줄인다.
 */
/*
 * 좁은 화면 — 시안은 616px 한 장뿐이라 그 아래는 여기서 정한다.
 *
 * 두 단으로 줄인다. 641px 부터는 **여백과 큰 글자만** 줄이고,
 * 481px 부터는 **표의 고정 칸까지** 줄여 키워드에 폭을 몰아 준다.
 */
@media (max-width: 640px) {
  .hm-card { padding: 24px 20px; }
  .hm-greet { margin-bottom: 14px; }
  .hm-panel { padding: 14px 12px; }
  .hm-photo { width: 176px; height: 176px; }
  /* 말풍선은 화면을 넘지 않게 폭을 화면에 맞춘다(시안 328px 은 여기서 의미가 없다). */
  .hm-tip { top: 60px; width: auto; left: 12px; right: 12px; max-width: none; }
}

/*
 * 휴대폰.
 *
 * **글자는 줄이지 않는다.** 점주는 대부분 휴대폰으로 보는데 여기서 12px 로 깎으면
 * 정작 읽어야 할 사람이 못 읽는다. 대신 **자리를 만든다** —
 * 리뷰 카드를 세로로 떨어뜨리고, 순위 표의 고정 칸을 줄이고, 사진을 작게 한다.
 */
@media (max-width: 560px) {
  /* 두 칸으로는 32px 숫자와 판정 문구가 같이 안 들어간다. 과감히 한 칸씩. */
  .hm-reviews { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .hm-review { min-height: 0; padding: 16px 14px; }
  .hm-review__value { font-size: 34px; line-height: 38px; }
  .hm-review__label { font-size: 16px; }
  .hm-review__label svg { width: 19px; height: 19px; }

  .hm-panel__title { font-size: 18px; line-height: 26px; }
  .hm-store__name { font-size: 20px; }
  .hm-store__meta, .hm-store__rating { font-size: 16px; }

  /* 순위 표 — 글자는 그대로 두고 고정 칸만 좁힌다. */
  .hm-rank__row { grid-template-columns: minmax(0, 1fr) 62px 48px 26px; min-height: 52px; }
  .hm-rank__cell--kw { gap: 6px; padding-left: 14px; }
  .hm-rank__kw { font-size: 16px; }
  .hm-rank__badge { font-size: 16px; }
  .hm-rank__ad { padding: 2px 8px; font-size: 14px; }
  .hm-rank__diff { font-size: 14px; }
  .hm-rank__cell--chev svg { width: 18px; height: 18px; }

  .hm-rank__panel { padding: 10px 12px 14px; }
  .hm-rival { gap: 12px; padding: 10px 8px; font-size: 14px; }
  .hm-rival__num { font-size: 12px; }
  .hm-versus { padding: 12px 12px 16px; }
  .hm-bar { grid-template-columns: 66px minmax(0, 1fr) 60px; }
  .hm-bar__label, .hm-bar__value { font-size: 14px; }

  /* 조언도 글자는 그대로 두고 여백만 줄인다 — 여기가 제일 많이 읽히는 문장이다. */
  .hm-advice { padding: 12px 12px 14px; }
  .hm-advice__step { gap: 8px; }
  .hm-advice__text { font-size: 14px; }

  .hm-photo { width: 156px; height: 156px; }
  .hm-photos__nav { width: 36px; height: 36px; }

  .hm-verdict { font-size: 14px; min-height: 34px; }
  .hm-tip { font-size: 14px; line-height: 21px; min-height: 0; padding: 14px 42px 14px 14px; }
  .hm-ranks__head { gap: 8px; }
  .hm-refresh, .hm-when { font-size: 14px; }
  .hm-cta { height: 54px; font-size: 16px; }
}

/*
 * 아주 좁은 화면(구형 기기). 여기서만 어쩔 수 없이 몇 가지를 줄인다 —
 * 그래도 본문(순위·리뷰 수)은 14px 아래로 내리지 않는다.
 */
@media (max-width: 380px) {
  .hm-card { padding: 20px 16px; }
  .hm-greet { font-size: 20px; }
  .hm-store__name { font-size: 20px; }
  .hm-rank__row { grid-template-columns: minmax(0, 1fr) 56px 42px 24px; }
  .hm-rank__cell--kw { padding-left: 12px; }
  .hm-rank__ad { padding: 2px 6px; font-size: 12px; }
  .hm-bar { grid-template-columns: 58px minmax(0, 1fr) 54px; }
  .hm-rival { gap: 10px; padding: 10px 4px; }
  /* 버튼 글자가 두 줄로 접히면 알약 모양이 무너진다 — 좌우 여백부터 줄인다. */
  .hm-advice__cta { padding: 8px 8px 8px 10px; font-size: 12px; }
  .hm-photo { width: 140px; height: 140px; }
  .hm-tip { left: 8px; right: 8px; }
}

/* ═══════════════════════════════════════════════════════════════════════
 * 이용안내 (/ads/guide) — `.gd-*`
 *
 * 껍데기(584px 카드·그림자·토큰)는 새 홈의 `.hm` 을 그대로 쓴다.
 * 같은 시안에서 나온 같은 폭·같은 선 색이라 따로 만들면 둘이 조금씩 어긋난다.
 * 여기에는 이 화면에만 있는 것(소개 영상 · 아코디언 · 미디어 칸)만 둔다.
 * ═══════════════════════════════════════════════════════════════════════ */

/* 카드 안이 전부 미디어라 좌우 여백을 홈보다 좁게 잡는다(시안 24px). */
.gd-card { padding: 24px; }

/* ── 맨 위 소개 영상 ────────────────────────────────
 * 아코디언이 아니라 **늘 보이는 자리**다(시안 135:609의 맨 윗칸).
 * 규격은 아코디언 안쪽 영상과 같다 — 같은 영상을 두 자리에서 다르게 보여 줄 이유가 없다.
 */
.gd-hero {
  position: relative;
  display: flex; justify-content: center;
  margin-bottom: 32px;
  border-radius: var(--radius-sm); overflow: hidden;
}
.gd-hero + .gd-hero { margin-top: -16px; }
.gd-hero__frame {
  position: relative;
  width: min(var(--gd-video-width, 480px), 100%);
  aspect-ratio: var(--gd-video-ratio, 480 / 720);
}
.gd-hero__frame > * {
  display: block; width: 100%; height: 100%; object-fit: contain; background: #000;
}

/*
 * 재생 버튼(시안 135:613 — 50px).
 *
 * 포스터 위에 얹는다. 누르면 사라지고 영상이 끝나면 다시 나온다.
 * `pointer-events: none` 을 주지 않는다 — 이 버튼 자체가 누르는 대상이다.
 * 대신 버튼 밖(영상 몸통)은 기본 컨트롤이 그대로 받는다.
 */
.gd-hero__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 50px; height: 50px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .92); color: #1d1d1f;
  box-shadow: 0 2px 12px rgba(0, 0, 0, .28);
  transition: transform .18s var(--ease), background .18s var(--ease);
}
.gd-hero__play:hover { transform: translate(-50%, -50%) scale(1.06); background: #fff; }
/*
 * 버튼 하나가 두 모습을 한다 — `play`(아직 안 틀림) · `sound`(음소거로 도는 중).
 * 아이콘 둘을 다 그려 두고 여기서 하나만 보인다. 누를 때마다 마크업을 새로 만들면
 * 버튼이 잠깐 사라졌다 나타나 눌린 자리가 흔들린다.
 */
.gd-hero__ico { display: none; line-height: 0; }
.gd-hero__play[data-mode="play"] .gd-hero__ico--play,
.gd-hero__play[data-mode="sound"] .gd-hero__ico--sound { display: block; }

/* 삼각형은 **채워서** 쓴다(별점과 같은 규칙). 시각적 무게 중심이 왼쪽에 쏠려 2px 밀어 준다. */
.gd-hero__ico--play svg { width: 24px; height: 24px; margin-left: 2px; fill: currentColor; stroke: none; }
/* 스피커는 몸통만 채우고 음파는 선이다 — 채우면 덩어리로 뭉친다. */
.gd-hero__ico--sound svg { width: 22px; height: 22px; fill: none; }
.gd-hero__ico--sound svg path:first-child { fill: currentColor; }

.gd-hero [hidden] { display: none !important; }

/* ── 아코디언 ───────────────────────────────────── */
.gd-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }

/*
 * 항목 한 칸. 닫혀 있으면 흰 상자, 펼치면 테두리가 포인트 컬러로 바뀐다 —
 * 시안이 열린 항목에만 `rgba(0,113,227,.4)` 를 줬다. 테넌트 색을 따라가게
 * 고정 파랑 대신 `--accent` 를 흐리게 쓴다(`color-mix` 없이 되도록 opacity 대신 겹칩).
 */
.gd-item {
  min-width: 0; overflow: hidden;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  background: var(--surface);
}
.gd-item.is-open { border-color: var(--accent); }

.gd-item__head {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: 48px; padding: 12px 12px 12px 20px;
  border: 0; background: transparent; cursor: pointer;
  font-family: inherit; letter-spacing: inherit; text-align: left;
}
/* 펼친 항목의 머리는 옅은 포인트색 — 지금 무엇을 보고 있는지가 한눈에 잡힌다. */
.gd-item.is-open .gd-item__head { background: var(--accent-soft); }

.gd-item__title {
  flex: 1; min-width: 0;
  font-size: 18px; font-weight: 600; line-height: 26px; color: var(--hm-ink);
}
.gd-item.is-open .gd-item__title { color: var(--text); }

/* 펼치면 위를 가리킨다. 아이콘 하나를 돌려 쓴다(닫힘/열림 두 벌을 두지 않는다). */
.gd-item__chev {
  flex-shrink: 0; display: flex; color: var(--hm-ink);
  transition: transform .22s var(--ease);
}
.gd-item__chev svg { width: 20px; height: 20px; }
.gd-item.is-open .gd-item__chev { transform: rotate(180deg); color: var(--text); }

/* 내용이 아직 없는 항목 — 눌리기는 하되 제목을 흐리게 해 미리 알려 준다. */
.gd-item.is-empty .gd-item__title { color: var(--hm-dim); }

.gd-item__panel { padding: 16px; }
.gd-empty {
  margin: 0; padding: 24px 8px; text-align: center;
  font-size: 14px; line-height: 22px; color: var(--text-3);
}

/* 블록 사이 가로선(시안 135:638). 색은 표 선과 같다. */
.gd-rule { height: 0; margin: 24px 0; border: 0; border-top: 1px solid var(--hm-line); }

/*
 * 펼칠 때 **위에서부터 차례로 올라온다** — 홈의 순위 펼침과 같은 움직임이다.
 *
 * 같은 `hm-rise`·`--hm-step` 을 쓴다(`.gd` 가 `.hm` 안에 있어 변수가 그대로 상속된다).
 * 두 화면이 다른 속도로 움직이면 같은 앱이 아닌 것처럼 보인다.
 *
 * `hidden` 이 풀리면(display 가 돌아오면) CSS 애니메이션은 저절로 처음부터 다시 돈다 —
 * 열 때마다 JS 로 클래스를 붙였다 뗄 필요가 없다.
 */
.gd-item__panel > * {
  animation: hm-rise .55s var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--hm-step));
}

/* ── 미디어 칸 ─────────────────────────────────── */
.gd-media { overflow: hidden; border-radius: var(--radius-sm); }
.gd-media__img { display: block; width: 100%; height: auto; }

/*
 * 세로 영상.
 *
 * 어두운 바탕 가운데에 세워 둔다 — 가로로 늘리면 사람 얼굴이 잘린다.
 *
 * ## 원본 규격(480x720)에 자리를 맞춘다
 *
 * 폭도 비율도 원본 그대로다. 480px 로 두면 확대·축소 없이 1:1 로 그려져 가장 선명하고
 * (아코디언 안쪽 폭이 504px 이라 들어간다), 좁은 화면에서는 `min()` 이 화면에 맞춰 줄인다.
 *
 * **비율을 못 박는 것이 핵심이다.** 안 주면 `<video>` 는 메타데이터를 받기 전까지
 * 기본값 300x150 으로 그려져, 열자마자 납작한 검은 칸이 보이다가 재생 순간 껑충 늘어난다.
 *
 * 다른 규격의 영상이 들어와도 `contain` 이라 잘리지 않고 검은 여백만 남는다.
 * 규격이 바뀌면 아래 두 변수만 고치면 된다.
 */
.gd-media--video {
  --gd-video-width: 480px;
  --gd-video-ratio: 480 / 720;
  display: flex; justify-content: center;
  /*
   * 바깥 바탕은 투명이다. 시안은 영상이 칸보다 훨씬 좁아서 어두운 판이 필요했는데,
   * 원본 규격(480px)으로 맞춘 지금은 좌우에 12px 짜리 검은 띠만 남아 테두리처럼 보인다.
   * 검정은 영상 자체 배경에만 둔다(비율이 다른 영상의 레터박스용).
   */
}
.gd-media--video .gd-media__frame {
  width: min(var(--gd-video-width), 100%);
  aspect-ratio: var(--gd-video-ratio);
}
.gd-media--video .gd-media__img {
  width: 100%; height: 100%; object-fit: contain; background: #000;
}

/* 가로 그림은 바탕 위에 얹는다(시안 #f7f7f7). 여백 없이 꽉 찬 그림이라 배경은 로딩 중에만 보인다. */
.gd-media--image { background: #f7f7f7; }
@media (prefers-color-scheme: dark) { .gd-media--image { background: var(--surface-2); } }


/* ── 좁은 화면 ─────────────────────────────────── */
@media (max-width: 640px) {
  .gd-card { padding: 16px; }
  .gd-hero { margin-bottom: 20px; }
  .gd-item__head { padding: 12px 10px 12px 14px; gap: 8px; }
  .gd-item__title { font-size: 16px; }
  .gd-item__panel { padding: 12px; }
  .gd-rule { margin: 16px 0; }
}
@media (max-width: 380px) {
  .gd-item__title { font-size: 16px; }
  .gd-hero__play { width: 44px; height: 44px; }
  .gd-hero__play svg { width: 21px; height: 21px; }
}

/* 운영자가 에디터로 쓴 본문. 편집기(.ed__area)와 같은 리듬으로 보이게 맞춘다. */
.gd-text { padding: 4px 2px; font-size: 14px; line-height: 22px; color: var(--text); }
.gd-text > :first-child { margin-top: 0; }
.gd-text > :last-child { margin-bottom: 0; }
.gd-text p { margin: 0 0 12px; }
.gd-text h2, .gd-text h3, .gd-text h4 { margin: 20px 0 8px; font-weight: 700; line-height: 1.4; }
.gd-text h2 { font-size: 18px; }
.gd-text h3 { font-size: 16px; }
.gd-text h4 { font-size: 16px; }
.gd-text ul, .gd-text ol { margin: 0 0 12px; padding-left: 22px; }
.gd-text li { margin-bottom: 4px; }
.gd-text blockquote {
  margin: 0 0 12px; padding: 10px 14px;
  border-left: 3px solid var(--hm-line); color: var(--text-2);
}
.gd-text a { color: var(--accent); text-decoration: underline; }
.gd-text hr { height: 0; margin: 16px 0; border: 0; border-top: 1px solid var(--hm-line); }

/* ═══════════════════════════════════════════════════════════════════════
 * 내 주문 (/ads/orders) — `.ol-*`
 *
 * 껍데기(584px 카드·그림자·토큰)는 새 홈·이용안내의 `.hm` 을 그대로 쓴다.
 * 개편 전 목록(`/orders/legacy`)이 쓰는 `.ads-item*` 은 지우지 않는다.
 *
 * 카드의 색은 `ol-card--{tone}` 하나로 정해진다(accent·success·warning·danger·muted) —
 * 배지·현재 단계·안내 줄이 전부 `--ol-tone` 을 따라가므로 색이 서로 어긋날 수 없다.
 * ═══════════════════════════════════════════════════════════════════════ */

/*
 * ⚠️ 테넌트는 `--accent` **하나만** 덮는다(`<html style="--accent: …">`). `--accent-soft` 는 기본 연파랑이
 * 그대로 남아, 붉은 브랜드에서 **연파랑 바탕에 빨간 글자** 가 된다(2026-09-16 실측: bg #e8f2fe · 글자 #c0300c).
 * 그래서 바탕도 그 브랜드 색에서 뽑는다. 아래 줄을 못 읽는 브라우저는 윗줄(기존 토큰)로 조용히 물러난다.
 */
.ol-card--accent  { --ol-tone: var(--accent);   --ol-tone-soft: var(--accent-soft); }
.ol-card--accent  { --ol-tone-soft: color-mix(in srgb, var(--accent) 12%, var(--surface)); }
/*
 * 접수 완료는 **브랜드색을 쓰지 않는다**(2026-09-16, 위 수정을 실측한 뒤 결정).
 *
 * 바탕을 브랜드색에서 뽑고 나니 이번에는 **반려(빨강)와 같은 색**이 됐다 —
 * 접수 `#f8e6e2`/`#c0300c` vs 반려 `#ffecea`/`#c9241a`. 둘은 진행 중 탭에 나란히 놓인다.
 * 상태 색은 브랜드가 아니라 **뜻**이 정해야 하므로, 테넌트가 덮을 수 없는 고정 파랑을 여기 적는다
 * (값은 ops.css 의 기본 파랑과 같다 — `var(--accent)` 를 쓰면 테넌트 색으로 덮인다).
 */
.ol-card--info {
  --ol-tone: #0071e3;
  --ol-tone-soft: #e8f2fe;
}
@media (prefers-color-scheme: dark) {
  .ol-card--info { --ol-tone: #0a84ff; --ol-tone-soft: #0a273f; }
}
.ol-card--success { --ol-tone: var(--hm-good);  --ol-tone-soft: var(--success-soft); }
/* 주황 그대로는 옅은 바탕 위 글자로 읽기 어렵다. 밝은 모드만 한 톤 눌러 쓴다. */
.ol-card--warning { --ol-tone: #b86e00;         --ol-tone-soft: var(--warning-soft); }
.ol-card--danger  { --ol-tone: var(--hm-bad);   --ol-tone-soft: var(--danger-soft); }
.ol-card--muted   { --ol-tone: var(--hm-dim);   --ol-tone-soft: var(--surface-2); }
/*
 * 끝난 광고(완료·기간 종료·취소)와 임시저장은 **카드째 물러난다**(2026-09-16 요청).
 *
 * 배지만 회색으로 바꾸면 카드는 여전히 진행 중과 같은 무게로 서 있다 — 바탕과 그림자까지 눌러야
 * 목록을 훑을 때 "지금 신경 쓸 것" 과 "끝난 것" 이 갈린다.
 * ⚠️ 바탕을 회색으로 깔면 배지 바탕(`--ol-tone-soft` = 같은 회색)이 묻힌다 — 배지만 흰 바탕으로 되돌린다.
 */
.ol-card--muted {
  background: var(--surface-2);
  box-shadow: none;
  border: 1px solid var(--hm-line);
}
.ol-card--muted .ol-card__title,
.ol-card--muted .ol-card__sentence { color: var(--hm-ink); }
.ol-card--muted .ol-badge { background: var(--surface); }
@media (prefers-color-scheme: dark) { .ol-card--warning { --ol-tone: var(--warning); } }

/* ── 머리: 제목 + 접수 버튼 ── */
.ol-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.ol-head .hm-greet { flex: 1; min-width: 0; margin-bottom: 0; }
.ol-head__new { flex: none; }
.ol-head__new svg { width: 15px; height: 15px; }

/* ── 탭 + 기간 ── */
.ol-filter { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
/* 좁은 화면에서 줄바꿈하지 않고 옆으로 민다 — 탭이 두 줄이 되면 어느 줄이 먼저인지 헷갈린다. */
.ol-tabs {
  flex: 1; min-width: 0;
  display: flex; gap: 6px; padding: 2px;
  overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
}
.ol-tabs::-webkit-scrollbar { display: none; }
.ol-tab {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  height: 36px; padding: 0 14px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font-size: 14px; font-weight: 600; color: var(--hm-ink); white-space: nowrap;
  transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.ol-tab:hover { color: var(--text); text-decoration: none; }
.ol-tab.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.ol-tab__n { font-size: 12px; opacity: .75; font-variant-numeric: tabular-nums; }
/*
 * 기간 — 달력 아이콘 버튼 + 아래로 여는 레이어.
 * `__anchor` 는 직접 선택 달력(`datepicker.js`)이 자리를 재는 투명한 판이다. 클릭은 받지 않는다.
 */
.ol-period { position: relative; flex: none; }
.ol-period__btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 36px; padding: 0 12px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: inherit; white-space: nowrap;
  color: var(--hm-ink); cursor: pointer;
}
.ol-period__btn svg { width: 16px; height: 16px; }
.ol-period__btn[aria-expanded="true"],
.ol-period__btn.is-set { border-color: var(--accent); color: var(--accent); }
.ol-period__anchor { position: absolute; inset: 0; pointer-events: none; }
.ol-period__menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  display: grid; min-width: 180px; padding: 6px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  background: var(--surface); box-shadow: var(--shadow-3);
}
.ol-period__item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 10px 12px; border: 0; border-radius: 6px; background: transparent;
  font: inherit; font-size: 14px; letter-spacing: inherit; text-align: left; color: var(--text); cursor: pointer;
}
.ol-period__item:hover { background: var(--surface-2); text-decoration: none; }
.ol-period__item.is-on { font-weight: 700; color: var(--accent); }
.ol-period__item.is-on::after { content: "✓"; margin-left: auto; }
.ol-period__item svg { width: 16px; height: 16px; flex: none; color: var(--hm-dim); }
.ol-period__item.is-on svg { color: var(--accent); }

/*
 * 광고 종류 — 탭 **맨 앞**(2026-09-21). 기간 버튼과 같은 알약이고 레이어도 같은 부품(`.ol-period__menu`)을 쓴다.
 * 다른 점은 둘: 왼쪽 끝에 서므로 레이어를 **왼쪽**에 맞춰 연다, 그리고 탭과 구분되게 오른쪽에 세로선을 둔다.
 * 탭은 옆으로 밀리는(`overflow-x`) 줄이라 종류 버튼이 그 안에 들어가면 같이 밀려 사라진다 — 그래서 밖에 둔다.
 */
.ol-type { position: relative; flex: none; padding-right: 10px; border-right: 1px solid var(--hm-line); }
.ol-type__btn {
  display: inline-flex; align-items: center; gap: 4px;
  height: 36px; padding: 0 10px 0 12px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: inherit; white-space: nowrap;
  color: var(--text); cursor: pointer;
}
.ol-type__btn svg { width: 16px; height: 16px; flex: none; }
.ol-type__btn svg:last-child { width: 14px; height: 14px; color: var(--hm-dim); transition: transform .15s var(--ease); }
.ol-type__btn[aria-expanded="true"] svg:last-child { transform: rotate(180deg); }
.ol-type__btn[aria-expanded="true"],
.ol-type__btn.is-set { border-color: var(--accent); color: var(--accent); }
.ol-type__menu { left: 0; right: auto; min-width: 160px; }
/*
 * 폰에서는 **두 줄**로 나눈다 — 윗줄 [종류] … [기간], 아랫줄 탭 네 개.
 * 한 줄에 다 세우면 390px 에서 탭이 "진행 중 · 정지" 까지만 보이고 완료·임시저장이 옆으로 밀려 숨는다
 * (옆으로 밀 수 있다는 걸 사장님이 모르면 없는 탭이 된다). 종류는 여전히 탭보다 **먼저**(왼쪽 위) 온다.
 */
@media (max-width: 560px) {
  .ol-filter { flex-wrap: wrap; row-gap: 12px; }
  .ol-type { order: 1; padding-right: 0; border-right: 0; }
  .ol-period { order: 2; margin-left: auto; }
  .ol-tabs { order: 3; flex: 1 1 100%; }
}

.ol-ending { margin: -4px 0 14px; font-size: 14px; color: var(--hm-ink); }

/* ── 카드 ── */
.ol-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 12px; }
.ol-card {
  margin-bottom: 0; padding: 20px 20px 16px;
  animation: hm-rise .45s var(--ease) both;
  animation-delay: calc(var(--i, 0) * 50ms);
}

.ol-card__top { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.ol-card__title {
  flex: 1; min-width: 0;
  font-size: 18px; font-weight: 700; line-height: 26px; color: var(--text);
}
.ol-card__title:hover { color: var(--accent); text-decoration: none; }
.ol-card__store { flex: none; max-width: 40%; font-size: 14px; color: var(--hm-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ol-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: var(--radius-full);
  background: var(--ol-tone-soft); color: var(--ol-tone);
  font-size: 14px; font-weight: 700;
}
.ol-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.ol-card__sentence { margin: 8px 0 0; font-size: 16px; line-height: 24px; color: var(--text); }

.ol-card__note {
  display: flex; align-items: flex-start; gap: 6px;
  margin: 10px 0 0; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--warning-soft); font-size: 14px; line-height: 22px; color: var(--text);
}
.ol-card__note svg { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--warning); }

/*
 * 단계 띠.
 *
 * 칸마다 **앞 칸 가운데에서 내 가운데까지** 선을 긋는다(`::before`, left:-50%).
 * 선을 따로 한 줄로 깔면 점 개수가 바뀔 때 좌표를 다시 계산해야 한다.
 */
.ol-steps {
  /* 단계 수를 적지 않는다 — 5개에서 4개로 줄었을 때 여기만 남아 칸이 비었다. */
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  margin: 16px 0 2px; padding: 0; list-style: none;
}
.ol-step {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  font-size: 12px; text-align: center; color: var(--hm-dim);
}
.ol-step::before {
  content: ""; position: absolute; top: 11px; left: -50%;
  width: 100%; height: 2px; background: var(--hm-line);
}
.ol-step:first-child::before { display: none; }
.ol-step.is-done::before,
.ol-step.is-now::before { background: var(--ol-tone); }

.ol-step__dot {
  position: relative; z-index: 1;
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--hm-line); background: var(--surface);
  font-size: 12px; font-weight: 700; letter-spacing: 0; color: var(--hm-dim);
}
.ol-step__dot svg { width: 13px; height: 13px; stroke-width: 3; }
.ol-step.is-done .ol-step__dot { border-color: var(--ol-tone); background: var(--ol-tone); color: #fff; }
.ol-step.is-now .ol-step__dot { border-color: var(--ol-tone); color: var(--ol-tone); box-shadow: 0 0 0 4px var(--ol-tone-soft); }
.ol-step.is-now .ol-step__label { font-weight: 700; color: var(--text); }

/*
 * 지금 단계에서 **퍼져나가는 물결**(2026-09-14 요청).
 *
 * 점 안(`__dot` 의 가상요소)이 아니라 **칸(`li`)의 `::after`** 로 그린다. 점은 z-index 로 쌓임 맥락이라
 * 안쪽에 그리면 흰 점 속까지 색이 번진다. 칸에 점과 같은 크기·자리로 깔고 점(z-index 1) 아래에 둔다.
 * `::before` 는 단계 사이 선이 이미 쓰고 있다.
 *
 * 멈춘 광고(정지·정지됨 — 주의·위험 톤)는 움직이지 않는다. 물결이 뛰면 "진행 중" 으로 읽힌다.
 * 완료 카드는 모든 칸이 `is-done` 이라 `is-now` 가 없어 저절로 빠진다.
 */
.ol-step.is-now::after {
  content: ""; position: absolute; top: 0; left: 50%; z-index: 0;
  width: 24px; height: 24px; margin-left: -12px; border-radius: 50%;
  background: var(--ol-tone); opacity: 0; pointer-events: none;
  animation: ol-ripple 1.8s cubic-bezier(.2, .6, .35, 1) infinite;
}
.ol-card--warning .ol-step.is-now::after,
.ol-card--danger .ol-step.is-now::after { animation: none; }

@keyframes ol-ripple {
  0%   { transform: scale(1);   opacity: .42; }
  70%  { opacity: .08; }
  100% { transform: scale(2.6); opacity: 0; }
}


.ol-step__label { line-height: 1.3; word-break: keep-all; }

/* 진행 막대 — 공용 `.ads-progress` 를 쓰고 색만 카드 톤을 따른다. */
.ol-bar { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.ol-bar .ads-progress { flex: 1; }
.ol-bar .ads-progress__bar { background: var(--ol-tone); }
.ol-bar__n { flex: none; font-size: 14px; font-weight: 600; color: var(--hm-ink); font-variant-numeric: tabular-nums; }

.ol-kws { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.ol-kw {
  padding: 2px 10px; border: 1px solid var(--hm-line); border-radius: var(--radius-full);
  background: var(--surface-2); font-size: 12px; color: var(--hm-ink);
}
.ol-kw--more { color: var(--hm-dim); }

.ol-card__meta { margin: 12px 0 0; font-size: 14px; color: var(--hm-dim); font-variant-numeric: tabular-nums; }

/* ── 버튼 줄: **한 줄에 버튼 하나** ── */
.ol-card__foot { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--hm-line); }
.ol-card__primary { display: flex; width: 100%; align-items: center; justify-content: center; gap: 6px; }
.ol-card__primary:disabled { opacity: .55; cursor: default; }

/* 광고 기간 — 끝남 탭의 기준이라 카드에 늘 적는다. */
.ol-card__period { margin: 12px 0 0; font-size: 14px; color: var(--hm-ink); font-variant-numeric: tabular-nums; }
.ol-card__period b { font-weight: 700; color: var(--text); }

.ol-pages { margin-top: 20px; }

/* 반려 사유 — 카드 안에서 바로 읽힌다. 상세로 들어가야 보이면 "고치러 가기" 와 두 화면으로 갈라진다. */
.ol-reject {
  margin-top: 10px; padding: 10px 12px;
  border: 1px solid var(--ol-tone-soft); border-left: 3px solid var(--ol-tone); border-radius: var(--radius-sm);
  background: var(--ol-tone-soft);
}
.ol-reject__label { display: block; font-size: 12px; font-weight: 700; color: var(--ol-tone); }
.ol-reject__text { margin: 2px 0 0; font-size: 14px; line-height: 22px; color: var(--text); white-space: pre-line; }

.ol-card__primary svg { width: 15px; height: 15px; }

/*
 * 키워드 전부 + 순위. 칩이 곧 탭이고, 누르면 아래 패널이 그 키워드로 바뀐다.
 * 선·면의 색은 상세의 `.od-chart__*` 를 그대로 쓴다 — 블록에 `.od` 를 같이 달아 `--od-plot` 을 물려받는다.
 * 같은 데이터가 두 화면에서 다른 색이면 안 된다.
 */
.ol-rank {
  margin-top: 14px; padding: 12px 12px 10px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface-2);
}
.ol-rank__kws { display: flex; flex-wrap: wrap; gap: 6px; }
.ol-rank__tab {
  padding: 4px 10px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 12px; font-weight: 600; letter-spacing: inherit; color: var(--hm-ink); cursor: pointer;
}
.ol-rank__tab:hover { color: var(--text); }
.ol-rank__tab.is-on { border-color: var(--od-plot); background: var(--od-plot-soft); color: var(--text); }
.ol-rank__panel { margin-top: 10px; }
.ol-rank__nums { margin: 0; font-size: 12px; color: var(--hm-dim); font-variant-numeric: tabular-nums; }
.ol-rank__nums b { font-weight: 700; color: var(--text); }
.ol-rank__plot { display: block; margin-top: 6px; }
.ol-rank__plot svg { display: block; width: 100%; height: 72px; }
/* 늘어난 SVG 안의 점. 선 굵기가 곧 점 지름이다(`.od-chart__dot` 의 r=3 과 같은 크기). */
.ol-rank__dot {
  fill: none; stroke: var(--od-plot); stroke-width: 6;
  stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.ol-rank__empty { margin: 4px 0 0; font-size: 14px; line-height: 22px; color: var(--text-2); }

/* 접수 화면(.of) — 반려된 주문을 고쳐서 다시 접수하러 온 길의 안내. */
.of-rejected { margin-bottom: 16px; }
/* 접수 화면 안내 줄 오른쪽 버튼(임시저장 삭제). 목록 카드에서 옮겨 왔다. */
.of-notice__action { flex: none; margin-left: auto; align-self: center; }



@media (max-width: 640px) {
  .ol-card { padding: 16px 16px 14px; }
  .ol-card__title { font-size: 16px; }
  .ol-step { font-size: 12px; }
  /* 탭이 밀려도 달력 버튼은 한 줄에 남긴다 — 직접 선택한 날짜 글자만 줄인다. */
  .ol-period__btn span { max-width: 104px; overflow: hidden; text-overflow: ellipsis; }
}

/* ════════════════════════════════════════════════════════════════════════
   주문 상세 · 광고 효과(일별 순위)   `.od-*`
   ────────────────────────────────────────────────────────────────────────
   접두사를 새로 판 이유가 있다. `.hm-rank` 는 가로 한 줄짜리 목록 행이고
   이쪽은 세로 카드라 규칙이 다르다 — 예전에 `.ads-kw` 를 두 컴포넌트가 나눠 쓰다
   뒤 규칙이 앞을 덮어써 레이아웃이 겹쳐 깨졌다(위 305행 주석).
   ════════════════════════════════════════════════════════════════════════ */

.od {
  --od-line: #ededf1;
  --od-dim: #92959d;
  --od-plot: #34a853;             /* 순위 선. 초록은 "잘 되고 있다" 로 읽힌다 */
  --od-plot-soft: rgba(52, 168, 83, .13);
}
@media (prefers-color-scheme: dark) {
  .od { --od-line: #2c2c2e; --od-dim: #8e8e93; --od-plot-soft: rgba(52, 168, 83, .18); }
}

.od .card__head { display: flex; align-items: baseline; gap: 10px; }
.od__kw {
  font-size: 14px; color: var(--od-dim);
  padding: 2px 8px; border: 1px solid var(--od-line); border-radius: var(--radius-full);
}

/* ── 키워드 탭 ── */
.od-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.od-tab {
  padding: 4px 12px; font-size: 14px; color: var(--text-2);
  border: 1px solid var(--border); border-radius: var(--radius-full);
  background: var(--surface);
}
.od-tab:hover { border-color: var(--border-strong); text-decoration: none; }
.od-tab.is-on { background: var(--accent-soft); border-color: var(--accent-soft); color: var(--accent); font-weight: 600; }

/* ── 날짜 카드 스트립 ──
   시간은 **왼→오로 흐른다**. 시안은 카드가 최신→과거인데 그래프는 과거→최신이라
   한 화면에서 시간이 반대로 흐르는데, 그건 읽는 사람에게는 그냥 버그다.
   대신 좁은 화면에서 초기 스크롤을 오른쪽 끝(오늘)에 두어 "지금" 이 먼저 보이게 한다. */
.od-strip {
  display: flex; gap: 8px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
  scrollbar-width: thin;
}
.od-strip--ghost { opacity: .45; pointer-events: none; }

.od-day {
  flex: 0 0 auto; min-width: 84px;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 8px 10px;
  border: 1px solid var(--od-line); border-radius: var(--radius);
  background: var(--surface); scroll-snap-align: end;
}
.od-day.is-today { border-color: var(--accent); }
.od-day.is-missing { background: var(--surface-2); }
.od-day.is-missing .od-day__rank { color: var(--od-dim); font-weight: 500; }

.od-day__date { font-size: 12px; color: var(--od-dim); letter-spacing: -.2px; }
.od-day__rank { font-size: 20px; font-weight: 700; line-height: 28px; color: var(--text); }
.od-day__rank small { font-size: 12px; font-weight: 600; margin-left: 2px; }
.od-day__rank.is-out { font-size: 16px; color: var(--od-dim); }
.od-day__meta { font-size: 12px; color: var(--od-dim); line-height: 20px; min-height: 17px; }

/* ── 그래프 + 요약 ── */
.od-body { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; }

.od-chart { flex: 1 1 auto; min-width: 0; }
.od-chart__head { font-size: 14px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.od-chart__head span { font-weight: 400; color: var(--od-dim); margin-left: 4px; }
.od-chart__plot { position: relative; }

.od-chart__area { fill: var(--od-plot-soft); stroke: none; }
.od-chart__line {
  fill: none; stroke: var(--od-plot); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;   /* 가로로 늘어나도 선 굵기는 그대로 */
}
.od-chart__dot { fill: var(--od-plot); }

/* 축 라벨. **반전 축은 라벨 없이는 거짓말이다** — 1위가 위라는 걸 여기서만 말한다. */
.od-chart__axis { position: absolute; right: 2px; font-size: 12px; color: var(--od-dim); }
.od-chart__axis--top { top: 2px; }
.od-chart__axis--bottom { bottom: 2px; }

.od-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.od-sum {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 6px; border: 1px solid var(--od-line); border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.od-sum__label { font-size: 12px; color: var(--od-dim); }
.od-sum__value { font-size: 16px; font-weight: 700; color: var(--text); }
.od-sum__value.is-up { color: var(--success); }

.od-empty {
  margin: 14px 0 0; padding: 0 2px;
  font-size: 14px; line-height: 22px; color: var(--text-2);
}
.od-empty--tight { margin-top: 8px; }

@media (min-width: 640px) {
  /* 넓으면 그래프와 요약이 나란히 선다. 요약은 세로 한 줄이 된다. */
  .od-body { flex-direction: row; align-items: stretch; gap: 18px; }
  .od-summary { grid-template-columns: 1fr; align-content: start; min-width: 116px; }
}
@media (max-width: 380px) {
  .od-day { min-width: 76px; }
  .od-day__rank { font-size: 20px; }
}
.od-day__up { color: var(--success); font-weight: 700; margin-left: 2px; }

/* ════════════════════════════════════════════════════════════════════════
   주문 상세 (/ads/orders/{idx}) — `.odp-*`
   ────────────────────────────────────────────────────────────────────────
   내용은 예전 상세 그대로, 틀만 주문 목록과 같게(584px `.hm` · `.hm-card` · `.ol-*` 배지·단계 띠·버튼).
   광고 효과 블록은 `.od-*` 를 그대로 쓰고 카드 껍데기만 바꿨다.
   개편 전 상세(`/orders/{idx}/legacy`)가 쓰는 `.card`·`.ads-dl`·`.ads-metrics` 는 지우지 않는다.
   ════════════════════════════════════════════════════════════════════════ */

.odp-head { margin-bottom: 16px; }
.odp-head .hm-greet { margin-bottom: 4px; }
.odp-sub { margin: 0; font-size: 14px; color: var(--hm-dim); font-variant-numeric: tabular-nums; }

/* 섹션 사이 간격을 한 곳에서 준다 — 카드마다 margin 을 달면 마지막 카드 아래가 들쑥날쑥해진다. */
/*
 * `minmax(0, 1fr)` · `min-width: 0` 이 없으면 광고 효과의 날짜 스트립(가로 스크롤)이 **자기 내용 폭만큼**
 * 그리드 칸을 밀어 넓혀, 휴대폰에서 페이지 전체가 옆으로 밀렸다. 그리드 항목의 기본 최소 폭은 내용 폭이다.
 */
.odp-stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.odp-stack > * { min-width: 0; }
.odp-stack > .hm-card,
.odp-stack > .notice { margin: 0; }
.odp-card { padding: 20px; }

.odp-h {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  margin: 0 0 12px; font-size: 16px; font-weight: 700; color: var(--text);
}
.odp-h__n { font-size: 14px; font-weight: 600; color: var(--hm-dim); }
.odp-card .ol-card__primary { margin-top: 16px; }

/* ── 접수 내용 ── */
.odp-dl { margin: 0; }
.odp-dl__row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 10px 0; border-bottom: 1px solid var(--hm-line); font-size: 14px;
}
.odp-dl__row:first-child { padding-top: 0; }
.odp-dl__row:last-child { padding-bottom: 0; border-bottom: 0; }
.odp-dl dt { flex: none; color: var(--hm-ink); }
.odp-dl dd {
  margin: 0; min-width: 0; text-align: right;
  font-weight: 600; color: var(--text); overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
}
/* 긴 글(가이드·요청사항)과 키워드 칩은 라벨 아래로 내려 왼쪽 정렬 — 오른쪽 정렬 긴 글은 읽기 어렵다. */
.odp-dl__row--block { flex-direction: column; gap: 6px; }
.odp-dl__row--block dd { text-align: left; font-weight: 500; line-height: 1.6; white-space: pre-line; }
.odp-dl__row--block .ol-kws { margin-top: 0; }
/* 칩 칸은 글이 아니라 마크업이다 — `pre-line` 이면 템플릿 줄바꿈이 빈 줄로 그려진다. */
.odp-dl__row--block dd.odp-dl__chips { white-space: normal; }
.odp-dl__row--total dt,
.odp-dl__row--total dd { font-size: 16px; font-weight: 700; color: var(--text); }

/* ── 진행 현황 ── */
.odp-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.odp-metric {
  padding: 12px 8px; text-align: center;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface-2);
}
.odp-metric__value { display: block; font-size: 20px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.odp-metric__value--text { font-size: 16px; }
.odp-metric__label { display: block; margin-top: 2px; font-size: 12px; color: var(--hm-dim); }
.odp-bar { margin-top: 14px; }
.odp-hint { margin: 10px 0 0; font-size: 14px; line-height: 22px; color: var(--text-2); }

/* ── 광고 효과: 예전 카드 머리의 키워드 칩 자리 ── */
.odp-card.od .odp-h .od__kw { font-weight: 500; }

/* ── 포스팅 목록: 표 대신 한 건 한 줄 ── */
.odp-posts { margin: 0; padding: 0; list-style: none; }
/* 진행 현황 요약 칸 바로 밑에 붙는 포스팅 목록 — 제목 없이 구분선 하나로 가른다. */
.odp-posts--inline { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--hm-line); }
/* 요약 칸이 셋일 때(상태 칸을 뺐다). */
.odp-metrics--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.odp-post {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--hm-line);
}
.odp-post:first-child { padding-top: 0; }
.odp-post:last-child { padding-bottom: 0; border-bottom: 0; }
.odp-post__no {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border: 1px solid var(--hm-line); border-radius: 50%; background: var(--surface-2);
  font-size: 12px; font-weight: 700; letter-spacing: 0; color: var(--hm-ink);
}
.odp-post__body { flex: 1; min-width: 0; }
.odp-post__dates { font-size: 14px; color: var(--hm-ink); font-variant-numeric: tabular-nums; }
.odp-post__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px; font-size: 14px; }
.odp-post__meta a { display: inline-flex; align-items: center; gap: 2px; }
.odp-post__meta svg { width: 13px; height: 13px; }
.odp-post__action { flex: none; }
.odp-post__action svg { width: 14px; height: 14px; }

/* ── 버튼 줄: 목록의 "한 줄에 버튼 하나" 처럼 세로로 ── */
.odp-actions { display: grid; gap: 8px; }
.odp-actions .ol-card__primary { margin-top: 0; }
.odp-actions__badge { justify-self: center; padding: 6px 12px; }
/* 잠긴 정지 버튼 아래 "언제 누를 수 있나" 한 줄 · 정지된 광고 안내(2026-10-02). */
.odp-actions__note { margin: -2px 4px 4px; font-size: 13px; line-height: 20px; color: var(--hm-dim, var(--text-3)); text-align: center; }
.odp-actions__note a { color: var(--accent); font-weight: 600; }
.odp-actions .btn:disabled { opacity: .45; cursor: not-allowed; }

@media (max-width: 640px) {
  .odp-card { padding: 16px; }
}

/* ════════════════════════════════════════════════════════════════════════
   네이버 플레이스 진단 (/ads/diagnosis/**) — `.dg-*`
   ────────────────────────────────────────────────────────────────────────
   One Thing Per Page 앱형 화면. **모양은 우리 홈(`.hm-*`)을 그대로 쓴다**(2026-09-15 요청 —
   처음 만든 것이 참고 시안과 너무 비슷했다). 회색 바탕 · 반투명 흰 헤더 · 흰 카드 · 회색 패널 ·
   판정 배지 · 비교 막대 · 상위 목록 · 아래 큰 버튼 하나.
   여기에는 홈에 없는 것(메뉴 없는 헤더 · 단계 목록 · 키워드 칩 · 분석 체크리스트)만 둔다.
   ════════════════════════════════════════════════════════════════════════ */

/*
 * 진단 화면은 아래 여백을 `.dg-main` 이 따로 잡는다 — `body.ads` 의 여백(예전 탭바 64px, 지금은 홈 인디케이터 몫)을 뺀다.
 *
 * ⚠️ 선택자가 `body.dg-body` 인 이유 — `.dg-body` 한 클래스로는 **`body.ads` 를 못 이긴다**
 * (요소+클래스가 클래스 하나보다 강하다). 그래서 64px 이 그대로 남아 진단 화면이 늘 한 화면보다
 * 64px 길었다. 눈에 안 띄다가 시작 화면을 "한 화면에 맞추기" 로 바꾸면서 드러났다.
 */
body.dg-body { padding-bottom: 0; }

/*
 * ── 뒤로가기 줄 ──
 *
 * 헤더는 홈(`ads_layout.php`)과 **같은 것**을 쓴다(2026-09-16 요청). 뒤로가기는 그 안이 아니라 **아래 한 줄**이다 —
 * 헤더에는 이미 인사말이 있어 가운데 자리를 다투면 좁은 폰에서 잘리고, 바로 밑 큰 제목과 같은 말을 두 번 하게 된다.
 */
.dg-backbar {
  max-width: 584px; margin: 0 auto 4px; display: flex; align-items: center; gap: 8px;
}
.dg-back {
  display: inline-flex; align-items: center; gap: 2px; margin-left: -8px;
  padding: 6px 10px 6px 6px; border-radius: var(--radius-full);
  font-size: 14px; font-weight: 600; color: var(--hm-ink);
}
.dg-back:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.dg-back svg { width: 18px; height: 18px; }
.dg-backbar__title {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 14px; color: var(--hm-dim);
}

/* ── 본문: 화면마다 살짝 올라온다(페이지가 넘어간 느낌) ── */
/*
 * 가로만 자른다 — 화면 전환 애니메이션(옆에서 밀려 들어오기)이 끝난 뒤에도 문서 폭이 2px 넓게 남아
 * 손가락으로 옆으로 밀렸다. `clip` 은 스크롤 상자를 만들지 않아 안의 sticky(접수 진행 막대)가 그대로 붙는다.
 */
.dg-main { padding-top: 24px; padding-bottom: calc(32px + env(safe-area-inset-bottom)); overflow-x: clip; }
.dg { animation: hm-rise .5s var(--ease) both; }

/*
 * 시작 화면 — **화면을 세로로 꽉 채우고 버튼을 아래에 붙인다**(2026-09-16 요청).
 *
 * 빼는 값은 화면 틀이 이미 쓰는 자리다: 헤더 57(56 + 아래 테두리 1) + `.dg-main` 위 24 + 아래 32 = 113.
 * 남는 공간은 가운데 돋보기 상자가 `margin-block: auto` 로 나눠 가진다 — 제목은 위, 버튼은 아래,
 * 연출은 그 사이 한가운데. 내용이 길어지면 `min-height` 라서 그냥 늘어난다(잘리지 않는다).
 */
.dg-start {
  display: flex; flex-direction: column;
  min-height: calc(100vh - 113px);
  min-height: calc(100dvh - 113px - env(safe-area-inset-bottom));
}
/*
 * 남는 공간을 위·아래로 똑같이 나누면 연출이 화면 **한가운데**로 내려간다(2026-09-16 "조금 더 위로" 요청).
 * 위는 제목 바로 아래로 붙이고, 남는 공간은 전부 아래(버튼 위)로 보낸다.
 */
.dg-start .dg-lens { margin-top: 20px; margin-bottom: auto; }
/* 매장·플레이스가 없어 안내만 뜨는 경우에도 버튼은 아래에 선다. */
.dg-start .hm-empty { margin-bottom: auto; }
.dg .hm-greet em { font-style: normal; color: var(--accent); }
/*
 * 시작 화면 제목. 디자이너 요청은 28px 인데, 폰(390px)에서는 `7.4vw` 가 이미 약 29px 이라 거의 같은 값이다.
 * 그래서 **최소만 28px 로 올리고 최대 32px 은 남긴다** — 작은 폰(360px)에서 26px 로 작아지던 것이 28px 이 되고,
 * 큰 화면에서는 32px 그대로다. 완전히 고정하고 싶으면 `font-size: 28px` 한 줄로 바꾸면 된다.
 */
/*
 * 줄 간격 1.34 → **1.5**, 자간도 `.hm` 의 -3% 에서 -1% 로 푼다(2026-09-16 "글자 사이 여백" 요청).
 * 큰 글씨에서 -3% 는 글자끼리 붙어 읽기 힘들다 — 작은 본문에서는 단정해 보이던 값이다.
 * `keep-all` 은 한국어 단어가 줄 끝에서 쪼개지지 않게 한다.
 */
.dg-hero {
  margin-bottom: 16px;
  font-size: clamp(24px, 7.4vw, 28px); line-height: 1.3; letter-spacing: -.01em; word-break: keep-all;
}

/*
 * 제목 타이핑(2026-09-16 요청).
 *
 * `display` 가 아니라 **`visibility`** 다 — 글자 자리를 처음부터 차지해야 줄바꿈이 고정되고,
 * 타이핑 내내 아래의 돋보기·버튼이 출렁이지 않는다.
 * 스크립트가 없거나 실패하면 이 규칙도 안 걸리므로 제목은 그냥 다 보인다(연출은 덤이다).
 */
.dg-type__c { visibility: hidden; }
.dg-type__c.is-on,
.dg-hero.is-done .dg-type__c { visibility: visible; }
/* 커서는 `absolute` 라 글자 흐름에 끼어들지 않는다 — 인라인이면 줄바꿈 자리가 밀린다. */
.dg-type__c.is-cursor { position: relative; }
.dg-type__c.is-cursor::after {
  content: ""; position: absolute; left: 100%; top: .18em;
  width: 2px; height: .78em; margin-left: 2px; background: var(--accent);
  animation: dg-caret .7s steps(1) infinite;
}
@keyframes dg-caret { 50% { opacity: 0; } }

/*
 * 타이핑이 끝난 뒤 뒤따라 나타나는 덩어리(키워드 화면의 카드·버튼).
 *
 * **자리는 처음부터 잡혀 있다** — `opacity` 만 켠다. `display` 로 감췄다 켜면 그 순간 화면이 아래로 밀린다.
 * 스크립트가 안 돌면 이 클래스도 안 붙으므로 카드는 그냥 보인다.
 */
/*
 * `--i` 는 **등장 순번**이다. 주면 위에서부터 차례로 뜨고(시작 화면: 연출 → 버튼),
 * 안 주면 0 이라 한꺼번에 뜬다(키워드 화면: 카드 한 덩어리).
 */
.dg-fade { opacity: 0; transition: opacity .45s var(--ease); transition-delay: calc(var(--i, 0) * 160ms); }
.dg-fade.is-in { opacity: 1; }
/*
 * ⚠️ 등장 애니메이션(`hm-rise` 같은)이 걸린 요소는 **그 애니메이션이 opacity 를 덮어써** 타이핑 중에 먼저 보인다
 * (결과 화면 점수판이 실제로 그랬다). 클래스를 두 번 적어 특이도를 올려 둔다 —
 * 뒤에 오는 `.dg-scorecard { animation: hm-rise ... }` 를 이겨야 하기 때문이다.
 * 등장 연출은 여기서 opacity 하나로 통일한다.
 */
.dg-fade.dg-fade { animation: none; }


.dg-eyebrow {
  display: flex; align-items: center; gap: 6px;
  margin: 0 0 8px; font-size: 14px; font-weight: 700; color: var(--accent);
}
.dg-eyebrow svg { width: 16px; height: 16px; }
/* 실시간 점 — 분석 중이라는 표시. */
.dg-live {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent); animation: dg-live 1.4s var(--ease) infinite;
}
@keyframes dg-live { 0% { opacity: 1; } 50% { opacity: .35; } 100% { opacity: 1; } }

.dg-center { text-align: center; }
.dg-card-title { margin-bottom: 12px; }
.dg-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.dg-card-head .hm-panel__title { min-width: 0; }
.dg-panel-note { margin: 16px 0 14px; font-size: 14px; line-height: 22px; color: var(--hm-ink); }

/* 버튼 안 아이콘(홈 `.hm-cta` 에는 아이콘이 없어 여기서 붙인다). */
.dg .hm-cta { display: flex; align-items: center; justify-content: center; gap: 6px; }
.dg .hm-cta svg { width: 18px; height: 18px; }
.dg-link { display: block; margin: 14px 0 0; text-align: center; font-size: 14px; color: var(--hm-ink); text-decoration: underline; }
.dg-foot-note { margin: 20px 0 0; font-size: 12px; line-height: 20px; text-align: center; color: var(--hm-dim); }

/* ── 1. 시작: 돋보기가 검색 목록을 훑는 연출(2026-09-16 요청) ── */
/*
 * 높이를 고정 236px 에서 **화면에 맞춰 늘고 주는 값**으로 바꿨다(2026-09-16 "적정하게" 요청).
 * 작은 폰에서는 212px 로 줄어 제목·버튼이 밀리지 않고, 큰 화면에서는 280px 까지만 커진다.
 * 안쪽 줄도 같이 늘어나도록 격자를 네 줄로 나눠 채운다(그래서 줄 높이를 고정하지 않는다).
 */
.dg-lens {
  position: relative; height: clamp(212px, 34vh, 280px); margin: 4px 0 24px; overflow: hidden;
  border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--hm-shadow);
}
.dg-lens__list {
  position: absolute; inset: 7% 5%;
  display: grid; grid-template-rows: repeat(4, 1fr); gap: 4%;
}
.dg-lens__row {
  display: flex; align-items: center; gap: 10px; min-height: 0;
  padding: 0 12px; border-radius: 10px; background: var(--surface-2);
}
.dg-lens__rank { flex: none; width: 16px; font-size: 14px; font-weight: 700; color: var(--hm-dim); font-variant-numeric: tabular-nums; }
.dg-lens__bar { height: 8px; border-radius: 4px; background: var(--hm-track); }
.dg-lens__bar--name { flex: 1; max-width: 132px; }
.dg-lens__bar--meta { flex: none; width: 44px; opacity: .55; }
/* 내 가게 줄만 색이 있다 — 돋보기가 여기를 지날 때 무엇을 찾는 중인지 읽힌다. */
.dg-lens__row.is-mine { background: var(--accent-soft); }
.dg-lens__name {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 14px; font-weight: 700; color: var(--accent);
}
.dg-lens__tag {
  flex: none; padding: 2px 8px; border-radius: var(--radius-full);
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700;
}
/* 돋보기와 그 아래 비추는 자리는 **같은 키프레임**을 쓴다 — 따로 두면 조금씩 어긋난다. */
.dg-lens__spot,
.dg-lens__glass { position: absolute; top: 0; left: 0; animation: dg-scan 5.4s var(--ease) infinite; }
.dg-lens__spot {
  width: 132px; height: 132px; margin: -12px 0 0 -12px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 20%, transparent) 0%, transparent 68%);
}
.dg-lens__glass { width: 108px; height: 108px; }
.dg-lens__glass::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 5px solid var(--accent);
  background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .9), rgba(255, 255, 255, .35) 45%, rgba(255, 255, 255, .1));
  box-shadow: 0 10px 24px rgba(0, 0, 0, .12);
}
/* 손잡이. 원 밖 오른쪽 아래로 비스듬히 뻗는다. */
.dg-lens__glass::after {
  content: ""; position: absolute; right: -16px; bottom: -6px;
  width: 34px; height: 12px; border-radius: 6px; background: var(--accent); transform: rotate(42deg);
}
/*
 * 자리를 **비율(%)로** 잡는다. 예전에는 `translate(150px, 38px)` 처럼 픽셀이라, 상자 높이가 화면에 따라
 * 달라지면 돋보기가 목록 위쪽만 훑거나 아래로 삐져나갔다. `left`·`top` 은 상자 크기를 기준으로 한다.
 */
@keyframes dg-scan {
  0% { left: 6%; top: 6%; transform: rotate(-6deg); }
  25% { left: 40%; top: 17%; transform: rotate(3deg); }
  50% { left: 14%; top: 38%; transform: rotate(-3deg); }
  75% { left: 44%; top: 48%; transform: rotate(5deg); }
  100% { left: 6%; top: 6%; transform: rotate(-6deg); }
}

/* ── 2. 키워드 ── */
.dg-switch { margin-top: 10px; font-size: 14px; }
.dg-switch > summary { display: inline-block; list-style: none; color: var(--hm-ink); text-decoration: underline; cursor: pointer; }
.dg-switch > summary::-webkit-details-marker { display: none; }
.dg-switch__list { display: grid; gap: 6px; margin-top: 10px; }
.dg-switch__list a { padding: 10px 12px; border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); font-weight: 600; }

.dg-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.dg-chip {
  padding: 10px 16px; border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: inherit; color: var(--hm-ink); cursor: pointer;
  transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.dg-chip:hover { color: var(--text); }
.dg-chip.is-on { border-color: var(--accent); background: var(--accent); color: #fff; }

.dg-input-wrap {
  position: relative; display: block; margin-top: 12px;
}
.dg-input-wrap > svg {
  position: absolute; top: 50%; left: 16px; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--hm-dim); pointer-events: none;
}
.dg-input {
  width: 100%; height: 52px; padding: 0 16px 0 44px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 16px; letter-spacing: inherit; color: var(--text);
}
/*
 * 입력 글자는 **16px 아래로 내리지 않는다** — iOS 사파리가 그보다 작은 입력칸에 손대면 화면을 확대한다.
 * 대신 안내 문구만 한 단계(Body-3) 줄인다. 16px 로는 안내 문구가 폰에서 한 글자 잘렸다.
 */
.dg-input::placeholder { font-size: 14px; }
.dg-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* ── 3. 분석 중 ── */
.dg-progress { height: 6px; margin-bottom: 8px; border-radius: var(--radius-full); background: var(--hm-track); overflow: hidden; }
.dg-progress > span { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--accent); transition: width .5s var(--ease); }
/* 막대가 꽉 찬 뒤 **이동 직전**에만 뜬다. 초록은 체크리스트의 ✓ 와 같은 색이라 "다 됐다" 로 바로 읽힌다. */
.dg-progress__done {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 10px 0 0; font-size: 14px; font-weight: 700; color: var(--hm-good);
  animation: hm-pop .32s var(--ease) both;
}
.dg-progress__done[hidden] { display: none; }
.dg-progress__done svg { width: 16px; height: 16px; }

.dg-checks { margin: 0; padding: 0; list-style: none; }
.dg-check {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 4px; border-bottom: 1px solid var(--hm-line);
  font-size: 16px; line-height: 24px; color: var(--hm-dim); transition: color .3s var(--ease);
}
.dg-check:last-child { border-bottom: 0; padding-bottom: 0; }
.dg-check__icon {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border: 2px solid var(--hm-line); border-radius: 50%;
}
.dg-check__icon svg { display: none; width: 13px; height: 13px; stroke-width: 3; }
.dg-check.is-run { color: var(--text); font-weight: 600; }
.dg-check.is-run .dg-check__icon { border-top-color: var(--accent); animation: dg-spin .8s linear infinite; }
.dg-check.is-done { color: var(--text); }
.dg-check.is-done .dg-check__icon { border-color: var(--hm-good); background: var(--hm-good); color: #fff; animation: hm-pop .32s var(--ease) both; }
.dg-check.is-done .dg-check__icon svg { display: block; }
.dg-check.is-fail { color: var(--hm-ink); }
.dg-check.is-fail .dg-check__icon { border-color: var(--hm-bad); background: var(--danger-soft); }
.dg-check__text b { font-weight: 800; color: var(--accent); }
@keyframes dg-spin { to { transform: rotate(360deg); } }

/* ── 4. 결과 ── */
/* 홈 판정 배지는 좋음·부족 둘뿐이라 "보완" 톤(주황)을 여기서 더한다. */
.hm-review.is-fair .hm-review__value { color: #b86e00; }
.hm-verdict.is-fair { background: var(--warning-soft); color: #b86e00; }
@media (prefers-color-scheme: dark) {
  .hm-review.is-fair .hm-review__value,
  .hm-verdict.is-fair { color: var(--warning); }
}
.dg-unit { margin-left: 2px; font-size: 16px; font-weight: 700; }
.dg-summary { margin: 16px 0 0; font-size: 16px; line-height: 24px; color: var(--text); word-break: keep-all; }
.dg-summary b { color: var(--accent); }

/* ── 4. 결과: 포인트색 점수판(2026-09-15 "빈약하다" 요청) ── */
/*
 * 높이를 줄였다(2026-09-22 요청) — 게이지 124 → 96px, 점수 40 → 32px, 카드·타일 여백을 한 단계씩.
 * 폰 첫 화면에서 점수판이 반 가까이를 먹어 아래 매장 정보가 안 보였다.
 */
.dg-scorecard {
  margin-bottom: 16px; padding: 20px 20px 16px; border-radius: var(--radius-lg);
  background: var(--accent);
  background: linear-gradient(145deg, var(--accent) 0%, color-mix(in srgb, var(--accent) 58%, #000) 100%);
  box-shadow: 0 14px 32px color-mix(in srgb, var(--accent) 30%, transparent);
  color: #fff; overflow: hidden; position: relative;
  animation: hm-rise .5s var(--ease) both;
}
/* 판 오른쪽 위의 옅은 빛 — 평평한 색판이 아니라 떠 있는 판으로 보이게. */
.dg-scorecard::before {
  content: ""; position: absolute; top: -60px; right: -60px; width: 200px; height: 200px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .22), transparent 70%); pointer-events: none;
}
.dg-scorecard__top { position: relative; display: flex; align-items: center; gap: 16px; }

.dg-gauge { position: relative; flex: none; width: 96px; height: 96px; }
.dg-gauge svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.dg-gauge circle { fill: none; stroke-width: 10; }
.dg-gauge__track { stroke: rgba(255, 255, 255, .2); }
.dg-gauge__bar {
  stroke: #fff; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: calc(100 - var(--p) * 100);
  animation: dg-gauge 1.2s var(--ease) .15s both;
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, .55));
}
@keyframes dg-gauge { from { stroke-dashoffset: 100; } }
.dg-gauge__num {
  position: absolute; inset: 0; display: flex; align-items: baseline; justify-content: center; padding-top: 30px;
  font-size: 32px; font-weight: 800; line-height: 1; letter-spacing: -.04em; font-variant-numeric: tabular-nums;
}
.dg-gauge__num small { margin-left: 2px; font-size: 14px; font-weight: 700; opacity: .8; }

.dg-scorecard__text { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.dg-scorecard__label { display: inline-flex; align-items: center; gap: 4px; font-size: 14px; font-weight: 600; opacity: .85; }
.dg-scorecard__label svg { width: 14px; height: 14px; }
.dg-scorecard__verdict { font-size: 20px; font-weight: 700; line-height: 28px; word-break: keep-all; }
.dg-scorecard__sub { font-size: 12px; opacity: .7; }

.dg-tiles { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 14px; }
.dg-tile {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
  padding: 10px; border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .14); backdrop-filter: blur(4px);
  animation: hm-rise .5s var(--ease) both;
}
.dg-tile:nth-child(2) { animation-delay: .08s; }
.dg-tile:nth-child(3) { animation-delay: .16s; }
.dg-tile__label { font-size: 12px; opacity: .8; white-space: nowrap; }
.dg-tile__value { font-size: 20px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; }
.dg-tile__value small { margin-left: 2px; font-size: 14px; font-weight: 700; opacity: .8; }
.dg-tile__sub { font-size: 12px; font-weight: 600; opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dg-tile__sub.is-up { color: #b9f6ca; opacity: 1; }
.dg-tile__sub.is-down { color: #ffd6d2; opacity: 1; }

/* ── 4. 결과: 키워드 칩 → 그 말의 순위 펼침(2026-09-16 개편) ── */
/*
 * 칩은 키워드 화면과 **같은 것**(`.dg-chip.ov-chip`)이고, 펼침 내용은 홈의 순위 펼침과 같은 부품
 * (`.hm-rivals` · `.hm-versus` · `.hm-advice`)이다. 여기서는 **칩 안 순위 배지**와 펼침 상자만 정한다.
 */
.dg-chips .ov-chip__rank { color: inherit; }
.dg-panel { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--hm-line); }
.dg-panel[hidden] { display: none; }
.dg-panel__head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.dg-panel__kw { font-size: 18px; font-weight: 700; color: var(--text); word-break: keep-all; }
/* 전체 N곳은 배지 옆 보조 정보라 오른쪽으로 민다. */
.dg-panel__head .hm-when { margin-left: auto; }
/* 결과 아래 보조 버튼(접수로 가기). 앱형 접수의 보조 버튼과 같은 모양을 빌려 쓴다. */
.dg-order { margin-top: 10px; text-decoration: none; }
.dg-order:hover { text-decoration: none; }

/*
 * 순위 **자리 막대**(`.dg-ladder*`)는 걷어냈다(2026-09-16 개편 — "검색하면 몇 번째에 보일까요?" 섹션 삭제).
 * 순위는 이제 키워드 칩을 누르면 그 자리에서 바로 나온다. 쓰는 화면이 없는 규칙을 남겨 두면
 * 다음 사람이 "어디에 쓰이나" 를 먼저 찾게 된다.
 */



/* ════════════════════════════════════════════════════════════════════════
   앱형 광고 접수 (/ads/orders-ver/new) — `.ov-*`
   ────────────────────────────────────────────────────────────────────────
   진단과 같은 틀(`.dg-*` 헤더 · `.hm` 카드)에 한 장씩 넘기는 접수. 사장님이 누르기만 하면 되게
   누를 자리는 크게(카드 전체가 버튼), 글은 크게, 효과는 금액·고른 카드·완료에만 준다.
   ════════════════════════════════════════════════════════════════════════ */

.ov-step[hidden], .ov-sheet[hidden] { display: none; }
.ov-step { animation: ov-in .38s var(--ease) both; }
/*
 * 타이핑이 끝나기 전에는 그 장의 내용을 **누를 수 없다**(2026-09-16).
 * `opacity: 0` 은 안 보일 뿐 그대로 눌린다 — 안 보이는 [다음] 이나 [결제하기] 가 눌리면 안 된다.
 * 진단 화면에는 걸지 않는다(`.ov` 안에서만) — 거기는 카드 한 장이라 오눌림이 없다.
 */
.ov .dg-fade:not(.is-in) { pointer-events: none; }
@keyframes ov-in { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
.ov-center { text-align: center; }
body.ov-lock { overflow: hidden; }

.ov-progress {
  position: sticky; top: calc(env(safe-area-inset-top, 0px) + 56px); z-index: 5;
  height: 4px; margin: -16px 0 20px; border-radius: var(--radius-full); background: var(--hm-track); overflow: hidden;
}
.ov-progress > span { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--accent); transition: width .45s var(--ease); }
/*
 * 위에 '이전' 줄이 생기면 끌어올리지 않는다(2026-09-16).
 * `-16px` 는 옛 머리말 바로 밑에 띠를 붙이려던 값이다. `.dg-backbar` 가 앞에 오면 이 음수 여백이
 * **감싼 상자 밖으로 새어 나가**(여백 상쇄) 카드 전체를 12px 끌어올려 띠가 '이전' 글자를 가로지른다.
 * 띠는 `.dg-backbar` 의 형제가 아니라 **형제 안쪽**에 있다 — `~ .ov-progress` 로는 안 걸린다.
 */
.dg-backbar ~ .ov-progress,
.dg-backbar ~ * .ov-progress { margin-top: 0; }
.ov-count { margin: 0 0 6px; font-size: 14px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }

.ov-cta { display: flex; align-items: center; justify-content: center; gap: 6px; height: 60px; font-size: 18px; font-weight: 700; }
.ov-cta svg { width: 20px; height: 20px; }
.ov-cta:disabled { opacity: .4; }
.ov-linkbtn { width: 100%; padding: 8px; border: 0; background: none; font: inherit; font-size: 16px; letter-spacing: inherit; cursor: pointer; }

/* 눌렀을 때 살짝 튀어오른다 — "골라졌다" 가 손끝에 느껴지게. */
.is-bump { animation: ov-bump .36s var(--ease); }
@keyframes ov-bump { 0% { transform: scale(1); } 40% { transform: scale(1.04); } 100% { transform: scale(1); } }

/* 사진 레이어를 감싸는 `.of` — 색 변수만 빌리고 위 여백은 없앤다(모달은 fixed 라 자리를 차지하지 않는다). */
.of.ov-host { padding-top: 0; }

/* ── 1. 광고: 알림 · 캐시 한 줄 ── */
.ov-notice {
  display: flex; gap: 8px; margin-bottom: 16px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--danger-soft); font-size: 14px; line-height: 22px; color: var(--text);
}
.ov-notice svg { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--hm-bad); }
.ov-notice.is-info { background: var(--accent-soft); }
.ov-notice.is-info svg { color: var(--accent); }
.ov-cashline {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 16px; padding: 12px 16px; border-radius: var(--radius-sm);
  background: var(--surface); box-shadow: var(--hm-shadow); font-size: 16px; color: var(--hm-ink);
}
.ov-cashline b { font-size: 18px; color: var(--accent); font-variant-numeric: tabular-nums; }
.ov-cashline a {
  flex: none; padding: 6px 14px; border-radius: var(--radius-full); background: var(--accent);
  font-size: 14px; font-weight: 700; color: #fff;
}
.ov-cashline a:hover { text-decoration: none; }

.ov-rows { margin: 0; }
.ov-row { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--hm-line); font-size: 16px; line-height: 24px; }
.ov-row:last-child { border-bottom: 0; }
/* `매장 가이드` 가 한 줄에 들어가는 폭. */
.ov-row dt { flex: none; width: 84px; color: var(--hm-dim); white-space: nowrap; }
.ov-row dd { flex: 1; min-width: 0; margin: 0; font-weight: 700; color: var(--text); word-break: keep-all; }
.ov-row__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ov-mini { padding: 2px 10px; border-radius: var(--radius-full); background: var(--accent-soft); color: var(--accent); font-size: 14px; font-weight: 600; }
/* 결제 확인 요약에서 대표 키워드 하나만 채워 둔다 — 여러 말 중 무엇에 돈을 쓰는지가 한눈에 보인다. */
.ov-mini.is-main { background: var(--accent); color: #fff; }

.ov-total {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px;
  margin-top: 16px; padding: 18px 16px; border-radius: var(--radius-sm); background: var(--accent-soft);
}
.ov-total__label { font-size: 16px; font-weight: 600; color: var(--text); }
.ov-total__label small { display: block; font-size: 12px; font-weight: 400; color: var(--hm-dim); }
.ov-total__value {
  font-size: clamp(28px, 8vw, 34px); font-weight: 800; line-height: 1; color: var(--accent);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ov-wallet { margin: 12px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-ink); text-align: center; }
.ov-wallet.is-short { color: var(--hm-bad); font-weight: 600; }

/* ── 1. 광고 / 3. 묶음 — 카드 전체가 버튼 ── */
.ov-options, .ov-packs { display: grid; gap: 12px; margin-bottom: 16px; }
.ov-option, .ov-pack {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; width: 100%;
  padding: 20px 56px 20px 20px; border: 2px solid transparent; border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--hm-shadow);
  font: inherit; letter-spacing: inherit; text-align: left; color: var(--text); cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease), box-shadow .2s var(--ease);
}
.ov-pack { animation: hm-rise .45s var(--ease) both; animation-delay: calc(var(--i, 0) * 70ms); }
.ov-option.is-on, .ov-pack.is-on {
  border-color: var(--accent); background: color-mix(in srgb, var(--accent) 5%, var(--surface));
  box-shadow: 0 10px 24px color-mix(in srgb, var(--accent) 18%, transparent);
}
.ov-option.is-soon { opacity: .5; cursor: default; }
.ov-option__head, .ov-pack__head { display: flex; align-items: center; gap: 8px; font-size: 20px; }
.ov-option__desc, .ov-pack__note { font-size: 14px; line-height: 22px; color: var(--hm-ink); }
.ov-option__price { font-size: 16px; font-weight: 700; color: var(--accent); }
.ov-option__price small { font-weight: 400; color: var(--hm-dim); }
.ov-pack__spec { font-size: 16px; font-weight: 600; color: var(--text); }
.ov-pack__price { font-size: 16px; color: var(--hm-ink); }
.ov-pack__price b { font-size: 24px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.ov-tag { padding: 2px 8px; border-radius: var(--radius-full); background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; }
.ov-tag.is-soon { background: var(--hm-track); color: var(--hm-ink); }
.ov-option__check {
  position: absolute; top: 50%; right: 18px; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  border: 2px solid var(--hm-line); border-radius: 50%; color: #fff; transition: all .2s var(--ease);
}
.ov-option__check svg { width: 16px; height: 16px; stroke-width: 3; opacity: 0; }
.is-on > .ov-option__check { border-color: var(--accent); background: var(--accent); }
.is-on > .ov-option__check svg { opacity: 1; }

.ov-when { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 0 0 8px; font-size: 16px; font-weight: 600; color: var(--text); }
.ov-when svg { width: 18px; height: 18px; color: var(--accent); }

/* ── 2. 키워드 ── */
.ov-card { padding: 24px 20px; }
.ov-lead { margin-top: 0; font-size: 16px; }
.ov-lead b { color: var(--text); }
.ov-chip { display: inline-flex; align-items: center; gap: 6px; padding: 10px 12px; font-size: 14px; }
.ov-chip__check { display: none; }
.ov-chip__check svg { width: 15px; height: 15px; stroke-width: 3; }
.ov-chip.is-on .ov-chip__check { display: inline-flex; }
.ov-chip__rank { font-size: 12px; font-weight: 600; opacity: .7; }
/*
 * 칩 안 `대표` 배지(2026-09-17). 광고 배지(`.ov-chip__ad`)와 **같은 크기**로 둔다 —
 * 한 칩에 둘이 같이 설 수 있어 크기가 다르면 줄이 울퉁불퉁해진다.
 * 고른 칩(포인트색 바탕) 위에서도 읽히도록 흰 반투명으로 뒤집는다.
 */
.ov-chip__main {
  flex: none; padding: 2px 8px; border-radius: var(--radius-full);
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; line-height: 20px;
}
.ov-chip.is-on .ov-chip__main,
.dg-chip.is-on .ov-chip__main { background: rgba(255, 255, 255, .28); color: #fff; }

/*
 * 대표 키워드 **섹션**(2026-09-17). 칩 목록 안 한 줄이었던 것을 칸으로 올렸다 —
 * 대표는 고르는 것이 아니라 **이미 정해진 것**이라, 고르는 말들과 같은 무게로 읽히면 안 된다.
 */
.ov-mainkw { padding: 20px; }
.ov-mainkw__label {
  display: flex; align-items: center; gap: 6px;
  margin: 0 0 8px; font-size: 14px; font-weight: 700; color: var(--hm-dim);
}
.ov-mainkw__label svg { width: 15px; height: 15px; color: var(--accent); }
.ov-mainkw__value { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.03em; color: var(--accent); }
.ov-mainkw__note { margin: 8px 0 0; font-size: 14px; color: var(--hm-ink); }

/* AI 가 조합해 둔 말들의 머리. 고를 대상이라 접지 않고 늘 펼쳐 둔다. */
/*
 * 2/7 검색어 카드 구조(2026-09-17 요청):
 *   타이틀 → 고른 검색어 → 직접 쓰기 → [AI가 추천하는 검색어 보기](접힘)
 *
 * 추천을 접어 두는 이유: 고른 것이 위에 모여 있으니 긴 목록을 늘 펼쳐 둘 이유가 없다.
 * (한때 "고를 대상을 감추면 한 번 더 눌러야 한다" 며 펼쳐 뒀는데, 고른 것을 위로 올리면서 그 이유가 사라졌다.)
 */
.ov-lead--title { margin: 0 0 12px; font-size: 16px; font-weight: 700; line-height: 24px; color: var(--text); }

/* 고른 검색어 칸 — 조회칸 바로 밑(2026-09-18). 비면 통째로 숨는다 — 빈 상자는 자리만 먹는다(`hidden` 은 스크립트가 켠다). */
.ov-picked { margin-top: 14px; }

.ov-suggest { margin-top: 18px; }
.ov-suggest > summary {
  display: inline-flex; align-items: center; gap: 6px;
  list-style: none; cursor: pointer;
  font-size: 16px; font-weight: 700; color: var(--accent);
}
.ov-suggest > summary::-webkit-details-marker { display: none; }
.ov-suggest > summary svg { width: 16px; height: 16px; fill: currentColor; }
.ov-suggest[open] > summary { margin-bottom: 12px; }

/*
 * 팁 — "이렇게 하면 더 낫습니다" 한 줄.
 * 경고(`.ov-notice`)와 색을 나눈다: 저쪽은 **막는 말**이고 이쪽은 **권하는 말**이라,
 * 같은 색이면 사장님이 무언가 잘못한 줄 안다.
 */
/* 글자가 작아 눈에 안 들어온다는 지적으로 키웠다(2026-09-17). 본문(15px)보다 살짝 크게 둔다. */
.ov-tip {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 14px 0 0; padding: 12px 14px;
  border-radius: var(--radius-sm); background: var(--surface-2);
  font-size: 16px; line-height: 24px; color: var(--text);
}
.ov-tip svg { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--accent); }
.ov-tip b { color: var(--text); }
/*
 * 칩 안 `광고` 배지 — 지금 돈을 쓰고 있는 키워드(2026-09-16).
 * 홈의 `.hm-rank__ad`(16px)를 그대로 쓰면 칩 높이를 밀어내서, 칩 전용으로 작게 둔다.
 * 고른 칩(포인트색 바탕) 위에서도 읽히도록 흰 반투명으로 뒤집는다.
 */
.ov-chip__ad {
  flex: none; padding: 2px 8px; border-radius: var(--radius-full);
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; line-height: 20px;
}
.ov-chip.is-on .ov-chip__ad,
.dg-chip.is-on .ov-chip__ad { background: rgba(255, 255, 255, .28); color: #fff; }
.ov-add { display: flex; gap: 8px; margin-top: 16px; }
.ov-add__field { flex: 1; min-width: 0; margin-top: 0; }
.ov-add__btn { flex: none; height: 52px; padding: 0 16px; border-radius: var(--radius-full); font-size: 16px; font-weight: 700; }

/* 관리자가 상품 설명에 넣은 줄바꿈을 살린다(접수 화면 카드와 같다). */
.ov-option__desc { white-space: pre-wrap; word-break: keep-all; }
/*
 * 칩 안 검색수 — `월 13,270회`.
 *
 * ⚠️ **평가(많다·적다)를 붙이지 않는다**(2026-09-17). 한때 `많이 찾아요` 같은 등급을 붙였는데
 * 사장님 말로는 **그 평가 때문에 오히려 고르기를 망설이게 된다.** 판단은 사장님 몫이고 화면은 숫자만 준다.
 */
.ov-chip__vol { font-size: 12px; font-weight: 600; opacity: .7; font-variant-numeric: tabular-nums; }

/*
 * 배지가 늘면서 긴 검색어가 **글자 중간에서 줄바꿈**돼 칩이 울퉁불퉁해졌다(2026-09-17 실측).
 * 칩은 한 줄로 두고 검색어만 말줄임한다 — 글자 노드는 그대로라 화면낭독기에는 전체가 읽힌다.
 */
.ov-chip { max-width: 100%; }
.ov-chip__text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/*
 * 늦게 붙는 라벨의 **자리표시**(스켈레톤).
 *
 * 위 `.ads-tag__vol.is-pending`(옛 접수 화면)과 **같은 연출**이라 키프레임(`ads-pulse`)을 함께 쓴다.
 * 자리를 비워 두면 칩 폭이 뛰어 줄바꿈이 통째로 바뀐다 — 그래서 값이 오기 전에도 자리를 잡아 둔다.
 */
.kw-skel {
  display: inline-block; width: 52px; height: 9px; border-radius: 4px;
  background: currentColor; opacity: .22; animation: ads-pulse 1.3s var(--ease) infinite;
}


/*
 * 입력창에서 치는 동안 뜨는 '찾는 수' 한 줄.
 *
 * 요청은 "입력창 **옆**" 이었지만 입력칸 안 오른쪽에 넣으면 390px 에서 친 글자가 배지에 가린다
 * (입력칸 약 238px 중 배지가 110px 쯤을 먹는다). 바로 **아래 줄**로 내려 글자를 가리지 않게 했다.
 */
.kw-vol { display: flex; align-items: center; margin: 8px 4px 0; font-size: 14px; line-height: 22px; }
.kw-vol__num {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--hm-ink); font-weight: 600; font-variant-numeric: tabular-nums;
}
.ov-help { margin: 16px 0 0; font-size: 14px; line-height: 22px; text-align: center; color: var(--hm-dim); }
.ov-help b { color: var(--text); }
.ov-help--left { margin-top: 12px; text-align: left; }
.ov-label { display: block; margin: 24px 0 8px; font-size: 16px; font-weight: 700; color: var(--text); }
.ov-label small { font-size: 14px; font-weight: 400; color: var(--hm-dim); }

/* ── 3. 하루 수량 — 큰 − 숫자 + ── */
.ov-stepper { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ov-stepper__btn {
  flex: none; display: flex; align-items: center; justify-content: center; width: 64px; height: 64px;
  border: 0; border-radius: 50%; background: var(--accent-soft); color: var(--accent); cursor: pointer;
  transition: transform .15s var(--ease), opacity .15s var(--ease);
}
.ov-stepper__btn:active { transform: scale(.9); }
.ov-stepper__btn:disabled { opacity: .35; cursor: default; }
.ov-stepper__btn svg { width: 28px; height: 28px; stroke-width: 2.5; }
.ov-stepper__value { flex: 1; min-width: 0; text-align: center; }
.ov-stepper__num {
  width: 100%; padding: 0; border: 0; background: transparent; text-align: center;
  font: inherit; font-size: 52px; font-weight: 800; letter-spacing: -.03em; color: var(--text);
  font-variant-numeric: tabular-nums; -moz-appearance: textfield;
}
.ov-stepper__num::-webkit-outer-spin-button,
.ov-stepper__num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ov-stepper__num:focus { outline: none; }
/*
 * 입력칸 모양(2026-09-21) — 숫자를 직접 칠 수 있다는 **손잡이**다. 연한 바탕 + 테두리 + 모서리 연필.
 * 누르면 테두리가 포인트색으로 바뀌어 "지금 치는 중" 이 보인다. 숫자는 테두리 안에 들어오게 44px 로 한 단계 줄였다.
 */
.ov-stepper__field {
  position: relative; display: block;
  padding: 6px 8px; border: 2px solid var(--hm-line); border-radius: var(--radius-sm);
  background: var(--surface-2); cursor: text;
  transition: border-color .15s var(--ease), background .15s var(--ease), box-shadow .15s var(--ease);
}
.ov-stepper__field:hover { border-color: var(--accent); }
.ov-stepper__field:focus-within { border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 4px var(--accent-soft); }
.ov-stepper__field .ov-stepper__num { font-size: 44px; line-height: 1.2; }
.ov-stepper__edit { position: absolute; top: 6px; right: 6px; display: flex; color: var(--accent); pointer-events: none; }
.ov-stepper__edit svg { width: 16px; height: 16px; }
.ov-stepper__field:focus-within .ov-stepper__edit { opacity: 0; }
.ov-stepper__hint {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 12px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-ink);
}
.ov-stepper__hint svg { width: 16px; height: 16px; flex: none; color: var(--accent); }
.ov-stepper__hint b { font-weight: 600; color: var(--text); }

/* 빠른 선택(플레이스) — 누르면 그 수량으로 바로 바뀐다. 지금 값과 같은 칩은 켜져 있다. */
.ov-quick { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 16px; }
.ov-quick__chip {
  height: 36px; padding: 0 14px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: inherit; color: var(--hm-ink);
  font-variant-numeric: tabular-nums; cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.ov-quick__chip:hover { color: var(--text); }
.ov-quick__chip.is-on { border-color: var(--accent); background: var(--accent); color: #fff; }
.ov-stepper__unit { display: block; margin-top: -2px; font-size: 16px; font-weight: 600; color: var(--hm-ink); }
.ov-live {
  margin: 16px 0 0; padding: 12px; border-radius: var(--radius-sm); background: var(--accent-soft);
  font-size: 16px; text-align: center; color: var(--text);
}
.ov-live b { font-size: 20px; color: var(--accent); font-variant-numeric: tabular-nums; }
.ov-live small { color: var(--hm-dim); }

/* ── 4. 기간 — 달력 버튼 + 기간 버튼 ── */
.ov-date {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 16px;
  border: 2px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface);
  font: inherit; letter-spacing: inherit; text-align: left; color: var(--text); cursor: pointer;
  transition: border-color .2s var(--ease);
}
.ov-date.is-set { border-color: var(--accent); }
.ov-date > svg { flex: none; width: 20px; height: 20px; color: var(--hm-dim); }
.ov-date__icon {
  flex: none; display: flex; align-items: center; justify-content: center; width: 48px; height: 48px;
  border-radius: 14px; background: var(--accent-soft); color: var(--accent);
}
.ov-date__icon svg { width: 24px; height: 24px; }
.ov-date__text { flex: 1; min-width: 0; font-size: 18px; font-weight: 700; line-height: 26px; }
.ov-date__text small { display: block; font-size: 14px; font-weight: 400; color: var(--hm-dim); }
.ov-daychips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.ov-daychip {
  height: 56px; border: 2px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface);
  font: inherit; font-size: 18px; font-weight: 700; letter-spacing: inherit; color: var(--text); cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.ov-daychip.is-on { border-color: var(--accent); background: var(--accent); color: #fff; }
.ov-daychip:disabled { opacity: .35; cursor: default; }

/* ── 5. 가이드 ── */
.ov-guidebox { padding: 16px; border-radius: var(--radius-sm); background: var(--surface-2); }
.ov-guidebox__head { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; font-size: 16px; font-weight: 700; color: var(--text); }
.ov-guidebox__head svg { width: 16px; height: 16px; color: var(--hm-dim); }
.ov-guidebox__head small { margin-left: auto; font-size: 12px; font-weight: 500; color: var(--hm-dim); }
.ov-guidebox__text { margin: 0; font-size: 14px; line-height: 22px; white-space: pre-wrap; word-break: keep-all; color: var(--hm-ink); }
.ov-guidebox__text + .ov-guidebox__text { margin-top: 8px; }
.ov-note {
  width: 100%; min-height: 150px; padding: 14px 16px; resize: vertical;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface);
  font: inherit; font-size: 16px; line-height: 24px; letter-spacing: inherit; color: var(--text);
}
.ov-note:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ov-note__help { margin: 8px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-dim); }

/* ── 6. 사진 — 칸 카드(예시는 흑백, 고른 사진은 컬러) ── */
.ov-pgroup__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ov-pgroup__title { margin: 0; font-size: 20px; font-weight: 700; color: var(--text); }
.ov-pgroup__hint { margin: 4px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-ink); word-break: keep-all; }
.ov-pgroup__count {
  flex: none; padding: 4px 10px; border-radius: var(--radius-full); background: var(--danger-soft);
  font-size: 14px; font-weight: 700; color: var(--hm-bad); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ov-pgroup__count.is-ok { background: color-mix(in srgb, var(--hm-good) 14%, var(--surface)); color: var(--hm-good); }
.ov-thumbs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 16px; }
.ov-thumb {
  position: relative; aspect-ratio: 1 / 1; border-radius: 10px; overflow: hidden; background: var(--surface-2);
  animation: hm-pop .35s var(--ease) both; animation-delay: calc(var(--i, 0) * 50ms);
}
.ov-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ov-thumb.is-guide img { filter: grayscale(1); opacity: .75; }
.ov-thumb.is-guide::after,
.ov-thumb.is-main::after {
  position: absolute; left: 4px; top: 4px; padding: 2px 6px; border-radius: 6px;
  background: rgba(0, 0, 0, .55); font-size: 12px; font-weight: 700; color: #fff;
}
.ov-thumb.is-guide::after { content: "예시"; }
.ov-thumb.is-main::after { content: "대표"; background: var(--accent); }
.ov-thumb--blank { border: 2px dashed var(--hm-line); background: transparent; }
.ov-thumb__more { display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 700; color: var(--hm-ink); }
.ov-pgroup__btn {
  display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; height: 54px; margin-top: 16px;
  border: 2px solid var(--accent); border-radius: var(--radius-sm); background: var(--surface);
  font: inherit; font-size: 16px; font-weight: 700; letter-spacing: inherit; color: var(--accent); cursor: pointer;
}
.ov-pgroup__btn:active { transform: scale(.98); }
.ov-pgroup__btn svg { width: 20px; height: 20px; }

/* ── 7. 결제 확인 — 보조 버튼 · 긴 글 ── */
.ov-secondary {
  display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; height: 52px; margin-top: 10px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface);
  font: inherit; font-size: 16px; font-weight: 600; letter-spacing: inherit; color: var(--text); cursor: pointer;
}
.ov-secondary svg { width: 20px; height: 20px; }
.ov-row__note { font-weight: 500; white-space: pre-wrap; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.ov-row__note.is-empty { color: var(--hm-dim); }

/* ── 5. 결제 확인 ── */
.ov-bill { margin-top: 8px; padding-top: 12px; border-top: 2px dashed var(--hm-line); }
.ov-bill__line { display: flex; justify-content: space-between; padding: 6px 0; font-size: 16px; color: var(--hm-ink); font-variant-numeric: tabular-nums; }
.ov-cash { margin-top: 16px; }
.ov-cash__line { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; font-size: 16px; color: var(--hm-ink); }
.ov-cash__line b { color: var(--text); font-variant-numeric: tabular-nums; }
.ov-cash__line b.is-short { color: var(--hm-bad); }

/* 결제 확인 시트 — 아래에서 올라온다. */
.ov-sheet { position: fixed; inset: 0; z-index: 100; }
.ov-sheet__dim { position: absolute; inset: 0; background: rgba(0, 0, 0, .45); animation: ov-fade .2s ease both; }
.ov-sheet__panel {
  position: absolute; left: 0; right: 0; bottom: 0; max-width: 584px; margin: 0 auto;
  padding: 12px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  border-radius: 24px 24px 0 0; background: var(--surface); text-align: center;
  animation: ov-up .32s var(--ease) both;
}
.ov-sheet__grip { display: block; width: 40px; height: 5px; margin: 0 auto 18px; border-radius: 3px; background: var(--hm-line); }
.ov-sheet__title { display: block; font-size: 24px; font-weight: 700; line-height: 32px; color: var(--text); }
.ov-sheet__title span { color: var(--accent); }
.ov-sheet__text { margin: 10px 0 18px; font-size: 16px; color: var(--hm-ink); }
@keyframes ov-fade { from { opacity: 0; } }
@keyframes ov-up { from { transform: translateY(100%); } }

/* ── 6. 완료 — 체크가 터지고 색 조각이 퍼진다 ── */
/* 가로만 자른다 — 퍼지는 링·조각이 화면을 2px 넓혔다. `clip` 은 스크롤 상자를 만들지 않아 위로 튀는 조각은 그대로 보인다. */
.ov-done { padding-top: 12px; overflow-x: clip; }
.ov-burst { position: relative; width: 132px; height: 132px; margin: 8px auto 20px; }
.ov-burst__ring {
  position: absolute; inset: 0; border-radius: 50%; background: var(--accent);
  box-shadow: 0 16px 36px color-mix(in srgb, var(--accent) 38%, transparent);
  animation: ov-pop .55s cubic-bezier(.2, 1.4, .4, 1) both;
}
.ov-burst__ring::after {
  content: ""; position: absolute; inset: -10px; border-radius: 50%; border: 3px solid var(--accent);
  opacity: 0; animation: ov-wave 1.1s var(--ease) .35s both;
}
.ov-burst__check { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; }
.ov-burst__check svg { width: 64px; height: 64px; stroke-width: 3; stroke-dasharray: 30; stroke-dashoffset: 30; animation: ov-draw .45s var(--ease) .35s forwards; }
.ov-burst__bit {
  position: absolute; top: 50%; left: 50%; width: 10px; height: 16px; margin: -8px 0 0 -4px; border-radius: 3px;
  background: var(--accent); opacity: 0;
  transform: rotate(var(--a)) translateY(0);
  animation: ov-confetti 1s var(--ease) .3s both;
}
.ov-burst__bit:nth-child(3n) { background: #f5b638; }
.ov-burst__bit:nth-child(3n+1) { background: var(--hm-good); }
.ov-burst__bit:nth-child(4n) { width: 8px; height: 8px; border-radius: 50%; }
@keyframes ov-pop { from { transform: scale(0); } to { transform: scale(1); } }
@keyframes ov-wave { 0% { opacity: .6; transform: scale(.9); } 100% { opacity: 0; transform: scale(1.5); } }
@keyframes ov-draw { to { stroke-dashoffset: 0; } }
@keyframes ov-confetti {
  0% { opacity: 1; transform: rotate(var(--a)) translateY(0) scale(.6); }
  70% { opacity: 1; }
  100% { opacity: 0; transform: rotate(var(--a)) translateY(-108px) rotate(200deg) scale(1); }
}
.ov-done__lead { margin: -8px 0 20px; font-size: 18px; line-height: 26px; text-align: center; color: var(--hm-ink); }



/* ════════════════════════════════════════════════════════════════════════
   접수 · 이미 잡히는 키워드   `.kr-*`
   ────────────────────────────────────────────────────────────────────────
   `.ads-tag*` 를 늘리지 않고 접두사를 새로 판다. 저건 입력칸 안의 칩이고
   이건 그 아래 목록이라, 한쪽 규칙이 다른 쪽을 덮으면 조용히 깨진다.
   ════════════════════════════════════════════════════════════════════════ */

.kr__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.kr__title { font-size: 14px; font-weight: 600; color: var(--text-2); }

.kr__list {
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
}

.kr__row {
  display: grid; grid-template-columns: 1fr auto auto 22px;
  align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px;
  border: 0; border-top: 1px solid var(--border);
  background: var(--surface); text-align: left; cursor: pointer; font: inherit;
}
.kr__row:first-child { border-top: 0; }
.kr__row:hover { background: var(--surface-2); }

/* 이미 넣은 줄. **감추지 않는다** — 사라지면 목록이 눌릴 때마다 들썩이고,
   무엇을 이미 넣었는지도 알 수 없다. */
.kr__row.is-added { background: var(--accent-soft); cursor: default; }
.kr__row.is-added .kr__add { transform: rotate(45deg); color: var(--accent); }

.kr__kw { font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kr__rank { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; }
.kr__rank.is-dim { font-weight: 500; color: var(--text-3); }
.kr__vol { font-size: 12px; color: var(--text-3); white-space: nowrap; }
.kr__add { font-size: 18px; line-height: 1; color: var(--text-3); text-align: center; transition: transform .15s; }

@media (max-width: 380px) {
  .kr__row { grid-template-columns: 1fr auto 20px; gap: 8px; }
  .kr__vol { display: none; }
}

/* ═════════════════════  접수 화면 (/ads/orders/new)  ═════════════════════
 * `.of-` = order form. **새 접수 화면 전용**이다.
 *
 * 값은 시안(피그마 `174:867`)에서 그대로 옮겼다. 다행히 이 저장소의 토큰이 이미 시안 색이다 —
 * `--bg #f5f5f7` · `--text #1d1d1f` · `--text-2 #6e6e73` · `--accent #0071e3` ·
 * `--accent-soft #e8f2fe` · `--hm-ink #5f626b` · `--hm-line #ededf1` · `--radius-sm 8px`.
 * 카드도 `.hm-card`(패딩 32/24 · radius 8 · 4방향 파란 그림자)가 시안 카드와 **같은 값**이라
 * 새로 만들지 않고 그대로 쓴다.
 *
 * 옛 화면(`/orders/new/legacy`)이 쓰는 `.ads-product*` · `.ads-tag*` · `.ads-range` ·
 * `.ads-chip*` · `.ads-amount*` · `.kr__*` · `.guide-box*` 는 한 줄도 건드리지 않는다.
 */
.of {
  /*
   * `--of-blue` 는 배지·칩 글자·결제 버튼·선택 표시의 **포인트 컬러**다.
   *
   * 시안은 여기에 #1677ff 를 썼지만 그 값을 그대로 두면 브랜드마다 다른 테넌트 색
   * (`ads_layout.php` 가 `--accent` 로 심는다)과 화면 안에서 두 색이 싸운다 —
   * 잔액 숫자는 테넌트 색인데 결제 버튼만 파랗게 남는다. 그래서 `--accent` 를 따라간다.
   * 이름은 그대로 둔다: 이 화면 안에서 '포인트 컬러' 를 가리키는 자리가 스무 곳이 넘어
   * 한꺼번에 바꾸면 어디가 왜 그 색인지가 흐려진다.
   */
  --of-blue: var(--accent);
  /*
   * 포인트 컬러를 옅게 깐 바탕·테두리. 고정 파랑용으로 만들어 둔 `--accent-soft` 는
   * 테넌트 색을 따라가지 않아(ops.css 의 상수다) 여기서 섞어 쓴다.
   * `color-mix` 를 모르는 브라우저는 바로 위 줄의 고정값으로 떨어진다.
   */
  --of-tint: var(--accent-soft);
  --of-tint: color-mix(in srgb, var(--accent) 8%, #fff);
  --of-edge: rgba(0, 113, 227, .4);
  --of-edge: color-mix(in srgb, var(--accent) 40%, #fff);
  --of-fill: #f9f9f9;      /* 검색창 바탕 */
  --of-chip: #f9fbfc;      /* 안 고른 기간 칩 */
  --of-soon: #aeaeae;      /* 준비중 배지 */
  --of-strip: #ebebeb;     /* 결제 바 위 단계 띠 */

  /* 시안은 제목이 위에서 32px 다. `.ads-main` 이 20px 를 주므로 12px 만 더한다. */
  padding-top: 12px;
}

.of-title {
  margin: 0 0 16px;
  font-size: 28px; font-weight: 700; line-height: 36px; color: var(--text);
}

/* ── 가로 슬라이더 (요약 카드 줄 · 상품 캐러셀 공용) ──────── */
/*
 * 화살표를 **트랙 위에 겹쳐** 얹는다. 트랙 밖에 자리를 만들면 카드 폭이 그만큼 줄어
 * 시안의 156·250 이 안 맞는다. 갈 곳이 없는 쪽 버튼은 JS 가 `hidden` 으로 감춘다.
 */
.of-slider { position: relative; }
.of-slide {
  position: absolute; top: 50%; z-index: 2;
  width: 40px; height: 40px; margin-top: -20px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: 50%;
  box-shadow: var(--shadow-2); cursor: pointer;
}
.of-slide[hidden] { display: none !important; }
.of-slide:hover { color: var(--text); }
.of-slide svg { width: 18px; height: 18px; }
.of-slide--prev { left: -14px; }
.of-slide--next { right: -14px; }

/* ── 요약 카드 4장 (시안 156×100) ──────────────────────────── */
/*
 * 가로 스크롤이다. 좁은 화면에서 4장을 접으면 두 줄이 되고, 그러면 화면 위쪽 절반을
 * 요약이 먹는다 — 여기는 접수하러 온 화면이지 대시보드가 아니다.
 */
.of-slider--stats { margin-bottom: 32px; }
.of-stats {
  display: flex; gap: 8px;
  padding-bottom: 2px;
  overflow-x: auto; scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.of-stats::-webkit-scrollbar { height: 0; }
.of-stat {
  position: relative;
  flex: 0 0 auto; width: 156px; height: 100px;
  padding: 10px; scroll-snap-align: start; overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
}
.of-stat__label { display: block; font-size: 12px; line-height: 12px; color: var(--hm-ink); }
.of-stat__value {
  display: block; margin-top: 8px;
  font-size: 20px; font-weight: 700; line-height: 20px; color: var(--text-2);
}
.of-stat--accent .of-stat__value { color: var(--accent); }
.of-stat__meta {
  display: block; margin-top: 8px;
  font-size: 8px; line-height: 8px; color: var(--hm-ink); opacity: .7;
}
/* 카드 오른쪽 아래에 붙는 작은 알약. `.btn` 을 쓰지 않는다 — 시안 크기가 훨씬 작다. */
.of-stat__action {
  position: absolute; right: 11px; bottom: 11px;
  padding: 4px 8px;
  font-size: 12px; font-weight: 600; line-height: 12px; color: var(--hm-ink);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: 100px;
}
.of-stat__action:hover { text-decoration: none; }
.of-stat__action--fill {
  color: #fff; background: var(--of-blue); border-color: var(--of-blue);
}

/* ── 카드 ──────────────────────────────────────────────────── */

.of-card { margin-bottom: 24px; }
.of-card__title {
  /* 카드 패딩 32 + 제목 26 + 24 = 시안의 첫 입력칸 위치(82). */
  margin: 0 0 24px;
  font-size: 20px; font-weight: 700; line-height: 28px; color: var(--text);
}
.of-card__title--lg { font-size: 24px; margin-bottom: 20px; }
.of-notice { margin-bottom: 16px; }
.of-store { margin: -8px 0 16px; font-size: 12px; color: var(--hm-ink); }

/* 시안의 세로 리듬은 필드 사이 24px 다. */
.of-field { margin-top: 24px; }
.of-label {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 12px;
  font-size: 16px; font-weight: 600; line-height: 16px; color: var(--text-2);
}
/*
 * 한 필드 안의 두 번째 제목(본사 가이드 → 매장 가이드).
 * 시안은 두 덩이 사이가 32 인데, 거기 본사 쪽은 맨 글씨다. 여기는 옅은 판이 이미
 * 갈라 주므로 24 로 좁힌다 — 32 를 그대로 쓰면 두 덩이가 남남처럼 멀어진다.
 */
.of-label--sub { margin-top: 24px; }
.of-tip { display: inline-flex; color: var(--text-3); cursor: help; }
.of-tip svg { width: 16px; height: 16px; }
/* 시안의 보조 문구는 전부 10px · opacity .7 다. */
.of-hint {
  margin: 12px 0 0;
  font-size: 12px; font-weight: 500; line-height: 20px; color: var(--text-2); opacity: .7;
}
/* 제목 바로 밑에 붙는 설명(사진 칸). 아래 여백은 다음 요소가 갖는다. */
.of-hint--tight { margin: 0; }

/* ── 상품 캐러셀 (시안 250×124) ────────────────────────────── */

/*
 * 카드 안에서 **오른쪽 여백만큼 흘러나간다**(시안: 세 번째 상품이 카드 끝에서 잘려 보인다).
 * 여백 안에 가두면 카드가 거기서 끝나는 것처럼 보여 옆으로 밀 생각을 하지 않는다.
 */
.of-carousel { position: relative; margin-right: -24px; }
.of-carousel__track {
  display: flex; gap: 8px;
  padding-right: 24px; padding-bottom: 2px;
  overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.of-carousel__track::-webkit-scrollbar { height: 0; }

.of-prod {
  position: relative;
  flex: 0 0 auto; width: 250px; height: 124px;
  padding: 10px; scroll-snap-align: start; overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  cursor: pointer;
}
.of-prod.is-on { background: var(--of-tint); border-color: var(--of-edge); }
.of-prod__name {
  display: block; padding-right: 60px;
  font-size: 16px; font-weight: 700; line-height: 16px; color: var(--text);
}
/*
 * 관리자가 `/cms/ad-product` 에서 넣은 **줄바꿈을 그대로 살린다.**
 * 카드가 250×124 라 여기 들어갈 자리는 세 줄(60px)이고 넘치면 카드가 자른다
 * (`.of-prod` 의 `overflow: hidden`) — 어디서 끊을지는 관리자가 정한다.
 */
.of-prod__desc {
  margin: 12px 0 0;
  font-size: 12px; line-height: 20px; color: var(--hm-ink);
  white-space: pre-wrap; word-break: break-word;
}
.of-prod__price {
  display: block; margin-top: 4px;
  font-size: 12px; line-height: 10px; color: var(--hm-ink); opacity: .7;
}
.of-prod__badge {
  position: absolute; right: 11px; top: 11px;
  padding: 4px 12px;
  font-size: 12px; font-weight: 600; line-height: 20px; color: #fff;
  background: var(--of-blue); border-radius: 100px;
}
.of-prod__badge--soon { background: var(--of-soon); }
/*
 * 준비중은 **보이되 못 고른다.** 감추면 "이 서비스는 이것 하나뿐인가" 로 읽힌다.
 * 배지는 흐리게 하지 않는다 — 왜 못 고르는지 말해 주는 것이 그 배지다.
 */
.of-prod.is-soon { cursor: not-allowed; }
.of-prod.is-soon .of-prod__name,
.of-prod.is-soon .of-prod__desc,
.of-prod.is-soon .of-prod__price { opacity: .4; }

/* ── 키워드 검색 (시안 h32 알약) ───────────────────────────── */

.of-search { position: relative; }
.of-search__icon {
  position: absolute; left: 11px; top: 50%; margin-top: -10px;
  display: flex; color: var(--hm-ink); pointer-events: none;
}
.of-search__icon svg { width: 20px; height: 20px; }
.of-search__input {
  width: 100%; height: 32px;
  padding: 0 34px 0 40px;
  font-size: 14px; font-weight: 600; color: var(--hm-ink);
  background: var(--of-fill);
  border: 1px solid var(--hm-line); border-radius: 100px;
}
.of-search__input::placeholder { color: var(--hm-ink); }
.of-search__input:focus {
  outline: none; border-color: var(--of-blue); background: var(--surface);
}
.of-search__clear {
  position: absolute; right: 10px; top: 50%; margin-top: -8px;
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  color: var(--hm-ink);
  background: transparent; border: 0; border-radius: 50%; cursor: pointer;
}
.of-search__clear svg { width: 13px; height: 13px; }

/*
 * 드롭다운. 자동완성처럼 보이지만 **네이버를 부르지 않는다** — 이미 DB 에 있는
 * 순위·기본 키워드를 글자로 거를 뿐이라 타이핑이 끊겨도 늦게 뜨는 일이 없다.
 */
/*
 * 시안 183:2613 실측 — 상자 h46 = 위아래 여백 11 + 줄 24. 검색창에 **붙어서** 뜬다
 * (띄우면 검색한 말과 그 결과가 두 덩이로 갈린다).
 */
.of-drop {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  padding: 10px 0;
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  box-shadow: var(--hm-shadow);
}
.of-drop[hidden] { display: none !important; }
.of-drop__list { max-height: 232px; overflow-y: auto; }
/*
 * 좌우 40px 는 **검색창 글자와 같은 세로선**이다(11 테두리 + 20 돋보기 + 8 사이).
 * 눌러 넣은 말과 그 결과가 한 줄로 이어져 보인다.
 */
.of-drop__row {
  width: 100%; height: 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0 40px;
  font-size: 14px; font-weight: 600; text-align: left; color: var(--hm-ink);
  background: transparent; border: 0; cursor: pointer;
}
.of-drop__row:hover { background: var(--of-fill); }
/* 이미 넣은 줄도 **빼지 않고 표시만** 한다 — 눌러서 뺄 수 있는 자리이기도 하다. */
.of-drop__row.is-added { color: var(--of-blue); font-weight: 600; }
.of-drop__row.is-added .of-drop__kw::after { content: ' ✓'; }
.of-drop__kw { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.of-drop__meta {
  flex: none;
  font-size: 12px; font-weight: 500; color: var(--text-2); text-align: right; opacity: .7;
}
/* 시안 183:2626 — 줄 끝의 화살표. 검색량이 아직 안 왔어도 자리는 지킨다. */
.of-drop__go { flex: none; display: inline-flex; color: var(--hm-ink); opacity: .7; }
.of-drop__go svg { width: 14px; height: 14px; }
.of-drop__row:hover .of-drop__go { color: var(--of-blue); opacity: 1; }

/* ── 사용 될 키워드 (시안 h80 상자 + 알약 칩) ──────────────── */

.of-chips {
  display: flex; flex-wrap: wrap; align-content: flex-start; gap: 8px;
  min-height: 80px; padding: 10px;
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
}
.of-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 4px 4px 12px;
  background: var(--of-tint); border-radius: 100px;
}
.of-chip__name { font-size: 12px; font-weight: 500; line-height: 20px; color: var(--of-blue); }
/* 검색량은 **같은 파랑에 더 작게**. 회색으로 두면 칩 안에서 남의 글자처럼 보인다. */
.of-chip__vol { font-size: 8px; font-weight: 500; line-height: 1.3; color: var(--of-blue); }
.of-chip__vol.is-low { opacity: .7; }
.of-chip__x {
  width: 14px; height: 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1; color: var(--of-blue);
  background: transparent; border: 0; cursor: pointer; opacity: .7;
}
.of-chip__x:hover { opacity: 1; }

/* ── 수량 (시안: 선 + 48×24 값칸) ──────────────────────────── */

.of-range { display: flex; align-items: center; gap: 12px; }
.of-range input[type="range"] {
  flex: 1; height: 24px;
  accent-color: var(--of-blue);
}
.of-range__num {
  flex: none; width: 48px; height: 24px;
  padding: 0 4px;
  font-size: 14px; font-weight: 600; text-align: center; color: var(--hm-ink);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: 100px;
}

/* ── 기간 (시안 h42 + 알약 칩) ─────────────────────────────── */

.of-date {
  position: relative;
  width: 100%; height: 42px;
  display: flex; align-items: center;
  padding: 0 40px 0 10px;
  font-size: 14px; font-weight: 600; color: var(--text-2); text-align: left;
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  cursor: pointer;
}
.of-date__text { flex: 1; }
.of-date__text.is-empty { color: var(--hm-ink); opacity: .5; }
.of-date__icon {
  position: absolute; right: 11px; top: 50%; margin-top: -10px;
  display: flex; color: var(--text-2);
}
.of-date__icon svg { width: 20px; height: 20px; }

.of-days { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.of-day {
  padding: 4px 12px;
  font-size: 12px; font-weight: 600; line-height: 20px; color: var(--text-2);
  background: var(--of-chip);
  border: 0; border-radius: 100px; cursor: pointer;
}
.of-day.is-on { color: #fff; background: var(--text-2); }
/*
 * 달력에서 직접 고른 뒤에는 잠긴다 — 하나 잘못 누르면 고른 기간이 통째로 덮인다.
 * 흐리게만 두고 감추지 않는 이유: 사라지면 원래 없던 기능인 줄 안다.
 */
.of-day:disabled { opacity: .4; cursor: default; }
/* 잠금을 푸는 칩. 테두리만 있는 꼴이라 기간 칩과 같은 줄에 있어도 안 헷갈린다. */
.of-day--reset {
  color: var(--hm-ink);
  background: transparent;
  border: 1px solid var(--hm-line);
}
.of-day--reset[hidden] { display: none !important; }
.of-day--reset:hover { color: var(--text-2); border-color: var(--text-3); }

/* ── 본사 가이드 · 매장 가이드 ─────────────────────────────── */
/*
 * 본사 가이드는 **옅은 판** 위의 글이다.
 *
 * 시안(183:2629)은 제목 + 10px 설명글뿐이고 판이 없다. 그런데 바로 아래 `매장 가이드` 가
 * 입력칸이라, 맨 글씨로 두면 위쪽도 고칠 수 있는 줄로 읽힌다. 그래서 판 하나만 깔고
 * `수정할 수 없음` 알약을 제목 줄 오른쪽에 단다. 머리줄까지 얹은 상자를 한 번 만들었다가
 * 시안의 리듬을 깨서 걷어냈다.
 *
 * 클래스 이름 주의: 사진 레이어의 예시 타일은 `.of-eg` 다. 거기에 `.of-guide` 를 쓰면
 * 뒤 규칙이 이 판을 덮어써 정사각형 투명 버튼이 된다(실제로 한 번 그랬다).
 */
.of-guide {
  padding: 10px;
  background: var(--of-fill); border-radius: var(--radius-sm);
}
/* 제목 줄 오른쪽 알약. 자물쇠 하나만으로는 장식으로 읽혀 글로도 한 번 말한다. */
.of-guide__tag {
  flex: none; display: inline-flex; align-items: center; gap: 4px;
  margin-left: auto; padding: 2px 8px;
  font-size: 12px; font-weight: 500; line-height: 14px; color: var(--hm-ink);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: 100px;
}
.of-guide__tag svg { width: 11px; height: 11px; }
/* 시안의 설명글은 힌트와 같은 10px 다. 본문처럼 키우면 점주가 읽어야 할 글로 보인다. */
.of-guide__text {
  margin: 0 0 6px;
  font-size: 12px; font-weight: 500; line-height: 18px; color: var(--text-2);
  white-space: pre-wrap; opacity: .7;
}
.of-guide__text:last-child { margin-bottom: 0; }
.of-note {
  width: 100%; min-height: 80px; padding: 10px;
  font: inherit; font-size: 14px; line-height: 22px; color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  resize: vertical;
}
.of-note::placeholder { color: var(--text-2); opacity: .4; }
.of-note:focus { outline: none; border-color: var(--of-blue); }

/* ── 사진 (시안: 겹친 썸네일 + 원형 + 버튼) ───────────────── */
/*
 * 시안은 사진을 **한 줄로 늘어놓지 않고 겹쳐 쌓는다.** 뒤 장이 5도 기울어 뒤에 깔리고
 * 앞 장이 그 위에 곧게 선다. 몇 장인지는 아래 `05/10` 이 말하므로 타일을 다 그릴 필요가 없다 —
 * 사진 열 장을 가로로 늘어놓으면 그 줄 하나가 화면을 다 먹는다.
 */
.of-photos { margin-top: 32px; }
/* 사진 칸끼리는 조금 더 띄운다(시안 38). 두 칸이 한 덩이로 붙어 보이면 분류가 흐려진다. */
.of-photos + .of-photos { margin-top: 38px; }
/* 사진 칸만 제목↔설명 간격이 8px 다(시안 `gap-[8px]`). */
.of-photos .of-label { margin-bottom: 8px; }
.of-photos__stack {
  position: relative;
  width: 108px; height: 92px; margin-top: 20px;
}
.of-photos__tile {
  position: absolute; left: 0; top: 3px;
  width: 80px; height: 80px; overflow: hidden;
  background: var(--surface); border-radius: var(--radius-sm);
}
.of-photos__tile img { width: 100%; height: 100%; object-fit: cover; }
/* 뒤 장. 기울기와 어둡게 덮는 막까지 시안 그대로다(앞 장이 도드라져 보인다). */
.of-photos__tile--back { left: 7px; top: 0; transform: rotate(5deg); }
.of-photos__tile--back::after {
  content: ''; position: absolute; inset: 0;
  background: rgba(32, 32, 32, .4);
}
/*
 * 본사가 올린 **예시**. 아직 한 장도 안 골랐을 때 그 자리에 깔린다.
 * 흑백인 것은 사진 레이어의 `.of-eg` 와 **같은 말**이다 — 흐린 것은 아직 내 사진이 아니다.
 */
.of-photos__tile--guide img { filter: grayscale(1); opacity: .8; }

/* 예시조차 없을 때. 빈 칸을 감추면 어디를 눌러야 할지 알 수 없다. */
.of-photos__tile--empty {
  background: var(--of-fill);
  border: 1px dashed var(--hm-line);
}
.of-photos__add {
  position: absolute; left: 79px; top: 55px;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: 50%;
  box-shadow: var(--shadow-2); cursor: pointer;
}
.of-photos__add svg { width: 20px; height: 20px; }
.of-photos__count {
  display: flex; align-items: center; gap: 2px;
  margin-top: 8px;
  font-size: 12px; line-height: 12px; color: var(--text-2);
}
.of-photos__count svg { width: 12px; height: 12px; }
/* 최소 장수를 못 채웠다는 **사실만** 알린다. 접수를 막는 것은 서버다. */
.of-photos__count.is-short { color: var(--danger); }

/* ── 하단 고정 결제 바 (시안: 단계 띠 36 + 흰 줄 80) ──────── */
/*
 * 하단 탭바를 걷어내면서(2026-09-18) 화면 **맨 아래**에 붙는다.
 * z-index 는 시트(60)보다 낮다 — 메뉴를 열면 결제 바 위에 시트가 덮여야 한다.
 */
.of-bar__spacer { height: 132px; }
.of-bar {
  position: fixed; left: 0; right: 0; z-index: 39;
  bottom: env(safe-area-inset-bottom);
}
.of-bar__inner { max-width: 608px; margin: 0 auto; }
/*
 * 회색 띠 = 단계 표시(시안 183:2635).
 *
 * 네 칸이 좁은 화면에서 줄바꿈되면 바 높이가 들쭉날쭉해져 본문 끝 여백
 * (`.of-bar__spacer`)과 어긋난다. 그래서 줄바꿈 대신 **가로 스크롤**이다.
 */
.of-bar__steps {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  height: 36px; padding: 0 12px;
  overflow-x: auto;
  background: var(--of-strip);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.of-bar__steps::-webkit-scrollbar { height: 0; }

.of-bstep {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 6px;
  padding: 0; border: 0; background: transparent; cursor: pointer;
  font-family: inherit; letter-spacing: inherit;
  font-size: 14px; line-height: 18px; color: var(--hm-ink);
}
.of-bstep[hidden] { display: none !important; }
/* 번호 알약(시안 18×18). 채운 칸만 포인트 컬러로 찬다. */
.of-bstep__no {
  flex: none; width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; line-height: 1; color: var(--hm-ink);
  background: var(--surface); border-radius: 50%;
}
.of-bstep.is-done .of-bstep__no { color: #fff; background: var(--of-blue); }
/* 아직 안 채운 **첫** 칸. 지금 어디를 보면 되는지가 이 한 칸이다. */
.of-bstep.is-now .of-bstep__label { color: var(--text); font-weight: 600; }
.of-bstep.is-now .of-bstep__no { color: var(--text); box-shadow: 0 0 0 2px var(--of-edge); }
.of-bar__row {
  display: flex; align-items: center; gap: 8px;
  height: 80px; padding: 12px;
  background: var(--surface);
}
.of-bar__save {
  flex: none; width: 56px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
  cursor: pointer;
}
.of-bar__save svg { width: 24px; height: 24px; }
.of-bar__cta {
  flex: 1; height: 56px;
  font-size: 20px; font-weight: 600; line-height: 28px; color: #fff;
  background: var(--of-blue);
  border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.of-bar.is-short .of-bar__cta { background: var(--of-soon); }

@media (min-width: 861px) {
  /* 데스크톱에는 탭바가 없다(`display:none`). 바가 바닥에 붙는다. */
  .of-bar { bottom: 0; }
  .of-bar__spacer { height: 128px; }
}
@media (max-width: 420px) {
  /* 좁은 화면에서 20px 결제 문구가 두 줄이 되지 않게. */
  .of-bar__cta { font-size: 18px; }
  .of-bar__steps { gap: 10px; justify-content: flex-start; }
  .of-bstep { font-size: 12px; }
}

/* ── 사진 선택 레이어 (시안 174:2115 → 183:3295) ───────────── */
/*
 * 사진첩(`partial/photo_album.php` · `photo-album.js`)은 본사 관리 화면과 **같은 파일**이라
 * 한 줄도 고치지 않는다. 시안 모양은 **이 모달 안에서만** 덮어쓴다 —
 * `#photo-modal` 밖(본사 사진첩)에는 이 규칙이 하나도 닿지 않는다.
 */
.of-album-modal { align-items: center; padding: 20px; }
.of-album {
  width: 100%; max-width: 384px;
  padding: 20px; overflow-y: auto;
  border-radius: var(--radius-sm);
}
/*
 * 본문 전체가 **하나의 격자**다(시안 183:3295).
 *
 * 칸에 들어가는 것이 세 종류인데 마크업에서는 서로 다른 부모 밑에 있다 —
 * 올린 사진(`.ph-item`, 사진첩 파티셜 안), 예시 자리(`.of-eg`, 파티셜 밖),
 * 올리기 칸(`.ph-drop`, 파티셜 안). 파티셜은 본사 화면과 공유라 못 고치므로,
 * 사이에 낀 상자들을 `display: contents` 로 녹여 셋이 **한 격자의 형제**가 되게 한다.
 * 줄 세우기는 `order` 로 한다: 사진(0) → 예시 자리(5) → 올리기 칸(9).
 */
/*
 * 끌어다 놓는 동안만 덮이는 막.
 *
 * `.of-album` 이 `position: relative` 가 아니면 모달 전체가 기준이 되므로 여기서 잡아 준다.
 * `pointer-events: none` 이 **중요하다** — 막이 마우스를 먹으면 그 위에서 `dragleave` 가
 * 떠 버려 막이 깜빡이고, 놓는 순간의 `drop` 도 막이 가로챈다.
 */
.of-album { position: relative; }
.of-album__mask {
  position: absolute; inset: 8px; z-index: 5;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
  background: rgba(255, 255, 255, .88);
  border: 2px dashed var(--of-blue); border-radius: var(--radius-sm);
}
.of-album__mask[hidden] { display: none !important; }
.of-album__mask-text {
  padding: 8px 16px;
  font-size: 14px; font-weight: 600; color: var(--of-blue);
}

.of-album__body {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 20px 16px; padding: 0;
}
/* 제목·조건은 한 덩이로 묶어 격자 간격이 그 둘 사이에 끼지 않게 한다. */
.of-album__head { grid-column: 1 / -1; }
.of-album__body > .ph-album { display: contents; }

.of-album__lead {
  margin: 0;
  font-size: 16px; font-weight: 700; line-height: 22px;
  color: var(--text-2); text-align: center;
}
.of-album__note {
  display: flex; align-items: center; justify-content: center; gap: 2px;
  margin: 4px 0 0;
  font-size: 12px; font-weight: 500; line-height: 10px;
  color: var(--text-2); opacity: .7;
}
/* 문구 사이의 `×` 는 곱하기 기호다 — 닫기 버튼으로 읽히지 않게 아주 작게 둔다. */
.of-album__note svg { width: 12px; height: 12px; }

/* 선택바·칸 머리글은 이 레이어에 없다(시안이 안내 문구 하나로 대신한다). */
.of-album .ph-selbar,
.of-album .ph-group__note { display: none; }
.of-album .ph-group { margin: 0; }
.of-album .ph-group + .ph-group { margin-top: 18px; }
/*
 * 지금 고르는 칸의 머리글만 감춘다 — 어느 칸을 여는지는 누른 `+` 가 이미 말했다.
 * 분류 전처럼 **다른 칸**은 머리글이 있어야 무엇인지 알 수 있다.
 */
.of-album .ph-group.is-active .ph-group__head { display: none; }
.of-album .ph-group__head { margin-bottom: 8px; }
.of-album .ph-group__title strong { font-size: 12px; font-weight: 600; color: var(--text-2); }
.of-album .ph-group__hint { display: none; }
/* 다른 칸(외부↔내부)은 그 칸의 `+` 로 들어가야 한다. 한 레이어에 섞으면 어디에 넣는지 흐려진다. */
.of-album .ph-group.of-hide { display: none; }

/* 타일 — 104×104 3열, 시안 gap 20/16. */
.of-album .ph-grid {
  grid-template-columns: repeat(3, 1fr);
  gap: 20px 16px;
  margin-top: 16px;
}

/*
 * 지금 고르는 칸은 통째로 녹여 위 `.of-album__body` 격자에 붙인다.
 * 마크업에서는 드롭존이 격자보다 **앞**이라 `order` 로 뒤로 민다.
 *
 * 지금 고르는 칸에만 건다 — 분류 전 칸은 머리글이 보이는 통짜 블록으로 아래에 남는다.
 */
.of-album .ph-group.is-active,
.of-album .ph-group.is-active > .ph-grid { display: contents; }
/* 올리기 자리는 사진·예시 **뒤**에 온다. */
.of-album .ph-group.is-active > .ph-drop { order: 9; }
/* 격자 폭을 다 쓰는 것들. 업로드 진행 패널은 맨 아래에 깔린다. */
.of-album .ph-group.is-active > .ph-album__empty { grid-column: 1 / -1; order: -1; }
.of-album .ph-group.is-active > .ph-plan { grid-column: 1 / -1; order: 10; }
/* 분류 전 칸은 격자 칸이 아니라 통짜 블록이다 — 머리글이 있어야 무엇인지 알 수 있다. */
.of-album .ph-group:not(.is-active) { grid-column: 1 / -1; order: 20; }

/*
 * 올리기 자리 — 사진 타일과 **같은 크기의 빈 칸**이다.
 * 예전에는 격자 위 얇은 점선 줄이었는데, 그러면 '사진을 더 넣는 곳' 이 격자 밖에 있어
 * 격자를 다 채운 사람 눈에 안 들어온다.
 */
.of-album .ph-drop {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; height: auto; margin: 0; padding: 0;
  background: var(--of-fill);
  border: 0; border-radius: var(--radius-sm);
}
.of-album .ph-drop__icon {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  color: var(--text-3);
  background: rgba(255, 255, 255, .9); border-radius: 50%;
}
.of-album .ph-drop__icon svg { width: 20px; height: 20px; }
.of-album .ph-drop__text { display: none; }
/*
 * 이 칸에 정확히 놓았을 때. 위에서 테두리를 없앴더니 `is-over` 가 배경만 바꿔
 * 바뀌었는지 알기 어려웠다. 점선을 도로 그린다.
 */
.of-album .ph-drop.is-over {
  background: var(--of-tint);
  box-shadow: inset 0 0 0 2px var(--of-blue);
}

.of-album .ph-item {
  /*
   * 선택 배지가 모서리 **밖으로** 나오므로 자르면 안 된다.
   * 대신 이미지 자체를 둥글게 깎는다.
   */
  overflow: visible;
  aspect-ratio: 1 / 1;
  background: transparent; border: 0; border-radius: 0;
}
.of-album .ph-item img {
  width: 100%; height: 100%;
  border-radius: var(--radius-sm);
  object-fit: cover;
}
.of-album .ph-pick.is-on { box-shadow: none; }

/*
 * 격자는 **흑백/컬러 한 가지 말**만 한다(시안 183:3295).
 *
 *   흑백   아직 우리 매장 사진이 없는 자리 — 본사가 깔아 둔 예시 가이드(`.of-eg`)
 *   컬러   내가 올린 우리 매장 사진
 *
 * 그래서 올린 사진에는 아무 필터도 걸지 않는다. 예전에 '올렸지만 안 고른 사진' 을 흑백으로
 * 뺐는데, 그러면 내 사진과 예시가 같은 색으로 보여 무엇을 올렸는지 알 수 없다.
 * 고름/안 고름은 가운데 `+` 와 모서리 `×` 가 말한다.
 */

/*
 * 고르는 표시.
 *
 * 안 고른 사진은 **가운데 큰 `+`**, 고른 사진은 **오른쪽 위 작은 `×`** 다.
 * 같은 요소(`.ph-pick__check`)를 상태에 따라 두 모양으로 쓴다 — 요소를 하나 더 두면
 * 사진첩 마크업을 고쳐야 하고, 그 파일은 본사 화면과 공유한다.
 */
.of-album .ph-pick__check {
  top: 50%; right: auto; left: 50%;
  width: 38px; height: 38px;
  transform: translate(-50%, -50%);
  background: rgba(255, 255, 255, .9);
  border: 0; box-shadow: none;
  color: var(--text-2);
}
.of-album .ph-pick__check svg { display: none; }
.of-album .ph-pick__check::after {
  content: '+';
  font-size: 20px; font-weight: 400; line-height: 1;
}
/*
 * 고른 사진의 `×` — 모서리 **밖으로** 반쯤 걸친다(시안: 타일 오른쪽 위 20px).
 * 흰 원 위의 검은 `×` 다. 사진 위에 걸치는 절반이 있어 배경을 흰색으로 채운다 —
 * 투명하게 두면 밝은 사진 위에서 사라진다.
 */
.of-album .ph-pick.is-on .ph-pick__check {
  top: -8px; right: -8px; left: auto;
  width: 20px; height: 20px;
  transform: none;
  background: #fff; box-shadow: none;
  color: var(--text);
}
.of-album .ph-pick.is-on .ph-pick__check::after { content: '×'; font-size: 14px; }

/*
 * 대표·분류·삭제.
 *
 * 시안에는 없다. 그래도 남긴 이유 — 이 레이어가 점주가 **자기 사진을 관리할 수 있는
 * 유일한 자리**다. 여기서 걷어내면 잘못 올린 사진을 지울 방법도, 썸네일로 나갈 한 장을
 * 고를 방법도 없어진다. 대신 타일 아래 한 줄로 눌러 두어 시안의 격자를 흐리지 않는다.
 */
.of-album .ph-item__bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  gap: 4px; padding: 2px 4px;
  font-size: 12px; color: #fff;
  background: rgba(0, 0, 0, .45);
  border: 0; border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}
.of-album .ph-item__caption { display: none; }
.of-album .ph-item__move {
  flex: 1; min-width: 0; height: 18px; padding: 0 2px;
  font-size: 12px; color: #fff;
  background: transparent; border: 0;
}
.of-album .ph-item__move option { color: var(--text); }
.of-album .ph-item__del { width: 16px; height: 16px; font-size: 14px; color: #fff; }
.of-album .ph-item__del:hover { color: #fff; background: rgba(255, 255, 255, .25); }
.of-album .ph-item__main {
  top: auto; bottom: 24px; left: 4px; right: auto;
  padding: 2px 6px; font-size: 12px;
}
.of-album .ph-item__badge { top: 4px; left: 4px; font-size: 9.5px; padding: 2px 6px; }

/*
 * 예시 가이드 = **아직 안 채운 자리**다.
 *
 * 사진 격자와 **같은 격자의 칸**이다(위 `.of-album__body` 참고). 그 칸의 사진이 늘면
 * 앞에서부터 그만큼 걷어 낸다(`syncGuideSlots()`) — 올린 사진이 예시 자리를 대신한다.
 * 흐리게 두는 이유 — 내가 올린 사진과 예시가 같은 무게로 보이면 뭘 올렸는지 헷갈린다.
 */
/* 상자는 녹이고 안의 자리만 격자 칸이 된다. 사진 뒤·올리기 칸 앞. */
.of-album__guides { display: contents; }
.of-album__guides.of-hide { display: none; }
.of-eg { order: 5; }
/* 이미 채운 자리는 걷는다. `[hidden]` 이 다른 규칙에 지지 않게 못 박는다. */
.of-eg[hidden] { display: none !important; }
/*
 * 이름은 `.of-eg`(example guide) 다. **`.of-guide` 를 쓰면 안 된다** —
 * 그 이름은 위쪽 접수 폼의 `본사 가이드` 상자가 이미 쓰고 있고, 같은 특이도라
 * 뒤에 오는 이 규칙이 앞을 덮어써 그 상자가 정사각형 투명 버튼이 된다.
 * (이 파일 달력 절 머리에 적어 둔 `.ads-kw` 전례와 똑같은 사고였다.)
 */
.of-eg {
  position: relative;
  aspect-ratio: 1 / 1; padding: 0;
  background: transparent; border: 0; cursor: pointer;
}
/* 예시 이미지가 없는 자리. 빈 칸이라도 '여기 한 장' 이라는 말은 해야 한다. */
.of-eg--blank { background: var(--of-fill); border-radius: var(--radius-sm); }
/*
 * 예시 이미지는 **흑백**이다 — 아직 우리 매장 사진이 아니라는 말을 색으로 한다.
 * 그 자리에 사진을 올리면 자리가 걷히고(`syncGuideSlots()`) 컬러 사진이 대신 선다.
 */
.of-eg img {
  width: 100%; height: 100%;
  object-fit: cover; border-radius: var(--radius-sm);
  filter: grayscale(1); opacity: .8;
}
.of-eg:hover img { opacity: 1; }
.of-eg__add {
  position: absolute; top: 50%; left: 50%;
  width: 38px; height: 38px;
  transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  background: rgba(255, 255, 255, .9);
  border-radius: 50%; box-shadow: var(--shadow-2);
}
.of-eg__add svg { width: 20px; height: 20px; }
.of-eg__caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 2px 4px;
  font-size: 12px; color: #fff; text-align: center;
  background: rgba(0, 0, 0, .45);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}

/* 시안 버튼 — 169×54, radius 6. */
.of-album__foot {
  gap: 8px; justify-content: center;
  padding: 20px 0 0; border: 0;
}
.of-album__btn {
  width: 169px; max-width: 50%; height: 54px;
  font-size: 16px; color: #1e2124;
  background: #f1f4f6;
  border: 0; border-radius: 6px; cursor: pointer;
}
.of-album__btn--go { color: #fff; background: var(--of-blue); }

/* ── 결제 시트 ─────────────────────────────────────────────── */
/*
 * `.modal` 은 `ops.css` 것이라 **고치지 않는다**(관리자 화면까지 흔들린다).
 * 여기서 정렬만 덮어 가운데 모달을 바닥 시트로 만든다.
 */
.of-sheet-modal { align-items: flex-end; padding: 0; }
.of-sheet {
  width: 100%; max-width: 608px; margin: 0 auto;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  animation: ofSheetUp .24s var(--ease);
}
@keyframes ofSheetUp { from { transform: translateY(16px); opacity: 0 } to { transform: none; opacity: 1 } }
.of-sheet__grip {
  width: 36px; height: 6px; margin: 8px auto 0;
  background: #d9d9d9; border-radius: 100px;
}
.of-sheet__body { padding: 26px 18px 0; }
/*
 * `.select` 의 화살표 배경은 그대로 두고 크기·색만 시안에 맞춘다.
 * 그 배경을 지우면 이 화면에만 화살표 없는 select 가 생긴다.
 */
.of-sheet__product {
  width: 100%; height: 46px; padding: 0 40px 0 10px;
  font-size: 14px; font-weight: 500; color: var(--text-2);
  background-color: var(--surface);
  background-position: right 11px center;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm);
}
.of-sheet__row {
  display: flex; align-items: center; gap: 10px;
  margin-top: 18px;
}
.of-sheet__label { flex: 1; font-size: 14px; font-weight: 500; color: var(--text-2); }

/*
 * 스테퍼는 **세 칸이 맞붙은 한 덩어리**다(시안 36×36 셋). 사이를 띄우면 세 개의 버튼처럼
 * 보이고, 가운데 숫자가 입력칸이라는 것이 읽히지 않는다.
 */
.of-step { display: flex; align-items: center; }
.of-step__btn {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--hm-line); border-radius: 0; cursor: pointer;
}
.of-step__btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.of-step__btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.of-step__btn svg { width: 16px; height: 16px; }
.of-step__num {
  width: 36px; height: 36px; padding: 0;
  font-size: 16px; font-weight: 500; text-align: center; color: var(--text-2);
  background: var(--surface);
  /* 가운데만 파란 테두리 — 여기가 **직접 칠 수 있는 칸**이라는 표시다. */
  border: 1px solid var(--accent); border-radius: 0;
  margin: 0 -0px; position: relative; z-index: 1;
}
/* 숫자 입력칸의 브라우저 기본 스피너는 지운다 — 옆에 ⊖⊕ 가 이미 있다. */
.of-step__num::-webkit-outer-spin-button,
.of-step__num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.of-step__num { -moz-appearance: textfield; }

.of-sheet__line {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-top: 12px;
  font-size: 14px; font-weight: 700; color: var(--text-2);
}
.of-sheet__line--total {
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--hm-line);
  font-size: 16px;
}
.of-sheet__line--total em { font-style: normal; font-size: 12px; font-weight: 400; }
.of-sheet__line--total strong { font-size: 24px; line-height: 24px; color: var(--accent); }
/* 시안 빨강은 `--danger`(#ff3b30)와 다른 값이라 따로 둔다. */
.of-sheet__shortage { margin: 20px 0 0; font-size: 14px; color: #ef4444; }
.of-sheet__foot {
  display: flex; gap: 4px;
  padding: 22px 19px calc(16px + env(safe-area-inset-bottom));
}
.of-sheet__foot .btn {
  flex: 1; height: 46px;
  font-size: 14px; font-weight: 700; border-radius: var(--radius-sm);
}

/* ═════════════════════  접수 화면 달력 (/ads/orders/new)  ═════════════════════
 * `.of-` 접두는 **새 접수 화면 전용**이다(of = order form).
 * 옛 화면(`/orders/new/legacy`)이 쓰는 `.ads-product*` · `.ads-tag*` · `.ads-range` ·
 * `.ads-chip*` · `.ads-amount*` · `.kr__*` 은 한 줄도 건드리지 않는다.
 * 예전에 `.ads-kw` 를 두 컴포넌트가 나눠 쓰다 뒤 규칙이 앞을 덮어써 깨진 전례가 있다.
 *
 * 달력은 `<body>` 바로 밑에 붙는다(부모의 `overflow` 에 잘리지 않게).
 * 그래서 `.hm` 안이 아니라 여기 최상위 규칙으로 둔다.
 */
.of-cal {
  position: absolute; z-index: 120;
  width: 320px; padding: 14px;
  /* 세로가 짧은 화면에서 `선택` 버튼이 화면 밖에 남지 않게. JS 의 위치 보정과 짝이다. */
  max-height: calc(100vh - 16px); overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  letter-spacing: -.03em;
}
.of-cal[hidden] { display: none !important; }

.of-cal__head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.of-cal__pick { flex: 1; display: flex; justify-content: center; gap: 6px; }
/*
 * 년·월은 **브라우저 기본 select** 다. 손으로 만든 드롭다운을 쓰지 않는다 —
 * iOS 에서 휠 피커가 공짜로 붙고, 스크린리더가 이미 아는 컨트롤이다.
 */
.of-cal__select {
  padding: 4px 6px;
  font-size: 14px; font-weight: 700; color: var(--text);
  background: transparent; border: 0; border-radius: var(--radius-sm);
  cursor: pointer;
}
.of-cal__select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.of-cal__nav {
  width: 28px; height: 28px; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; color: var(--text-2);
  background: transparent; border: 0; border-radius: 50%; cursor: pointer;
}
.of-cal__nav:hover { background: var(--surface-2); color: var(--text); }

.of-cal__week {
  display: grid; grid-template-columns: repeat(7, 1fr);
  margin-bottom: 2px;
  font-size: 12px; font-weight: 600; color: var(--text-3); text-align: center;
}
.of-cal__month {
  margin: 6px 0 4px;
  font-size: 12px; font-weight: 600; color: var(--text-2);
}

.of-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); }

/*
 * 기간 표시가 두 겹인 이유.
 *
 * 띠(`.is-in`)는 **칸** 배경이고 양끝 동그라미는 **버튼** 배경이다. 한 요소에 둘 다 주면
 * 겹쳐 그릴 수가 없다 — 사이를 잇는 띠는 칸 끝까지 차야 하고, 동그라미는 칸 안에 들어와야 한다.
 */
.of-cal__cell { display: block; }
.of-cal__cell.is-in { background: var(--accent-soft); }
/* 양끝은 바깥쪽 모서리를 둥글게 잘라 띠가 뭉툭하게 끝나지 않게 한다. */
.of-cal__cell.is-start { border-radius: 50% 0 0 50%; }
.of-cal__cell.is-end { border-radius: 0 50% 50% 0; }
.of-cal__cell.is-start.is-end { border-radius: 50%; }

.of-cal__day {
  width: 100%; height: 34px;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; color: var(--text);
  background: transparent; border: 0; border-radius: 50%; cursor: pointer;
}
.of-cal__day:disabled { color: var(--text-3); opacity: .45; cursor: default; }
/* 지난달·다음달 날짜. 빈칸으로 두면 달력이 끊겨 보인다. */
.of-cal__day.is-out { color: var(--text-3); }
/*
 * 오늘.
 *
 * 굵기만 주면 다른 날과 구별이 안 된다 — `오늘` 버튼을 누른 뒤 어디로 갔는지 보이지
 * 않으면 버튼이 안 먹은 것으로 읽힌다. 밑에 점을 찍어 눈으로 잡히게 한다.
 */
.of-cal__day.is-today { position: relative; font-weight: 700; }
.of-cal__day.is-today::after {
  content: ''; position: absolute; left: 50%; bottom: 4px;
  width: 4px; height: 4px; margin-left: -2px;
  background: var(--accent); border-radius: 50%;
}
.of-cal__day.is-today.is-edge::after { background: #fff; }
.of-cal__day.is-today:disabled::after { background: var(--text-3); }
.of-cal__day:not(:disabled):not(.is-edge):hover { background: var(--surface-2); }
/* 양끝. `is-out` 보다 뒤에 와야 지난달 칸을 골랐을 때도 글자가 하얗게 남는다. */
.of-cal__day.is-edge { background: var(--accent); color: #fff; font-weight: 650; }

.of-cal__hint {
  margin: 8px 0 0;
  min-height: 17px;
  font-size: 12px; color: var(--text-2);
}
.of-cal__foot {
  display: flex; align-items: center; gap: 6px;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--border);
}
.of-cal__spacer { flex: 1; }

/* 좁은 화면에서는 바닥에서 올라오는 시트가 된다. JS 는 좌표를 건드리지 않는다. */
@media (max-width: 520px) {
  .of-cal {
    position: fixed;
    top: auto !important; left: 0 !important; right: 0; bottom: 0;
    width: auto;
    padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
    border: 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }
  .of-cal__day { height: 40px; font-size: 14px; }
}

/* ════════════════════════════════════════════════════════════════════════
   캐시 충전 (/ads/charge) · 내 정보 (/ads/me) · 세금계산서 정보 (/ads/tax-info)
   `.ch-*` · `.me-*` · `.tx-*`
   ────────────────────────────────────────────────────────────────────────
   2026-09-17 개편. 이 셋만 옛 관리자 틀(`.card`·`.field`·`.ads-stat`·2열 `.ads-wallet`)로
   남아 있어, 탭바에서 한 칸 옮겼을 뿐인데 다른 앱처럼 보였다. 껍데기를 `.hm`(584px) 로 맞췄다.
   **이로써 점주 화면에 옛 틀은 남지 않았다**(`/main/legacy`·`/orders/legacy` 같은 동결 화면만 예외).

   그 셋만 쓰던 규칙 여덟 묶음(`.ads-wallet`·`.ads-money`·`.ads-calc`·`.ads-after`·`.ads-guide`·
   `.ads-bank`·`.ads-account`·`.ads-doc*`)은 **같이 지웠다.** www 전체(.php·.js)에서 참조가
   0건임을 확인하고 지웠다 — 이 셋에는 legacy 화면이 없어서 되돌아갈 곳이 없다.
   쓰는 화면이 없는 규칙을 남기면 다음 사람이 "어디에 쓰이나" 부터 찾게 된다.

   ⚠️ 반대로 `.ads-chip*`·`.ads-dl`·`.ads-stat*`·`.ads-page-head` 는 **남겨 뒀다** —
   옛 주문·옛 홈·로그인·본사 화면이 아직 쓴다.

   금액 블록은 접수 화면의 `.ov-total`, 배지는 주문 목록의 `.ol-badge`, 팁·경고는 `.ov-tip`·
   `.ov-notice` 를 **그대로** 쓴다. 같은 뜻이 화면마다 다르게 생기지 않게 하는 것이 이 개편의 요점이다.
   세금계산서 입력칸은 아예 내 정보 것(`.me-form`·`.me-field`·`.hm-input`)을 빌려 쓴다.
   ════════════════════════════════════════════════════════════════════════ */

/*
 * 글씨를 넣는 칸 — 두 화면이 같이 쓴다(`.hm` 껍데기의 부품이라 접두어도 `hm-`).
 * 진단 화면의 `.dg-input` 과 같은 높이·같은 테두리인데, 저쪽은 왼쪽에 돋보기 아이콘이 있어
 * 왼쪽 여백이 44px 다. 아이콘 없는 칸을 따로 둔다.
 */
.hm-input {
  width: 100%; height: 52px; padding: 0 16px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface);
  font: inherit; font-size: 16px; letter-spacing: inherit; color: var(--text);
}
.hm-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.hm-input::placeholder { color: var(--text-3); }

/* ── 충전: 머리 ── */
.ch-head { margin-bottom: 16px; }
.ch-head .hm-greet { margin-bottom: 4px; }
.ch-sub { margin: 0; font-size: 14px; line-height: 22px; color: var(--hm-dim); }

/*
 * 지금 캐시 — 이 화면에 들어온 이유라 숫자 하나만 크게 세운다.
 * 대기 중 입금은 **캐시가 아니다.** 같은 크기로 나란히 두면 합쳐서 읽으므로 작은 한 줄로 밑에 붙인다.
 */
.ch-balance { padding: 24px 20px; text-align: center; }
.ch-balance__label { margin: 0; font-size: 14px; color: var(--hm-ink); }
.ch-balance__value {
  margin: 6px 0 0;
  font-size: clamp(32px, 9vw, 40px); font-weight: 800; line-height: 1.1; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.ch-balance__value small { margin-left: 2px; font-size: 18px; font-weight: 700; }
.ch-balance__pending {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 12px 0 0; padding-top: 12px; border-top: 1px solid var(--hm-line);
  font-size: 14px; color: var(--hm-ink);
}
.ch-balance__pending svg { flex: none; width: 16px; height: 16px; color: var(--hm-dim); }
.ch-balance__pending b { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }

/* ── 충전·내 정보: 카드 속 제목 ── */
.ch-card, .me-card { padding: 24px 20px; }
.ch-h, .me-h {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 14px; font-size: 18px; font-weight: 700; line-height: 26px; color: var(--text);
}
/*
 * 한 카드 안의 다음 토막.
 *
 * 충전은 **금액 → 입금자명 → 낼 금액 → 계좌 → 버튼** 이 한 흐름이라 카드를 쪼개지 않았다.
 * 카드로 쪼개면 계좌가 버튼과 다른 상자에 들어가, 좁은 화면에서 또 멀어진다.
 * 대신 줄 하나로 토막을 나눈다.
 */
.ch-h--next { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--hm-line); }
.ch-h__n { margin-left: auto; font-size: 14px; font-weight: 600; color: var(--hm-dim); }

/* ── 금액 ── */
.ch-money {
  display: flex; align-items: baseline; gap: 8px;
  padding: 12px 18px;
  border: 2px solid var(--hm-line); border-radius: var(--radius-lg); background: var(--surface);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.ch-money:focus-within { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.ch-money__input {
  flex: 1; min-width: 0; width: 100%; padding: 0; border: 0; background: none;
  font: inherit; font-size: clamp(28px, 8vw, 34px); font-weight: 800; letter-spacing: inherit;
  text-align: right; color: var(--text); font-variant-numeric: tabular-nums;
}
.ch-money__input:focus { outline: none; }
.ch-money__input::placeholder { color: var(--hm-track); }
.ch-money__unit { flex: none; font-size: 18px; font-weight: 700; color: var(--hm-ink); }

/* 누르면 **더한다.** 10만 → 30만이 세 번 누르기로 끝난다(갈아치우면 매번 지우고 다시 쳐야 한다). */
.ch-quick { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.ch-quick__btn {
  display: inline-flex; align-items: center; gap: 4px;
  height: 38px; padding: 0 14px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 14px; font-weight: 700; letter-spacing: inherit;
  color: var(--accent); cursor: pointer;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.ch-quick__btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.ch-quick__btn svg { width: 15px; height: 15px; }
.ch-quick__btn--reset { color: var(--hm-dim); }
.ch-quick__btn--reset:hover { border-color: var(--hm-line); background: var(--surface-2); }

.ch-min { margin: 12px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-dim); word-break: keep-all; }
/* 모자랄 때만 붉게. 늘 붉으면 최소 금액 안내가 경고처럼 읽혀 첫 화면부터 겁을 준다. */
.ch-min.is-short { font-weight: 700; color: var(--hm-bad); }

.ch-tip { margin-top: 12px; }

/* ── 낼 금액 ── */
.ch-calc { margin: 0; }
.ch-calc__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 8px 0; font-size: 14px;
}
.ch-calc__row dt { color: var(--hm-ink); }
.ch-calc__row dd { margin: 0; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.ch-total { margin-top: 6px; }
.ch-after { margin-top: 10px; }

/* ── 계좌: 버튼 바로 위 ── */
.ch-bank {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px;
  margin-top: 20px; padding: 14px 16px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface-2);
}
.ch-bank__label { flex: none; font-size: 14px; font-weight: 700; color: var(--hm-dim); }
/* 계좌는 줄바꿈을 허용한다 — `국민 123456-78-901234 (주)뷰쓰리` 가 좁은 화면에서 넘친다. */
.ch-bank__value {
  flex: 1 1 100%; min-width: 0; order: 1;
  font-size: 16px; font-weight: 700; line-height: 24px; color: var(--text);
  font-variant-numeric: tabular-nums; word-break: break-all;
}
.ch-bank__copy {
  flex: none; margin-left: auto;
  display: inline-flex; align-items: center; gap: 4px;
  height: 30px; padding: 0 12px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 14px; font-weight: 700; letter-spacing: inherit;
  color: var(--accent); cursor: pointer;
}
.ch-bank__copy:hover { border-color: var(--accent); }
.ch-bank__copy svg { width: 14px; height: 14px; }

/* `.ov-notice` 는 접수 화면에서 카드 맨 위에 서느라 아래 여백을 갖고 있다. 여기서는 사이에 낀다. */
.ch-notice { margin: 12px 0 0; }
.me-notice { margin: 0 0 16px; }

.ch-submit { width: 100%; margin-top: 16px; }
.ch-foot { margin: 10px 0 0; font-size: 14px; line-height: 22px; text-align: center; color: var(--hm-dim); word-break: keep-all; }

/* ── 충전 내역 ── */
.ch-empty { margin: 0; padding: 12px 0 4px; font-size: 14px; color: var(--hm-dim); }
.ch-list { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
/*
 * 색은 `ol-card--{tone}` 이 변수(`--ol-tone`·`--ol-tone-soft`)로만 정해 주고 `.ol-badge` 가 읽는다.
 * ⚠️ 바탕은 여기서 정하지 않는다 — `ol-card--muted`(취소된 요청)가 바탕까지 눌러 주는데,
 * 이 규칙이 뒤에 있어 `background` 를 적으면 그걸 덮어써 취소 건이 살아 있는 건과 같아 보인다.
 */
.ch-item { padding: 14px 16px; border: 1px solid var(--hm-line); border-radius: var(--radius-sm); }
.ch-item__top { display: flex; align-items: center; gap: 8px; }
.ch-item__amount { flex: none; font-size: 18px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.ch-item__del {
  flex: none; margin-left: auto; padding: 4px 10px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-full); background: var(--surface);
  font: inherit; font-size: 12px; letter-spacing: inherit; color: var(--hm-dim); cursor: pointer;
}
.ch-item__del:hover { border-color: var(--hm-bad); color: var(--hm-bad); }
.ch-item__meta { margin: 8px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-ink); font-variant-numeric: tabular-nums; }
/* 거절 사유는 목록에서 바로 읽혀야 한다 — 이유를 모르면 같은 실수를 그대로 반복한다. */
.ch-item__reason {
  margin: 8px 0 0; padding: 8px 10px;
  border-left: 3px solid var(--ol-tone, var(--hm-bad)); border-radius: var(--radius-sm);
  background: var(--ol-tone-soft, var(--danger-soft));
  font-size: 14px; line-height: 22px; color: var(--text); white-space: pre-line;
}

/* ── 세금 정보 모달 ── */
.ch-modal { padding: 32px 24px; text-align: center; }
.ch-modal__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; margin-bottom: 16px;
  border-radius: 50%; background: var(--warning-soft); color: #b86e00;
}
.ch-modal__icon svg { width: 26px; height: 26px; }
.ch-modal__title { margin: 0 0 8px; font-size: 18px; font-weight: 700; color: var(--text); }
.ch-modal__text { margin: 0 0 20px; font-size: 14px; line-height: 22px; color: var(--hm-ink); word-break: keep-all; }
.ch-modal__later { margin-top: 8px; }

/* ──────────────────────────  내 정보 (/ads/me)  ────────────────────────── */

/*
 * 읽기만 하는 값.
 *
 * 예전에는 `disabled` 인 입력칸이었다 — 입력칸 모양은 "여기에 쓰라" 는 뜻이라
 * 눌러도 안 써지면 고장으로 읽힌다. 주문 상세의 `.odp-dl` 과 같은 모양으로 맞춘다.
 */
.me-dl { margin: 0; }
.me-dl__row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--hm-line); font-size: 14px;
}
.me-dl__row:first-child { padding-top: 0; }
.me-dl__row:last-child { padding-bottom: 0; border-bottom: 0; }
.me-dl dt { flex: none; width: 108px; color: var(--hm-dim); word-break: keep-all; }
.me-dl dd {
  flex: 1; min-width: 0; margin: 0;
  font-weight: 600; line-height: 1.5; text-align: right; color: var(--text); word-break: break-word;
}
.me-dl dd.is-num { font-variant-numeric: tabular-nums; }
.me-dash { font-weight: 400; color: var(--hm-dim); }

.me-doc { display: inline-flex; align-items: center; gap: 4px; margin-left: 8px; color: var(--accent); }
.me-doc:first-child { margin-left: 0; }
.me-doc svg { flex: none; width: 15px; height: 15px; }

.me-note { margin: 14px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-dim); word-break: keep-all; }

/* ── 비밀번호: 이 화면에서 유일하게 쓰는 칸 ── */
.me-form { display: grid; gap: 14px; }
.me-field { display: block; }
.me-field__label { display: block; margin-bottom: 6px; font-size: 14px; font-weight: 600; color: var(--hm-ink); }
.me-hint { margin: -4px 0 0; font-size: 14px; line-height: 22px; color: var(--hm-dim); word-break: keep-all; }

/* ── 세금계산서(읽기 전용) ── */
.me-store.is-next { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--hm-line); }
.me-store__name {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 10px; font-size: 16px; font-weight: 700; color: var(--text);
}
.me-edit { margin-top: 18px; }

/*
 * 로그아웃 — 카드로 감싸지 않는다.
 * 카드로 두면 계정·비밀번호·세금 정보와 같은 무게로 서서, 훑어 내려오다 그냥 눌린다.
 */
.me-logout {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 14px; margin-top: 4px;
  font-size: 14px; font-weight: 600; color: var(--hm-dim);
}
.me-logout:hover { color: var(--hm-bad); text-decoration: none; }
.me-logout svg { width: 17px; height: 17px; }

@media (max-width: 640px) {
  .ch-card, .me-card, .ch-balance { padding: 20px 16px; }
  .me-dl dt { width: 92px; }
}

/* ──────────────────────  세금계산서 정보 (/ads/tax-info)  ──────────────────────
 * 충전에서 [사업자 정보 넣으러 가기] 로 바로 넘어오는 화면이라, 입력칸 한 벌은
 * 내 정보의 비밀번호 칸(`.me-form`·`.me-field`·`.hm-input`)을 **그대로** 쓴다.
 * 여기 있는 것은 이 화면에만 있는 조각뿐이다. */

/* 필수 표시. `ops.css` 의 `.req` 는 `.field__label` 안에서만 걸려 새 라벨에는 안 먹는다. */
.tx-req { margin-left: 2px; font-style: normal; font-weight: 700; color: var(--hm-bad); }

/* 입력칸 밑 설명 — 라벨과 달리 `<span>` 이라 줄을 따로 만들어 준다. */
.tx-hint { display: block; margin: 6px 0 0; }

/*
 * 다 채운 뒤 다시 들어온 길에서 맨 위에 서는 **돌아갈 문**.
 * 카드가 아니라 한 줄짜리 링크다 — 이 화면의 일은 이미 끝났고, 여기서 할 일은 나가는 것뿐이다.
 */
.tx-done {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 16px; padding: 12px 16px;
  border-radius: var(--radius-sm); background: var(--success-soft);
  font-size: 14px; color: var(--text);
}
.tx-done:hover { text-decoration: none; }
.tx-done > svg:first-child { flex: none; width: 18px; height: 18px; color: var(--hm-good); }
.tx-done > svg:last-child { flex: none; width: 18px; height: 18px; margin-left: auto; color: var(--hm-dim); }
.tx-done span { min-width: 0; }
.tx-done b { font-weight: 700; color: var(--hm-good); }

.tx-multi { margin: 0 0 16px; }

/* ── 사업자등록증 ── */
/*
 * 위 `<form>` 밖이다(파일은 고른 즉시 올라간다). 선 하나로 갈라 두면
 * [저장] 이 파일까지 같이 보내는 것처럼 읽히지 않는다.
 */
.tx-docs { margin-top: 24px; padding-top: 22px; border-top: 1px solid var(--hm-line); }
.tx-h3 { margin: 0 0 12px; font-size: 14px; font-weight: 600; color: var(--hm-ink); }

.tx-doclist { display: grid; gap: 8px; margin: 0 0 12px; padding: 0; list-style: none; }
.tx-doc {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--hm-line); border-radius: var(--radius-sm); background: var(--surface-2);
}
.tx-doc__link {
  flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: 6px;
  font-size: 14px; color: var(--accent);
}
.tx-doc__link svg { flex: none; width: 16px; height: 16px; }
.tx-doc__link span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/*
 * 파일 고르기 — `<label>` 이 곧 버튼이다(안의 `<input type=file>` 은 숨어 있다).
 * 점선 테두리로 "여기에 넣는 자리" 라는 것을 사진첩(`.ph-drop`)과 같은 말투로 말한다.
 */
.tx-pick {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  height: 46px; padding: 0 16px;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); background: var(--surface);
  font-size: 14px; font-weight: 600; color: var(--accent); cursor: pointer;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.tx-pick:hover { border-color: var(--accent); background: var(--accent-soft); }
.tx-pick svg { width: 16px; height: 16px; }

/* ── 마지막 줄 ── */
/*
 * 덜 채웠으면 버튼을 **감추지 않고 잠근다.** 감추면 왜 못 가는지 알 수 없다.
 * `.ov-cta:disabled` 는 `opacity: .4` 라 글자가 안 읽힌다 — 이 버튼은 그 글자가 곧 안내라 더 진하게 둔다.
 */
.tx-go { width: 100%; margin-top: 4px; }
.tx-go:disabled { opacity: 1; background: var(--hm-track); color: var(--hm-ink); font-size: 16px; }

/* 조용한 글자 링크. 카드로 감싸면 [충전 계속하기] 와 같은 무게로 서서 무엇이 본래 할 일인지 흐려진다. */
.tx-later {
  display: block; padding: 14px; margin-top: 4px;
  font-size: 14px; font-weight: 600; text-align: center; color: var(--hm-dim);
}
.tx-later:hover { color: var(--text); text-decoration: none; }

@media (max-width: 640px) {
  .tx-card { padding: 20px 16px; }
}

/* ── 매장 정보 줄 — 네이버 검색 결과의 플레이스 정보와 같은 모양(2026-09-22, `partial/_place_info.php`) ──
 * 회색 18px 아이콘 + 한 줄 글, 줄 사이 8px. 사진 아래에 가는 선 하나로 갈라 붙인다.
 * `지도` 는 네이버처럼 **파란 글자**다 — 테넌트 포인트색(빨강 등)으로 칠하면 경고처럼 읽힌다.
 *   고정 파랑은 주문 목록의 "접수 완료"(`.ol-card--info`)와 같은 값이다.
 */
.pi { --pi-link: #0071e3; --pi-ico: #b8b9bd; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--hm-line); display: grid; gap: 8px; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .pi { --pi-link: #4da3ff; --pi-ico: #6e6f75; } }
:root[data-theme="dark"] .pi { --pi-link: #4da3ff; --pi-ico: #6e6f75; }
.pi-row { display: flex; align-items: flex-start; gap: 10px; font-size: 16px; line-height: 24px; color: var(--text); }
.pi-row__ico { flex: none; display: flex; width: 18px; height: 24px; align-items: center; color: var(--pi-ico); }
.pi-row__ico svg { width: 18px; height: 18px; }
.pi-row__body { flex: 1; min-width: 0; word-break: keep-all; overflow-wrap: anywhere; }
.pi-blind { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.pi-toggle {
  display: inline; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; letter-spacing: inherit; text-align: left; color: inherit;
}
.pi-toggle__chev { display: inline-flex; margin-left: 6px; vertical-align: 2px; color: var(--hm-dim); transition: transform .15s var(--ease); }
.pi-toggle__chev svg { width: 12px; height: 8px; }
.pi-toggle[aria-expanded="true"] .pi-toggle__chev { transform: rotate(180deg); }
.pi-link { margin-left: 8px; color: var(--pi-link); white-space: nowrap; }
.pi-link:hover { text-decoration: underline; }
.pi-tel { color: inherit; }
.pi-tel:hover { color: var(--pi-link); text-decoration: none; }
.pi-more { margin-top: 8px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-2); display: grid; gap: 6px; font-size: 14px; line-height: 22px; color: var(--hm-ink); }
.pi-more p { margin: 0; }
.pi-tag {
  display: inline-block; margin-right: 6px; padding: 0 6px; border: 1px solid var(--hm-line); border-radius: 4px;
  font-size: 12px; line-height: 20px; color: var(--hm-dim); background: var(--surface);
}
.pi-more__guide { padding-top: 6px; border-top: 1px dashed var(--hm-line); }

/* ════════════════════════════════════════════════════════════════════════
   AI 도우미(챗봇) 버튼 · 대화 조각 — `.cb-*` (2026-10-02, 2026-10-06 레이어로 바뀜)
   ────────────────────────────────────────────────────────────────────────
   2026-10-06 부터 버튼은 작은 창 대신 **전체 화면 레이어**(`.ai-layer`, 아래 `.ai-*` 절)를 연다.
   여기 남은 것은 버튼과, 레이어 안에서도 쓰는 대화 조각(말풍선·이동 버튼·입력·문의·탭)이다.
   작은 창(`.cb-panel`·`.cb-head`·질문 버튼 한 줄 등)은 `backup/ai-chatbot-20261006/ads.cb-ai.css` 에 있다.
   ────────────────────────────────────────────────────────────────────────
   마크업 `ads/page/partial/_chatbot.php`, 동작 `ads/assets/js/chatbot.js`.
   포털 레이아웃과 앱형 화면(진단·접수) 모두에 붙는다.

   층(z-index): 버튼 50 · 레이어 75. 메뉴 시트(60)보다 버튼은 낮고 레이어는 높다 —
   시트를 열면 버튼이 덮이고, 레이어를 연 채 시트를 열 일은 없다(레이어가 화면을 덮는다).
   접수 결제 시트(`.ov-sheet` 100)·토스트(200)는 늘 레이어 위다.

   색은 토큰(`--surface`·`--text`·`--accent`)만 쓴다 — 다크 모드는 ops.css 가 토큰을 바꿔 준다.
   ════════════════════════════════════════════════════════════════════════ */
.cb-fab {
  position: fixed; z-index: 50;
  right: 16px; bottom: calc(16px + env(safe-area-inset-bottom));
  display: inline-flex; align-items: center; gap: 6px;
  height: 52px; padding: 0 18px 0 16px;
  border: 0; border-radius: var(--radius-full);
  /*
   * 채팅 화면의 ✦ 구슬(`.ai-orb`)과 같은 옷(2026-10-06 요청) — 포인트색 그라데이션이 천천히 돌고 ✦ 가 반짝인다.
   * 버튼과 그 안 화면이 한 식구로 보이게. 도는 각도(`--ai-orb-a`)·반짝임(`ai-twinkle`)은 아래 `.ai-*` 절의 것을 같이 쓴다.
   * @property 를 모르는 브라우저는 그라데이션이 멈춰 있을 뿐이다.
   */
  background: conic-gradient(from var(--ai-orb-a, 0deg),
    var(--accent), color-mix(in srgb, var(--accent) 45%, #fff), var(--accent),
    color-mix(in srgb, var(--accent) 70%, #000), var(--accent));
  color: #fff;
  font: inherit; font-size: 15px; font-weight: 700;
  box-shadow: 0 10px 28px color-mix(in srgb, var(--accent) 38%, transparent);
  cursor: pointer;
  transform-origin: 85% 50%;
  transition: transform .32s var(--spring), opacity .2s var(--ease), box-shadow .2s var(--ease);
  animation: ai-orb-turn 6s linear infinite;
}
.cb-fab:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 16px 36px color-mix(in srgb, var(--accent) 45%, transparent); }
.cb-fab:active { transform: scale(.96); }
.cb-fab:focus-visible { outline: 3px solid var(--accent-edge); outline-offset: 2px; }
/* ✦ — 구슬과 같은 반짝임. 글자라 아이콘 svg 보다 구슬과 똑같이 보인다. */
.cb-fab__ico { display: inline-grid; place-items: center; width: 22px; height: 22px; font-size: 17px; line-height: 1; }
.cb-fab__ico::before { content: "✦"; animation: ai-twinkle 2.4s ease-in-out infinite; }
.cb-fab:hover .cb-fab__ico::before { animation-duration: .9s; }
/*
 * 화면에 들어오면 버튼 둘레에 은은한 빛 고리가 두 번 퍼진다(2026-10-02 "있어 보이게" 요청).
 * 계속 깜빡이면 거슬리므로 두 번만이다. 고리는 버튼 뒤 가상 요소라 클릭을 가로채지 않는다.
 */
.cb-fab::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: var(--accent); opacity: 0; pointer-events: none;
  animation: cb-fab-ring 1.8s var(--ease) .6s 2;
}
@keyframes cb-fab-ring {
  0% { transform: scale(1); opacity: .45; }
  100% { transform: scale(1.35, 1.6); opacity: 0; }
}
/* 접수(옛 화면)의 하단 고정 결제 바(132px) 위로 올린다. */
body:has(.of-bar) .cb-fab { bottom: calc(148px + env(safe-area-inset-bottom)); }
/* 레이어를 연 동안 버튼은 레이어 속으로 빨려 들어가듯 작아지며 사라진다(레이어 머리에 닫기가 있다). */
html.cb-open .cb-fab { transform: scale(.4); opacity: 0; pointer-events: none; }
html.cb-open .cb-fab::before { animation: none; }
/* 폰에서도 'AI 도우미' 글자를 남긴다(2026-10-02 요청) — 아이콘만으로는 무슨 버튼인지 모른다. */
@media (max-width: 520px) {
  .cb-fab { height: 46px; padding: 0 14px 0 12px; font-size: 14px; }
  .cb-fab__ico { width: 20px; height: 20px; }
}
/*
 * 폰·태블릿에서는 본문 끝에 버튼 높이만큼 여백을 더 준다 — 맨 아래 꽉 찬 버튼(`.hm-cta` 홈으로·다음 등)을
 * 도우미 버튼이 가리지 않게. 넓은 화면은 본문이 가운데 584~980px 라 오른쪽 아래와 겹치지 않는다.
 */
@media (max-width: 860px) {
  body:has(#cb-fab) .ads-main { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
  /*
   * 진단 첫 화면(`.dg-start`)은 세로를 꽉 채워 '홈으로'·'시작' 버튼을 화면 바닥에 붙인다 — 여백만 늘리면
   * 버튼은 그대로 바닥에 있고 아래로 스크롤만 생긴다. 채우는 높이를 도우미 버튼 자리(약 66px)만큼 줄인다.
   */
  body:has(#cb-fab) .dg-start {
    min-height: calc(100vh - 113px - 66px);
    min-height: calc(100dvh - 113px - 66px - env(safe-area-inset-bottom));
  }
}

/* 새 말풍선은 살짝 튀어 오르며 들어온다(지난 대화를 다시 그릴 때는 `.no-anim` 으로 끈다). */
.cb-msg, .cb-links, .cb-handoff, .cb-source { animation: cb-pop .36s var(--spring) both; }
.cb-msg--me { transform-origin: right bottom; }
.cb-msg--bot { transform-origin: left bottom; }
.cb-log .no-anim { animation: none; }
@keyframes cb-pop { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .cb-fab, .cb-fab__ico { transition: none; }
  .cb-fab, .cb-fab::before, .cb-fab__ico::before, .cb-msg, .cb-links, .cb-handoff, .cb-source { animation: none; }
}

.cb-tabs { display: flex; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--border); }
.cb-tab {
  padding: 8px 12px; border: 0; border-bottom: 2px solid transparent;
  background: none; color: var(--text-2); font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
}
.cb-tab.is-on { color: var(--text); border-bottom-color: var(--accent); }

.cb-log {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px 14px;
}
.cb-msg {
  max-width: 86%; padding: 10px 13px;
  border-radius: 16px; font-size: 14.5px; line-height: 1.55;
  overflow-wrap: anywhere;
}
.cb-msg--bot { align-self: flex-start; background: var(--surface-2); border: 1px solid var(--border); border-bottom-left-radius: 6px; }
.cb-msg--me { align-self: flex-end; background: var(--accent); color: #fff; border-bottom-right-radius: 6px; }
.cb-msg--note { color: var(--text-2); font-size: 13px; }
.cb-msg strong { font-weight: 700; }

/* 타이핑 중 끝에 깜빡이는 막대. 말풍선을 누르면 남은 글자를 한 번에 보여 준다(chatbot.js). */
.cb-msg.is-typing { cursor: pointer; }
.cb-msg.is-typing::after {
  content: ''; display: inline-block; width: 2px; height: 1em; margin-left: 2px; vertical-align: -2px;
  background: currentColor; animation: cb-caret .8s steps(1) infinite;
}
@keyframes cb-caret { 50% { opacity: 0; } }

/* 답 아래 화면 이동 버튼(2026-10-02) — 점주에게 주소를 보이지 않고 이것으로 보낸다. */
.cb-links { align-self: flex-start; display: flex; flex-wrap: wrap; gap: 6px; margin-top: -2px; }
.cb-link {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 8px 14px; border-radius: var(--radius-full);
  background: var(--accent); color: #fff; font-size: 13.5px; font-weight: 700; text-decoration: none;
}
.cb-link::after { content: '›'; font-size: 16px; line-height: 1; }
.cb-link:hover { filter: brightness(1.05); }

/* 저장된 답 아래 한 줄 — 어디서 온 답인지 + AI 에게 다시 묻기(2026-10-02). */
.cb-source { align-self: flex-start; margin-top: -4px; padding-left: 4px; font-size: 12px; color: var(--text-3); }
.cb-source__again {
  padding: 0; border: 0; background: none; color: var(--accent);
  font: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}

.cb-handoff { align-self: flex-start; }
.cb-handoff__btn {
  padding: 9px 14px; border: 1px solid var(--accent); border-radius: var(--radius-full);
  background: var(--surface); color: var(--accent); font: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer;
}

.cb-input {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 12px; border-top: 1px solid var(--border);
}
.cb-input[hidden] { display: none; }
.cb-input__box {
  flex: 1; min-height: 42px; max-height: 120px; resize: none;
  padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 12px;
  background: var(--surface); color: var(--text);
  /* 16px 아래면 iOS 사파리가 입력할 때 화면을 확대한다. */
  font: inherit; font-size: 16px; line-height: 1.4;
}
.cb-input__box:focus { outline: none; border-color: var(--accent); }
.cb-input__send {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; flex: none; border: 0; border-radius: 12px;
  background: var(--accent); color: #fff; cursor: pointer;
}
.cb-input__send svg { width: 18px; height: 18px; }
.cb-input.is-busy .cb-input__send { opacity: .4; pointer-events: none; }

.cb-ticket { padding: 12px 14px; border-top: 1px solid var(--border); background: var(--surface-2); }
.cb-ticket[hidden] { display: none; }
.cb-ticket__title { margin: 0; font-size: 14.5px; font-weight: 700; }
.cb-ticket__hint { margin: 2px 0 8px; font-size: 12.5px; color: var(--text-2); }
.cb-ticket__input {
  width: 100%; resize: vertical; padding: 10px 12px;
  border: 1px solid var(--border-strong); border-radius: 12px;
  background: var(--surface); color: var(--text); font: inherit; font-size: 16px; line-height: 1.4;
}
.cb-ticket__foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.cb-ticket__cancel, .cb-ticket__send {
  height: 38px; padding: 0 14px; border-radius: var(--radius-full); font: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
}
.cb-ticket__cancel { border: 1px solid var(--border); background: var(--surface); color: var(--text); }
.cb-ticket__send { border: 0; background: var(--accent); color: #fff; }

.cb-tickets { flex: 1; min-height: 0; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.cb-empty { margin: 24px 8px; text-align: center; font-size: 13.5px; color: var(--text-2); }
.cb-tk { padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.cb-tk__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cb-tk__badge {
  padding: 2px 8px; border-radius: var(--radius-full);
  background: var(--warning-soft); color: var(--text); font-size: 12px; font-weight: 700;
}
.cb-tk.is-answered .cb-tk__badge { background: var(--success-soft); }
.cb-tk__when { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.cb-tk__q { margin: 8px 0 0; font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.cb-tk__a { margin-top: 10px; padding: 10px 12px; border-radius: 10px; background: var(--surface-2); }
.cb-tk__a strong { display: block; font-size: 12px; color: var(--text-2); }
.cb-tk__a p { margin: 4px 0 0; font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }

/* ════════════════════════════════════════════════════════════════════════
   AI 도우미 대화 화면 · 레이어 — `.ai-*` (2026-10-06)
   ────────────────────────────────────────────────────────────────────────
   마크업 `ads/page/partial/_ai_chat.php` — 버튼이 여는 전체 화면 레이어(`.ai-layer`, `_chatbot.php`)와
   `/ads/ai` 직접 주소(`ai/index.php`)가 같이 쓴다. 동작은 `chatbot.js`. 모양은 LG AI Chat
   (lge.co.kr/ai-commerce/aiAssistant) — 얇은 상단 바, 왼쪽 정렬 큰 인사, ✦ 알약 질문,
   말풍선 없는 답, 바닥의 둥근 입력 시트. 대화·입력·문의 칸은 위젯의 `.cb-*` 를 그대로 쓰고
   여기서는 다른 점만 덮는다(`.ai .cb-msg--bot` 등).

   화면 높이를 꽉 채운 세로 띠다 — 상단 바 · 스크롤되는 본문(`.ai-main`) · 입력 시트.
   본문만 스크롤해서 입력 시트가 늘 바닥에 있다(폰 키보드는 viewport `interactive-widget` 으로 밀어 올린다).
   PC 는 글 기둥을 가운데 760px 로 묶는다(LG 는 왼쪽에 붙는데, 넓은 화면에서는 눈이 너무 멀리 간다).
   ════════════════════════════════════════════════════════════════════════ */
body.ai-body { padding-bottom: 0; background: var(--bg); }
.ai {
  display: flex; flex-direction: column;
  height: 100vh; height: 100dvh;
  color: var(--text);
}

/*
 * 레이어 — 막(curtain) 전환(2026-10-06, awwwards 참고 영상).
 * 레이어 자체는 움직이지 않고 그냥 보였다 숨는다. 그 순간을 **막이 가린다**:
 *   덮기  어두운 막이 아래에서 올라온다 — 윗변이 둥근 돔(가운데가 높다)이고, 다 덮을 즈음 평평해진다.
 *   걷기  막이 다시 아래로 내려간다 — 윗변이 다시 돔이 되며 위에서부터 새 화면이 드러난다.
 * 순서(덮기 → 바꾸기 → 걷기)는 chatbot.js `curtainSwap`. 앞선 시도(원 물결 · 아래서 올라오는 한 장)는 걷었다.
 *
 * 막의 모양: 화면보다 양옆으로 넓은 판(140vw)의 윗변을 타원으로 깎는다(`border-radius: 50% / 돔 높이`).
 * 넓게 잡아야 화면 양끝에서도 곡선이 이어진다(영상처럼 가장자리가 가운데보다 낮다).
 * 판 높이는 화면 + 돔 높이 — 평평해져 화면 끝까지 올라와도 아래가 비지 않는다.
 * 색: 처음엔 영상처럼 거의 검정이었는데 "레이어 이질감" 이 커서(2026-10-06) **반투명 유리막**으로 바꿨다 —
 * 바탕색을 반쯤 깔고 뒤를 흐리게(backdrop-filter) 비친다. 막 뒤에서 화면이 바뀌는 모습도 흐릿하게 비쳐 덜 끊겨 보인다.
 * 윗변에 얇은 흰 빛(inset 그림자)을 둬 유리 가장자리가 보이게 하고, 포인트색을 아주 옅게 섞는다.
 * backdrop-filter 를 모르는 브라우저는 바탕색을 진하게(92%) 깔아 막처럼 보이게 한다.
 */
.ai-layer { position: fixed; inset: 0; z-index: 75; }
.ai-layer[hidden] { display: none; }
.ai-layer > .ai { background: var(--bg); }

.ai-curtain {
  --ai-dome: 34vh;
  position: fixed; z-index: 90; top: 0; left: -20vw;
  width: 140vw; height: calc(100vh + var(--ai-dome));
  background: color-mix(in srgb, var(--bg) 92%, var(--accent));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), 0 -18px 50px color-mix(in srgb, var(--accent) 10%, transparent);
  border-radius: 50% 50% 0 0 / var(--ai-dome) var(--ai-dome) 0 0;
  transform: translate3d(0, 100vh, 0);
  pointer-events: none;
  /* 걷기(내려가기) — 막 덮기를 뗀 순간 이 값으로 돌아간다. */
  transition: transform .68s cubic-bezier(.76, 0, .24, 1), border-radius .68s cubic-bezier(.76, 0, .24, 1);
  will-change: transform;
}
.ai-curtain[hidden] { display: none; }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ai-curtain {
    background: color-mix(in srgb, color-mix(in srgb, var(--bg) 94%, var(--accent)) 58%, transparent);
    -webkit-backdrop-filter: blur(22px) saturate(160%);
    backdrop-filter: blur(22px) saturate(160%);
  }
}
.ai-curtain.is-cover {
  transform: translate3d(0, 0, 0);
  border-radius: 50% 50% 0 0 / 0 0 0 0;
  transition: transform .62s cubic-bezier(.76, 0, .24, 1), border-radius .62s cubic-bezier(.5, 0, .75, 0);
}
/* 막이 다니는 동안(뒤 화면 포함) 스크롤되지 않게 — 레이어가 떠 있는 동안도. */
html.cb-open, html.cb-open body { overflow: hidden; }

.ai-col { width: 100%; max-width: 760px; margin: 0 auto; padding: 0 20px; }
@media (max-width: 520px) { .ai-col { padding: 0 16px; } }

.ai-bar {
  position: relative;
  flex: none; display: flex; align-items: center; gap: 4px;
  height: calc(56px + env(safe-area-inset-top)); padding: env(safe-area-inset-top) 8px 0;
}
.ai-bar__title {
  flex: 1; min-width: 0; margin: 0; text-align: center;
  font-size: 16px; font-weight: 700; letter-spacing: var(--tr-tight);
  /* 양쪽 버튼 폭이 달라도(☰ / 초기화·✕) 제목은 화면 가운데 — 띠 위에 따로 띄운다. */
  position: absolute; left: 50%; transform: translateX(-50%); pointer-events: none; white-space: nowrap;
}
.ai-bar__btn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border: 0; border-radius: var(--radius-full);
  background: transparent; color: var(--text); cursor: pointer; text-decoration: none;
  transition: background var(--dur-fast) var(--ease);
}
.ai-bar__btn svg { width: 22px; height: 22px; }
.ai-bar__btn:hover { background: var(--surface-2); }
.ai-bar__btn:focus-visible { outline: 3px solid var(--accent-edge); outline-offset: 1px; }
/* 초기화 — 오른쪽 끝 ✕ 옆. 글자를 붙인다(아이콘만으로는 뜻이 안 읽힌다 — 예전 ＋ 가 그랬다). */
.ai-reset {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 4px;
  height: 34px; padding: 0 12px 0 10px; border: 1px solid var(--border); border-radius: var(--radius-full);
  background: var(--surface); color: var(--text); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
}
.ai-reset svg { width: 15px; height: 15px; }
.ai-reset:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.ai-reset:active:not(:disabled) svg { transform: rotate(-120deg); transition: transform .3s var(--spring); }
.ai-reset:disabled { opacity: .4; cursor: default; }
.ai-reset:focus-visible { outline: 3px solid var(--accent-edge); outline-offset: 1px; }

.ai-main { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* 대화 칸은 위젯의 `.cb-log` 지만 여기서는 스스로 스크롤하지 않는다(본문이 스크롤한다). */
.ai .ai-log { overflow: visible; padding: 16px 0 32px; gap: 14px; }

/* ── 첫 화면 ── */
.ai-hello { display: flex; flex-direction: column; align-items: flex-start; padding: 8px 0; }
/*
 * 첫 화면은 채팅처럼 나온다(2026-10-06 요청) — ✦ 구슬이 떠오르고 → 인사가 한 글자씩 쳐지고 →
 * 질문 버튼이 하나씩 튀어나온다. 순서는 chatbot.js 가 `--i`(몇 번째)와 `.is-play` 로 정한다.
 * `.is-anim` 이 없으면(지난 대화를 다시 그릴 때·움직임 줄이기) 바로 다 보인다.
 */
.ai-orb {
  position: relative; display: grid; place-items: center;
  width: 44px; height: 44px; margin-bottom: 14px; border-radius: 50%;
  color: #fff; font-size: 18px;
  background: conic-gradient(from var(--ai-orb-a, 0deg),
    var(--accent), color-mix(in srgb, var(--accent) 45%, #fff), var(--accent),
    color-mix(in srgb, var(--accent) 70%, #000), var(--accent));
  box-shadow: 0 8px 24px color-mix(in srgb, var(--accent) 35%, transparent);
  animation: ai-orb-turn 6s linear infinite;
}
.ai-orb::before { content: "✦"; animation: ai-twinkle 2.4s ease-in-out infinite; }
@property --ai-orb-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@keyframes ai-orb-turn { to { --ai-orb-a: 360deg; } }
@keyframes ai-twinkle { 0%, 100% { transform: scale(1) rotate(0); } 50% { transform: scale(1.25) rotate(90deg); } }
.ai-hello.is-anim .ai-orb { opacity: 0; transform: scale(.3) rotate(-90deg); }
.ai-hello.is-orb .ai-orb { opacity: 1; transform: none; transition: opacity .3s var(--ease), transform .7s var(--spring); }
.ai-hello.is-anim .ai-hello__brand { opacity: 0; transform: translateY(6px); }
.ai-hello.is-orb .ai-hello__brand { opacity: 1; transform: none; transition: opacity .3s var(--ease) .1s, transform .4s var(--spring) .1s; }
/* 인사를 치는 동안 끝에 깜빡이는 막대. */
.ai-hello__title.is-typing::after {
  content: ''; display: inline-block; width: 3px; height: .95em; margin-left: 3px; vertical-align: -3px;
  border-radius: 2px; background: var(--accent); animation: cb-caret .7s steps(1) infinite;
}
/* 하나씩 — 아래에서 튀어 오르며 살짝 커졌다 자리 잡는다. */
.ai-seq { --i: 0; }
.ai-hello.is-anim .ai-seq { opacity: 0; transform: translateY(14px) scale(.92); }
.ai-hello.is-play .ai-seq,
.ai-follow .ai-seq { animation: ai-seq-in .55s var(--spring) both; animation-delay: calc(var(--i) * 85ms); }
@keyframes ai-seq-in {
  0% { opacity: 0; transform: translateY(14px) scale(.92); filter: blur(3px); }
  60% { opacity: 1; filter: none; }
  100% { opacity: 1; transform: none; }
}
/* 버튼이 자리 잡을 때 ✦ 가 한 번 반짝인다. */
.ai-hello.is-play .ai-chip.ai-seq::before,
.ai-follow .ai-chip.ai-seq::before { animation: ai-twinkle .7s ease-in-out both; animation-delay: calc(var(--i) * 85ms + .25s); }
.ai-hello__brand { margin: 0 0 6px; font-size: 13px; color: var(--text-2); }
.ai-hello__title { margin: 0 0 22px; font-size: 26px; line-height: 1.35; font-weight: 700; letter-spacing: var(--tr-tighter); }
@media (max-width: 520px) { .ai-hello__title { font-size: 23px; } }
.ai-group { margin-top: 32px; width: 100%; }
.ai-group__title { margin: 0 0 12px; font-size: 15px; font-weight: 700; }

/* ✦ 알약 질문 — 세로로 쌓는다(LG). 글이 길면 줄을 바꾼다(폰에서 잘리지 않게). */
.ai-chips { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.ai-chip {
  display: inline-flex; align-items: baseline; gap: 8px; max-width: 100%;
  padding: 10px 16px; border: 1px solid var(--border); border-radius: var(--radius-full);
  background: var(--surface); color: var(--text); box-shadow: var(--shadow-1, 0 1px 2px rgba(0, 0, 0, .04));
  font: inherit; font-size: 14px; line-height: 1.4; text-align: left; cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), transform .2s var(--spring);
}
.ai-chip::before { content: "✦"; flex: none; font-size: 12px; color: var(--accent); }
.ai-chip:hover { border-color: var(--accent); }
.ai-chip:active { transform: scale(.98); }
.ai-chip:focus-visible { outline: 3px solid var(--accent-edge); outline-offset: 1px; }
.ai.is-busy .ai-chip, .ai.is-busy .ai-more { opacity: .5; pointer-events: none; }
.ai-more {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
  padding: 9px 14px; border: 0; border-radius: var(--radius-full);
  background: var(--surface-2); color: var(--text-2); font: inherit; font-size: 13.5px; cursor: pointer;
}
.ai-more::before { content: "↻"; font-size: 14px; }
.ai-more:hover { color: var(--text); }

/* ── 대화 ── */
/* 내 질문 — 오른쪽 회색 알약 + 아래 시각. */
.ai .cb-msg--me {
  max-width: min(78%, 560px); padding: 10px 16px;
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 20px; font-size: 15px;
}
.ai-at { align-self: flex-end; margin-top: -8px; font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
/* 답 — 말풍선 없이 본문 폭 그대로(LG). 굵은 글씨는 소제목처럼 보이게 조금 더 진하게. */
.ai .cb-msg--bot {
  max-width: 100%; padding: 4px 0 0; margin-top: 4px;
  background: none; border: 0; border-radius: 0;
  font-size: 15.5px; line-height: 1.75;
}
.ai .cb-msg--bot strong { font-weight: 800; }
.ai .cb-msg--note { font-size: 13.5px; color: var(--text-2); }
.ai .cb-links { margin-top: 0; }
.ai .cb-source { padding-left: 0; }

/*
 * 답변 생성중(2026-10-06 "모션 들어가자") — 테두리를 따라 빛이 돌고(conic + @property),
 * ✦ 가 돌며 맥박 치고, 글자 위로 빛이 지나가고, 점 세 개가 물결친다. 문구는 기다림이 길어지면 바뀐다(chatbot.js).
 * @property 를 모르는 브라우저는 테두리 빛만 멈춰 있다.
 */
@property --ai-think-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.ai-thinking {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; margin-top: 4px;
  padding: 8px 16px 8px 12px; border: 1.5px solid transparent; border-radius: var(--radius-full);
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    conic-gradient(from var(--ai-think-a), var(--accent-edge) 0 55%, var(--accent) 75%, color-mix(in srgb, var(--accent) 40%, #fff) 85%, var(--accent-edge) 100%) border-box;
  box-shadow: 0 6px 20px color-mix(in srgb, var(--accent) 16%, transparent);
  font-size: 13.5px; font-weight: 700; color: var(--accent);
  animation: cb-pop .35s var(--spring) both, ai-think-turn 1.8s linear infinite;
}
@keyframes ai-think-turn { to { --ai-think-a: 360deg; } }
.ai-thinking__star { display: inline-block; font-size: 14px; animation: ai-star 1.6s ease-in-out infinite; }
@keyframes ai-star {
  0% { transform: rotate(0) scale(1); }
  50% { transform: rotate(180deg) scale(1.35); filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 60%, transparent)); }
  100% { transform: rotate(360deg) scale(1); }
}
.ai-thinking__text {
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent) 35%, color-mix(in srgb, var(--accent) 25%, #fff) 50%, var(--accent) 65%, var(--accent) 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: ai-shimmer 1.6s linear infinite;
}
.ai-thinking__text.is-swap { animation: ai-shimmer 1.6s linear infinite, ai-text-swap .4s var(--spring); }
@keyframes ai-shimmer { from { background-position: 100% 0; } to { background-position: -150% 0; } }
@keyframes ai-text-swap { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.ai-thinking__dots { display: inline-flex; gap: 3px; }
.ai-thinking__dots i { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); animation: cb-dot 1s infinite ease-in-out; }
.ai-thinking__dots i:nth-child(2) { animation-delay: .15s; }
.ai-thinking__dots i:nth-child(3) { animation-delay: .3s; }
@keyframes cb-dot { 0%, 80%, 100% { opacity: .25; transform: none; } 40% { opacity: 1; transform: translateY(-3px); } }

.ai-follow { margin-top: 10px; }
.ai-follow__title { margin: 0 0 10px; font-size: 14.5px; font-weight: 700; }
.ai .no-anim, .ai .no-anim .ai-seq, .ai .no-anim .ai-seq::before { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .ai-thinking, .ai-seq, .ai-chip::before, .ai-orb, .ai-orb::before,
  .ai-thinking__star, .ai-thinking__text, .ai-thinking__dots i { animation: none !important; }
  .ai-hello.is-anim .ai-seq, .ai-hello.is-anim .ai-orb, .ai-hello.is-anim .ai-hello__brand { opacity: 1; transform: none; }
  .ai-thinking__text { color: var(--accent); background: none; }
}

/* ── 입력 시트 ── */
.ai-dock {
  flex: none; position: relative; z-index: 2;
  padding: 12px 0 calc(12px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -8px 28px rgba(0, 0, 0, .06);
}
.ai .ai-input { display: flex; align-items: flex-end; gap: 8px; padding: 0; border: 0; background: none; }
.ai .ai-input__box {
  flex: 1; min-height: 48px; max-height: 160px; padding: 13px 16px;
  border: 1px solid var(--border); border-radius: 24px; background: var(--bg);
  font-size: 15px; line-height: 1.45;
}
.ai .ai-input__send { width: 48px; height: 48px; border-radius: 50%; flex: none; }
.ai .ai-ticket { padding: 0 0 12px; border-top: 0; background: none; }

/* ── ☰ 서랍 — 넓은 화면은 왼쪽에서 나오는 360px 판, 폰은 화면 전체(LG). ── */
.ai-drawer { position: fixed; inset: 0; z-index: 80; }
.ai-drawer[hidden] { display: none; }
.ai-drawer__scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, .32); opacity: 0; transition: opacity .26s var(--ease); }
.ai-drawer__panel {
  position: absolute; top: 0; bottom: 0; left: 0; width: min(360px, 100%);
  display: flex; flex-direction: column;
  padding-top: env(safe-area-inset-top);
  background: var(--surface); box-shadow: var(--shadow-3, 0 12px 32px rgba(0, 0, 0, .18));
  transform: translateX(-100%); transition: transform .38s cubic-bezier(.16, 1, .3, 1);
  outline: none;
}
.ai-drawer.is-open .ai-drawer__scrim { opacity: 1; }
.ai-drawer.is-open .ai-drawer__panel { transform: none; }
.ai-drawer.is-closing .ai-drawer__panel { transition-duration: .22s; transition-timing-function: var(--ease); }
@media (max-width: 520px) { .ai-drawer__panel { width: 100%; box-shadow: none; } }
@media (prefers-reduced-motion: reduce) { .ai-drawer__scrim, .ai-drawer__panel { transition: none; } }
html.ai-drawer-open, html.ai-drawer-open body { overflow: hidden; }

.ai-drawer__head { display: flex; align-items: center; justify-content: space-between; height: 56px; padding: 0 8px 0 20px; }
.ai-drawer__title { margin: 0; font-size: 17px; font-weight: 700; }
.ai-drawer__tabs { padding: 0 12px; }
.ai-drawer__body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
.ai-drawer__body[hidden] { display: none; }
.ai-drawer__new {
  display: flex; align-items: center; justify-content: center; gap: 6px; flex: none;
  margin: 14px 16px 6px; height: 44px; border: 1px solid var(--border); border-radius: var(--radius-full);
  background: var(--surface); color: var(--text); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
}
.ai-drawer__new svg { width: 16px; height: 16px; }
.ai-drawer__new:hover { border-color: var(--accent); }
.ai-sessions { display: flex; flex-direction: column; padding: 6px 8px 20px; }
.ai-sess {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 12px; border: 0; border-radius: var(--radius);
  background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.ai-sess:hover { background: var(--surface-2); }
.ai-sess[aria-current="true"] { background: var(--accent-tint); }
.ai-sess__title { flex: 1; min-width: 0; font-size: 14.5px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ai-sess__when { flex: none; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.ai-sessions__empty { margin: 48px 16px; text-align: center; }
.ai-sessions__empty strong { font-size: 15px; }
.ai-sessions__empty p { margin: 6px 0 0; font-size: 13.5px; color: var(--text-2); }
