/* HanFlow PDF — 웹앱(PWA). 태블릿·모바일·데스크톱 반응형, 터치 최적화. */
/* 글꼴 셀프호스팅(260722): CDN 호출 0 — 문서와 무관해도 외부 요청 자체를 없앰(개인정보 문의 대응). */
@font-face{
  font-family:"Pretendard"; font-style:normal; font-weight:45 920; font-display:swap;
  src:local("Pretendard Variable"), url("./vendor/PretendardVariable.woff2") format("woff2-variations");
}
:root{
  --brand:#1b45c4; --brand-2:#3a63e0; --brand-soft:#e9eefc;
  --bg:#f4f6fb; --surface:#ffffff; --ink:#1a2233; --ink-soft:#5b6b86;
  --line:#e3e8f2; --shadow:0 2px 14px rgba(20,40,90,.10);
  --page-bg:#ffffff; --stage-bg:#eef1f7; --canvas-shadow:0 2px 16px rgba(20,40,90,.16);
  --appbar-h:56px; --botbar-h:54px; --radius:13px;
  --safe-t:env(safe-area-inset-top,0px); --safe-b:env(safe-area-inset-bottom,0px);
  font-family:"Pretendard","Pretendard Variable",-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Malgun Gothic",system-ui,sans-serif;
}
/* ── 26개 언어(260725) — 글자체·글자방향 ────────────────────────────────
   Pretendard 는 한글·라틴·키릴은 덮지만 태국·아랍·데바나가리 글리프가 없다.
   글리프가 없으면 브라우저가 알아서 대체하긴 하나, 시스템 정품 글꼴을 앞세워야
   자간·줄높이가 무너지지 않는다(전이법칙 213: 번역은 길이·높이를 바꾼다). */
:root:lang(th){ font-family:"Noto Sans Thai","Leelawadee UI","Thonburi","Pretendard",system-ui,sans-serif; }
:root:lang(hi){ font-family:"Noto Sans Devanagari","Nirmala UI","Kohinoor Devanagari","Pretendard",system-ui,sans-serif; }
:root:lang(ar),:root:lang(fa){ font-family:"Noto Naskh Arabic","Segoe UI","Geeza Pro",Tahoma,"Pretendard",system-ui,sans-serif; }
:lang(th),:lang(hi),:lang(ar),:lang(fa){ line-height:1.55; }   /* 위·아래 글자 잘림 방지 */

/* 오른쪽→왼쪽(아랍어·페르시아어). 문서 뷰어(캔버스·페이지 무대)는 절대 뒤집지 않는다. */
html.hf-rtl .stage, html.hf-rtl .pages, html.hf-rtl .pagewrap, html.hf-rtl canvas{ direction:ltr; }
html.hf-rtl .textlayer, html.hf-rtl .annotlayer{ direction:ltr; }
html.hf-rtl input[type="number"], html.hf-rtl input[type="tel"]{ direction:ltr; text-align:center; }
html.hf-rtl .toast{ direction:rtl; }

/* 배경 테마 (뷰어 무대 + 페이지) */
body[data-bg="sepia"]{ --stage-bg:#ece2cf; --page-bg:#f7efdd; }
body[data-bg="sepia"] .pagewrap canvas{ filter:sepia(.42) saturate(.9) brightness(.99); }
body[data-bg="dark"]{ --stage-bg:#15181d; --page-bg:#1f242c; --canvas-shadow:0 2px 18px rgba(0,0,0,.5); }
/* 다크 = 야간 읽기 모드: 페이지 색 반전(흰배경→어둡게, 검은글자→밝게) + 색상 보정 */
body[data-bg="dark"] .pagewrap canvas{ filter:invert(.9) hue-rotate(180deg) brightness(1.03) contrast(.95); }

/* hidden 속성은 항상 우선(명시적 display:flex 가 [hidden] 을 덮어쓰는 문제 차단) */
[hidden]{ display:none !important; }
*{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html,body{ margin:0; height:100%; overflow:hidden; background:var(--bg); color:var(--ink); overscroll-behavior:none; }
body{ display:flex; flex-direction:column; -webkit-font-smoothing:antialiased; }
svg{ display:block; }
button{ font-family:inherit; cursor:pointer; }

/* ===== 앱바 ===== */
.appbar{
  height:calc(var(--appbar-h) + var(--safe-t)); padding-top:var(--safe-t);
  flex:0 0 auto; display:flex; align-items:center; gap:6px; padding-left:10px; padding-right:10px;
  background:var(--surface); border-bottom:1px solid var(--line); box-shadow:0 1px 0 rgba(20,40,90,.03); z-index:40;
  transition:margin-top .2s ease;
}
/* 몰입 모드: 화면 터치로 상·하단 메뉴 숨김/복귀 (body overflow:hidden 이 밀려난 바를 가림) */
body.immersive .appbar{ margin-top:calc(-1px - var(--appbar-h) - var(--safe-t)); }
body.immersive .botbar{ margin-bottom:calc(-1px - var(--botbar-h) - var(--safe-b)); }
.brand{ display:flex; align-items:center; gap:8px; text-decoration:none; color:var(--ink); font-weight:800; letter-spacing:-.01em; }
.brand .logo{ width:26px; height:26px; flex:0 0 auto; }
.brand-txt{ font-size:16px; }
.brand-txt b{ color:var(--brand); font-weight:800; }
.doc-name{ margin-left:8px; font-size:13.5px; color:var(--ink-soft); font-weight:600; max-width:30vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.spacer{ flex:1 1 auto; }

.iconbtn{
  width:40px; height:40px; flex:0 0 auto; border:0; background:transparent; color:#3a4660;
  border-radius:10px; display:inline-flex; align-items:center; justify-content:center; transition:background .12s;
}
.iconbtn svg{ width:22px; height:22px; }
.iconbtn.sm{ width:34px; height:34px; }
/* ★260730 문서를 열었을 때만 보이는 것(뒤로/닫기). 문서가 없을 때 ← 가 보이면 «어디로 가는 버튼인가»가 된다. */
.doc-only{ display:none; }
body.hf-doc .doc-only{ display:inline-flex; }
/* ★260804 #87: 페이지 서랍 버튼(햄버거)은 문서가 열려 있을 때만 — 홈에서는 서랍이 무의미하고,
   직전 문서 썸네일이 남아 보이던 실기기 신고의 노출 경로였다. (.menu-only 는 이 규칙이 없어 늘 보였다) */
.menu-only{ display:none; }
body.hf-doc .menu-only{ display:inline-flex; }
.iconbtn.sm svg{ width:18px; height:18px; }
.iconbtn:hover{ background:var(--brand-soft); color:var(--brand); }
.iconbtn:active{ background:#dde6fb; }

.btn-open{
  display:inline-flex; align-items:center; gap:6px; height:40px; padding:0 14px; margin-left:4px;
  border:0; border-radius:11px; background:var(--brand); color:#fff; font-weight:700; font-size:14px;
}
.btn-open svg{ width:19px; height:19px; }
.btn-open:hover{ background:var(--brand-2); }
.btn-open:active{ transform:translateY(1px); }

/* 검색 */
.search-wrap{ position:relative; }
.search-box{
  position:absolute; right:0; top:48px; display:flex; align-items:center; gap:2px;
  background:var(--surface); border:1px solid var(--line); border-radius:12px; box-shadow:var(--shadow);
  padding:5px 6px; z-index:50;
}
.search-box input{ border:0; outline:0; font-size:14px; width:190px; padding:6px 8px; background:transparent; color:var(--ink); }
.search-count{ font-size:12px; color:var(--ink-soft); min-width:42px; text-align:center; }

/* 드롭다운 */
.dd{ position:relative; }
.menu{
  /* ⛔★★260912 — **아랍어·페르시아어에서 보기 메뉴가 화면 밖에 있었다.**
   *   RTL 에서는 ⋮ 버튼이 **왼쪽**으로 가는데(실측 x=10) 메뉴는 `right:0` 이라 오른쪽 기준으로
   *   붙어 **x=-191** 로 밀려났다 — 그 나라 손님은 이 메뉴를 **아예 볼 수 없었다**(잘림이 아니라
   *   통째로 사라진 것이다). 26언어 잘림 전수(12화면)를 돌리자 122사례로 드러났다.
   *   ⇒ `right` 대신 **논리 속성 `inset-inline-end`** 를 쓴다. LTR 이면 오른쪽, RTL 이면 왼쪽에
   *     붙어 두 방향 모두 «버튼 아래»에 온다. (`right:0` 은 미지원 브라우저용으로 남긴다.) */
  position:absolute; right:0; inset-inline-end:0; inset-inline-start:auto;
  top:48px; min-width:210px; max-width:calc(100vw - 20px);
  background:var(--surface); border:1px solid var(--line);
  border-radius:13px; box-shadow:var(--shadow); padding:6px; z-index:50;
  /* 화면(작은 폰·가로모드)보다 길면 내부 스크롤 — 끝 항목까지 항상 접근 가능 (260723 데스크톱과 동일 수정) */
  /* ★260725 PHY '메뉴가 잘려 보인다': 창 아래끝에 딱 붙어 끝나 스크롤인지 잘린 건지 구분이 안 됐다.
     하단 여백을 키워 '더 있다'가 보이게 하고, 라벨이 줄바꿈되지 않도록 폭을 늘린다. */
  max-height:calc(100dvh - 104px); overflow-y:auto; overscroll-behavior:contain;
}
.menu .mi{
  display:flex; align-items:center; gap:10px; width:100%; border:0; background:transparent; color:var(--ink);
  padding:11px 12px; border-radius:9px; font-size:14.5px; text-align:left; font-weight:600;
  /* ★260725 에는 '최근 문서 남기지 않기'가 두 줄로 접혀 잘린 것처럼 보여 `nowrap` 을 넣었다.
   * ★★260912 정정 — 그 `nowrap` 이 이제는 **진짜 잘림**을 만든다(좁은 폰 320px 에서 네덜란드어
   *   「⭐ Document toevoegen aan favorieten」 298px 필요 / 286px 그릇). 그릇에 높이가 안 박혀
   *   있으므로 줄을 바꾸면 그릇이 같이 늘어난다 — 260725 의 걱정은 이제 성립하지 않는다. */
  white-space:normal; overflow-wrap:anywhere; line-height:1.3;
}
.menu .mi:hover{ background:var(--brand-soft); color:var(--brand); }
.menu .mi.active{ color:var(--brand); background:var(--brand-soft); }
.mi-ic{ width:20px; text-align:center; opacity:.8; }
.mi-sep{ height:1px; background:var(--line); margin:5px 4px; }
.menu .mi.disabled{ opacity:.4; pointer-events:none; }

/* ★260725 PHY '보내기 버튼이 잘 안 보인다' → 아이콘만이 아니라 라벨 달린 강조 버튼(브랜드 테두리)로. */
.btn-send{
  display:inline-flex; align-items:center; gap:6px; height:40px; padding:0 13px; margin-left:4px; flex:0 0 auto;
  border:1.6px solid var(--brand); border-radius:11px; background:var(--brand-soft); color:var(--brand);
  font-weight:800; font-size:14px; white-space:nowrap;
}
.btn-send svg{ width:19px; height:19px; }
.btn-send:hover{ background:#dde6fb; }
.btn-send:active{ transform:translateY(1px); }
.btn-send.dim{ opacity:.78; filter:grayscale(.15); }
@media (max-width:720px){ .btn-send span{ display:none; } .btn-send{ padding:0 10px; } }
/* ★260725 dim = 흐리게 보이되 클릭은 됨(눌러야 '무엇이 필요한지' 안내할 수 있다) */
.menu .mi.dim{ opacity:.5; }
.iconbtn.dim{ opacity:.45; }
/* 메뉴 내 가로 배치(배경 3종) */
.mi-row{ display:flex; gap:5px; padding:2px 4px; }
.mib{ flex:1 1 0; border:1px solid var(--line); background:transparent; color:var(--ink); font-size:12px; font-weight:600; padding:9px 2px; border-radius:9px; white-space:nowrap; }
.mib:hover{ background:var(--brand-soft); color:var(--brand); }

/* ===== 무대 ===== */
/* ⛔★★260911 PHY 신고「화면 축소가 안 된다」의 뿌리 — 실측으로 확정했다(법칙 참조).
 *   820px 이상에서 `.shellwrap` 이 **가로 flex** 가 되면(shell.css:213) `.stage` 는 가로 flex 아이템이다.
 *   가로 flex 아이템의 기본 `min-width:auto` 는 «내용만큼은 안 줄어든다»이므로,
 *   확대한 종이가 무대를 **밀어 넓힌다**. 그런데 축소 하한은 `viewer.clientWidth / 종이폭` 이라
 *   ⇒ **확대할 때마다 바닥이 같이 올라가는 톱니바퀴**가 된다. 한 번 확대하면 영영 못 돌아온다.
 *   실측(1280×800 · 720×540 종이): 뷰어폭 1197→1412→1667→1967→2321→2738,
 *     바닥 1.663→1.961→2.315→2.732→3.224→3.803, 배율도 똑같이 3.803 에서 멎었다.
 *   `min-width:0` 한 줄로 뷰어폭이 1197 에 고정되고 380%→323→275→234→199→169→166%(바닥) 로 내려온다.
 *   ⚠️`min-height:0` 은 이미 있었다 — 세로만 막고 가로를 안 막은 것이 이 사고다. 지우지 말 것. */
.stage{ position:relative; flex:1 1 auto; min-height:0; min-width:0; display:flex; background:var(--stage-bg); }

/* ⛔★★260911 pdf.js 의 «숨은 캔버스»가 **화면 높이를 훔치고 있었다**(모든 기기 · 태블릿이 가장 심하다).
 *   `canvas.hiddenCanvasElement` 는 pdf.js 가 글자 폭을 재려고 만드는 것인데, 이름과 달리
 *   `body`(세로 flex)의 **자식으로 배치되어 자리를 차지한다.** 산수가 정확히 맞는다:
 *     창높이 − 상단막대 55 − **숨은 캔버스** − 하단막대 53 = 남는 보는 자리
 *     1280×800 : 캔버스 640 ⇒ 보는 자리 **50px**   (PHY 태블릿 화면)
 *      819×800 : 캔버스 410 ⇒ 281px
 *      390×844 : 캔버스 195 ⇒ 539px                (폰도 손해 보고 있었다)
 *   흐름에서 빼내면 태블릿 690px · 폰 734px 로 회복된다(폰 기준 +36%).
 *   ⚠️`display:none` 으로 지우지 않는다 — pdf.js 가 이 캔버스를 실제로 쓴다(`getContext`·`measureText`).
 *     **자리만** 안 차지하게 흐름 밖으로 옮긴다. 그래야 재는 일은 그대로 되고 화면만 돌아온다.
 *   ⚠️이 규칙이 사라지면 「최대 축소 = 꽉 찬 화면」의 «화면» 값이 다시 엉터리가 된다(PHY 260911 지시). */
canvas.hiddenCanvasElement{ position:absolute !important; left:-99999px !important; top:0 !important; }

/* 뷰어 */
.viewer{ flex:1 1 auto; min-width:0; overflow:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain; scroll-behavior:auto; }
/* ⛔★★260911 astra 5차 «배포 차단급» — **확대한 종이의 왼쪽을 볼 수 없었다.**
 *   세로 flex 에서 `align-items:center` 는 아이가 그릇보다 넓으면 **양쪽으로 똑같이 삐져나가게** 한다.
 *   그런데 스크롤은 원점(0)부터 오른쪽으로만 갈 수 있어, **왼쪽 음수 영역에는 영영 못 간다.**
 *   PHY 260911 「여백 0·꽉 참」으로 종이가 화면보다 넓어지면서 이 함정이 실제 문제가 됐다.
 *   ⛔★★260912 astra 반증 — 처음 고침은 `safe center` 였고, **옛 브라우저 대비로 `align-items:center`
 *     를 앞줄에 두었다.** 그런데 그 «대비»가 **바로 그 버그였다.**
 *     `safe` 정렬은 **사파리 17.6 부터**인데 우리 앱은 **iOS 15 부터** 지원한다
 *     (`IPHONEOS_DEPLOYMENT_TARGET = 15.0`). iOS 15·16·17.0~17.5 손님은 `safe` 를 못 알아들어
 *     앞줄 `center` 로 되돌아간다 = **고치기 전과 똑같이 왼쪽을 못 본다.**
 *     PHY 260911 지시(②축소·여백 0)의 핵심인데 아이패드 상당수에서 안 고쳐진 셈이었다.
 *   ⇒ **어느 판에서나 되는 길**로 바꾼다: 가운데 정렬을 `margin-inline:auto` 로 한다.
 *     자동 여백은 **넘치면 0 으로 줄어들** 뿐, 왼쪽을 못 가는 음수 영역을 만들지 않는다.
 *     (이것이 `safe` 가 생기기 전부터 쓰던 정석이다. 지금도 모든 판에서 똑같이 동작한다.)
 *   ⚠️`align-items:center` 로 되돌리지 말 것 — 그러면 이 결함이 그대로 돌아온다. */
.pages{
  min-height:100%; padding:18px 0 28px; display:flex; flex-direction:column; gap:16px; transform-origin:top center;
  align-items:flex-start;
}
.pages > *{ margin-inline:auto; }
.pagewrap{ position:relative; background:var(--page-bg); box-shadow:var(--canvas-shadow); border-radius:3px; overflow:hidden; }
.pagewrap canvas{ display:block; }
.pagewrap .ph{ display:flex; align-items:center; justify-content:center; color:var(--ink-soft); font-size:13px; }
/* 텍스트 레이어 (검색·선택) */
.textLayer{ position:absolute; inset:0; overflow:hidden; opacity:1; line-height:1; }
.textLayer span{ color:transparent; position:absolute; white-space:pre; cursor:text; transform-origin:0 0; }
/* ★260731 PHY 실기기 신고: 「드래그 시 텍스트가 겹쳐보인다」(안드로이드 · 선택 팝업이 함께 떠 있었다)
 *   글자는 위에서 `color:transparent` 로 숨겨 두는데, **선택되는 순간 브라우저가 «선택 전경색»으로 다시 칠한다**
 *   (안드로이드 웹뷰에서 특히 그렇다). 그러면 숨어 있던 글자층이 드러나고,
 *   pdf.js 의 글자 위치는 캔버스 그림을 **글꼴 메트릭으로 근사**한 값이라 정확히 겹치지 않는다
 *   → 같은 글이 **두 벌로 어긋나 보인다**. 하이라이트만 남기고 글자는 계속 투명하게 둔다.
 *   `-webkit-text-fill-color` 까지 적어야 한다 — 웹킷/블링크는 선택 시 `color` 만으로는 안 먹는다. */
.textLayer span::selection{ background:rgba(0,110,255,.28); color:transparent; -webkit-text-fill-color:transparent; }
.textLayer span::-moz-selection{ background:rgba(0,110,255,.28); color:transparent; }
.textLayer .hl{ background:rgba(255,201,0,.45); border-radius:2px; }
.textLayer .hl.cur{ background:rgba(255,140,0,.6); }
body[data-bg="dark"] .pagewrap{ outline:1px solid rgba(255,255,255,.06); }

/* 페이지 모드(한 페이지씩) */
.viewer.mode-page .pages{ justify-content:flex-start; }
.viewer.mode-page .pagewrap{ display:none; }
.viewer.mode-page .pagewrap.shown{ display:block; }
/* 꽉채움(모바일·태블릿 한 페이지씩): 페이지가 화면 전체를 채움 — transform 으로 남는 축 늘림 */
.viewer.mode-page.fill{ overflow:hidden; }
.viewer.mode-page.fill .pages{ padding:0; gap:0; align-items:flex-start; }
/* 🔴★★260916 PHY 아이패드 신고 ② 「미리보기 페이지가 꽉 참이 아니라 **확대된 상태**」의 둘째 뿌리.
 *   윗줄에서 `align-items:flex-start` 를 줬지만 191행의 `.pages > *{ margin-inline:auto; }` 가
 *   **이겨서** 종이가 가운데로 놓인다. 그 상태에서 `transform-origin:0 0` 으로 가로를 늘리면
 *   종이가 **오른쪽으로 밀리며 잘린다**(실측 1024×768 에서 좌 279px 회색 띠 + 제목 오른쪽 잘림 ·
 *   (1024−466)/2 = 279 로 셈과 맞는다). 사진으로도 확인했다.
 *   ⇒ 꽉 채움 모드에서는 **가운데 정렬을 끈다.** 늘리기의 기준점이 화면 왼쪽 위여야 한다. */
.viewer.mode-page.fill .pagewrap{ transform-origin:0 0; box-shadow:none; border-radius:0; margin-inline:0; }

/* ===== 페이지 목록 패널 ===== */
/* 🔴★★260916 PHY 폴드7 **접었을 때** 「패널 열면 이전과 동일현상(본문이 덮이고 시커멓다)」
 *   ⇒ 숫자 경계(768 → 560 → …)를 또 고르는 대신 **비율**로 바꿔 경계 자체를 없앴다.
 *     패널 = min(216px, 40vw) ⇒ 본문은 **언제나 60% 이상**을 갖는다.
 *   ⚠️GPT sol 이 경고한 대가를 숨기지 않고 적는다: 접은 폴드(≈393px)에서 본문은 236px 이고
 *     A4 원문 10pt 글자는 **4 CSS px 남짓**으로 줄어든다. 「꽉 참」은 지켜지지만 **읽기는 나빠진다.**
 *     PHY 께 이 대가를 말씀드리고 그래도 밀기를 원하셔서 이렇게 한다. */
.panel{
  flex:0 0 auto; width:0; overflow:hidden; background:var(--surface);
  transition:width .2s ease; z-index:30;
  display:flex; flex-direction:column;   /* ★아래 목록이 «남은 자리»를 갖게 한다 */
  /* 🔴★260916 — 테두리를 **열렸을 때만** 둔다. 폰에서 패널이 `position:absolute`(흐름 밖)일 때는
   *   닫혀 있어도 이 1px 이 안 보였지만, 이제 흐름 안에 있으므로 **닫힌 패널이 1px 을 먹는다**
   *   (실측: 뷰어 360 → 359). 화면 왼쪽에 이유 없는 세로줄이 생기고, 그 1px 때문에
   *   배율 계산이 흔들려 **관문 ⑪ 이 빨간불**이 됐다(쪽 옮긴 뒤 562px 넘침). 작은 값이 조용히
   *   퍼지는 자리다. */
  border-right:0;
}
.panel.open{ width:188px; border-right:1px solid var(--line); }
.panel-tabs{ display:flex; gap:4px; padding:8px 10px 6px; flex:0 0 auto; }
/* ⛔★260911 PHY 「26개국어 전부 그 어떤 메뉴 및 버튼에서도 텍스트 잘림이 일어나면 안 된다」.
 *   여기 `white-space:nowrap` 이 범인이었다 — 패널 폭이 188px 로 고정인데 탭 둘이 나눠 쓰니
 *   한 칸이 90px 남짓이다. 독일어 「Lesezeichen」 은 **86px + 여백**이 필요해 넘쳤고,
 *   러시아어 「Страница」 도 68px 로 넘쳤다(관문 실측: 필요 86px / 그릇 44px).
 *   ⇒ **줄을 접게** 한다. 글자가 길면 두 줄이 되고 그릇이 같이 는다.
 *   ⚠️`nowrap` 으로 되돌리지 말 것 — 한국어만 보면 멀쩡해 보이는 것이 이 고장의 성질이다. */
.ptab{
  flex:1 1 0; min-width:0; border:0; background:transparent; color:var(--ink-soft); font-weight:700; font-size:12.5px;
  padding:8px 4px; border-radius:9px; white-space:normal; overflow-wrap:anywhere; line-height:1.25;
}
.ptab.active{ background:var(--brand-soft); color:var(--brand); }
/* 🔴★260916 GPT sol 반증 — `height:calc(100% - 44px)` 는 **탭 높이를 44 로 짐작한 값**이었다.
 *   터치 환경의 탭은 최소 44px 이고 그 부모의 세로 패딩이 14px 이라 실제로는 **58px 이상**이며,
 *   폭이 좁아 탭이 두 줄이 되면 더 커진다 ⇒ 목록 **아래가 잘려** 마지막 쪽에 못 닿는다.
 *   ⇒ 짐작을 버리고 **남은 자리**를 쓴다(`flex:1; min-height:0`). 폭이 어떻든 저절로 맞는다. */
.thumbs{ position:relative; overflow:auto; flex:1 1 auto; min-height:0; padding:0 12px 16px; display:flex; flex-direction:column; gap:10px; -webkit-overflow-scrolling:touch; }
/* ★flex:0 0 auto 필수 — 없으면 세로 flex 가 52장 전체를 화면 높이에 맞춰 납작하게 압축(260702 갤럭시 실기기 버그) */
.thumb{ position:relative; flex:0 0 auto; border:2px solid transparent; border-radius:7px; overflow:hidden; background:#fff; box-shadow:0 1px 6px rgba(20,40,90,.12); cursor:pointer; }
.thumb canvas,.thumb .tph{ display:block; width:100%; }
.thumb .tph{ min-height:60px; background:#f0f3fa; }
.thumb.active{ border-color:var(--brand); }
.thumb .tn{ position:absolute; bottom:4px; right:5px; background:rgba(20,30,55,.72); color:#fff; font-size:11px; padding:1px 6px; border-radius:6px; }
/* 북마크된 페이지: 썸네일 우상단 리본 */
.thumb.bm::after{ content:"🔖"; position:absolute; top:2px; right:4px; font-size:14px; filter:drop-shadow(0 1px 2px rgba(0,0,0,.3)); }
.panel-scrim{ position:absolute; inset:0; background:rgba(15,25,50,.35); opacity:0; pointer-events:none; transition:opacity .2s; z-index:25; }
/* 북마크 목록 탭 */
.bmlist{ overflow:auto; flex:1 1 auto; min-height:0; padding:0 10px 16px; display:flex; flex-direction:column; gap:6px; -webkit-overflow-scrolling:touch; }
.bm-item{
  display:flex; align-items:center; gap:8px; padding:11px 10px; border-radius:10px; cursor:pointer;
  background:var(--bg); border:1px solid var(--line); font-size:13.5px; font-weight:600; color:var(--ink);
}
.bm-item.active{ border-color:var(--brand); background:var(--brand-soft); }
.bm-item .bm-pg{ flex:1 1 auto; }
.bm-item .bm-del{ border:0; background:transparent; color:var(--ink-soft); font-size:13px; padding:4px 6px; border-radius:7px; }
.bm-item .bm-del:hover{ background:#fde8e7; color:#c0392b; }
.bm-empty{ padding:18px 8px; font-size:12.5px; color:var(--ink-soft); line-height:1.7; text-align:center; }

/* ===== 환영 화면 ===== */
/* ★260725 잘림 수정: 최근 문서가 늘면 내용이 화면보다 길어지는데, 가운데 정렬 플렉스는
   넘친 부분이 위·아래로 동시에 잘려 스크롤조차 안 됐다(PHY 보고). 컨테이너를 스크롤
   가능하게 하고 정렬은 margin:auto 로 넘긴다 — 짧으면 세로 중앙, 길면 전부 스크롤. */
.welcome{ position:absolute; inset:0; display:flex; align-items:flex-start; justify-content:center; background:var(--stage-bg); z-index:20; padding:24px; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; }
.welcome.hide{ display:none; }
.welcome-inner{ text-align:center; max-width:440px; width:100%; margin:auto; }
.welcome-logo{ width:62px; height:62px; margin:0 auto 18px; filter:drop-shadow(0 6px 16px rgba(27,69,196,.28)); }
.welcome h1{ font-size:24px; font-weight:800; letter-spacing:-.02em; margin:0 0 10px; color:var(--ink); }
.welcome h1 b{ color:var(--brand); }
.welcome p{ font-size:14.5px; color:var(--ink-soft); line-height:1.6; margin:0 0 22px; }
.cta{
  display:inline-flex; align-items:center; gap:9px; height:52px; padding:0 26px; border:0; border-radius:14px;
  background:var(--brand); color:#fff; font-size:16px; font-weight:700; box-shadow:0 6px 18px rgba(27,69,196,.30);
}
.cta svg{ width:21px; height:21px; }
.cta:hover{ background:var(--brand-2); }
.cta:active{ transform:translateY(1px); }
.welcome-drop{ margin-top:16px; font-size:13px; color:var(--ink-soft); }
.welcome-recv{
  margin-top:14px; padding:11px 18px; border:1.5px solid var(--line); border-radius:12px;
  background:var(--surface); color:var(--ink); font-size:13.5px; font-weight:700; box-shadow:var(--shadow);
}
.welcome-recv span{ color:var(--ink-soft); font-weight:500; }
.welcome-recv:active{ background:var(--brand-soft); }

/* 기기 간 보내기/받기 */
.ho-card{ width:min(430px,100%); }
.ho-input{
  width:100%; padding:11px 12px; border:1.5px solid var(--line); border-radius:11px;
  font-size:14.5px; background:var(--bg); color:var(--ink); outline:none;
}
.ho-input:focus{ border-color:var(--brand); background:var(--surface); }
.ho-code-input{ text-align:center; font-size:26px; font-weight:800; letter-spacing:.35em; }
.ho-code{
  text-align:center; font-size:44px; font-weight:900; letter-spacing:.22em; color:var(--brand);
  padding:18px 6px 12px; user-select:all;
}
.stage.drag .welcome-drop{ color:var(--brand); font-weight:700; }
.stage.drag::after{ content:""; position:absolute; inset:12px; border:2.5px dashed var(--brand); border-radius:18px; pointer-events:none; z-index:60; }

.recents{ margin-top:26px; text-align:left; }
.recents-h{ font-size:12.5px; font-weight:700; color:var(--ink-soft); margin-bottom:8px; }
.recents-list{ display:flex; flex-direction:column; gap:7px; }
.recent-item{ display:flex; align-items:center; gap:10px; padding:11px 13px; background:var(--surface); border:1px solid var(--line); border-radius:11px; font-size:14px; color:var(--ink); font-weight:600; }
.recent-item:hover{ border-color:var(--brand); }
.recent-item .ri-ic{ width:18px; height:18px; color:#c0392b; flex:0 0 auto; }
.recent-item .ri-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1 1 auto; }
.recent-item .ri-meta{ font-size:11.5px; color:var(--ink-soft); font-weight:500; }
.recent-item .ri-fav{ flex:0 0 auto; border:0; background:transparent; font-size:18px; line-height:1; color:#c6cede; padding:4px 6px; border-radius:8px; }
.recent-item .ri-fav.on{ color:#f5b942; }
.recent-item .ri-fav:hover{ background:var(--brand-soft); }
/* ★260829 PHY 실기기 신고② — 홈의 최근 문서에도 파일 탭과 같은 ✕(목록에서 지우기).
 *   손가락으로 눌러야 하므로 파일 탭(.fr-del)과 같은 크기를 준다 — 두 목록이 다르게 보이면 안 된다. */
.recent-item .ri-del{ flex:0 0 auto; border:0; background:transparent; font-size:16px; line-height:1; color:#c6cede; padding:6px 8px; border-radius:8px; }
.recent-item .ri-del:hover{ background:rgba(220,60,60,.10); color:#d9534f; }
.install-tip{ margin-top:22px; }
.install-btn{ border:1px dashed var(--brand); background:var(--brand-soft); color:var(--brand); font-weight:700; font-size:13.5px; padding:11px 16px; border-radius:11px; }

/* ===== 하단 바 ===== */
.botbar{
  height:calc(var(--botbar-h) + var(--safe-b)); padding-bottom:var(--safe-b);
  flex:0 0 auto; display:flex; align-items:center; justify-content:center; gap:4px;
  background:var(--surface); border-top:1px solid var(--line); z-index:40;
  transition:margin-bottom .2s ease;
}
#btnBm.on{ color:#e8a13c; }
#btnBm.on .bm-shape{ fill:#f5b942; stroke:#e8a13c; }
.botbar .bot-sep{ width:1px; height:24px; background:var(--line); margin:0 8px; }
.pagejump{ border:0; background:transparent; color:var(--ink); font-weight:700; font-size:14px; padding:8px 12px; border-radius:9px; min-width:74px; }
.pagejump:hover{ background:var(--brand-soft); }
.zoomlbl{ border:0; background:transparent; color:var(--ink); font-weight:700; font-size:13.5px; padding:8px 8px; border-radius:9px; min-width:52px; }
.zoomlbl:hover{ background:var(--brand-soft); }

/* 페이지 이동 모달 */
.jump-modal{ position:fixed; inset:0; background:rgba(15,25,50,.4); display:flex; align-items:center; justify-content:center; z-index:90; }
.jump-card{ background:var(--surface); border-radius:16px; padding:22px; width:260px; box-shadow:0 18px 50px rgba(15,25,50,.35); }
.jump-title{ font-weight:700; font-size:15px; margin-bottom:14px; }
.jump-card input{ width:100%; font-size:18px; text-align:center; padding:12px; border:1.5px solid var(--line); border-radius:11px; outline:0; }
.jump-card input:focus{ border-color:var(--brand); }
.jump-actions{ display:flex; gap:8px; margin-top:16px; }
.jb{ flex:1; height:46px; border:0; border-radius:11px; font-weight:700; font-size:15px; }
.jb.ghost{ background:#eef1f7; color:var(--ink); }
.jb.primary{ background:var(--brand); color:#fff; }
a.jb{ display:flex; align-items:center; justify-content:center; text-decoration:none; cursor:pointer; } /* 라이선스 모달 '구매 안내' 링크 */

/* 로딩 */
/* ★260808 PHY 실기기 신고 ②「텍스트 인식 누르면 1분 가까이 아무런 반응을 하지 않다가(실행된지도
 *   몰랐다) 갑자기 결과가 나타난다」의 **원인이 바로 이 한 줄이었다.**
 *   진행 표시는 `position:absolute; z-index:70` 으로 `#stage` 안에 갇혀 있었다. 그런데 스캔 화면은
 *   `.scanui`(120) · 스캔 문서 화면은 `.sc-doc`(126) 로 **화면 전체를 덮는 fixed 층**이다.
 *   즉 돌기는 돌았는데 **그 밑에 깔려 아무도 못 봤다.** 손님에게 «반응 없음»과 «안 보이는 반응»은
 *   같은 말이다 — 화면이 말하지 않으면 하지 않은 것이다(법칙 449).
 *   → 진행 표시를 겹화면들보다 위(140)로 올리고 fixed 로 바꾼다. 결제 관문(.gate 200)보다는 아래다.
 *   ⚠️여기 숫자를 낮추면 그때 이 병이 그대로 돌아온다 — 새 전면층을 만들 때는 140 미만으로 둘 것. */
.loading{ position:fixed; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; background:rgba(244,246,251,.7); backdrop-filter:blur(2px); z-index:140; }
body[data-bg="dark"] .loading{ background:rgba(31,36,44,.7); }
.spin{ width:38px; height:38px; border:3.5px solid var(--brand-soft); border-top-color:var(--brand); border-radius:50%; animation:spin .8s linear infinite; }
.loading-txt{ font-size:13.5px; color:var(--ink-soft); font-weight:600; }
@keyframes spin{ to{ transform:rotate(360deg); } }

/* 토스트 */
.toast{ position:fixed; left:50%; bottom:calc(var(--botbar-h) + var(--safe-b) + 18px); transform:translateX(-50%); background:rgba(26,34,51,.94); color:#fff; font-size:13.5px; font-weight:600; padding:11px 18px; border-radius:11px; z-index:95; box-shadow:0 8px 24px rgba(0,0,0,.25); max-width:84vw; text-align:center; }

/* ===== 반응형 ===== */
/* 페이지 목록 버튼은 모든 화면에서 노출(데스크톱도 미리보기 사용 가능) */
/* 🔴★★260916 PHY 아이패드/태블릿 신고 ② 「**좌측 미리보기 패널을 열어둔 상태에서 우측 메인화면이
 *   여백없이 가득차야 한다**」 — 사진 실측: 패널이 종이 **위에 덮여** 제목 왼쪽이 가려지고(「016년도」),
 *   오른쪽에는 회색 여백이 남았다.
 *   뿌리: 이 규칙이 **1024px 이하 전부**에서 패널을 `position:absolute`(덮개)로 만들었다.
 *     덮개는 뷰어 폭을 **안 줄이므로** 종이는 여전히 화면 전체 폭에 맞춰지고, 그 왼쪽이 패널에 가린다.
 *   ⇒ **폰(≤767px)에서만 덮개**로 둔다(390px 에서 216px 을 빼면 174px — 종이를 볼 수가 없다).
 *     태블릿(768~1024px)에서는 데스크톱과 같이 **자리를 차지해 본문을 민다** ⇒ 남은 폭에 다시 맞춰진다.
 *   ⚠️패널이 열려 폭이 바뀌어도 **창 크기 변화 신호는 안 온다** — `togglePanel` 에서 직접 다시 맞춘다. */
/* 🔴★★260916 PHY 갤럭시 폴드7 「패널 열면 메인이 시커멓고 꽉 찬 화면이 아니다」
 *   ── 어제 내가 쓴 경계 **768px 은 근거 없는 숫자**였다. 나는 폴드7 을 904px 로 **짐작하고**
 *   시험했는데, 실기기의 펼친 화면은 **767px 이하**로 잡혀 「폰 갈래」(덮기+가림막)에 들어갔다.
 *   실측(라이브): 740px·767px = 가림막 보임·가린 216px / 768px = 가림막 없음·가린 0px.
 *
 *   ⇒ 경계를 «기기 이름»이나 임의의 숫자가 아니라 **«패널을 빼고 남는 자리»**로 세운다.
 *     패널 216px + 본문 최소 344px = **560px**.
 *   ⚠️정직하게 적는다(GPT sol 반증): **560 도 «고른» 숫자다.** 「344px 면 읽을 만하다」는
 *     증명이 아니라 설계 판단이다. 다만 768 과 달리 **까닭이 있는** 숫자이고, 폭이 줄면
 *     폰처럼 덮는 쪽이 낫다는 판단은 그대로다(패널이 본문보다 넓어지면 안 된다).
 *   ⚠️밀기 갈래에서 가림막을 끄므로 **패널 밖을 눌러 닫는 길이 없다.** 닫는 길은 같은 단추
 *     다시 누르기와 썸네일 고르기뿐이다(뒤로가기는 패널을 안 닫는다 — `back.js` 의 겹화면
 *     목록에 `.panel` 이 없다. sol 이 내 잘못된 전제를 잡았다). 밀기 갈래에서는 상단바가
 *     늘 보이므로 그 단추에 언제나 닿을 수 있다.
 *   🔴★GPT sol 구현반증 ④ — 처음에 `559px`/`560px` 로 썼더니 **559 < 폭 < 560 이 빈 구간**이 됐다
 *     (배율·DPR 때문에 실제로 소수 폭이 나온다). 그 틈에서는 두 규칙이 다 안 걸려
 *     기본 188px 패널에 가림막도 꺼진 «아무도 뜻하지 않은» 상태가 된다. ⇒ `559.98px` 로 메운다. */
/* 🔴★260916 PHY 「모바일에서 좌측 미리보기화면 크기를 **20프로 정도 줄이는** 게 좋겠다」
 *   216×0.8 = 173 · 40vw×0.8 = 32vw.
 *   ⚠️GPT sol 반증 — 그냥 줄이면 **좁은 폰에서 탭이 잘린다**: 터치용 `.ptab{min-width:44px}`(:453) 둘 =
 *     88 + 간격 4 + 좌우 패딩 20 + 테두리 1 = **최소 113px**. 320px 화면에서 32vw 는 102px 이라
 *     `.panel{overflow:hidden}` 에 잘린다 — 260911 PHY 지시 「26개국어 어디서도 글자 잘림 금지」 위반.
 *   ⇒ **바닥 120px** 을 둔다(113 에 여유 7px). 393px 폰은 126px 로 뜻대로 좁아지고,
 *     320px 폰만 120px 에서 멈춘다. */
@media (max-width:1024px){ .panel.open{ width:max(120px, min(173px, 32vw)); } .panel-scrim{ display:none; } }
@media (min-width:1025px){ .botbar{ display:flex !important; } }

/* 태블릿·모바일: 하단바 노출, 상단 일부 축약 */
@media (max-width:760px){
  .brand-txt{ display:none; }
  .doc-name{ max-width:38vw; }
  .btn-open span{ display:none; }
  .btn-open{ padding:0 11px; }
  .search-box input{ width:150px; }
  .welcome h1{ font-size:21px; }
}
/* ★260730 PHY 실기기 신고(「사용하기 불편하다」) — 실측으로 원인을 세 개 찾았다(360px 폰 기준):
     ① 상단 줄 내용이 **420px** 인데 화면은 360px → 「열기」와 **「⋮ 더보기」가 화면 밖**이었다
        (그 메뉴 안에 공유·합치기·페이지편집·OCR 등 7개가 들어 있다 = 기능에 닿을 길이 없었다).
        내가 ← 를 넣어 더 나빠졌지만, ← 없이도 374px 로 이미 넘쳐 있었다 — 교수님 폰이 411px 라 겨우 보였던 것.
     ② 버튼이 **40×40**(애플 HIG 44 · 구글 Material 48 미달), 이웃 간격 6px
     ③ 쪽 이동 버튼 사이 간격이 **0px** — 다음 쪽을 누르려다 쪽번호 입력창이 열린다
   고침: 문서를 볼 때 좁은 화면에서는 **꼭 필요한 6개만** 남긴다(← 쪽목록 검색 편집 저장 더보기).
        · 로고 = 문서를 보는 중에는 장식이다
        · 「내 기기로 보내기」 = ⋮ 메뉴에 **이미 같은 항목이 있다**(중복이었다)
             ※260829 그 기능 자체를 뺐다(PHY 결정 ㉡) — 아래 규칙도 함께 지운다.
        · 「열기」 = ← 로 목록에 가서 여는 것이 자연스럽고 참고 앱들도 그렇게 한다 */
@media (max-width:520px){
  body.hf-doc .brand{ display:none; }
  body.hf-doc #btnOpenTop{ display:none; }
}
/* 손가락 크기 — 누르는 것은 44px 이상, 이웃 사이는 8px 이상(coarse=터치 기기에서만 키운다) */
@media (pointer:coarse){
  .appbar .iconbtn{ width:44px; height:44px; }
  .appbar{ gap:8px; }
  .botbar .iconbtn{ width:44px; height:44px; }
  .botbar{ gap:4px; }
  .botbar .bot-sep{ margin:0 6px; }
  /* 누를 수 있는 것은 «글자 상자»도 44px — 쪽번호·배율·패널 탭이 31px 이었다(손가락으로 못 맞춘다) */
  .pagejump, .zoomlbl{ min-height:44px; }
  .ptab{ min-height:44px; min-width:44px; }
  /* ★260730 되돌릴 수 없어 보이는 버튼은 «옆 버튼과 붙여 두지 않는다» — 「전체 지움」을 눌러
     지워진 것을 본 사람은 그 순간 당황한다(되돌리기가 있어도). 왼쪽에 틈과 구분선을 준다. */
  #annotClear{ margin-left:10px; border-left:1px solid var(--line, #e3e6ee); padding-left:10px; }
  /* ★260730 색·굵기줄은 기본으로 접는다(편집 막대 124px → 56px = 화면의 16% → 7%).
     펼치는 방법: 이미 고른 도구를 한 번 더 누른다. 그 사실을 알 수 있게 활성 도구에 ▾ 를 붙인다. */
  #editbar .eb-r2{ display:none; }
  #editbar.pal-open .eb-r2{ display:flex; }
  #editbar [data-tool].active{ position:relative; }
  #editbar [data-tool].active::after{
    content:'▾'; position:absolute; right:3px; bottom:1px; font-size:10px; line-height:1;
    color:var(--brand, #1b45c4); opacity:.75;
  }
  #editbar.pal-open [data-tool].active::after{ content:'▴'; }
}
@media (max-width:420px){
  .doc-name{ display:none; }
  /* absolute 는 좁은 .search-wrap 기준이라 화면폭 확장이 안 됨 → fixed 로 전체폭 */
  .search-box{ position:fixed; left:8px; right:8px; top:calc(var(--appbar-h) + var(--safe-t) + 6px); }
  .search-box input{ width:100%; flex:1; }
  /* 하단바 7개 컨트롤이 좁은 화면에 모두 들어가게 축약 */
  /* ★여기서 36px 로 줄이던 것이 위 44px 규칙을 이겼다(뒤에 오는 규칙이 이긴다) — 쪽 이동이 0px 간격이 된 원인.
       좁은 화면에서도 «누르는 크기»는 줄이지 않는다. 대신 구분선·여백을 줄여 자리를 만든다. */
  .botbar{ gap:2px; }
  .botbar .bot-sep{ margin:0 4px; }
  .pagejump{ min-width:60px; padding:8px 6px; font-size:13px; }
  .zoomlbl{ min-width:44px; padding:8px 4px; font-size:12.5px; }
}
/* 모바일·태블릿: 페이지가 화면에 딱 맞게(여백 0)
 * ⛔★★260911 PHY 「여백이 절대 있으면 안 된다」 — 두 가지를 고쳤다.
 *   ㉠ **조건이 태블릿을 놓치고 있었다.** JS 의 `isMobileView()` 는 «좁은 화면 **또는** 터치»인데
 *      여기 CSS 는 «좁은 화면»만 봤다. 교수님 태블릿은 1280px 이라 이 블록이 **아예 안 걸렸고**,
 *      데스크톱 값(위 18px·아래 28px·쪽 사이 16px)이 그대로 쓰였다. 조건을 JS 와 맞춘다.
 *   ㉡ **배율만 고쳐서는 «여백 0» 이 안 된다**(astra 반증). 배율을 아무리 키워도
 *      문서 처음·끝의 패딩과 쪽 사이 간격에는 무대 배경이 드러난다 ⇒ 둘 다 0 으로 만든다.
 *   ⚠️쪽 경계는 배경(빈틈)이 아니라 **종이 위에 그린 1px 선**으로 보인다 —
 *     자리를 안 차지하므로 여백이 아니고, 쪽이 붙어 보이는 것도 막는다. */
@media (max-width:1024px), (pointer:coarse){
  .pages{ padding:0; gap:0; }
  .pagewrap{ border-radius:0; box-shadow:none; }
  /* ⛔★260911 astra 3차 — 처음엔 `inset box-shadow` 로 그렸는데, 쪽 위에 **불투명 캔버스**가
   *   통째로 덮여 그 선이 안 보였다(그림자는 상자 배경 위에 그려지고 캔버스가 그 위에 온다).
   *   ⇒ 캔버스 **위**에 뜨는 덧그림(::before)으로 그린다. 자리를 안 차지하므로 여백이 아니다. */
  .pagewrap + .pagewrap{ position:relative; }
  .pagewrap + .pagewrap::before{
    content:''; position:absolute; left:0; right:0; top:0; height:1px;
    /* ⛔★astra 5차 — z-index:6 은 주석층(5)보다 위라 **손님 글씨를 1px 덮었다.**
     *   PDF 캔버스 위이면서 주석 **아래**여야 한다 ⇒ 4. */
    background:rgba(15,25,50,.30); z-index:4; pointer-events:none;
  }
}

/* 데스크톱: 하단바 대신 상단에 배율 표시 가능하나 일단 하단 유지(터치 일관성) */
@media (hover:hover) and (pointer:fine){
  .viewer{ scrollbar-width:thin; }
}

/* ===== 주석 편집(annot.js) ===== */
.editbar{
  position:sticky; top:0; display:flex; flex-wrap:wrap; align-items:center; gap:6px; row-gap:4px;
  padding:7px 12px; background:var(--surface); border-bottom:1px solid var(--line);
  z-index:39;
}
/* 긴 언어(de·zh 등)에서 버튼이 잘리지 않게 줄바꿈 허용 — sticky 흐름 레이아웃이라 높이 증가만으로 안전 (260723) */
/* 데스크톱: 2단 마크업을 한 줄로 펼침(display:contents) + order 로 자연스러운 순서 재배열 */
.ebrow{ display:contents; }
.editbar [data-tool="hl"]{ order:1; } .editbar [data-tool="pen"]{ order:2; }
.editbar [data-tool="text"]{ order:3; } .editbar [data-tool="erase"]{ order:4; }
#annotColors{ order:5; } .eb-r2 .eb-sep{ order:6; } .editbar [data-w]{ order:7; }
#annotUndo{ order:8; } #annotClear{ order:9; } .eb-flex{ order:10; } #annotDone{ order:11; }
.eb{
  display:inline-flex; align-items:center; gap:6px; flex:0 0 auto;
  height:38px; padding:0 12px; border-radius:10px; border:1px solid transparent;
  background:transparent; color:var(--ink); font-size:13.5px; font-weight:600; cursor:pointer;
}
.eb svg{ width:19px; height:19px; }
.eb:active{ transform:scale(.96); }
.eb.active{ background:#eaf2fc; border-color:#c3dcf6; color:#1b45c4; }
.eb.sm{ padding:0 10px; }
.eb.done{ background:#1b45c4; color:#fff; font-weight:700; padding:0 16px; }
.eb-sep{ flex:0 0 1px; height:22px; background:var(--line); margin:0 3px; }
.eb-flex{ flex:1 1 auto; }
.cwrow{ display:inline-flex; gap:7px; flex:0 0 auto; align-items:center; }
.cw{ width:26px; height:26px; border-radius:50%; border:2px solid rgba(0,0,0,.12); cursor:pointer; flex:0 0 auto; }
.cw.active{ border-color:#1b45c4; box-shadow:0 0 0 2px rgba(27,69,196,.25); transform:scale(1.12); }
.wd{ display:block; background:currentColor; border-radius:99px; }
.wd-s{ width:16px; height:2px; } .wd-m{ width:16px; height:4px; } .wd-l{ width:16px; height:7px; }
.iconbtn .badge{
  position:absolute; top:2px; right:2px; min-width:15px; height:15px; padding:0 4px;
  border-radius:99px; background:#e8413c; color:#fff; font-size:10px; font-weight:800;
  display:flex; align-items:center; justify-content:center; line-height:1;
}
#btnAnnot{ position:relative; }
#btnSave.has{ color:#1b45c4; }
.pagewrap canvas.annotLayer{
  position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; z-index:5;
}
.pagewrap canvas.annotLayer.on{ pointer-events:auto; touch-action:none; cursor:crosshair; }
body[data-bg] .pagewrap canvas.annotLayer{ filter:none; } /* 배경 필터에서 주석 제외 */
.annotText{
  position:absolute; z-index:6; min-width:180px; min-height:1.6em; max-width:70%;
  background:rgba(255,255,255,.92); border:1.5px dashed #1b45c4; border-radius:6px;
  padding:4px 8px; font-family:inherit; line-height:1.28; resize:both; outline:none;
}

/* ===== 문서 도구 모달(합치기 · 페이지 편집) ===== */
.tool-modal{ position:fixed; left:0; right:0; top:var(--hf-vvt, 0px); height:var(--hf-vvh, 100%);
  background:rgba(15,25,50,.45); display:flex; align-items:center; justify-content:center; z-index:90; padding:14px; }
/* ★260808 PHY 실기기 신고 ②「(결과창에서) 뒤로가기도 안먹히고」 — 여기에 두 번째 원인이 있었다.
 *   back.js 는 닫을 겹화면을 찾으면 닫기 버튼을 누르고, 없으면 `hidden` 을 세운다. 그런데 위 규칙의
 *   `display:flex` 는 브라우저 기본 `[hidden]{display:none}` 을 **이긴다**(제작자 스타일 > 사용자
 *   에이전트 스타일). 그래서 `hidden` 이 세워져도 화면에는 그대로 남았다 —
 *   «닫았다»고 적히지만 안 닫힌다(법칙 70: 보냈다≠갔다).
 *   ★한 자리만 고치지 않는다: 이 규칙은 `.tool-modal` 을 쓰는 **모든** 겹화면에 함께 걸린다. */
.tool-modal[hidden]{ display:none !important; }
/* 🔴★★260914 PHY 실기기 — 「라이선스 키를 입력할 수 없다. 키보드가 가리고 **스크롤이 안 내려간다**」
 *   ㉠카드에 **스크롤이 없었다** ⇒ 내용이 보이는 높이를 넘으면 아래쪽(입력칸·버튼)에 손이 닿지 않는다.
 *   ㉡`.tool-modal{position:fixed; inset:0}` 는 **레이아웃 뷰포트**에 맞춰 서므로 키보드가 떠도 안 줄어든다
 *     ⇒ 실제로 보이는 높이(`visualViewport`)를 CSS 변수로 받아 그 안에 세운다(app.js 가 심는다).
 *   ⚠️`--hf-vvh` 가 아직 없을 때를 위해 기본값을 둔다(브라우저·초기 프레임). */
.tool-card{
  background:var(--surface); border-radius:18px; padding:16px; width:min(560px,100%);
  max-height:calc(var(--hf-vvh, 86vh) - 24px);
  overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch;
  display:flex; flex-direction:column; gap:10px;
  box-shadow:0 18px 50px rgba(15,25,50,.35);
}
.tool-head{ display:flex; align-items:center; justify-content:space-between; }
.tool-title{ font-weight:800; font-size:16px; }
.tool-hint{ font-size:12.5px; color:var(--ink-soft); line-height:1.55; }
.tool-actions{ display:flex; gap:8px; }
/* ★260918 PHY: 「계정생성, 비번 찾기 버튼이 유독 작다. 잘보이게 하라」
 *   밑줄 글자였던 두 길을 **단추**로 올렸다. 「비밀번호를 잊으셨나요?」는 긴 언어가 많아
 *   한 줄에 안 들어가므로 **줄바꿈을 허용**한다(감추거나 잘라 내지 않는다 · 전이법칙 213).
 *   높이는 글자 수에 따라 늘어나도 좋다 — 작아지는 것만 막는다. */
.acct-links{ margin-top:8px; }
.acct-links .jb{
  background:#eef1f7; color:var(--ink);
  height:auto; min-height:46px; padding:10px 8px;
  white-space:normal; line-height:1.25; font-size:14px;
}
/* 용량 줄이기(260725): 파일 정보 + 버튼 3개. 번역문이 길어지는 언어가 있어 줄바꿈을 허용한다(전이법칙 213). */
.rd-info{ font-size:13px; font-weight:700; color:var(--ink); word-break:break-all; }
.rd-actions{ flex-wrap:wrap; }
.rd-actions .jb{ flex:1 1 auto; min-width:0; white-space:normal; }
.tool-add{
  border:1.5px dashed var(--brand); background:var(--brand-soft); color:var(--brand);
  font-weight:700; font-size:14px; padding:12px; border-radius:11px;
}
/* 합치기 목록 */
.merge-list{ overflow:auto; min-height:64px; max-height:44vh; display:flex; flex-direction:column; gap:6px; }
.merge-row{
  display:flex; align-items:center; gap:7px; padding:10px 10px; border:1px solid var(--line);
  border-radius:11px; background:var(--bg); font-size:13.5px; font-weight:600;
}
.mg-no{ flex:0 0 20px; text-align:center; color:var(--brand); font-weight:800; }
.mg-name{ flex:1 1 auto; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mg-meta{ flex:0 0 auto; font-size:11.5px; color:var(--ink-soft); }
.mg-b{ flex:0 0 auto; width:34px; height:34px; border:1px solid var(--line); background:var(--surface); border-radius:8px; font-size:13px; color:var(--ink); }
.mg-b:active{ background:var(--brand-soft); }
.mg-x{ color:#c0392b; }
/* 페이지 편집 그리드 */
.pe-card{ width:min(760px,100%); height:min(86vh, 100% - 20px); }
.pe-grid{
  flex:1 1 auto; overflow:auto; -webkit-overflow-scrolling:touch;
  display:grid; grid-template-columns:repeat(auto-fill, minmax(104px, 1fr)); gap:10px; padding:2px;
  align-items:start; align-content:start; /* 행/트랙 stretch 로 타일·행간이 늘어나는 것 방지 */
}
.pe-tile{ position:relative; border:2px solid var(--line); border-radius:11px; background:var(--bg); overflow:hidden; cursor:pointer; }
.pe-tile.sel{ border-color:var(--brand); box-shadow:0 0 0 2px rgba(27,69,196,.2); }
.pe-tile.del .pe-th{ opacity:.25; }
.pe-tile.del{ border-style:dashed; }
.pe-th{ display:flex; align-items:center; justify-content:center; background:#fff; min-height:70px; overflow:hidden; }
.pe-th canvas{ display:block; width:100%; }
.pe-num{ position:absolute; top:4px; left:6px; background:rgba(20,30,55,.72); color:#fff; font-size:10.5px; padding:1px 6px; border-radius:6px; }
.pe-btns{ display:flex; }
.pe-b{ flex:1 1 0; height:34px; border:0; border-top:1px solid var(--line); background:var(--surface); font-size:14px; color:var(--ink); }
.pe-b:active{ background:var(--brand-soft); }
.pe-x{ color:#c0392b; }
.pe-actions .jb{ font-size:13.5px; }

/* ===== 안드로이드 앱 전용 UI(기본앱 안내 · 강제 업데이트) ===== */
.deftip{
  position:fixed; left:10px; right:10px; bottom:calc(var(--botbar-h) + var(--safe-b) + 12px);
  display:flex; align-items:center; gap:10px; z-index:80;
  background:#1a2233; color:#fff; border-radius:13px; padding:12px 14px;
  font-size:13px; line-height:1.5; box-shadow:0 10px 28px rgba(0,0,0,.3);
}
/* ★★260829 PHY 실기기 신고(2차)② 「기본 PDF 프로그램 설정 카드는 **홈에만** 떠야 한다」.
 *   범인은 `document.body.appendChild(tip)` — 탭 전환은 화면(div)만 감추므로 body 자식인 이 카드는
 *   파일·스캔·도구·설정 어디서나 남았다(PHY 파일 탭 스크린샷이 그 증거).
 *   ⇒ **DOM 자리를 옮기지 않는다.** GPT sol 반증: `stage` 안으로 옮기면 ㉠문서를 열었을 때도 남고
 *     ㉡`position:fixed` 라 어차피 홈 스크롤을 따라가지도 않는다 — 자리가 아니라 **상태**의 문제다.
 *   ⇒ 이미 있는 두 상태(`body[data-tab]` · `body.hf-doc`)로 생명주기를 다스린다.
 *     기본은 «안 보임» — 새 화면이 생겨도 저절로 안 보인다(빠뜨림이 «노출»로 기울지 않게). */
.deftip{ display:none; }
body[data-tab="home"] .deftip{ display:flex; }
body.hf-doc .deftip{ display:none; }   /* 문서를 열고 있는 동안에는 홈 탭이어도 안 보인다 */
.deftip b{ color:#9db9ff; }

/* ★260829 신고(3차)① — [설정] 이 **우리 화면**을 먼저 연다(옛 판은 곧장 남의 앱 정보로 보냈다).
 *   안드로이드에 «PDF 기본 앱»을 정하는 화면이 없으므로, 두 걸음을 번호로 보여 주는 수밖에 없다.
 *   ※`.gate` 를 함께 입어 덮개·가운데 정렬을 물려받는다(z-index 200 — 라이선스 모달 135 위). */
.defsheet-card{ text-align:left; max-width:360px; }
.defsheet-card h3{ margin:0 0 12px; font-size:17px; font-weight:800; color:var(--ink); }
.defsheet-now{ margin:0 0 4px; font-size:14px; font-weight:700; color:var(--ink); }
.defsheet-why{ margin:0 0 16px; font-size:13px; line-height:1.6; color:var(--ink-soft); }
.defsheet-b{
  display:block; width:100%; margin-bottom:9px; border:0; border-radius:11px;
  background:var(--brand); color:#fff; font-weight:700; font-size:14px; padding:13px 14px;
  text-align:left; line-height:1.4;
}
/* ★남이 기본인 동안 ②는 눌러도 선택창이 안 뜬다(그 앱만 열린다). 그래서 «잠겼다»를 눈으로 보인다 —
 *   눌리는데 아무 일도 안 일어나는 버튼이 제일 나쁘다(신고 ④에서 배운 것). */
.defsheet-b:disabled{ background:var(--brand-soft); color:var(--ink-soft); font-weight:600; }
/* ㉡ ★260911 — `.gate-card{max-width:340px}` 가 **뒤에 선언되어** 위의 `.defsheet-card{max-width:360px}` 를
 *   덮어 버렸다(astra 반증). 같은 자세함이면 «나중 것»이 이긴다 — 그래서 **여기서 다시** 못 박는다.
 *   ⛔이 줄을 지우면 카드가 340px 로 좁아져 줄바꿈이 늘고, 잘림 신고가 재발한다. */
.gate-card.defsheet-card{ max-width:360px; }
.defsheet-x{
  display:block; width:100%; border:0; background:none; color:var(--ink-soft);
  font-size:13.5px; padding:10px 0 2px;
}

/* ★260829 신고(3차)③ — Word·PowerPoint·한글·ZIP 은 우리가 «그릴» 수 없다.
 *   그리는 척하면 빈 화면이 뜬다(신고②의 「열리지도 않는다」가 그 죄였다).
 *   ⇒ 할 수 있는 것만 내놓는 카드: 공유 · 다른 앱으로 열기. */
.assetview-card{ text-align:left; max-width:340px; }
.av-kind{
  display:inline-block; margin-bottom:9px; padding:3px 9px; border-radius:7px;
  background:var(--brand-soft); color:var(--brand); font-size:11.5px; font-weight:800; letter-spacing:.02em;
}
.assetview-card h3{ margin:0 0 4px; font-size:16px; font-weight:800; color:var(--ink); word-break:break-all; }
.av-meta{ margin:0 0 16px; font-size:13px; color:var(--ink-soft); }
.av-b{
  display:block; width:100%; margin-bottom:9px; border:0; border-radius:11px;
  background:var(--brand); color:#fff; font-weight:700; font-size:14px; padding:13px 14px;
}
.av-b2{ background:var(--brand-soft); color:var(--brand); }
.av-x{ display:block; width:100%; border:0; background:none; color:var(--ink-soft); font-size:13.5px; padding:10px 0 2px; }
.deftip button{
  flex:0 0 auto; border:0; border-radius:9px; background:var(--brand); color:#fff;
  font-weight:700; font-size:13px; padding:9px 14px;
}
/* ★260829 PHY 실기기 신고④ 「스캔 후 사진을 열면 공유하기·PDF 만들기 버튼이 안 먹힌다」.
 *   먹통이 아니었다 — 그 둘만 gateOk() 를 무는데(비구매자면 라이선스 모달), 그 모달이
 *   `.tool-modal`(z-index 90)이라 스캔 문서 화면 `.sc-doc`(126) **밑**에서 열리고 있었다.
 *   ⇒ 아무 일도 안 일어난 것처럼 보인다. 스캔 계층(126·시트 130) 위로 올린다.
 *   ※값은 **135** — 스캔 화면(126)·스캔 시트(130) 위, 진행 표시 `.loading`(140) **아래**다.
 *     ★GPT sol 반증(260829): 처음엔 150 으로 올렸는데, 그러면 «진행 표시 위에 입력 가능한 창»이 되어
 *       로딩 중에도 라이선스를 두 번 낼 수 있다. 가려야 할 것은 스캔 화면이지 진행 표시가 아니다. */
#licModal{ z-index:135; }
/* ⛔★★260911 PHY 신고「기본 설정 화면에서 텍스트가 잘린다 · 26언어 어디서도 잘리면 안 된다」.
 *   뿌리는 번역 길이가 아니라 **글자를 담는 그릇에 못 박힌 높이**였다(아래 `.gate-card button`).
 *   ★GPT astra 반증이 셋을 더 짚었다 — 셋 다 안 고치면 «버튼만 늘리고 카드가 잘리는» 꼴이 된다:
 *     ㉠ 높이 48px 고정 — 두 줄이면 약 69px 필요(line-height 1.4 × 2 + 세로 패딩) ⇒ 넘쳐 잘린다
 *     ㉡ `.gate-card{max-width:340px}` 가 **뒤에 선언되어** `.defsheet-card{max-width:360px}` 를 덮는다
 *        ⇒ 폭이 좁아져 줄바꿈이 더 늘어난다(잘림을 키우는 쪽으로 작용했다)
 *     ㉢ 카드가 길어지면 화면 밖으로 나가는데 **스크롤 장치가 없다**(`html,body` 가 overflow:hidden)
 *   ⇒ ㉠높이는 `min-height` 로 ㉡`.defsheet-card` 를 뒤에 다시 선언해 되찾고 ㉢카드에 세로 스크롤을 준다. */
.gate{ position:fixed; inset:0; z-index:200; background:rgba(15,25,50,.55); backdrop-filter:blur(3px); display:flex; align-items:center; justify-content:center; padding:28px; }
.gate-card{
  background:#fff; border-radius:18px; padding:28px 24px; max-width:340px; width:100%; text-align:center;
  box-shadow:0 22px 60px rgba(15,25,50,.4);
  /* ㉢ 내용이 화면보다 길어지면 **카드 안에서** 구른다 — 밖으로 잘려 나가지 않는다. */
  max-height:calc(100vh - 56px); overflow-y:auto; -webkit-overflow-scrolling:touch;
}
.gate-ic{ font-size:38px; margin-bottom:10px; }
.gate-card h2{ margin:0 0 8px; font-size:19px; color:var(--ink); }
.gate-card p{ margin:0 0 18px; font-size:14px; color:var(--ink-soft); line-height:1.6; }
/* ㉠ ★`height` 가 아니라 `min-height` 다. 글자가 길어지면 그릇이 **같이 는다**.
 *   ⛔여기를 `height` 로 되돌리면 26언어 전부에서 두 줄짜리 버튼이 다시 잘린다(PHY 260911). */
.gate-card button{
  width:100%; min-height:48px; height:auto; border:0; border-radius:12px;
  background:var(--brand); color:#fff; font-size:15.5px; font-weight:700;
  padding:12px 14px; line-height:1.35; white-space:normal; overflow-wrap:anywhere;
}

/* 모바일·태블릿: 편집바 2단 전면 노출(가로 스크롤 없이 모든 기능 한 화면) + 큰 터치 타깃 */
@media (max-width:760px){
  .editbar{ flex-direction:column; align-items:stretch; gap:7px; padding:8px 8px 10px; }
  .ebrow{ display:flex; align-items:center; gap:4px; min-width:0; }
  .eb-r1 .eb{
    /* ★260912 — 높이가 못 박혀 있어(56px), 라벨이 두 줄이 되는 언어(터키·말레이·타이…)에서
     *   **세로로 잘렸다**. 그릇에 높이를 박으면 글자가 잘린다 — PHY 신고의 뿌리와 같은 꼴. */
    flex:1 1 0; min-width:0; min-height:56px; height:auto; padding:4px 2px;
    flex-direction:column; justify-content:center; gap:3px;
    font-size:10px; font-weight:600; letter-spacing:-.02em; border-radius:11px;
  }
  .eb-r1 .eb svg{ width:22px; height:22px; }
  /* ★★260912 — 좁은 폰(320px)에서 「전체 지움」이 잘렸다(필요 42px · 그릇 38px). 새로 연
   *   «편집 막대» 훑기가 잡았다. 버튼 8개가 304px 를 나눠 가지면 한 칸이 38px 인데 `nowrap` 이라
   *   줄을 못 바꾼다 — 26개 언어에는 더 긴 낱말이 있으니 폭을 넓히는 쪽으로는 못 막는다.
   *   ⛔왼쪽 구분선(260730 PHY: 되돌릴 수 없는 버튼은 떼어 둔다)은 **그대로 둔다** — 줄바꿈만 연다. */
  /* ★line-height 는 1.15 로는 모자랐다 — 타이어 「ล้างทั้งหมด」는 위아래 결합 기호가 있어
   *   글자 상자가 25px 을 쓰는데 23px 에서 잘렸다(전수 훑기가 8사례로 잡았다). */
  .eb-r1 .eb span{ white-space:normal; overflow-wrap:anywhere; line-height:1.45; }
  .eb-r1 .eb.done{ font-size:13px; font-weight:700; }
  .eb-flex{ display:none; }
  /* ★260805 #90: 색·굵기줄을 «막대에 떠 있는 창»으로 — 흐름에서 빼내 **화면 높이를 안 먹게** 한다.
   *   260730 에 교수님이 지적하신 「막대가 화면의 16%」는 이 줄이 흐름에 끼어 높이를 더했기 때문이다.
   *   이제 도구를 고르면 저절로 열리지만(색을 따로 누를 필요 없음) 막대 높이는 1단 그대로다.
   *
   * ★260805 #90 (2차 의견 GPT sol 이 짚고 실측으로 확정): 처음 판은 `bottom:calc(100% + 6px)` 로
   *   막대 **위**에 띄웠다. 그런데 그 자리는 앱바가 차지한 자리다. 여기 `z-index:41` 은 앱바(40)를
   *   이긴다고 «적혀» 있었지만 통하지 않는다 — 부모 `.editbar` 가 `position:sticky; z-index:39` 라
   *   **쌓임 맥락을 스스로 만들고**, 그 안의 41 은 맥락 밖에서 아무 뜻이 없다. 바깥 기준으로는
   *   통째로 39 이므로 앱바 뒤로 숨는다.
   *   실측(Playwright 390×844): 팔레트 top=-10px(화면 밖) · 색 동그라미 visible=false ·
   *   팔레트 한가운데를 elementFromPoint 로 집으면 **앱바**가 잡혔다. 손님 눈에 아예 안 보였다.
   *   ★고침 = 막대 **아래**로 내린다. 위로 띄우려면 편집 중 앱바를 가려야 하는데(뒤로가기·제목이
   *   덮인다) 그건 더 나쁘다. 아래는 문서 보기 위에 떠서 앱바를 건드리지 않는다. */
  #editbar.pal-open .eb-r2{
    position:absolute; left:8px; right:8px; top:calc(100% + 6px);
    background:var(--surface); border:1px solid var(--line); border-radius:12px;
    padding:8px; box-shadow:0 6px 20px rgba(0,0,0,.16); z-index:41;
  }
  .editbar{ position:sticky; }              /* 떠 있는 창의 기준 상자 */
  .eb-r2{ gap:8px; }
  .cwrow{ gap:8px; }
  .cw{ width:36px; height:36px; }
  .eb-r2 .eb-sep{ height:26px; margin:0 2px; }
  .editbar .eb.sm{ flex:1 1 0; height:42px; justify-content:center; padding:0; border:1px solid var(--line); }
  .wd-s{ width:22px; } .wd-m{ width:22px; } .wd-l{ width:22px; }
}

/* ★260725 PHY: 무료/유료 구분을 '눌러 보기 전에' 알 수 있게 — 유료 항목 Pro 배지 + 라이선스 창 안내표 */
.mi-pro{
  margin-left:auto; padding:1px 6px; border-radius:5px;
  font-size:10.5px; font-weight:800; letter-spacing:.02em;
  background:var(--brand-soft); color:var(--brand); flex:none;
}
.menu .mi.has-lic .mi-pro{ display:none; }        /* 정품 등록 후에는 배지를 숨긴다 */
.lic-plan{ border:1px solid var(--line); border-radius:10px; overflow:hidden; margin:0 0 12px; }
.lic-plan-row{ display:flex; gap:10px; align-items:flex-start; padding:9px 11px; font-size:12.5px; }
.lic-plan-row + .lic-plan-row{ border-top:1px solid var(--line); }
.lic-plan-k{
  flex:none; min-width:38px; text-align:center; padding:1px 6px; border-radius:5px;
  font-size:10.5px; font-weight:800; background:#eef1f6; color:#5b6b86;
}
.lic-plan-k.pro{ background:var(--brand-soft); color:var(--brand); }
.lic-plan-v{ color:var(--sub); line-height:1.55; }

/* ★260727 앱 안 결제 — 네이티브에서만 보인다. 가격 글자는 스토어가 준 문자열을 그대로 그린다. */
.iap-list{ display:flex; flex-direction:column; gap:8px; margin:0 0 10px; }
.iap-item{
  display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
  border:1px solid var(--line); border-radius:10px; padding:11px 12px; background:#fff;
}
.iap-item:active{ background:#f4f6fb; }
.iap-item.best{ border-color:var(--brand); box-shadow:0 0 0 2px var(--brand-soft) inset; }
.iap-item-t{ flex:1 1 auto; min-width:0; }
.iap-item-n{ font-size:13.5px; font-weight:700; }
/* ★260728 월·연 꼬리표 — 구글은 두 요금제의 스토어 이름이 같아, 이것이 없으면 어느 쪽이 연간인지 알 수 없다. */
.iap-item-per{ margin-inline-start:6px; padding:1px 6px; border-radius:999px; font-size:11px; font-weight:600;
  background:#eef2ff; color:#4338ca; vertical-align:middle; white-space:nowrap; }
.iap-item-d{ font-size:11.5px; color:var(--sub); margin-top:2px; }
.iap-item-p{ flex:none; font-size:13.5px; font-weight:800; color:var(--brand); white-space:nowrap; }
.iap-item[disabled]{ opacity:.55; cursor:default; }
.iap-or{ text-align:center; font-size:11.5px; color:var(--sub); margin:14px 0 8px; }
.iap-actions{ flex-wrap:wrap; gap:6px; }
.iap-actions .jb{ font-size:11.5px; padding:6px 10px; }

/* ★260920 #545 바깥 로그인(구글·애플) — PHY 「클로드 모바일처럼 로그인 간편하게」.
   ⛔구글 단추는 GIS 가 제 모양으로 그린다(우리가 색을 덮지 않는다 — 브랜드 규칙). 자리만 가운데로 둔다. */
.acct-oauth-slot{ display:flex; justify-content:center; margin:2px 0 8px; min-height:44px; }
.acct-oauth{ margin-bottom:2px; }
/* 애플 단추는 애플 지침대로 검정 바탕·흰 글씨. 구글 단추(높이 44px)와 눈높이를 맞춘다. */
.jb.oauth{ display:flex; align-items:center; justify-content:center; gap:8px;
  height:44px; border-radius:999px; font-size:14px; font-weight:600; cursor:pointer;
  background:#000; color:#fff; border:1px solid #000; max-width:280px; margin:0 auto; }
.jb.oauth:hover{ opacity:.88; }
.oauth-ico{ width:17px; height:17px; flex:none; background-repeat:no-repeat; background-position:center; background-size:contain; }
/*  Apple 로고(공식 모양) — 글자와 같은 흰색으로 칠한다. */
#acctAppleIco{ background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512' fill='%23fff'%3E%3Cpath d='M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z'/%3E%3C/svg%3E"); }
@media (prefers-color-scheme: dark){
  /*  어두운 배경에서는 애플 지침이 흰 단추를 권한다 — 로고도 검정으로 뒤집는다. */
  .jb.oauth{ background:#fff; color:#000; border-color:#dcdfe6; }
  #acctAppleIco{ background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512' fill='%23000'%3E%3Cpath d='M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z'/%3E%3C/svg%3E"); }
}
