/* =====================================================================
 * family.css — 가족공유(Phase 2 · Bundle 9) 전용 CSS
 * ---------------------------------------------------------------------
 * 🔴 규칙
 *   ① 모든 선택자는 `.family-*` / `#family-*` 로 시작한다.
 *      기존 이서톡 CSS 규칙을 **한 줄도 갈아엎지 않는다** — 덮어쓸 일이 있으면
 *      `.family-*` 를 함께 적어 특이도로 이긴다(아래 hero-open 두 줄이 그 경우다).
 *   ② 색·모서리·그림자는 index.html 의 토큰만 쓴다
 *      (--surface · --surface2 · --ink · --ink2 · --muted · --line ·
 *       --acc · --ok · --warn · --danger · --r-* · --shadow*).
 *   ③ 글자 크기는 앱 전체 배율을 따른다 — `calc(NNpx * var(--fz,1))`.
 *   ④ 새 화면처럼 만들지 않는다. 공유는 위험한 기능이라 **화려함보다 상태**다.
 *      상태는 색 하나로만 말한다 : 대기=warn · 내 차례=acc · 공유 중=ok.
 * ===================================================================== */

/* =====================================================================
 * ⓪ 가족 정체성 색 — **저장소에서 색값이 적히는 유일한 곳** `[Bundle 9-C]`
 * ---------------------------------------------------------------------
 * 🔑 색은 닉네임이 아니라 **직책**에 고정한다. 닉네임을 바꿔도 색은 안 변한다.
 *    그래야 "하늘색 글은 아빠" 라는 시각 언어가 몇 년이 지나도 유지된다.
 *
 * 🔴 JS 는 색을 모른다. `FamilyIdentity` 가 내보내는 것은 `data-fam` 한 글자
 *    (`dad`·`mom`·`gpa`·`gma`·`mgpa`·`mgma`·`none`)뿐이고, 그 글자를 실제 색으로
 *    바꾸는 표는 **아래 한 곳**에만 있다. 기능마다 RGB 를 적으면 반드시 한쪽이 낡는다.
 *
 * ⓘ 이서아빠 하늘 / 이서엄마 분홍은 **새로 고른 색이 아니다** — 이미 지도 위치 버튼이
 *   쓰는 `rgb(54,110,180)` / `rgb(214,86,142)`(index.html:1690-1691, `BubbleTint` 계약)를
 *   그대로 가져왔다. 조부모 4색은 그 채도에 맞춰 같은 톤으로 골랐다(형광 금지 · 파스텔).
 * ===================================================================== */
:root{
  --fam-dad:  rgb(54,110,180);    /* 이서아빠   · 하늘  — BubbleTint sky 와 동일 */
  --fam-mom:  rgb(214,86,142);    /* 이서엄마   · 분홍  — BubbleTint pink 와 동일 */
  --fam-gpa:  rgb(196,112,36);    /* 할아버지   · 주황 */
  --fam-gma:  rgb(168,130,20);    /* 할머니     · 노랑·골드 */
  --fam-mgpa: rgb(46,138,89);     /* 외할아버지 · 초록 */
  --fam-mgma: rgb(122,91,196);    /* 외할머니   · 보라 */
  --fam-none: var(--ink2);        /* 아직 직책이 없는 사람 (Bundle 11 전) */
}
/* 어두운 배경에서는 같은 색이 그대로면 가라앉는다 — 명도만 올린다(색상은 유지) */
html[data-theme="dark"]{
  --fam-dad:  rgb(126,178,240);
  --fam-mom:  rgb(240,146,190);
  --fam-gpa:  rgb(238,166,92);
  --fam-gma:  rgb(226,192,84);
  --fam-mgpa: rgb(110,204,150);
  --fam-mgma: rgb(180,156,246);
}

/* 🔽 key → 색 표. **이 여섯 줄이 전부다.** 아래 모든 화면이 `--fam-c` 만 읽는다. */
[data-fam="dad"] { --fam-c: var(--fam-dad) }
[data-fam="mom"] { --fam-c: var(--fam-mom) }
[data-fam="gpa"] { --fam-c: var(--fam-gpa) }
[data-fam="gma"] { --fam-c: var(--fam-gma) }
[data-fam="mgpa"]{ --fam-c: var(--fam-mgpa) }
[data-fam="mgma"]{ --fam-c: var(--fam-mgma) }
[data-fam="none"]{ --fam-c: var(--fam-none) }

/* 이름 한 개(공유 시트의 사람 목록) */
.family-name{color:var(--fam-c, var(--ink2));font-weight:800}
.family-sep{color:var(--muted);font-weight:700}

/* ---------------------------------------------------------------------
 * ⓪-b 앨범 사진 댓글 — 작성자를 직책색으로
 *   ⚠ 바꾸는 것은 **이름 색과 아주 옅은 왼쪽 선**뿐이다.
 *     · 본문은 기존 `var(--ink)` 그대로 (`.pc-item` 이 이미 준다)
 *     · 시간은 기존 `var(--muted)` 그대로
 *     · 댓글 배경을 사람색으로 칠하지 않는다 — 목록이 알록달록해지면 글이 안 읽힌다
 *   ⚠ `.pc-item[data-fam] b` 는 특이도 (0,2,2) 라 index.html 의 `.pc-item b`(0,1,1) 를 이긴다.
 *     '내 댓글은 회색' 규칙은 index.html 에서 **뺐다**(마커 `가족색`) — 나도 직책색이다.
 * ------------------------------------------------------------------- */
.pc-item[data-fam] b{color:var(--fam-c, var(--acc))}
.pc-item[data-fam]:not([data-fam="none"]){
  border-left:2px solid var(--fam-c);
  border-left-color:color-mix(in srgb, var(--fam-c) 42%, transparent);
  padding-left:8px}

/* ---------------------------------------------------------------------
 * ① 앨범 상세 머리의 공유 버튼 (#album-more 바로 앞)
 *    `.inbtn` 을 그대로 쓰되 **글자가 들어가야 해서** 폭만 푼다.
 *    ⚠ `#album-detail.hero-open .detail-head .inbtn` 이 원형(50%)을 주므로
 *      같은 자리에서 우리 것만 다시 알약으로 되돌린다(특이도 0,4,1 > 0,3,1).
 * ------------------------------------------------------------------- */
.detail-head .inbtn.family-share-btn{
  width:auto;min-width:36px;padding:0 11px;border-radius:13px;gap:5px;
  background:var(--surface2);color:var(--ink2);
  font-size:calc(12px * var(--fz,1));font-weight:800;white-space:nowrap}
#album-detail.hero-open .detail-head .inbtn.family-share-btn{border-radius:13px}
.detail-head .inbtn.family-share-btn[data-state="approve"]{color:var(--acc)}
.detail-head .inbtn.family-share-btn[data-state="waiting"]{color:var(--warn)}
.detail-head .inbtn.family-share-btn[data-state="active"] {color:var(--ok)}
.detail-head .inbtn.family-share-btn[data-state="error"]  {color:var(--danger)}
/* [test분리 2026-08-31] 테스트 공유 — 실가족 초록(--ok)을 **재사용하지 않는다.**
   기존 경고 토큰(--warn)을 그대로 쓴다(새 RGB 하드코딩 0). 개발자에게만 보인다. */
.detail-head .inbtn.family-share-btn[data-state="test"]   {color:var(--warn)}
/* '승인 필요' 만 눈에 띄는 점을 단다 — 내가 지금 처리해야 하는 유일한 상태다 */
.family-share-btn .family-dot{
  width:7px;height:7px;border-radius:50%;background:var(--acc);flex:none;
  box-shadow:0 0 0 2px rgba(255,255,255,.55)}

/* ---------------------------------------------------------------------
 * ② 공유 시트 (#family-share-sheet · 기존 `.sheet` 문법 그대로)
 * ------------------------------------------------------------------- */
#family-share-sheet{max-height:78vh;display:flex;flex-direction:column;gap:10px}
.family-sheet-sub{
  font-size:calc(12.5px * var(--fz,1));color:var(--ink2);line-height:1.55;
  white-space:pre-wrap}
.family-sheet-sub.is-bad{color:var(--danger);font-weight:700}
#family-circle-list{display:flex;flex-direction:column;gap:8px;overflow-y:auto;
  overscroll-behavior:contain;padding:2px 0}
.family-empty{
  text-align:center;color:var(--muted);padding:26px 12px;line-height:1.8;
  font-size:calc(13px * var(--fz,1))}

/* 한 줄 = 가족 하나. **세로 3단**으로 읽힌다 — 가족 → 사람들 → 버튼.
   🔴 absolute·fixed 를 쓰지 않는다. 전부 정상 document flow 라서
      사람이 1명이든 4명이든, 이름이 두세 줄로 늘어나든 버튼 행이 그만큼 아래로 밀릴 뿐
      **절대 겹치지 않는다.** (이름 영역 ↔ 버튼 행 간격은 아래 `gap` 하나가 정한다) */
.family-row{
  background:var(--surface2);border-radius:var(--r-md,14px);
  padding:12px 13px;display:flex;flex-direction:column;gap:11px}
.family-row-name{
  font-size:calc(14px * var(--fz,1));font-weight:800;color:var(--ink);
  display:flex;align-items:center;gap:6px}
/* 이름 영역 — 여러 명이면 자연스럽게 다음 줄로 넘어간다.
   `keep-all` 이라 '외할아버지' 같은 낱말이 글자 단위로 쪼개지지 않는다. */
.family-row-people{
  font-size:calc(12.5px * var(--fz,1));font-weight:700;color:var(--ink2);
  line-height:1.6;word-break:keep-all;overflow-wrap:anywhere}
.family-row-people.is-bad,.family-row-people.is-bad .family-name{color:var(--danger)}
.family-row-act{display:flex;align-items:center;gap:7px;flex-wrap:wrap}

/* 상태 칩 — 색 하나로 상태를 말한다 */
.family-chip{
  font-size:calc(11.5px * var(--fz,1));font-weight:800;
  padding:4px 10px;border-radius:999px;flex:none;
  background:var(--surface);color:var(--ink2);border:1px solid var(--line)}
.family-chip[data-state="waiting"]{color:var(--warn);border-color:var(--warn)}
.family-chip[data-state="approve"]{color:#fff;background:var(--acc);border-color:var(--acc)}
.family-chip[data-state="active"] {color:var(--ok);border-color:var(--ok)}

/* [공유봤어요 2026-09-07 · FA-2] 공유 중인 사람 줄의 보조문구 —
     `공유 중 · 9월 7일에 봤어요` / `공유 중 · 아직 안 봤어요`
   🔴 `.family-row-act`(flex·wrap) 안의 **정상 flex 아이템**이다. absolute·fixed 를 쓰지 않으므로
      이름이 길든 글씨가 크든 `공유 끊기` 버튼과 **겹칠 수가 없다** — 자리가 좁으면 다음 줄로 내려간다.
   🔴 `flex:1 1 auto` + `min-width:0` — 버튼(`flex:none`)이 먼저 자리를 잡고 이 문구가 줄어든다.
      반대로 두면 큰 글씨에서 버튼이 찌그러진다.
   🔴 색은 `--muted` 가 아니라 `--ink2` 다. 부모님 소식은 읽으라고 있는 글자이지 비활성 표시가 아니다
      (다크/라이트 둘 다 본문 대비를 갖는 토큰이다). 새 RGB 0.
   ⓘ 문구가 없을 때는 `hidden` 이라 자리도 높이도 안 차지한다 — `display` 를 여기서 지정하지 않는
     이유가 그것이다(지정하면 `[hidden]` 을 덮어 빈 칸이 남는다). */
.family-seen{
  font-size:calc(12px * var(--fz,1));font-weight:700;color:var(--ink2);
  line-height:1.5;flex:1 1 auto;min-width:0;
  word-break:keep-all;overflow-wrap:anywhere}
.family-seen[hidden]{display:none}

/* 시트 안 작은 버튼들 — 기존 `.btn` 을 쓰지 않는다(높이 46px 은 여기 안 맞다) */
.family-act{
  font-size:calc(12.5px * var(--fz,1));font-weight:800;
  padding:8px 13px;border-radius:12px;flex:none;
  background:var(--surface);color:var(--ink2);border:1px solid var(--line)}
.family-act:active{transform:scale(.96)}
.family-act.is-go{background:var(--acc);color:#fff;border-color:var(--acc)}
.family-act.is-bad{color:var(--danger);border-color:var(--danger)}
.family-act[disabled]{opacity:.45}
.family-sheet-foot{display:flex;gap:8px;flex:none}

/* [person-first 2026-08-31] 한 줄 = 사람 한 명. 체크박스로 여러 명을 고른다.
   🔴 기존 3단(그룹/사람들/버튼) 구조를 갈아엎지 않았다 — 머리 줄(.family-row-head)만
      하나 두고, 그 안에 체크박스와 이름을 나란히 놓는다. 나머지 규칙은 그대로다.
   ⓘ 줄 전체가 <label> 이라 이름을 눌러도 체크된다(부모님이 쓰실 화면이라 표적이 커야 한다). */
.family-row-head{display:flex;align-items:center;gap:11px}
.family-row.is-person{cursor:pointer}
.family-pick{
  flex:none;width:21px;height:21px;margin:0;accent-color:var(--acc);cursor:pointer}
.family-pick:disabled{opacity:.45;cursor:default}
/* 요청 버튼이 시트 아래 폭을 채운다 — '닫기' 보다 이쪽이 주 동작이다 */
#family-sheet-request{flex:1;min-width:0}
#family-sheet-close{flex:none}

/* [test분리 2026-08-31] 개발 테스트 영역 — 실가족과 **시각적으로 갈라 놓는다.**
   개발자 계정에서만 렌더된다. 색은 기존 경고 토큰(--warn) 재사용 · 새 RGB 0. */
.family-testsep{
  margin:6px 2px 2px;padding-top:9px;border-top:1px dashed var(--line);
  font-size:calc(11px * var(--fz,1));font-weight:800;color:var(--muted);letter-spacing:.3px}
.family-row.is-test{background:var(--surface);box-shadow:0 0 0 1px var(--warn) inset}
.family-row.is-test .family-row-name{color:var(--warn)}

/* ---------------------------------------------------------------------
 * ③ 앨범 목록 카드의 상시 배지 — `.ac-txt` 안쪽 **제목 위** chip
 *    ⚠ 기존 여행+(.album-travel-badge) · D-Day(.album-dday-badge) 는
 *      카드 **오른쪽 위**, 자동기록(.album-geo-chip) 은 **왼쪽 위**다.
 *      그래서 이 배지는 `.ac-txt` 안(카드 왼쪽 아래 덩어리)에 두어 어느 것과도 안 겹친다.
 *    🔴 `.ac-txt` 의 **맨 앞**이다 — 읽는 순서가
 *         👥 가족 공유 중 → 이서 모음집 2 → 모음집 · 8월 26일 · 34장
 *       이어야 한다. 메타줄 아래에 있으면 카드에서 가장 늦게 읽히는데,
 *       이건 장식이 아니라 *"지금 남에게 보인다"* 는 D-2 안전표시다.
 *    🔴 absolute 를 쓰지 않는다(우하단 고정 금지) — 제목과 같은 흐름 안이다.
 * ------------------------------------------------------------------- */
.family-share-badge{
  display:inline-block;margin:0 0 5px;
  padding:3px 9px;border-radius:999px;
  font-size:calc(11px * var(--fz,1));font-weight:800;color:#fff;
  background:rgba(52,199,123,.86);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  text-shadow:0 1px 5px rgba(0,0,0,.3)}
.family-share-badge[data-state="pending"]{background:rgba(255,174,51,.9)}
/* [test분리 2026-08-31] 🧪 테스트 공유 중 — 초록(실가족)과 **반드시 달라야 한다.**
   승인 대기와 같은 노랑 계열이지만 글자가 `🧪 테스트 공유 중` 이라 뜻이 갈린다.
   개발자 계정에서만 만들어지는 배지다(family.js Badge.paint). */
.family-share-badge[data-state="test"]{background:rgba(255,174,51,.9)}

/* ---------------------------------------------------------------------
 * ④ 업로드 시트 경고 — 막지 않는다. **알고 넣게** 한다.
 * ------------------------------------------------------------------- */
.family-up-warn{display:none}
.family-up-warn.on{
  display:block;
  background:var(--surface2);border-left:3px solid var(--ok);
  border-radius:10px;padding:9px 11px;
  font-size:calc(12.5px * var(--fz,1));font-weight:700;color:var(--ink2);
  line-height:1.5;word-break:keep-all}

/* ---------------------------------------------------------------------
 * ⑤ 설정 화면 행 — 기존 `.set-card` / `.set-row` 문법 그대로 쓴다
 * ------------------------------------------------------------------- */
#family-set-sub[data-state="need"]{color:var(--acc);font-weight:800}

/* =====================================================================
 * ⑥ 가족 Viewer 셸 (Phase 2 · Bundle 10)
 * ---------------------------------------------------------------------
 * 이 아래 규칙은 전부 `html.family-viewer` 안에 갇혀 있다 —
 * Owner 화면에는 **한 픽셀도 닿지 않는다.**
 *
 * 큰 글씨에 대하여
 *   디자인 문서의 `110%` 제안을 전역 `FzSvc` 저장값으로 밀어 넣지 않는다.
 *   그건 사용자가 자기 손으로 정한 값이고, 같은 기기를 Owner 도 쓴다 —
 *   몰래 고치면 두 상태가 섞인다. 대신 **Viewer 화면 안에서만** 기본 글씨와
 *   터치 타깃을 키운다. 사용자가 글자 크기를 또 키우면 `--fz` 가 곱해져 같이 커진다.
 * ===================================================================== */

/* 상단바가 없다 — `_strip()` 이 `#top-bar` 를 통째로 지웠다. 화면 맨 위 여백은 여기서 준다. */
html.family-viewer #views{padding-top:var(--sat)}

/* 🔴 840px 이상에서 index.html 은 `#views` 를 **그리드 다판**으로 바꾸고
   `.view{display:none}` 으로 잠근다(`.pane-on` 인 판만 보인다).
   Viewer 는 항상 한 판이라(`LayoutSvc.calcMode` 가 1 을 고정) 그 규칙을 되돌려야
   PC·태블릿에서 화면이 통째로 비지 않는다. 레일은 그대로 쓴다(탭 내용은 하단바와 동일). */
@media (min-width:840px){
  html.family-viewer #views{display:block;grid-template-columns:none}
  html.family-viewer #views .view{position:absolute;inset:0;display:none}
  html.family-viewer #views .view.on{display:flex}
}

/* ---------- 판(앨범 목록 ↔ 앨범 상세) ---------- */
/* 🚨 [장식가둠 2026-09-05 · 실기 blocker Round 3 ②] `z-index:0` 한 칸이 **이 줄의 핵심**이다.
   🐛 실기 : *"Travel+ 연결 앨범의 금테두리와 여행+ 메달이 목록 카드에서 끝나지 않고
      앨범 상세 안까지 따라온다."* (real Chromium 412px 스크린샷으로 재현했다)

   [확인된 사실 — 마크업도 CSS 도 이미 목록 전용이었다]
     `.album-origin-frame` · `.album-travel-badge` · `.album-att-ribbon` 은 셋 다
     `.album-card.wide …` 로 스코프돼 있고, `AlbumList._card()` 말고는 만드는 곳이 없다.
     그런데도 상세에 보였다 — **스택 문맥(stacking context) 누수**다.
       · `#fv-detail.on` 은 `z-index:2` 라 자기 스택 문맥을 만든다.
       · `#fv-list` 는 `position:absolute` 지만 `z-index:auto` 라 **문맥을 안 만든다.**
       → 그 안의 카드 장식(`.album-origin-frame` z6 · `.album-travel-badge` z5)이
         부모 문맥으로 그대로 올라가 **z-index 5·6 으로 칠해진다** → z2 인 상세를 덮는다.
     ⓘ 리본만 안 새던 이유가 이 진단의 증거다 — 리본은 `.ac-txt`(z-index:2 · 자기 문맥)
       안이라 2 로 잘리고, 프레임·메달만 5·6 으로 빠져나왔다. 실기에서 보인 것도 그 둘이다.

   [해결] 판마다 **자기 스택 문맥**을 갖게 한다. 그러면 판 안의 어떤 z-index 도
     판 밖으로 못 나간다 — "따라오지 말라" 고 부탁하는 것이 아니라 **나갈 수가 없다.**
   🔴 `.album-card` 쪽 z-index 를 낮추지 않았다. 그것들은 카드 안에서 서로의 순서를
      정하는 값이고(메달 5 < 외곽 6), 건드리면 Owner 격자에서 순서가 바뀐다.
   🔴 Owner 는 한 글자도 안 변한다 — 이 규칙은 `html.family-viewer` 안이다.
   ⚠ `.fv-detail.on{z-index:2}` 는 그대로 둔다. 같은 문맥 안 형제끼리의 위아래는
     여전히 그 값이 정한다(목록 0 < 상세 2). */
html.family-viewer .fv-pane{position:absolute;inset:0;display:flex;flex-direction:column;overflow:hidden;background:var(--bg);z-index:0}
html.family-viewer .fv-detail{display:none}
html.family-viewer .fv-detail.on{display:flex;z-index:2}

/* ---------- 머리글 ---------- */
html.family-viewer .fv-head{
  flex:none;display:flex;align-items:center;gap:8px;
  padding:calc(var(--sat) + 14px) 18px 12px}
/* [셸통일 2026-08-31 · Bundle C] 글자 크기·자간을 Owner `.view-head`(index.html:1576)와
   같은 값으로 맞췄다 — `#top-bar` 가 없어 위 padding-top(`--sat` 보정)만 Viewer 몫으로 남는다.
   Owner CSS 는 안 건드리고 값만 그대로 옮겼다(class 를 공유하지 못하는 이유는 Owner 의
   `.view-head` 가 뒤로가기 버튼 레이아웃을 안 가진 순수 타이틀 한 줄이라 구성이 다르기 때문). */
html.family-viewer .fv-head h1{
  font-size:calc(20px * var(--fz,1));font-weight:800;letter-spacing:-.5px;color:var(--ink);
  margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 터치 타깃 48px — 부모님 손가락 기준. 아이콘만 키우면 안 눌린다. */
html.family-viewer .fv-back{
  flex:none;width:48px;height:48px;margin-left:-12px;
  display:flex;align-items:center;justify-content:center;
  border-radius:16px;color:var(--ink2)}
html.family-viewer .fv-back:active{background:var(--surface2)}
html.family-viewer .fv-back .icon{width:26px;height:26px}

html.family-viewer .fv-scroll{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 16px 24px}

/* [셸통일 2026-08-31 · Bundle C] 설정 화면만 Owner `.set-scroll`(index.html:1763)과 같은
   카드 사이 간격(gap 12px)·여백(padding 6px 16px 40px)을 쓴다 — `.set-card` 들이 서로
   붙어 있던 것을 Owner 값 그대로 맞췄다. 다른 Viewer 화면(`.fv-scroll` 공용)은 그대로 둔다. */
html.family-viewer #fv-settings-body{padding:6px 16px 40px;display:flex;flex-direction:column;gap:12px}
/* ⭐ [설정잘림 2026-08-31] 🐛 "설정이 아래에서 잘린다 · 프로필 설명도 잘리고 글꼴 아래는
   화면 밖이라 못 누른다 · 로그아웃까지 못 간다" (사용자 실기 신고)
   [확인된 사실]
     · 위 줄이 이 칸을 `display:flex;flex-direction:column` 으로 만든다(Owner `.set-scroll` 과 같은 값).
     · flex 자식의 기본은 `flex-shrink:1` 이다 → 카드 높이 합이 화면보다 크면 **카드가 눌린다.**
       `.set-card` 는 `overflow:hidden`(index.html:1764) 이라 눌린 만큼 **안쪽 글자가 잘린다.**
     · 그리고 다 눌려서 들어가 버리니 `scrollHeight == clientHeight` = **스크롤이 아예 안 생긴다.**
       "아래가 잘렸는데 스크롤도 안 된다" 는 두 증상이 사실은 이 한 가지 원인이다.
     · Owner 는 이 사고를 이미 겪고 규칙을 만들어 뒀다 —
       `#view-settings .set-scroll>*{flex:none}`(index.html:1967,
       주석 그대로 "세로 스크롤 카드 잘림 방지 (flex 자식 압축 금지)").
       Bundle C 가 Owner 의 padding·gap 만 가져오고 **이 한 줄을 안 가져왔다.**
   [해결] Owner 와 **같은 규칙**을 Viewer 칸에도 건다. 새 규칙이 아니라 빠뜨린 짝이다.
   ⓘ 이 한 줄로 알림·비밀번호·앱 버전·새로고침·로그아웃(family.js:2182~2195)이
      비로소 화면에 제 높이로 서고, 끝까지 스크롤된다. */
html.family-viewer #fv-settings-body>*{flex:none}

/* ---------- 앨범 카드 ----------
   [시각통일 2026-08-31] Owner 카드와 **같은 class**(`.album-card.wide` · index.html:794~839,1586~)를
   그대로 쓴다 — CSS 는 index.html 에 이미 있으므로 여기서는 목록 컨테이너 여백만 정한다.
   Owner CSS 는 한 글자도 건드리지 않았다.
   [반응형통일 2026-08-31 · Bundle C] Owner `#album-grid`(index.html:1585)와 **같은 값**
   (auto-fill · minmax(300px,1fr) · gap 12px)으로 맞췄다 — 넓은 화면에서 카드가 여러 열로
   흐르는 것도 Owner 와 같아진다(폰 폭에서는 auto-fill 이 스스로 1열로 접혀 지금과 똑같다). */
html.family-viewer .fv-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:12px;align-content:start}

/* ---------- 앨범 상세 히어로 ----------
   [히어로재사용 2026-08-31 · Bundle C] Owner 의 실제 `#album-hero*` id(index.html:741~,3135~)를
   family.js 가 그대로 재사용한다 — 여기서는 CSS 를 한 줄도 새로 안 만든다(index.html 의
   unscoped 규칙을 그대로 물려받는다). 예전에 있던 `.fv-hero*` 껍데기는 걷어냈다. */

/* ---------- 앨범 상세 사진 ----------
   [배치통일 2026-08-31] 고정 3열 정사각 격자를 버리고 Owner 와 **같은 배치 엔진**(PhotoMason)을 쓴다.
   칸 자체는 Owner 와 같은 `.ph-item`(index.html:1592) 이라 모서리·캡션·▶배지 문법을 그대로 물려받는다.
   여기서 정하는 것은 '담는 자리' 뿐이다 — 좌표·높이는 전부 PhotoMason 이 인라인으로 박는다. */
/* ⭐ [사진폭 2026-08-31] 🐛 "사진 영역 오른쪽에 큰 빈 여백" (사용자 실기 신고)
   [확인된 사실]
     · 이 `.fv-mason` 은 `#album-photos` 의 자식인데, 그 부모는 Owner CSS 로
       `display:flex;flex-wrap:wrap`(index.html:1599) 이다 → **이 div 는 flex 아이템**이다.
     · flex 아이템의 기본은 `flex:0 1 auto` = 폭이 **내용 기준(shrink-to-fit)** 이다.
       block 이었다면 저절로 100% 였을 폭이, 여기서는 100% 가 아니다.
     · `PhotoMason.innerW(cont)` 는 `cont.clientWidth` 를 잰다(app.js:23264).
       그래서 배치 엔진이 **좁은 폭**을 받아 그 폭 안에만 사진을 깔았다 = 오른쪽 여백.
     · Owner 는 이 wrapper 자체가 없다 — 칸을 `#album-photos` 에 바로 넣고
       `PhotoMason.layout($('#album-photos'), g)` 를 부른다(app.js:23482~23489).
   [해결] wrapper 를 한 줄 통째로 쓰게 만든다. 값은 `PhotoMason` 이 제 `.pm-wrap` 에
     인라인으로 박는 것과 **같은 값**이다(app.js:23355~23356) — 새 규칙이 아니다.
     이제 `clientWidth` = `#album-photos` 안쪽 폭 그대로 → Owner 와 같은 단 계산이 나온다. */
html.family-viewer .fv-mason{display:flex;flex-wrap:wrap;gap:6px;position:relative;flex:0 0 100%;width:100%}
/* 폴백 : 배치 엔진이 안 돌았을 때(app.js 미로드 등) 사진이 **안 보이는 상태를 만들지 않는다.**
   `.ph-item` 은 안쪽 그림이 absolute 라 높이를 안 주면 칸이 접힌다 → 두 칸씩 정사각으로 흐르게 둔다.
   PhotoMason 이 돌면 각 칸에 인라인 width/height/position 이 박혀 이 규칙을 덮는다(인라인이 이긴다). */
html.family-viewer .fv-mason .ph-item{flex:1 1 calc(50% - 3px);aspect-ratio:1}
html.family-viewer .fv-mason .ph-item:active{opacity:.75}

/* ---------- 공유 D-Day ----------
   카드 자체는 Owner 와 같은 `.dday-card`(index.html:1720) 다 — 배경사진·스크림·숫자 크기를 그대로 쓴다.
   여기서 정하는 것은 '세로로 쌓는 자리' 와 **누를 수 없다는 표시**뿐이다.
   (Owner 카드는 눌러 수정창을 여는 `cursor:pointer` 인데 Viewer 에는 수정창이 없다) */
html.family-viewer .fv-ddays{display:flex;flex-direction:column;gap:12px;padding:4px 0 8px}
html.family-viewer .fv-ddays .dday-card{cursor:default}

/* ---------- 빈 상태 · 오류 ----------
   둘은 **다른 화면이다.** 오류를 빈 상태처럼 그리면 부모님이
   "아직 안 왔구나" 로 읽고 기다린다 — 사실은 다시 눌러야 하는 상황이다. */
html.family-viewer .fv-empty{
  padding:64px 24px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:8px}
html.family-viewer .fv-empty-emoji{font-size:calc(46px * var(--fz,1));opacity:.55;line-height:1}
html.family-viewer .fv-empty-title{
  font-size:calc(17px * var(--fz,1));font-weight:800;color:var(--ink2);word-break:keep-all}
html.family-viewer .fv-empty-sub{
  font-size:calc(14.5px * var(--fz,1));font-weight:600;color:var(--muted);line-height:1.6;word-break:keep-all}
html.family-viewer .fv-retry{
  margin-top:12px;min-height:48px;padding:0 26px;border-radius:16px;
  background:var(--acc);color:#fff;font-size:calc(15.5px * var(--fz,1));font-weight:800}
html.family-viewer .fv-retry:active{transform:scale(.96)}

/* ---------- 설정 ----------
   [Bundle A 2026-08-31] 카드/행 자체는 Owner 의 `.set-card`/`.set-row`/`.sr-ic`/`.sr-sub`/
   `.profile-row`/`.avatar`/`.set-hint`(index.html, 전역 class)를 그대로 쓴다 — Viewer 전용
   `.fv-me*`/`.fv-set*` 껍데기는 여기서 걷어냈다. 남기는 것은 Owner에 대응 부품이 없는
   "그 자리에서 고르는" 세그먼트 버튼(`.fv-seg`)뿐이다(Owner 는 FzSvc/ThemeSvc/FontSvc 모두
   각자 `.sheet` 를 여는데, Viewer 는 Owner 시트를 DOM 에 두지 않는 계약이라 시트 대신 쓴다). */

/* [설정보강 2026-08-31] 고르기 줄 — 부모님용이라 **시트를 열지 않고 그 자리에서** 고른다.
   터치 타깃 48px 유지. 줄바꿈을 허용해 글씨를 키워도 버튼이 서로 안 겹친다. */
html.family-viewer .fv-seg{
  display:flex;flex-wrap:wrap;gap:8px;padding:12px 14px 14px;border-top:1px solid var(--line)}
html.family-viewer .fv-seg-b{
  flex:1 1 auto;min-width:76px;min-height:48px;padding:0 12px;border-radius:14px;
  background:var(--surface2);color:var(--ink2);font-weight:800;
  border:2px solid transparent;white-space:nowrap}
html.family-viewer .fv-seg-b.on{background:var(--acc);color:#fff;border-color:var(--acc)}
html.family-viewer .fv-seg-b:active{transform:scale(.96)}

/* [테마색 2026-08-31] 테마 색상 20종 — Owner 팔레트 시트(`#palette-grid`, index.html:2601)와
   **같은 4열 · 같은 부품**(`.pal-dot`/`.pal-name`, index.html:2604~2605 · 전역 class)을 쓴다.
   담는 자리만 `.fv-seg` 로 바꾼 것이다 — Viewer 는 Owner `.sheet` 를 DOM 에 두지 않으므로
   FzSvc/FontSvc/ThemeSvc 와 **똑같이** 그 자리에서 고른다. 색값·이름은 `PaletteSvc.PALETTES`
   하나에서만 온다(여기에 색을 적지 않는다).
   ⚠ 고른 표시는 Owner `.pal-cell.sel`(index.html:2603)과 같게 **테두리**로 한다 —
     `.fv-seg-b.on` 의 '배경을 악센트로' 를 그대로 쓰면 색 견본 위에 악센트가 깔려
     정작 무슨 색인지 안 보인다. */
html.family-viewer .fv-seg-b.fv-pal{
  flex:0 0 calc(25% - 6px);min-width:0;padding:10px 4px;white-space:normal;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px}
html.family-viewer .fv-seg-b.fv-pal.on{background:var(--surface2);color:var(--ink2);border-color:var(--acc)}
html.family-viewer .fv-seg-b.fv-pal .pal-dot{width:34px;height:34px}

/* [접기 2026-08-31] 테마 색상 20색은 **누를 때만** 펼친다.
   Owner 는 같은 문제를 `.sheet`(`#palette-sheet`)로 푸는데 Viewer 는 Owner 시트를 DOM 에
   하나도 두지 않는 계약이라, 같은 자리에서 접었다 편다. 기본은 접힘(`.on` 없음). */
html.family-viewer .fv-seg.fv-fold{display:none}
html.family-viewer .fv-seg.fv-fold.on{display:flex}
/* 펼침 표시 화살표 — 열리면 아래를 가리킨다 */
html.family-viewer .fv-chev{
  margin-left:8px;flex:none;color:var(--muted);font-weight:800;
  font-size:calc(17px * var(--fz,1));line-height:1;transition:transform .18s}
html.family-viewer .fv-chev.on{transform:rotate(90deg)}
/* `.sr-sub` 가 `margin-left:auto` 로 오른쪽 끝을 잡으므로 화살표는 그 뒤에 붙는다 */

/* [프로필정리 2026-08-31] 프로필 카드 보기 모드 — 기본에는 입력칸이 없고 버튼 두 개만 있다.
   ⚠ 늘 열려 있던 raw `<input>` 은 관리자 화면처럼 보이고 표시 이름을 두 번 보여 줬다(사용자 신고).
   버튼 생김새는 값 고르기 세그먼트(`.fv-seg-b`)와 같은 언어를 쓰되, 카드 안 작은 동작이라
   터치 타깃만 44px 로 조금 낮춘다(부모님 손가락 기준은 유지). */
html.family-viewer .fv-prof-acts{display:flex;flex-wrap:wrap;gap:8px}
html.family-viewer .fv-prof-b{
  flex:0 1 auto;min-height:44px;padding:0 14px;border-radius:13px;
  background:var(--surface2);color:var(--ink2);font-weight:800;
  font-size:calc(13.5px * var(--fz,1));border:2px solid transparent;white-space:nowrap}
html.family-viewer .fv-prof-b.on{background:var(--acc);color:#fff;border-color:var(--acc)}
html.family-viewer .fv-prof-b:active{transform:scale(.96)}
/* 이름 편집칸 — 누를 때만 생긴다(`_openNameEdit`). 자리 자체는 늘 있고 비어 있다. */
html.family-viewer .fv-name-edit{
  display:flex;flex-direction:column;gap:10px;padding:0 16px 16px}
html.family-viewer .fv-name-edit input{
  width:100%;min-height:48px;padding:0 14px;border-radius:14px;
  background:var(--surface2);border:2px solid var(--line);color:var(--ink);
  font-size:calc(15px * var(--fz,1));font-weight:700}
html.family-viewer .fv-name-edit input:focus{outline:none;border-color:var(--acc)}

/* ---------- 탭 라벨을 조금 크게 ----------
   `--fz` 를 그대로 곱해 사용자의 글자 크기 설정을 존중한다. */
html.family-viewer #bottom-nav button{font-size:calc(12px * var(--fz,1))}
html.family-viewer #bottom-nav button .icon{width:26px;height:26px}
html.family-viewer #side-rail button{font-size:calc(12px * var(--fz,1))}
html.family-viewer #side-rail button .icon{width:26px;height:26px}


/* =====================================================================
 * ⑤ 앨범 소셜 `.as-*` — 함께 보는 사람 + 앨범/사진 한마디  [Phase 3 · 3-1]
 * ---------------------------------------------------------------------
 * 🔴 접두사 규칙 : 이 파일의 ①규칙은 `.family-*` 였지만, Bundle 10 부터 화면별
 *   접두사(`.fv-*` 가족 Viewer 셸 · `.pc-*` Owner 사진댓글)를 함께 쓰고 있다.
 *   `.as-*`(album social)은 그 세 번째다 — **Owner 상세와 Viewer 상세가 같이 쓰는
 *   유일한 조각**이라 어느 한쪽 접두사에 넣을 수 없다.
 *
 * 🔴 새 색을 하나도 만들지 않는다. 사람 이름 색은 위 ⓪의 `--fam-*` 표를 그대로 읽고
 *   (`[data-fam]` → `--fam-c`), 나머지는 전부 앱 토큰이다.
 *
 * 🔴 `.pc-*` 를 재사용하지 않는 이유 : 저 규칙들은 `PhotoMason` 격자 안에서 **좌표를
 *   갖는다**(`position:absolute` · `left/width` 를 JS 가 px 로 넣는다). 시트 안에
 *   그대로 넣으면 폭이 0 이 되거나 화면 밖으로 나간다. 보이는 언어는 맞추되
 *   배치 규칙은 새로 쓴다.
 * ===================================================================== */

/* ---------- ① 히어로 우하단 · 함께 보는 사람 ----------
   ⓘ `#album-hero` 는 이미 `position:relative`(index.html:741) 라 새로 좌표계를 만들지 않는다.
   ⓘ 히어로가 접히면(`.collapsed` · height 0 · overflow hidden) 이 칩도 같이 사라진다 —
     의도한 동작이다. 스크롤을 올리면 다시 보인다.

   🔴 [칩잘림 2026-09-04] 🐛 신고 : *"`👥 3명` 칩의 **아래가 잘려** 보인다."*
     [확인된 사실] 잘린 것이 아니라 **가려진 것**이다.
       · `#album-hero` 는 `z-index:auto` 라 쌓임 맥락을 만들지 않는다 → 이 칩의 `z-index`
         는 형제인 `#album-photos` 와 **같은 층에서 직접 겨룬다.**
       · `#album-photos{margin-top:-22px; z-index:3}`(index.html:781) 는 시안의 '겹쳐
         올라오는 둥근 사진판' 이라 히어로 하단 **22px 를 덮는다.**
       · 칩도 `z-index:3` 인데 DOM 이 **뒤**라 같은 값에서 사진판이 이긴다 →
         `bottom:8px`+높이 34px 중 **아래 14px** 이 사진판 밑으로 들어갔다.
     [해결] **자리를 옮기지 않는다.** 층만 사진판 위로 한 칸 올린다.
       · px 를 억지로 띄우면 `--fz`(글자 크기)·기기마다 다시 어긋나고, 위로 올리면
         `#album-hero-txt`(bottom:34px) 의 메타 줄과 겹친다 — 둘 다 새 버그다.
       · 사진판의 `padding-top:18px` 덕에 칩 아래끝(히어로 하단 8px)은 **첫 사진 줄보다
         위**라, 층을 올려도 사진을 가리지 않는다. 높이·레이아웃 변화 0px.
     ⚠ `.fab`(z-index:20) · `.detail-head`(z-index:6) 보다는 낮게 유지한다.
     ⓘ `bottom` 을 8 → 14px 로만 올린다. 층을 올려도 칩 아래끝이 사진판 안으로 14px 들어가
       **첫 사진 줄에 딱 붙어** 답답했다(실측: 칩 425~461 · 사진판 상단 447). 6px 만 띄우면
       파고드는 깊이가 8px 로 줄어 숨통이 트인다.

   🔴 [칩자리 2026-09-04 · 바로 위 처방의 정정] 🐛 재신고 : *"칩이 아직도 히어로와 첫 사진의
     **경계선에 걸쳐** 보인다."* — 맞다. 층(z-index)만 올린 위 처방은 **가려짐만** 풀었고
     **자리는 그대로**라 제품 기준을 만족하지 못했다. 히트테스트가 칩을 돌려준다는 것은
     합격 근거가 아니다.
     [확인된 사실] 위 처방의 전제 하나가 틀렸다 — 사진판의 `padding-top` 은 18px 이 아니라
       **4px** 이다. `index.html:781` 의 `padding-top:18px` 을 **뒤에 오는**
       `index.html:1599` 의 `padding:4px 10px 96px` 단축 속성이 덮는다(같은 `#album-photos`
       특이도 · 나중 규칙 승 · 둘 다 같은 `<style>` 블록 안이고 media query 밖이다).
       그래서 첫 사진 줄은 히어로 하단 **18px** 지점에서 시작한다.
       실측(375×812 · --fz 1 · 실제 CSS 를 그대로 실은 DOM probe) :
         히어로 하단 357.3 · 사진판 상단 335.3 · 첫 사진 상단 339.3 · 칩 307.3~343.3
       → 칩 아래끝이 사진판 안으로 **8px**, **첫 사진 위로 4px** 파고들어 있었다.
     [해결] 자리를 **사진판 위로 완전히 뺀다.** 다만 34px 짜리 알약을 그대로 올리면
       `#album-hero-txt`(bottom:34px) 의 제목 상자와 부딪힌다 — 쓸 수 있는 세로 틈이
       `사진판 상단 − 제목 상자 아래` = 약 38px 뿐이라 36px 알약은 숨 쉴 자리가 없다.
       그래서 알약을 34 → **28px**(테두리 포함 30px) 로 살짝 줄이고 `bottom` 을 **26px** 로 올린다.
       실측(2줄 꽉 찬 제목 · 긴 메타 · 긴 라벨 · --fz 0.8/1/1.3/1.6 전부) :
         · 사진판 상단까지 **아래 여백 +4px** (전 구간 동일 · 이전엔 −8px)
         · 제목 상자까지 **위 여백 +1 ~ +16px** (전 구간 겹침 0)
         · 글자·이모지 잘림 0 (`scrollWidth/scrollHeight` 로 확인)
       히어로 높이 · `#album-hero-txt` · 사진판 · 그 밖의 히어로 내용은 **한 px 도 안 움직인다**
       (칩은 `position:absolute` 라 흐름 밖이다). 칩이 없는 앨범은 이 규칙이 아예 안 걸린다.
     ⚠ `bottom` 을 28px 로 올리면 `--fz 0.8`(메타 줄이 가장 얇을 때) 에서 제목 상자와
       **−1px** 로 닿는다 — 실측으로 확인한 **26px 이 상한**이다.
     ⚠ 남은 것 하나(이번 신고 밖 · 손대지 않음) : 메타 줄이 아주 길면 그 꼬리가 칩 **뒤로**
       지나간다(`#album-hero-sub` 는 히어로 폭을 다 쓰고 칩은 반투명이다). 이전에도 그랬고
       이번 변경으로 나빠지지 않았다. 고치려면 칩이 있을 때만 메타 줄에 오른쪽 여백을
       줘야 하는데, 그건 히어로 본문을 건드리는 일이라 따로 승인을 받고 한다. */
#album-social-aud.as-aud{
  position:absolute;right:14px;bottom:26px;z-index:4;
  min-height:28px;padding:0 11px;border-radius:15px;
  background:rgba(20,14,20,.52);color:#fff;font-weight:800;
  font-size:calc(12.5px * var(--fz,1));line-height:28px;
  border:1px solid rgba(255,255,255,.28);backdrop-filter:blur(6px);
  white-space:nowrap;max-width:calc(100% - 28px);overflow:hidden;text-overflow:ellipsis}
#album-social-aud.as-aud:active{transform:scale(.96)}

/* ---------- ② 한마디 남기기 (사진 목록 **맨 아래** · 격자 안의 마지막 칸) ----------
   🔄 [한마디위치 2026-09-02] 히어로 아래에서 사진 뒤로 옮겼다(app.js `_mountComments`).
     이제 `#album-photos`(flex-wrap 격자) 의 **자식**이므로 한 줄을 통째로 차지해야 한다 —
     `flex:0 0 100%` 가 없으면 사진 칸 옆에 끼어 들어가 격자가 깨진다.
   ⚠ 경계선도 아래(border-bottom)가 아니라 **위**다. 맨 끝 블록에 아랫줄을 그으면
     허공에 떠 있는 선이 된다. */
#album-social.as-block{
  flex:0 0 100%;width:100%;box-sizing:border-box;
  padding:14px 16px 10px;display:flex;flex-direction:column;gap:9px;
  margin-top:10px;border-top:1px solid var(--line)}
.as-title{font-size:calc(14px * var(--fz,1));font-weight:900;color:var(--ink)}
.as-list{display:flex;flex-direction:column;gap:6px}
.as-load{font-size:calc(12.5px * var(--fz,1));color:var(--muted);font-weight:700;padding:2px 0}

/* 한 줄 = 이름 · 본문 · 시각. `.pc-item` 과 **같은 읽기 순서**를 유지한다. */
.as-item{
  font-size:calc(13px * var(--fz,1));line-height:1.5;color:var(--ink);
  word-break:break-word;padding-left:8px;border-left:2px solid transparent}
.as-item[data-fam]{border-left-color:var(--fam-c, transparent)}
.as-item b{font-weight:800;color:var(--fam-c, var(--acc));margin-right:5px}
.as-item .as-body{color:var(--ink)}
.as-item .as-time{
  font-style:normal;font-size:calc(10px * var(--fz,1));
  color:var(--muted);margin-left:6px;white-space:nowrap}

/* 입력 — 부모님 손가락 기준으로 48px. 보내기 직전 확인창은 **일부러 없다**(3-1 계약). */
.as-add{display:flex;gap:8px;align-items:center}
.as-input{
  flex:1 1 auto;min-width:0;min-height:44px;padding:0 13px;border-radius:14px;
  background:var(--surface2);border:2px solid var(--line);color:var(--ink);
  font-size:calc(14px * var(--fz,1));font-weight:600}
.as-input:focus{outline:none;border-color:var(--acc)}
.as-send{
  flex:none;min-height:44px;padding:0 15px;border-radius:14px;
  background:var(--acc);color:#fff;font-weight:800;
  font-size:calc(13.5px * var(--fz,1));border:2px solid var(--acc)}
.as-send:active{transform:scale(.96)}

/* ---------- ③ 사진 칸의 💬 (가족 Viewer 격자 전용) ----------
   ⚠ Owner 격자의 `.pc-badge` 와 **다른 클래스**다. 저쪽은 펼침 상태(`.on`)가
     "댓글칸이 아래 열려 있다" 를 뜻하지만, 여기 `.on` 은 "댓글이 있다" 는 뜻이다. */
.as-badge{
  position:absolute;right:6px;bottom:6px;z-index:2;
  min-width:26px;height:26px;padding:0 7px;border-radius:13px;
  background:rgba(20,14,20,.50);color:#fff;
  font-size:calc(11px * var(--fz,1));font-weight:800;line-height:26px;
  text-align:center;white-space:nowrap;border:1px solid rgba(255,255,255,.22)}
.as-badge:not(.on){opacity:.72}
.as-badge:active{transform:scale(.92)}

/* ---------- ④ 작은 시트 (함께보기 · 사진 댓글이 같이 쓴다) ----------
   🔴 강제 popup 이 아니다 — 사람이 눌렀을 때만 뜨고, 바깥을 누르면 닫힌다.
   ⓘ `#modal`·`.sheet` 와 겹치지 않게 z-index 를 그 위로 둔다(뒤로가기 층 순서와 같다). */
.as-sheet{position:fixed;inset:0;z-index:1400;display:none}
.as-sheet.on{display:block}
.as-sheet-bg{position:absolute;inset:0;background:rgba(10,6,10,.44)}
.as-sheet-in{
  position:absolute;left:0;right:0;bottom:0;
  max-height:74vh;display:flex;flex-direction:column;
  background:var(--surface);border-radius:20px 20px 0 0;
  padding:6px 0 max(14px, env(safe-area-inset-bottom));
  box-shadow:0 -8px 34px rgba(0,0,0,.28)}
.as-sheet-head{
  flex:none;position:relative;padding:12px 46px 10px 18px;
  font-size:calc(15px * var(--fz,1));font-weight:900;color:var(--ink)}
.as-sheet-x{
  position:absolute;right:10px;top:6px;width:38px;height:38px;border-radius:19px;
  background:transparent;color:var(--muted);font-size:calc(16px * var(--fz,1));font-weight:800}
.as-sheet-x:active{background:var(--surface2)}
.as-sheet-body{
  flex:1 1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:0 18px 4px;display:flex;flex-direction:column;gap:10px}
.as-people{line-height:1.9;font-size:calc(14.5px * var(--fz,1))}
.as-sheet-empty{font-size:calc(13px * var(--fz,1));color:var(--muted);font-weight:700}
.as-sheet-note{font-size:calc(12.5px * var(--fz,1));color:var(--warn);font-weight:700}
.as-sheet-sub{font-size:calc(12.5px * var(--fz,1));color:var(--muted);font-weight:600;line-height:1.55}

/* 가족 Viewer 는 글자·터치 타깃을 한 단계 키운다 — 셸의 기존 기준(`.fv-*`)과 같은 축이다 */
html.family-viewer #album-social.as-block{padding:16px 16px 12px}
html.family-viewer .as-title{font-size:calc(15px * var(--fz,1))}
html.family-viewer .as-item{font-size:calc(14px * var(--fz,1))}
html.family-viewer .as-input{min-height:48px;font-size:calc(15px * var(--fz,1))}
html.family-viewer .as-send{min-height:48px;font-size:calc(14.5px * var(--fz,1))}
html.family-viewer .as-badge{min-width:30px;height:30px;line-height:30px;font-size:calc(12px * var(--fz,1))}

/* =====================================================================
 * 여행+ Viewer — **Owner 여행책 그대로** (Phase 3 · 3-2 / 3-4 · 정본화 2026-09-05)
 * ---------------------------------------------------------------------
 * 🔑 종이·표지·섹션 제목·밑줄·따옴표·Day·사진·자유서식은 **`erp.css` 것을 그대로
 *   물려받는다.** Viewer 여행 화면의 id 가 원래부터 `view-erp` 이고 종이가
 *   `.erp-paper` 라서, `erp.css` 의 `#view-erp …` 규칙 400줄이 그대로 걸린다.
 *
 * 🚨 [실기 blocker B · 2026-09-05] 예전에 여기 있던 것을 지웠다.
 *   ① `.fv-trip-paper` 가 `display:block` + `scroll-snap-type:none` 으로 **가로 책장을
 *      세로 흐름으로 되돌리고** 있었다. 그 한 줄이 Owner 여행책의 *장(page) 구조* 를
 *      통째로 지웠다 — 실기에서 "긴 세로 웹페이지" 로 보인 원인이다.
 *   ② `.fv-trip-page/-cover/-head/-meta/-sum/-names/-name/-index/-di/-dayh/-blocks/
 *      -sched/-text/-div/-empty/-photo` 는 **Viewer 전용 두 번째 여행책 디자인**이었다.
 *      그 renderer(`family.js` `_coverHtml`…`_blockHtml`)가 사라져 전부 죽은 규칙이다.
 *   🔴 되살리지 말 것 — 두 벌을 유지하면 언젠가 또 갈라진다. Viewer 여행+ 는
 *      Owner 여행책의 **읽기 전용 projection** 이지 비슷한 다른 화면이 아니다.
 *
 * 남은 것은 **flex 자식이 줄어들 수 있게 하는 한 줄**뿐이다.
 *   `#view-erp .erp-paper` 는 `flex:1` 인데, Viewer 종이는 `.fv-pane`(flex column)의
 *   자식이라 `min-height:0` 이 없으면 내용 높이만큼 늘어나 장의 `height:100%` 가
 *   화면 밖으로 밀린다. Owner 쪽은 `#view-erp` 자신이 그 자리라 필요 없었다.
 * ===================================================================== */
html.family-viewer #view-erp .erp-paper.fv-trip-paper{ min-height:0 }

/* 내 준비물 — **참가자일 때만** 이 DOM 이 생긴다(plain Viewer 는 0개). */
html.family-viewer .fv-prep-ta{
  width:100%;min-height:140px;border:0;background:transparent;resize:vertical;
  font-family:var(--erp-hand-body,inherit);font-size:calc(16px * var(--fz,1));
  line-height:1.8;color:var(--erp-paper-ink,#2f3033)}
html.family-viewer .fv-prep-btns{display:flex;gap:8px;margin-top:10px}
html.family-viewer .fv-prep-btns .fv-retry{margin-top:0;min-height:44px;padding:0 20px}
html.family-viewer .fv-prep-cancel{
  min-height:44px;padding:0 18px;border-radius:16px;background:var(--surface2);
  color:var(--ink2);font-size:calc(14.5px * var(--fz,1));font-weight:800}
html.family-viewer .fv-prep-cancel:active{transform:scale(.96)}

/* =====================================================================
 * ⑥ 앨범 「함께한 사람」 `.aa-*` — Owner 앨범 참가자  [Phase 4 · 4-1B]
 * ---------------------------------------------------------------------
 * 🔑 시각 언어는 여행+ 참가자 칩(`erp.css` `.erp-att-*`)에서 가져오되 **종이 톤은 빼고**
 *   앱 토큰(`--surface2`·`--ink2`·`--muted`·`--acc`)만 쓴다 — 앨범 상세는 종이가 아니다.
 *   이름 색은 `[data-fam]` → `--fam-c` 한 표에서 온다(새 RGB 0개).
 *
 * 🔄 [자리반전 2026-09-04] `#album-attendees` 는 이제 `#album-photos` **안의 첫 자식**이다.
 *   밖의 형제였을 때는 스크롤 컨테이너 앞이라 **상단에 붙박였다**(실기 회귀).
 *   `#album-photos` 는 `flex-wrap` 격자이므로 `.as-block`(한마디)과 **똑같이**
 *   `flex:0 0 100%` 로 한 줄을 통째로 차지해야 한다 — 없으면 사진 칸 옆에 끼어 격자가 깨진다.
 *
 * 🚨 사진 칸의 모양·간격은 그대로 둔다. 격자에 더해지는 것은 이 블록 **한 줄뿐**이고,
 *   히어로의 `👥 N명` 칩(`.as-aud`) · Day 점프(`#album-day-jump`) · 사진 `+`(`.fab`)는
 *   전부 `position:absolute` 라 자리가 밀리지 않는다.
 * ⚠ 비어 있으면 0픽셀이다(`:empty`) — 참가자가 없거나 Owner 가 아닌 화면은 지금과 똑같다.
 * ⚠ 높이를 px 로 못 박지 않는다(`line-height` · `min-height`) — `--fz` 를 키워도 안 잘린다.
 * ===================================================================== */
#album-attendees:empty{display:none}
/* 🔴 [칩정리 2026-09-04] 위아래로 **숨통**을 준다(사용자 실기: "히어로 밑에 달라붙어 답답하다").
     · 위 16px  = 이 블록이 이미 쓰는 좌우 여백과 **같은 값**이다(새 숫자를 만들지 않는다).
     · 아래 16px = 같은 값. 🔄 [자리반전] 예전 38px 은 `#album-photos{margin-top:-22px}` 가
       **앞 형제의 아래 22px 를 덮기 때문에** 갚던 빚이었다. 이제 격자 **안**이라 덮이지
       않으므로 빚이 사라졌다 — 아래로는 격자 `gap:6px` 이 더해져 실효 22px 이 보인다.
   ⚠ 카드·배경 상자·구분선을 만들지 않는다 — 여백만으로 한 절을 구분한다. */
#album-attendees{flex:0 0 100%;width:100%;box-sizing:border-box}
#album-attendees .aa-block{
  padding:16px 16px 16px;display:flex;flex-direction:column;gap:8px;align-items:flex-start}
.aa-head{font-size:calc(12px * var(--fz,1));font-weight:900;color:var(--ink2);letter-spacing:.2px}
.aa-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.aa-chip{
  display:inline-flex;align-items:center;gap:5px;
  min-height:32px;padding:5px 11px;border-radius:16px;background:var(--surface2);
  font-size:calc(13px * var(--fz,1));font-weight:800;line-height:1.3}
.aa-chip .family-name{line-height:1.3}
.aa-x{
  width:22px;height:22px;line-height:20px;border-radius:11px;flex:none;
  background:rgba(0,0,0,.08);color:var(--muted);
  font-size:calc(13px * var(--fz,1));font-weight:800}
.aa-x:active{background:rgba(0,0,0,.16)}
.aa-add{
  min-width:32px;min-height:32px;border-radius:16px;
  background:var(--surface2);color:var(--muted);
  font-size:calc(15px * var(--fz,1));font-weight:800;line-height:1}
.aa-add:active{transform:scale(.94)}
/* 이름 직접 적기 칸 — 칩 줄 안에 그대로 앉는다(여행+ `.erp-att-in` 과 같은 자리) */
.aa-in{
  min-width:150px;min-height:32px;padding:0 11px;border-radius:16px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);
  font-size:calc(13px * var(--fz,1));font-weight:700}
.aa-in:focus{outline:none;border-color:var(--acc)}
.aa-note{font-size:calc(12.5px * var(--fz,1));color:var(--muted);font-weight:700;line-height:1.5}
/* [칩정리 2026-09-04] `.aa-go`(「여행+에서 관리」) 규칙을 지웠다 — 칩과 같은 알약이라
   네 번째 참가자처럼 읽혔다. 손잡이 자체가 없어졌으므로 스타일도 남기지 않는다. */

/* ── 후보 고르기 시트 — 껍데기는 `.as-sheet`(앨범소셜) 것을 그대로 빌려 쓴다 ── */
.aa-sheet-sec{font-size:calc(12.5px * var(--fz,1));color:var(--ink2);font-weight:900;padding-top:2px}
.aa-people{line-height:1.9;font-size:calc(14px * var(--fz,1))}
.aa-pick{display:flex;flex-direction:column;gap:2px}
.aa-pick-i{
  display:flex;align-items:center;gap:10px;min-height:46px;padding:0 2px;
  font-size:calc(14.5px * var(--fz,1))}
.aa-ck{width:20px;height:20px;flex:none;accent-color:var(--acc)}
.aa-sheet-btns{display:flex;flex-wrap:wrap;gap:8px;padding-top:2px}
.aa-ok{
  min-height:44px;padding:0 20px;border-radius:16px;background:var(--acc);color:#fff;
  font-size:calc(14.5px * var(--fz,1));font-weight:800}
.aa-ok:active{transform:scale(.96)}
.aa-manual{
  min-height:44px;padding:0 16px;border-radius:16px;background:var(--surface2);color:var(--ink2);
  font-size:calc(14px * var(--fz,1));font-weight:800}
.aa-manual:active{transform:scale(.96)}
.aa-sheet-sub{font-size:calc(12.5px * var(--fz,1));color:var(--muted);font-weight:600;line-height:1.55}

/* =====================================================================
 * [Phase 4 · 4-2] 「이서와 실제 함께한 곳」 — 세그먼트와 지도 판
 * ---------------------------------------------------------------------
 * 🔴 Owner 의 `#ab-seg`·`#map-seg` **id 규칙을 빌리지 않는다**(그 id 에는
 *   `AlbumMapSeg` 라는 Owner controller 가 걸려 있다 · app.js:27567).
 *   빌리는 것은 알약 버튼의 시각 class `.ab-seg-btn`(index.html:894) 하나뿐이고,
 *   그 class 에는 아무 JS 도 안 걸려 있다. 껍데기 값만 여기 다시 적는다.
 * ⓘ 새 색을 만들지 않는다 — `--surface2`·`--surface`·`--ink` 그대로라 다크에서도 읽힌다.
 * ===================================================================== */
html.family-viewer .fv-topseg{
  flex:none;display:flex;gap:4px;margin:0 16px 10px;padding:4px;
  background:var(--surface2);border-radius:15px}
@media (min-width:600px){ html.family-viewer .fv-topseg{max-width:380px} }

/* 지도 판 — `.fv-scroll` 과 같은 자리를 차지하되 스크롤 대신 **꽉 찬 한 판**이다.
   🔴 높이를 `flex:1` 로 준다. Leaflet 은 높이 0 인 자리에서 타일을 한 장도 안 그린다. */
html.family-viewer .fv-places-wrap{
  flex:1;min-height:0;position:relative;overflow:hidden;
  margin:0 16px 16px;border-radius:18px;background:var(--surface2)}
html.family-viewer #fv-places-canvas{position:absolute;inset:0}
/* 빈 화면·오류 화면이 같은 자리에 들어와도 가운데에 놓이게 한다 */
html.family-viewer .fv-places-wrap .fv-empty{position:absolute;inset:0;display:flex;
  flex-direction:column;align-items:center;justify-content:center;padding:24px}

/* 마커 — 사진도 png 도 쓰지 않는다. CSS 로만 그린 물방울 핀 하나다. */
html.family-viewer .fv-place-pin{
  display:block;width:22px;height:22px;margin:4px auto 0;
  border-radius:50% 50% 50% 0;transform:rotate(-45deg);
  background:var(--acc);border:2px solid var(--surface);
  box-shadow:0 2px 6px rgba(0,0,0,.28)}

html.family-viewer .fv-place-pop{display:flex;flex-direction:column;gap:3px;min-width:130px}
html.family-viewer .fv-place-pop b{
  font-size:calc(14px * var(--fz,1));font-weight:800;color:var(--ink);line-height:1.35}
html.family-viewer .fv-place-pop small{
  font-size:calc(12px * var(--fz,1));font-weight:700;color:var(--muted);line-height:1.45}
