/* ============================================================================
   오빠두 디지털 명함 — namecard.css
   Deep Jade v2.1 스코프 토큰 · 모바일 우선 · 마크업 계약서 v1.0 전수 커버
   전역 :root 불가침. 앱 내부 값은 전부 var(--nc-*).
   ========================================================================== */

/* ── 1. 스코프 토큰 (정본 · 임의 변경 금지) ─────────────────────────────── */
/* (body.nc-standalone = 크롬리스 문서 body — 토큰만 상속받고 값은 불변) */

.nc-app, .nc-public, .nc-gate, .nc-modal-back, body.nc-standalone {
  --nc-primary: #059669;         /* primary-500 · 면 채움 전용 */
  --nc-primary-text: #047E57;    /* primary-600 · 흰 배경 위 텍스트/링크 (AA) */
  --nc-primary-hover: #036546;   /* primary-700 */
  --nc-primary-50: #EEF9F6;
  --nc-primary-tint: #D2F1E7;    /* primary-100 · 칩·이니셜 아바타 */
  --nc-bg-page: #F7F7F5;         /* gray-50 */
  --nc-surface: #FFFFFF;
  --nc-fg-strong: #1B1B18;       /* gray-900 */
  --nc-fg: #45453F;              /* gray-700 */
  --nc-fg-muted: #8A8A85;        /* gray-500 */
  --nc-hairline: #E6E6E2;        /* gray-200 · 콘텐츠 내부 구분선 전용 */
  --nc-fill: #F0F0ED;            /* gray-100 · 인풋·secondary 채움 */
  --nc-fill-strong: #E6E6E2;     /* gray-200 · 빈 상태 아이콘 원 */
  --nc-warn: #C5870F;            /* warning 정본 */
  --nc-warn-bg: #FAF2E1;         /* amber-50 정본 */
  --nc-danger: #D14343;          /* error 정본 */
  --nc-danger-bg: #F9ECEA;       /* 유도값(정본 대응 없음) */
  --nc-radius-badge: 2px;
  --nc-radius-btn: 6px;
  --nc-radius-card: 8px;
  --nc-radius-modal: 12px;
  --nc-shadow-xs: 0 1px 2px rgba(17,17,16,.04);
  --nc-shadow-sm: 0 1px 2px rgba(17,17,16,.04), 0 2px 6px rgba(17,17,16,.04);
  --nc-shadow-md: 0 1px 3px rgba(17,17,16,.05), 0 6px 20px rgba(17,17,16,.06);
  --nc-shadow-lg: 0 2px 8px rgba(17,17,16,.06), 0 18px 44px rgba(17,17,16,.09);
  --nc-shadow-up: 0 -6px 20px rgba(17,17,16,.07);
  --nc-shadow-cta: 0 6px 18px rgba(5,150,105,.28);
  --nc-pad-screen: 16px;
  --nc-pad-card: 18px;
  --nc-gap: 12px;
  --nc-ease: cubic-bezier(.2,.8,.2,1);
  --nc-dur-fast: 160ms;
  --nc-dur-modal: 280ms;
  font-family: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  color: var(--nc-fg-strong);
}
.nc-app { min-width: 0; }

/* ── 1-c. 크롬리스 웹앱 문서 (templates/standalone.php) ───────────────────
   사이트 헤더·푸터 없이 셔트코드 콘텐츠만 렌더되는 body. 앱처럼 배경을 채우고,
   wp_head/wp_footer 가 딸려 출력하는 테마 잔여물(백투탑 버튼·구형 알림 div)을 숨긴다. */
body.nc-standalone {
  margin: 0;
  background: var(--nc-bg-page);
  min-height: 100dvh;
}
body.nc-standalone .back-to-top-button,
body.nc-standalone #custom-notification,
body.nc-standalone .generate-back-to-top { display: none !important; }

/* ── 1-b. 파생 토큰 (정본 블록은 위에서 불변 — 그 위에 얹는 얇은 레이어) ────
   · --nc-warn-text / --nc-danger-text
     정본 --nc-warn(#C5870F) 는 --nc-warn-bg(#FAF2E1) 위에서 2.75:1,
     정본 --nc-danger(#D14343) 는 --nc-danger-bg(#F9ECEA) 위에서 3.96:1 로
     둘 다 WCAG AA(4.5:1) 미달이다. 배경 토큰은 그대로 두고 '전경 전용' 값을
     디자인 시스템 정본에서 가져온다 —
       #95650A = colors_and_type.css --amber-700 (.badge-amber 의 전경색)  → 4.55:1
       #A82F2F = colors_and_type.css .badge-error 의 전경색                → 5.85:1
     주의 — 그 결과 정본 --nc-warn / --nc-danger 는 '정의만 되고 참조되지 않는' 상태가 된다.
       정본 블록은 발주자 확정본이라 임의로 줄이지 않는다(의도된 미참조).
   · --nc-shadow-cta-xl : 02_design_spec §4 A1 이 명시한 96px 원형 CTA 글로우 정본값
   · --nc-modal-gutter  : 모달 오버레이 상하 여백. A7 아바타의 -30px 오버랩이
     짧은 뷰포트(가로 모드)에서 화면 밖으로 잘리지 않게 스크롤 여유를 만든다.
   ------------------------------------------------------------------------ */

.nc-app, .nc-public, .nc-gate, .nc-modal-back {
  --nc-warn-text: #95650A;
  --nc-danger-text: #A82F2F;
  --nc-shadow-cta-xl: 0 10px 28px rgba(5,150,105,.35);
  --nc-modal-gutter: 48px;
}

/* OppaduNotify(사이트 전역, 무조건 로드)는 테마 z 스케일 --z-modal:400 / --z-toast:500 을
   쓴다. 이 앱 모달은 z-index:10000 이라 A6 [삭제] 확인 모달·복사 토스트가 뒤에 깔려
   보이지 않는다(삭제 불가). namecard.css 는 명함 페이지에서만 로드되므로 여기서만 올린다. */
.oppadu-modal-overlay { z-index: 10010 !important; }
#oppadu-toast-container { z-index: 10020 !important; }


/* ── 2. 테마(GeneratePress 부모 + 자식) 간섭 리셋 ───────────────────────────
   부모 main.css: ul/ol margin+list-style · button 배경#55555e · input 테두리
   · p margin-bottom 1.5em · h1~h3 42/35/29px · img height:auto
   자식 style.css:2215: a, a.visited { text-decoration: underline } (전역)
   :where() 로 특이도 (0,1,0) 고정 → 테마(0,0,1)는 이기고 컴포넌트 클래스에는 진다.
   테마가 (0,1,1)로 거는 input[type=…] 은 아래에서 .nc-app .nc-input (0,2,0)로 재정의.
   ------------------------------------------------------------------------ */

.nc-app, .nc-app *, .nc-app *::before, .nc-app *::after,
.nc-public, .nc-public *, .nc-public *::before, .nc-public *::after,
.nc-gate, .nc-gate *, .nc-gate *::before, .nc-gate *::after,
.nc-modal-back, .nc-modal-back *, .nc-modal-back *::before, .nc-modal-back *::after {
  box-sizing: border-box;
}

.nc-app :where(h1, h2, h3, h4, h5, h6, p, ul, ol, li, dl, dd, figure, figcaption, blockquote, hr, pre, summary, fieldset),
.nc-public :where(h1, h2, h3, h4, h5, h6, p, ul, ol, li, dl, dd, figure, figcaption, blockquote, hr, pre, summary, fieldset),
.nc-gate :where(h1, h2, h3, h4, h5, h6, p, ul, ol, li, dl, dd, figure, figcaption, blockquote, hr, pre, summary, fieldset),
.nc-modal-back :where(h1, h2, h3, h4, h5, h6, p, ul, ol, li, dl, dd, figure, figcaption, blockquote, hr, pre, summary, fieldset) {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: normal;
  text-transform: none;
  list-style: none;
  color: inherit;
}

.nc-app :where(button, input, select, textarea),
.nc-public :where(button, input, select, textarea),
.nc-gate :where(button, input, select, textarea),
.nc-modal-back :where(button, input, select, textarea) {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  text-transform: none;
  -webkit-appearance: none;
  appearance: none;
}

.nc-app :where(a),
.nc-public :where(a),
.nc-gate :where(a),
.nc-modal-back :where(a) {
  color: inherit;
  text-decoration: none;
}

.nc-app :where(img),
.nc-public :where(img),
.nc-gate :where(img),
.nc-modal-back :where(img) {
  display: block;
  max-width: 100%;
  height: auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  filter: none;
  cursor: auto;
}

.nc-app :where(svg),
.nc-public :where(svg),
.nc-gate :where(svg),
.nc-modal-back :where(svg) { display: block; }


/* ── 3. 전역 · 유틸 ────────────────────────────────────────────────────── */

/* 아이콘 스프라이트 컨테이너 (includes/icons.php) */
.nc-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* 아이콘 기본 — 문맥별 크기는 부모 컴포넌트가 정한다 */
.nc-i {
  width: 24px;
  height: 24px;
  display: block;
  flex: none;
  fill: none;
  stroke: currentColor;
}

/* 시각 숨김 · 스크린리더 노출 (display:none 금지) */
.nc-sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* JS 계약 — 강제 숨김 */
.nc-hidden { display: none !important; }


/* ── 4. 앱 셸 · 탭바 ───────────────────────────────────────────────────── */

.nc-app {
  max-width: 480px;
  margin-inline: auto;
  padding: var(--nc-pad-screen) var(--nc-pad-screen) calc(76px + env(safe-area-inset-bottom));
  min-height: 100dvh;
  background: var(--nc-bg-page);
  line-height: 1.5;
  font-size: 15px;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}

/* 모바일에서 테마 컨테이너 좌우 패딩을 넘어 화면 끝까지 페이지 배경 확장.
   (모바일 브라우저는 스크롤바가 오버레이라 100vw 로 가로 스크롤이 생기지 않는다)

   주의 — 브레이크포인트는 반드시 max-width 캡(480px)과 같아야 한다.
   481~600px 에서 이 음수 마진을 쓰면 width:auto 가 100vw 로 부풀었다가 max-width 로
   480 에 잘리고, 좌우 마진이 둘 다 auto 가 아니라 over-constrained(CSS 2.1 §10.3.3)
   → LTR 에서 margin-right 가 무시되어 앱이 뷰포트 좌측에 붙는다. 그러면 뷰포트 기준
   중앙에 놓이는 고정 바(.nc-tabs-inner / .nc-actionbar-inner / .nc-public-cta-inner)와
   최대 60px 어긋난다(폴더블 내측 화면·태블릿 세로·창 축소 데스크톱에서 실제로 보임).
   ≤480px 에서는 100vw ≤ 480 이라 캡이 개입하지 않아 안전하다. */
@media (max-width: 480px) {
  .nc-app,
  .nc-public,
  .nc-gate {
    max-width: none;   /* 방어적 — 이 구간에선 어차피 100vw ≤ 480 */
    margin-inline: calc(50% - 50vw);
  }
}

/* 하단 고정 탭바 */
.nc-tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 900;
  background: var(--nc-surface);
  border-top: 1px solid var(--nc-hairline);
  padding-bottom: env(safe-area-inset-bottom);
}
.nc-tabs-inner {
  max-width: 480px;
  margin: 0 auto;
  display: flex;
  align-items: stretch;
}
.nc-tab-btn {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 44px;
  min-height: 58px;
  color: var(--nc-fg-muted);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--nc-dur-fast) var(--nc-ease);
}
.nc-tab-btn .nc-i { width: 22px; height: 22px; }
.nc-tab-btn.on { color: var(--nc-primary-text); font-weight: 700; }
.nc-tab-btn:active { color: var(--nc-primary-hover); }
.nc-tab-label { font-size: 11px; line-height: 1; }

/* 탭 패널 — JS 계약 (이 두 줄이 없으면 전 탭 동시 표시) */
.nc-tab { display: none; }
.nc-tab.on { display: block; }
.nc-tab.on > * + * { margin-top: var(--nc-gap); }


/* ── 5. 레이아웃 프리미티브 ────────────────────────────────────────────── */

/* 화면 래퍼 — 좌우 패딩은 .nc-app 이 담당, 여기선 세로 리듬만 */
.nc-screen {
  display: flex;
  flex-direction: column;
  gap: var(--nc-gap);
  padding: 0;
}
/* .nc-screen--scan — 전용 선언 없음(.nc-screen 의 리듬 그대로). A1 전용 조정 시 여기에 */
/* A3 — 하단 고정 액션바 높이만큼 여유 */
.nc-screen--form { padding-bottom: 72px; }

.nc-stack {
  display: flex;
  flex-direction: column;
  gap: var(--nc-gap);
}

.nc-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  padding: 4px 0 2px;
}
.nc-head-title { font-size: 22px; font-weight: 800; line-height: 1.3; }
/* 정보를 담은 소형 텍스트는 --nc-fg(9.65:1). --nc-fg-muted(3.47:1)는 AA 미달이라
   장식·메타(개수·브랜드 푸터·아이콘·placeholder)에만 남긴다. 아래 동일. */
.nc-head-sub { flex-basis: 100%; font-size: 12px; color: var(--nc-fg); }
.nc-head-count { font-size: 12px; font-weight: 600; color: var(--nc-fg-muted); }

.nc-card {
  background: var(--nc-surface);
  border-radius: var(--nc-radius-card);
  box-shadow: var(--nc-shadow-sm);
  padding: var(--nc-pad-card);
}
.nc-card-title { font-size: 16px; font-weight: 800; line-height: 1.35; }
.nc-card-sub { margin-top: 2px; font-size: 12px; color: var(--nc-fg); }

/* 카드 내부 구분선 */
.nc-hr {
  height: 0;
  margin: var(--nc-gap) 0;
  border: 0;
  border-top: 1px solid var(--nc-hairline);
  background: none;
}


/* ── 6. 버튼 ───────────────────────────────────────────────────────────── */

.nc-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 46px;
  padding: 0 var(--nc-pad-screen);
  border-radius: var(--nc-radius-btn);
  background: var(--nc-fill);
  color: var(--nc-fg-strong);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--nc-dur-fast) var(--nc-ease),
    box-shadow var(--nc-dur-fast) var(--nc-ease),
    transform var(--nc-dur-fast) var(--nc-ease);
}
.nc-btn .nc-i { width: 18px; height: 18px; }
.nc-btn:active { background: var(--nc-fill-strong); transform: scale(.98); }

.nc-btn-primary { background: var(--nc-primary); color: var(--nc-surface); }
.nc-btn-primary:active { background: var(--nc-primary-hover); }

.nc-btn-danger { background: var(--nc-danger-bg); color: var(--nc-danger-text); }
.nc-btn-danger:active { background: var(--nc-danger-bg); }

/* JS 가 btn.disabled 로 잠그는 순간(A3 저장 중) 시각 피드백 — 없으면 먹통처럼 보인다 */
.nc-btn:disabled,
.nc-btn[disabled] {
  opacity: .55;
  cursor: not-allowed;
}
.nc-btn:disabled:active,
.nc-btn[disabled]:active { transform: none; background: var(--nc-fill); }
.nc-btn-primary:disabled:active,
.nc-btn-primary[disabled]:active { background: var(--nc-primary); }

.nc-btn-lg { min-height: 52px; padding: 0 20px; font-size: 16px; }
.nc-btn-lg .nc-i { width: 20px; height: 20px; }
/* 큰 CTA 만 제이드 글로우 */
.nc-btn-primary.nc-btn-lg { box-shadow: var(--nc-shadow-cta); }

.nc-btn-md { min-height: 48px; }
.nc-btn-md .nc-i { width: 18px; height: 18px; }

.nc-btn-sm { min-height: 40px; padding: 0 var(--nc-gap); gap: 6px; font-size: 13px; }
.nc-btn-sm .nc-i { width: 16px; height: 16px; }
/* sm 버튼 히트 영역 44px 확보 */
.nc-btn-sm::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

.nc-btn-block { width: 100%; }

.nc-btn-row { display: flex; gap: var(--nc-gap); }
.nc-btn-row > * { flex: 1 1 0; min-width: 0; }
.nc-btn-row--3 > * { flex: 1 1 0; }
/* 3분할(A8 미리보기·링크 복사·내 vcf)은 칸이 좁다 — 라벨 줄바꿈을 막게 패딩·간격을 줄인다.
   360px: 카드 내부 292 → 버튼 89.3, 여유 = 89.3 − 16 − 16(아이콘) − 5 = 52.3px */
.nc-btn-row--3 > .nc-btn-sm { padding: 0 8px; gap: 5px; }
/* A6 삭제 버튼 고정폭 */
.nc-btn-del { flex: none; width: 96px; }

.nc-textbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 44px;
  padding: 0 8px;
  color: var(--nc-fg);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--nc-dur-fast) var(--nc-ease), opacity var(--nc-dur-fast) var(--nc-ease);
}
.nc-textbtn .nc-i { width: 14px; height: 14px; }
.nc-textbtn:active { opacity: .7; }
.nc-textbtn--jade { color: var(--nc-primary-text); font-weight: 700; }
/* 텍스트 버튼도 '읽혀야 하는 텍스트' — muted(3.47:1) 금지, 위계는 굵기로 준다 */
.nc-textbtn--muted { color: var(--nc-fg); font-weight: 500; }
/* A1 "앨범에서 선택"만 밑줄 */
.nc-hero .nc-textbtn--muted { text-decoration: underline; text-underline-offset: 3px; }

/* 파일 인풋 숨김 — display:none 대신 clip (키보드 포커스 유지) */
.nc-file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* 라벨로 감싼 파일 인풋의 포커스 링을 라벨에 표시 */
.nc-btn:has(.nc-file-input:focus-visible),
.nc-textbtn:has(.nc-file-input:focus-visible),
.nc-cta-circle:has(.nc-file-input:focus-visible) {
  outline: 2px solid var(--nc-primary-text);
  outline-offset: 2px;
}


/* ── 7. 폼 ─────────────────────────────────────────────────────────────── */

.nc-form { display: block; }
.nc-fgroup + .nc-fgroup { margin-top: var(--nc-pad-card); }
.nc-group-head {
  margin-bottom: 8px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .06em;
  color: var(--nc-fg);
}
.nc-fgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--nc-gap);
}
.nc-field {
  display: block;
  min-width: 0;
  cursor: pointer;
}
.nc-field--full { grid-column: 1 / -1; }
.nc-field-label {
  display: block;
  margin-bottom: 5px;
  font-size: 13px;
  font-weight: 600;
  color: var(--nc-fg);
}
.nc-req { color: var(--nc-primary-text); }

/* 테마가 input[type=…] 에 (0,1,1)로 테두리·패딩을 걸어 (0,2,0) 으로 재정의 */
.nc-app .nc-input {
  display: block;
  width: 100%;
  max-width: 100%;
  height: 46px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--nc-radius-btn);
  background: var(--nc-fill);
  color: var(--nc-fg-strong);
  font-family: inherit;
  font-size: 16px;   /* iOS 자동 확대 방지 하한 */
  font-weight: 400;
  line-height: 1.4;
  -webkit-appearance: none;
  appearance: none;
  transition:
    background-color var(--nc-dur-fast) var(--nc-ease),
    box-shadow var(--nc-dur-fast) var(--nc-ease);
}
.nc-app .nc-input::placeholder { color: var(--nc-fg-muted); opacity: 1; }
.nc-app .nc-input:focus {
  outline: none;
  background: var(--nc-surface);
  box-shadow: 0 0 0 2px var(--nc-primary-text);
}
.nc-app .nc-input:focus-visible { outline: none; }

.nc-app .nc-textarea {
  height: auto;
  min-height: 78px;
  padding: 12px 14px;
  resize: vertical;
}

/* 추가 정보 접기 */
.nc-more { display: block; margin-top: var(--nc-pad-card); }
.nc-more-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding-top: var(--nc-gap);
  border-top: 1px solid var(--nc-hairline);
  list-style: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.nc-more-head::-webkit-details-marker { display: none; }
.nc-more-head::marker { content: ""; }
.nc-more-title { font-size: 15px; font-weight: 700; }
.nc-more-sub {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: var(--nc-fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nc-more-chev {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--nc-fg-muted);
  transition: transform var(--nc-dur-fast) var(--nc-ease);
}
.nc-more[open] .nc-more-chev { transform: rotate(180deg); }
.nc-more-body { padding-top: var(--nc-gap); }


/* ── 8. 공통 시각 요소 ─────────────────────────────────────────────────── */

.nc-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  overflow: hidden;
  background: var(--nc-fill);
  line-height: 1;
}
.nc-avatar--initial {
  background: var(--nc-primary-tint);
  color: var(--nc-primary-hover);
  font-weight: 800;
  overflow: hidden;
}
.nc-avatar--empty {
  background: var(--nc-fill-strong);
  color: var(--nc-fg-muted);
}
.nc-avatar--empty .nc-i { width: 28px; height: 28px; }
.nc-avatar--ring { box-shadow: 0 0 0 4px var(--nc-surface); }
.nc-avatar--xl { width: 88px; height: 88px; font-size: 30px; }

.nc-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  padding: 6px 10px;
  border-radius: var(--nc-radius-badge);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.35;
}
.nc-chip .nc-i { width: 14px; height: 14px; }
.nc-chip--ok { background: var(--nc-primary-tint); color: var(--nc-primary-hover); }
/* 12/700 텍스트 — 정본 --nc-warn 은 이 배경 위 2.75:1(AA 미달) → 전경 전용 파생색 */
.nc-chip--warn { background: var(--nc-warn-bg); color: var(--nc-warn-text); }

.nc-spinner {
  display: block;
  width: 22px;
  height: 22px;
  flex: none;
  border: 2.5px solid var(--nc-hairline);
  border-top-color: var(--nc-primary);
  border-radius: 50%;
  animation: nc-spin .8s linear infinite;
}
@keyframes nc-spin { to { transform: rotate(360deg); } }

.nc-sk {
  display: block;
  border-radius: var(--nc-radius-btn);
  background-color: var(--nc-fill);
  background-image: linear-gradient(90deg,
    var(--nc-fill) 25%,
    var(--nc-fill-strong) 37%,
    var(--nc-fill) 63%);
  background-size: 200% 100%;
  animation: nc-shimmer 1.4s ease-in-out infinite;
}
.nc-sk--label { width: 72px; height: 12px; }
.nc-sk--input { width: 100%; height: 44px; }
@keyframes nc-shimmer {
  from { background-position: 100% 0; }
  to   { background-position: -100% 0; }
}


/* ── 9. A1 스캔 시작 ───────────────────────────────────────────────────── */

.nc-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 28px 0 20px;
}
.nc-hero-title { font-size: 20px; font-weight: 800; line-height: 1.35; }
.nc-hero-sub {
  max-width: 30ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--nc-fg);
}
/* 96px 원형 촬영 CTA (<label>) — 뷰포트당 Primary 1개 */
.nc-cta-circle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  margin-top: 10px;
  border-radius: 50%;
  background: var(--nc-primary);
  color: var(--nc-surface);
  /* 스펙 §4 A1 정본값 (파생 토큰 --nc-shadow-cta-xl) — 동일 그림자 2겹은 offset·blur 가
     스펙과 달라져 '더 진하고 더 좁은' 그림자가 되므로 쓰지 않는다 */
  box-shadow: var(--nc-shadow-cta-xl);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--nc-dur-fast) var(--nc-ease),
    transform var(--nc-dur-fast) var(--nc-ease);
}
.nc-cta-circle .nc-i { width: 40px; height: 40px; }
.nc-cta-circle:active { background: var(--nc-primary-hover); transform: scale(.98); }
.nc-cta-label { font-size: 16px; font-weight: 700; }

.nc-steps {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 4px 0;
  list-style: none;
}
.nc-step {
  display: flex;
  align-items: center;
  gap: 6px;
}
.nc-step-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  background: var(--nc-surface);
  box-shadow: var(--nc-shadow-sm);
  color: var(--nc-fg);
}
.nc-step-ico .nc-i { width: 15px; height: 15px; }
.nc-step-label { font-size: 11px; font-weight: 600; color: var(--nc-fg); }
.nc-step-arrow { width: 14px; height: 14px; color: var(--nc-fg-muted); }


/* ── 10. A1-w 내 명함 미작성 경고 배너 ─────────────────────────────────── */

.nc-warn {
  display: flex;
  align-items: flex-start;
  gap: var(--nc-gap);
  padding: 14px var(--nc-pad-screen);
}
/* A7 모달 안에서는 우상단 닫기 버튼과 겹치지 않게 우측 여유 */
.nc-modal--qr .nc-warn { padding-right: 52px; }
.nc-warn-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 50%;
  background: var(--nc-warn-bg);
  color: var(--nc-warn-text);
}
.nc-warn-ico .nc-i { width: 19px; height: 19px; }
.nc-warn-body { flex: 1; min-width: 0; }
.nc-warn-title { font-size: 14px; font-weight: 700; line-height: 1.4; }
.nc-warn-desc { margin-top: 2px; font-size: 13px; line-height: 1.5; color: var(--nc-fg); }
.nc-warn-go {
  margin-left: -8px;   /* 텍스트 버튼 좌측 패딩 상쇄 → 본문과 좌측 정렬 */
  font-size: 13px;
}
.nc-warn-go .nc-i { width: 14px; height: 14px; }


/* ── 11. A2 업로드·인식 중 ─────────────────────────────────────────────── */

.nc-shot { margin: 0; }
.nc-shot-img {
  display: block;
  width: 100%;
  height: 224px;
  object-fit: cover;
  border-radius: var(--nc-radius-card);
  background: var(--nc-fill);
  box-shadow: var(--nc-shadow-sm);
}

/* .nc-progress — 전용 선언 없음. 표면은 .nc-card 가 전담(aria-live 훅 전용 클래스) */
.nc-steplist {
  display: flex;
  flex-direction: column;
  gap: var(--nc-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nc-steprow {
  display: flex;
  align-items: center;
  gap: var(--nc-gap);
}
.nc-steprow-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 50%;
}
.nc-steprow-ico .nc-i { width: 14px; height: 14px; }
.nc-steprow-label {
  min-width: 0;
  font-size: 14px;
  color: var(--nc-fg-muted);
}
/* 상태 3종 */
.nc-steprow.is-done .nc-steprow-ico { background: var(--nc-primary); color: var(--nc-surface); }
.nc-steprow.is-done .nc-steprow-label { color: var(--nc-fg); }
.nc-steprow.is-active .nc-steprow-ico { background: none; }
.nc-steprow.is-active .nc-steprow-label { font-size: 15px; font-weight: 700; color: var(--nc-fg-strong); }
.nc-steprow.is-wait .nc-steprow-ico { background: var(--nc-fill-strong); }
.nc-steprow.is-wait .nc-steprow-label { font-size: 14px; color: var(--nc-fg-muted); }

/* .nc-status — 전용 선언 없음. 스타일은 .nc-steprow-label 이 전담(JS 텍스트 교체 훅) */

.nc-skeleton-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.nc-skeleton-form .nc-sk--input + .nc-sk--label { margin-top: 6px; }


/* ── 12. A3 인식 결과 확인·수정 ────────────────────────────────────────── */

.nc-origin {
  display: flex;
  align-items: center;
  gap: var(--nc-gap);
  width: 100%;
  padding: 10px 14px;
  border-radius: var(--nc-radius-card);
  background: var(--nc-surface);
  box-shadow: var(--nc-shadow-sm);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--nc-dur-fast) var(--nc-ease), transform var(--nc-dur-fast) var(--nc-ease);
}
.nc-origin:active { background: var(--nc-bg-page); transform: scale(.99); }
.nc-origin-thumb {
  width: 56px;
  height: 36px;
  flex: none;
  border-radius: var(--nc-radius-btn);
  object-fit: cover;
  background: var(--nc-fill);
}
.nc-origin-label {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--nc-fg-strong);
}
.nc-origin-chev { width: 18px; height: 18px; color: var(--nc-fg-muted); }

/* 셀카 행 */
.nc-face-row {
  display: flex;
  align-items: center;
  gap: var(--nc-gap);
  margin-top: var(--nc-pad-card);
  padding-top: var(--nc-pad-card);
  border-top: 1px solid var(--nc-hairline);
}
.nc-face-thumb {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  background: var(--nc-fill);
}
.nc-face-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  background: var(--nc-primary-50);
  color: var(--nc-primary-text);
}
.nc-face-ico .nc-i { width: 22px; height: 22px; }
/* 썸네일이 노출되면 아이콘 원을 숨긴다 (DOM 순서 의존: thumb → ico) */
.nc-face-thumb:not(.nc-hidden) + .nc-face-ico { display: none; }
.nc-face-desc {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--nc-fg);
}

/* 하단 고정 액션 바 — 탭바 바로 위 */
.nc-actionbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(59px + env(safe-area-inset-bottom));
  z-index: 880;
  background: var(--nc-surface);
  box-shadow: var(--nc-shadow-up);
  padding: var(--nc-gap) var(--nc-pad-screen);
}
.nc-tab.on > .nc-actionbar { margin-top: 0; }
.nc-actionbar-inner {
  max-width: 480px;
  margin: 0 auto;
  display: flex;
  gap: var(--nc-gap);
}
.nc-actionbar-inner > .nc-btn { flex: none; }
.nc-actionbar-inner > .nc-btn-block { flex: 1 1 0; width: auto; }


/* ── 13. A4 저장 완료 ──────────────────────────────────────────────────── */

.nc-done {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 28px 0 12px;
  animation: nc-rise var(--nc-dur-modal) var(--nc-ease) both;
}
.nc-done-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin-bottom: 6px;
  border-radius: 50%;
  background: var(--nc-primary-tint);
  color: var(--nc-primary-text);
}
.nc-done-badge .nc-i { width: 30px; height: 30px; }
.nc-done-title { font-size: 20px; font-weight: 800; line-height: 1.35; }
.nc-done-sub { font-size: 14px; color: var(--nc-fg); }
@keyframes nc-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}


/* ── 14. A5 명함첩 ─────────────────────────────────────────────────────── */

.nc-search { position: relative; }
.nc-search-ico {
  position: absolute;
  left: 14px;
  top: 50%;
  width: 18px;
  height: 18px;
  transform: translateY(-50%);
  color: var(--nc-fg-muted);
  pointer-events: none;
}
.nc-app .nc-search-input {
  display: block;
  width: 100%;
  max-width: 100%;
  height: 46px;
  padding: 0 14px 0 42px;
  border: 0;
  border-radius: var(--nc-radius-btn);
  background: var(--nc-surface);
  box-shadow: var(--nc-shadow-sm);
  color: var(--nc-fg-strong);
  font-family: inherit;
  font-size: 16px;
  font-weight: 400;
  -webkit-appearance: none;
  appearance: none;
  transition: box-shadow var(--nc-dur-fast) var(--nc-ease);
}
.nc-app .nc-search-input::placeholder { color: var(--nc-fg-muted); opacity: 1; }
.nc-app .nc-search-input::-webkit-search-decoration,
.nc-app .nc-search-input::-webkit-search-cancel-button { -webkit-appearance: none; }
.nc-app .nc-search-input:focus {
  outline: none;
  box-shadow: var(--nc-shadow-sm), 0 0 0 2px var(--nc-primary-text);
}
.nc-app .nc-search-input:focus-visible { outline: none; }

.nc-list {
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--nc-surface);
  border-radius: var(--nc-radius-card);
  box-shadow: var(--nc-shadow-sm);
  overflow: hidden;
}
.nc-row { display: block; }
.nc-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--nc-gap);
  width: 100%;
  min-height: 68px;
  padding: 10px 14px;
  text-align: left;
  color: var(--nc-fg-strong);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--nc-dur-fast) var(--nc-ease);
}
.nc-item:active { background: var(--nc-bg-page); }
/* .nc-list 가 overflow:hidden 이라 outline-offset 링이 잘린다 → 안쪽 링으로 대체
   (키보드 사용자의 주 탐색 경로) */
.nc-app .nc-item:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--nc-primary-text);
}
/* 행 구분 헤어라인 — 아바타 폭만큼 좌측 인셋 */
.nc-row + .nc-row .nc-item::before {
  content: "";
  position: absolute;
  left: 57px;
  right: 0;
  top: 0;
  height: 1px;
  background: var(--nc-hairline);
}
.nc-item-face {
  width: 44px;
  height: 44px;
  flex: none;
  font-size: 17px;
}
.nc-item-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.nc-item-name {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 회사·직책·날짜는 장식이 아니라 명함의 핵심 정보 — 어두운 행사장에서도 읽혀야 한다 */
.nc-item-sub {
  font-size: 13px;
  line-height: 1.35;
  color: var(--nc-fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nc-item-date { flex: none; font-size: 12px; color: var(--nc-fg); }

.nc-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 44px 0;
}

.nc-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 48px 24px;
}
.nc-empty-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  margin-bottom: 6px;
  border-radius: 50%;
  background: var(--nc-fill-strong);
  color: var(--nc-fg-muted);
}
.nc-empty-ico .nc-i { width: 32px; height: 32px; }
.nc-empty-title { font-size: 17px; font-weight: 800; line-height: 1.4; }
.nc-empty-desc { max-width: 28ch; font-size: 14px; line-height: 1.55; color: var(--nc-fg); }
.nc-empty .nc-btn { margin-top: 10px; }
.nc-empty--search { padding: 40px 24px; }


/* ── 15. 모달 공통 (A3 원본 · A6 시트 · A7 QR) ─────────────────────────── */

.nc-modal-back {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: flex-end;   /* 시트 기본 · 센터형은 margin:auto 로 무효화 */
  justify-content: center;
  /* 콘텐츠가 뷰포트보다 높으면(가로 모드 · A7 + 경고 배너) 여기서 스크롤한다.
     계약 §4.4 대로 .nc-modal--qr 에는 overflow-y 를 걸지 않는다(아바타 -30px 오버랩). */
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--nc-modal-gutter) 0;
  animation: nc-fade var(--nc-dur-modal) var(--nc-ease) both;
  -webkit-tap-highlight-color: transparent;
}
/* 딤은 의사요소로 분리 — color-mix() 미지원(구형 인앱 WebView·iOS<16.2)에서
   폴백이 '불투명 #1B1B18'이 되는 문제를 피하면서 rgba 하드코딩도 하지 않는다.
   ::before 는 이벤트 타깃이 되지 않으므로 배경 클릭 닫기(e.target === back) 계약 유지.
   position:fixed 라 back 이 스크롤돼도 딤은 화면에 고정된다. */
.nc-modal-back::before {
  content: "";
  position: fixed;
  inset: 0;
  background: var(--nc-fg-strong);
  opacity: .45;
}
@keyframes nc-fade { from { opacity: 0; } to { opacity: 1; } }

.nc-modal {
  position: relative;
  z-index: 1;              /* 딤(::before) 위 */
  width: 100%;
  max-width: 480px;
  padding: var(--nc-pad-card);
  background: var(--nc-surface);
  animation: nc-modal-in var(--nc-dur-modal) var(--nc-ease) both;
}
@keyframes nc-modal-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* 바텀시트 (A6) */
.nc-modal--sheet {
  border-radius: var(--nc-radius-modal) var(--nc-radius-modal) 0 0;
  box-shadow: var(--nc-shadow-lg);
  /* 88dvh 유지 + 오버레이 상하 여백을 뺀 값으로 한 번 더 캡 —
     flex-end 정렬은 넘치면 위쪽이 스크롤로 도달 불가하므로 애초에 넘기지 않는다 */
  max-height: min(88dvh, calc(100dvh - 2 * var(--nc-modal-gutter)));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* 오버레이 하단 여백을 상쇄해 화면 밑에 밀착 */
  margin-bottom: calc(-1 * var(--nc-modal-gutter));
  padding-bottom: calc(var(--nc-pad-card) + env(safe-area-inset-bottom));
}

/* 센터형 (A7 · A3 원본) */
.nc-modal--center {
  margin: auto;
  width: calc(100% - 2 * var(--nc-pad-screen));
  max-width: 358px;
  border-radius: var(--nc-radius-modal);
  box-shadow: var(--nc-shadow-lg);
}

/* A7 — 아바타가 상단을 -30px 오버랩하므로 잘리면 안 된다 */
.nc-modal--qr {
  overflow: visible;
  padding-top: var(--nc-pad-card);
}

/* A3 원본 확대 */
.nc-modal--img {
  max-width: 480px;
  padding: var(--nc-pad-card);
  background: var(--nc-surface);
}
.nc-modal-img {
  display: block;
  width: 100%;
  max-width: 100%;
  max-height: 80dvh;
  object-fit: contain;
  border-radius: var(--nc-radius-btn);
  background: var(--nc-fill);
}

.nc-sheet-handle {
  display: block;
  width: 36px;
  height: 4px;
  margin: 0 auto var(--nc-gap);
  border-radius: var(--nc-radius-badge);
  background: var(--nc-hairline);
}

.nc-modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--nc-gap);
  margin-bottom: var(--nc-gap);
}
/* A7 — 닫기 버튼만 있는 변형 (흐름에서 빼고 우상단 고정) */
.nc-modal-head--qr {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  margin: 0;
}
.nc-modal-titles { flex: 1; min-width: 0; }
.nc-modal-title { font-size: 19px; font-weight: 800; line-height: 1.3; }
.nc-modal-sub { margin-top: 2px; font-size: 13px; color: var(--nc-fg); }

.nc-modal-close {
  position: relative;
  /* A3 원본 모달의 헤더는 제목이 .nc-sr-only(position:absolute) 라 in-flow 자식이
     이 버튼 하나뿐 → space-between 이 flex-start 처럼 동작해 좌상단에 붙는다.
     auto 마진으로 형제 유무와 무관하게 우측 고정(A6·A7 배치에는 영향 없음). */
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 50%;
  background: var(--nc-fill);
  color: var(--nc-fg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--nc-dur-fast) var(--nc-ease), transform var(--nc-dur-fast) var(--nc-ease);
}
.nc-modal-close .nc-i { width: 18px; height: 18px; }
.nc-modal-close:active { background: var(--nc-fill-strong); transform: scale(.98); }
/* 히트 영역 44px */
.nc-modal-close::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}


/* ── 16. A6 명함 상세 ──────────────────────────────────────────────────── */

.nc-detail-imgs {
  display: flex;
  gap: 10px;
}
.nc-detail-card-img {
  flex: 1.6 1 0;
  min-width: 0;
  height: 104px;
  object-fit: cover;
  border-radius: var(--nc-radius-btn);
  background: var(--nc-fill);
}
.nc-detail-face-img {
  flex: none;
  width: 104px;
  height: 104px;
  object-fit: cover;
  border-radius: var(--nc-radius-btn);
  background: var(--nc-fill);
}

.nc-detail-rows {
  margin: var(--nc-gap) 0 0;
  padding: 0;
  list-style: none;
}
.nc-drow {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  /* padding 0 — 행 높이 44px 를 링크가 그대로 히트 영역으로 쓸 수 있게(아래 --link 참고) */
  padding: 0;
}
.nc-drow + .nc-drow { border-top: 1px solid var(--nc-hairline); }
.nc-drow-ico { width: 17px; height: 17px; flex: none; color: var(--nc-fg-muted); }
.nc-drow-ico-empty { display: block; width: 17px; height: 17px; flex: none; }
.nc-drow-label { flex: none; width: 52px; font-size: 13px; color: var(--nc-fg); }
.nc-drow-val {
  flex: 1;
  min-width: 0;
  padding-block: 5px;   /* 여러 줄로 접힐 때 행 구분선과 붙지 않게 */
  font-size: 14px;
  line-height: 1.5;
  color: var(--nc-fg);
  overflow-wrap: anywhere;
}
/* tel/mailto 링크는 행 전체 높이를 히트 영역으로 늘린다.
   부모가 align-items:center 라 기본값이면 링크 박스가 텍스트 높이(≈22px)뿐이어서
   행의 위아래를 눌러도 반응하지 않는다 — 44×44 필수요건 위반. */
.nc-drow-val--link {
  display: flex;
  align-items: center;
  align-self: stretch;
  min-height: 44px;
  padding-block: 5px;
  font-size: 15px;
  font-weight: 600;
  color: var(--nc-primary-text);
  text-decoration: none;
}
.nc-drow-val--link:active { color: var(--nc-primary-hover); }

/* 행 모디파이어 — data key 10종 전수 */
.nc-drow--company,
.nc-drow--department,
.nc-drow--position,
.nc-drow--mobile,
.nc-drow--phone,
.nc-drow--fax,
.nc-drow--email,
.nc-drow--website { align-items: center; }
/* 여러 줄이 될 수 있는 행은 상단 정렬 */
.nc-drow--address,
.nc-drow--memo { align-items: flex-start; padding: 10px 0; }
.nc-drow--address .nc-drow-ico,
.nc-drow--address .nc-drow-label,
.nc-drow--memo .nc-drow-ico-empty,
.nc-drow--memo .nc-drow-label { margin-top: 2px; }
/* 행 자체가 10px 패딩을 가지므로 값의 세로 패딩은 뺀다(아이콘·라벨 정렬 유지) */
.nc-drow--address .nc-drow-val,
.nc-drow--memo .nc-drow-val { padding-block: 0; }
.nc-drow--memo .nc-drow-val { white-space: pre-line; }
/* 팩스는 전용 아이콘이 없어 phone 심볼을 재사용 — 톤을 한 단계 낮춘다 */
.nc-drow--fax .nc-drow-ico { opacity: .7; }
/* 아이콘 없는 행 (memo 등) — 자리만 유지 */
.nc-drow--noicon .nc-drow-ico-empty { visibility: hidden; }

.nc-sheet-actions { margin-top: var(--nc-pad-card); }


/* ── 17. A7 교환 QR (1c 라이트) ────────────────────────────────────────── */

.nc-qr-id {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
  /* 카드 패딩(18) − 48 = −30px → 아바타가 모달 상단을 30px 오버랩 */
  margin-top: -48px;
}
/* 경고 배너가 삽입된 경우엔 오버랩을 쓰지 않는다 */
.nc-warn + .nc-qr-id { margin-top: 0; }
.nc-qr-face {
  width: 84px;
  height: 84px;
  margin-bottom: 10px;
  font-size: 30px;
}
.nc-qr-name { font-size: 18px; font-weight: 800; line-height: 1.3; }
.nc-qr-role { font-size: 13px; color: var(--nc-fg); }

.nc-qr-wrap {
  display: flex;
  justify-content: center;
  margin-top: var(--nc-gap);
}
/* quiet zone — qrcode.min.js 는 모듈을 캔버스 가장자리까지 꽉 채우므로(자체 여백 0)
   여백은 전적으로 이 패딩이 만든다. 교환 URL(≈67바이트, ECC M) → QR 버전5 = 37모듈,
   260px 기준 1모듈 ≈ 7px → 권장 4모듈 ≈ 28px.
   A7 은 모달 배경도 흰색이라 [박스 패딩 + 모달 패딩 18] 이 실효 여백이 된다:
   좌우 14+18=32px(≈4.5모듈), 상하 20+12(텍스트까지 간격)=32px(≈4.5모듈).
   inset 헤어라인은 quiet zone 한가운데(10px 지점)에 선을 그어 여백을 잘라내므로
   외곽 그림자로 대체한다. (폭 검증 360px: 260+28=288 ≤ 모달 내부 292) */
.nc-qr-box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 20px 14px;
  border-radius: var(--nc-radius-btn);
  background: var(--nc-surface);
  box-shadow: var(--nc-shadow-xs);
}
/* canvas 는 qrcode.min.js 가 실제 픽셀 크기로 그린다 — CSS로 늘리지 않는다 */
.nc-qr-box canvas,
.nc-qr-box img {
  display: block;
  max-width: 100%;
  height: auto;
}
/* A8 고정 QR 150px → 1모듈 ≈ 4.05px, 4모듈 ≈ 16px. 여기선 헤어라인이 정확히
   quiet zone 경계에 놓이므로 카드 윤곽을 유지해도 안전하다 (150+32=182, 카드 내부 292) */
.nc-qr-box--sm { padding: 16px; box-shadow: inset 0 0 0 1px var(--nc-hairline); }

.nc-qr-hint {
  margin-top: var(--nc-gap);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
  color: var(--nc-fg);
}
.nc-qr-foot {
  display: flex;
  justify-content: center;
  margin-top: var(--nc-gap);
}


/* ── 18. A8 내 명함 ────────────────────────────────────────────────────── */

.nc-my-photo-row {
  display: flex;
  align-items: center;
  gap: var(--nc-gap);
}
.nc-my-photo { width: 64px; height: 64px; }
.nc-my-photo-ph { width: 64px; height: 64px; }
.nc-my-photo-ph .nc-i { width: 28px; height: 28px; }
/* 사진이 있으면 플레이스홀더를 숨긴다 (DOM 순서 의존: img → ph) */
.nc-my-photo:not(.nc-hidden) + .nc-my-photo-ph { display: none; }
.nc-my-photo-desc {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--nc-fg);
}
/* 폼 다음 저장 버튼 */
.nc-form + .nc-btn { margin-top: var(--nc-pad-card); }

.nc-myqr { text-align: center; }
.nc-myqr .nc-btn-row--3 { margin-top: var(--nc-gap); }


/* ── 19. B1 공개 교환 페이지 (1a 포토 히어로 / 1b 이니셜 센터 폴백) ─────── */

.nc-public {
  max-width: 480px;
  margin-inline: auto;
  min-height: 100dvh;
  background: var(--nc-bg-page);
  line-height: 1.5;
  font-size: 15px;
  overflow-wrap: anywhere;
  -webkit-tap-highlight-color: transparent;   /* 상대가 보는 화면 — 회색 하이라이트 방지 */
  -webkit-text-size-adjust: 100%;
}

/* 1a — 하단 고정 CTA 만큼 여유 */
.nc-public--hero { padding-bottom: calc(88px + env(safe-area-inset-bottom)); }

/* 1b — 세로 센터, CTA는 카드 안 */
.nc-public--center {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--nc-pad-screen) var(--nc-pad-screen) calc(var(--nc-pad-screen) + env(safe-area-inset-bottom));
}

.nc-public-hero { display: block; width: 100%; }
.nc-public-hero-img {
  display: block;
  width: 100%;
  height: 264px;
  object-fit: cover;
  background: var(--nc-fill);
}

.nc-public-card {
  position: relative;
  background: var(--nc-surface);
  border-radius: var(--nc-radius-card);
  box-shadow: var(--nc-shadow-md);
  padding: 22px 20px;
}
.nc-public--hero .nc-public-card { margin: -30px var(--nc-pad-screen) 0; }
.nc-public--center .nc-public-card { padding: 28px 24px; text-align: center; }

.nc-public-initial {
  display: flex;
  margin: 0 auto 14px;
}
.nc-public-name { font-size: 24px; font-weight: 800; line-height: 1.25; }
.nc-public--center .nc-public-name { font-size: 22px; }
.nc-public-role { margin-top: 4px; font-size: 14px; color: var(--nc-fg); }
.nc-public-org { margin-top: 2px; font-size: 15px; font-weight: 600; color: var(--nc-fg); }

.nc-public-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}
.nc-prow {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0;   /* 링크가 행 높이 44px 를 그대로 히트 영역으로 쓴다 */
}
.nc-prow + .nc-prow { border-top: 1px solid var(--nc-hairline); }
.nc-prow-ico { width: 17px; height: 17px; flex: none; color: var(--nc-fg-muted); }
.nc-prow-val {
  flex: 1;
  min-width: 0;
  padding-block: 5px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--nc-fg);
  overflow-wrap: anywhere;
}
/* B1 은 상대가 보는 화면이고 이 링크가 주요 액션 — 44×44 히트 영역 필수 */
.nc-prow-val--link {
  display: flex;
  align-items: center;
  align-self: stretch;
  min-height: 44px;
  font-size: 15px;
  font-weight: 600;
  color: var(--nc-primary-text);
  text-decoration: none;
}
.nc-prow-val--link:active { color: var(--nc-primary-hover); }
/* 행 모디파이어 — B1 키 5종 전수 */
.nc-prow--mobile,
.nc-prow--phone,
.nc-prow--email,
.nc-prow--website { align-items: center; }
.nc-prow--address { align-items: flex-start; padding: 10px 0; }
.nc-prow--address .nc-prow-ico { margin-top: 2px; }
.nc-prow--address .nc-prow-val { padding-block: 0; }

.nc-public-hint {
  margin-top: var(--nc-gap);
  font-size: 12px;
  line-height: 1.55;
  color: var(--nc-fg);   /* 처음 온 상대에게 주는 조작 안내 — 읽혀야 한다 */
}
.nc-public--center .nc-public-card .nc-btn-primary { margin-top: var(--nc-pad-card); }

.nc-public-brand {
  padding: 20px var(--nc-pad-screen);
  text-align: center;
  font-size: 12px;
  color: var(--nc-fg-muted);
}

/* 하단 고정 CTA 바 (1a) */
.nc-public-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 900;
  background: var(--nc-surface);
  box-shadow: var(--nc-shadow-up);
  padding: var(--nc-gap) var(--nc-pad-screen);
  padding-bottom: calc(var(--nc-gap) + env(safe-area-inset-bottom));
}
.nc-public-cta-inner {
  max-width: 480px;
  margin: 0 auto;
}


/* ── 20. B2 만료 링크 · G1 게이트 ──────────────────────────────────────── */

.nc-gate {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  max-width: 480px;
  margin-inline: auto;
  min-height: 100dvh;
  padding: 76px var(--nc-pad-screen) calc(60px + env(safe-area-inset-bottom));
  background: var(--nc-bg-page);
  text-align: center;
  line-height: 1.5;
  font-size: 15px;
  -webkit-tap-highlight-color: transparent;
}
.nc-gate--expired { padding-top: 60px; }
.nc-gate--auth,
.nc-gate--soon { padding-top: 88px; }

.nc-gate-brand {
  position: absolute;
  top: var(--nc-pad-screen);
  left: var(--nc-pad-screen);
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.nc-wordmark { font-size: 16px; font-weight: 800; color: var(--nc-primary-hover); }
.nc-gate-brand-sub { font-size: 12px; color: var(--nc-fg-muted); }

.nc-gate-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 320px;
}
.nc-gate-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin-bottom: 8px;
  border-radius: 50%;
  background: var(--nc-fill-strong);
  color: var(--nc-fg-muted);
}
.nc-gate-ico .nc-i { width: 28px; height: 28px; }
.nc-gate-ico--jade {
  width: 72px;
  height: 72px;
  background: var(--nc-primary-tint);
  color: var(--nc-primary-hover);
}
.nc-gate-ico--jade .nc-i { width: 32px; height: 32px; }

.nc-gate-title { font-size: 19px; font-weight: 800; line-height: 1.4; }
.nc-gate--expired .nc-gate-title { font-size: 17px; }
.nc-gate-desc { font-size: 14px; line-height: 1.55; color: var(--nc-fg); }
.nc-gate--soon .nc-gate-desc { max-width: 26ch; }
.nc-gate-cta {
  width: 100%;
  max-width: 280px;
  margin-top: var(--nc-gap);
}
/* 스펙 §4 B2 는 이 링크를 14/700 으로 명시 — .nc-textbtn 기본 13px 를 덮는다 */
.nc-gate--expired .nc-textbtn { margin-top: 4px; font-size: 14px; }
.nc-gate .nc-public-brand {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(16px + env(safe-area-inset-bottom));
  padding: 0 var(--nc-pad-screen);
}


/* ── 21. 포커스 링 (키보드·접근성) ─────────────────────────────────────── */

.nc-app :focus-visible,
.nc-public :focus-visible,
.nc-gate :focus-visible,
.nc-modal-back :focus-visible {
  outline: 2px solid var(--nc-primary-text);
  outline-offset: 2px;
}


/* ── 22. 반응형 ────────────────────────────────────────────────────────── */

/* 360px 무붕괴 — 2열 필드 페어를 1열로 */
@media (max-width: 379px) {
  .nc-fgrid { grid-template-columns: 1fr; }
  .nc-detail-face-img { width: 84px; height: 84px; }
  .nc-btn-del { width: 84px; }
  .nc-steps { gap: 4px; }
  .nc-step { gap: 4px; }
  /* A8 3분할 sm 버튼("미리보기 · 링크 복사 · 내 vcf")이 CJK 임의 줄바꿈으로 2줄이 되는 폭 */
  .nc-btn-row--3 > .nc-btn-sm { padding: 0 6px; gap: 4px; font-size: 12px; }
  .nc-btn-row--3 > .nc-btn-sm .nc-i { width: 14px; height: 14px; }
}

/* 데스크톱 — 480px 중앙 컬럼 유지 */
@media (min-width: 768px) {
  .nc-app { border-radius: var(--nc-radius-card); }
  /* 데스크톱은 떠 있는 카드 — 하단 상쇄 마진을 되돌리면 오버레이 여백(48px)이 그대로 보인다 */
  .nc-modal--sheet { border-radius: var(--nc-radius-modal); margin-bottom: 0; }
}


/* ── 23. 모션 최소화 ───────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .nc-app, .nc-app *,
  .nc-public, .nc-public *,
  .nc-gate, .nc-gate *,
  .nc-modal-back, .nc-modal-back * {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .nc-btn:active,
  .nc-cta-circle:active,
  .nc-origin:active,
  .nc-modal-close:active { transform: none; }
  /* 스피너는 정적 링으로 대체 */
  .nc-spinner {
    animation: none !important;
    border-color: var(--nc-hairline);
    border-top-color: var(--nc-primary);
  }
  .nc-sk { animation: none !important; background-image: none; }
}
