/* ═══════════════════════════════════════════════════════════════════════════
   MARKONE 공용 디자인 시스템  [2026-08-21 신설]
   ───────────────────────────────────────────────────────────────────────────
   기획서 D-1~D-8 구현. **모든 화면이 이 한 파일을 쓴다.**

   ★why 별도 파일인가: 로그인 화면처럼 페이지마다 <style> 에 복사하면 15개 화면이
     제각각 갈라지고, 클래스 충돌 같은 사고가 전 화면에 조용히 퍼진다
     (2026-08-21 `.pw` 사고 — 장식용 클래스가 비밀번호 칸을 흔들고 있었다).
   ★CSP 는 `style-src 'self'` 라 같은 출처의 .css 파일은 nonce 없이 통과한다.
     nonce 붙은 <style> 은 **서버가 값을 계산해 넣는 규칙**(별 좌표 등)에만 쓴다.
   ★★`/assets/` 는 vhost 가 `immutable, max-age=31536000` 을 건다 —
     **파일을 고쳐도 1년간 옛것이 나간다.** 그래서 링크에 `?v=filemtime` 을 붙인다
     (`_layout.php` 의 `mk_asset()` 이 자동으로 처리한다. 직접 <link> 를 쓰지 말 것).

   ★★대비 이탈 1건 — 의도적이다:
     D-2 의 `Text Muted #8892A0` 는 **흰 배경에서 3.15:1** 로 D-7(본문 4.5:1 이상)을 위반한다.
     이용자 다수가 40~60대라 가독성이 미관보다 우선이므로 `--muted` 를 **#6B7684(4.62:1)** 로 쓴다.
     남색 배경 위 캡션은 `--muted-on-navy`(#9FB4CC, 6.29:1) 를 따로 둔다.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── D-2 컬러 ─────────────────────────────────────────────────────────── */
  --navy:#16304F; --navy-l:#25456B; --accent:#C0392B;
  --bg:#F5F7FA; --surface:#FFFFFF; --line:#DFE5EC;
  --tx:#1F2429; --tx2:#5C6672;
  --muted:#6B7684;            /* ★D-2 의 #8892A0 이 아니다 — 위 주석 참조 */
  --muted-on-navy:#9FB4CC;
  --ok:#1F6B3B; --warn:#8A6D2F;
  --ok-bg:#EDF6F0; --warn-bg:#FBF5E9; --bad-bg:#FDF6F4; --info-bg:#EEF3F9;

  /* 입력 테두리는 Border(#DFE5EC)가 아니라 더 진한 값을 쓴다 —
     연한 회색 테두리는 흰 배경에서 "칸이 있는지" 자체가 안 보인다(고령 사용자). */
  --field-line:#8892A0;

  /* ── D-4 모서리·그림자 ────────────────────────────────────────────────── */
  --r-card:14px; --r-btn:10px; --r-inp:8px; --r-pill:20px;
  --shadow:0 1px 3px rgba(22,48,79,.06);
  --shadow-lg:0 8px 28px rgba(0,10,26,.14);

  /* ── 레이아웃 치수 ────────────────────────────────────────────────────── */
  --hd-h:56px;                /* 상단 헤더 */
  --tab-h:60px;               /* 모바일 하단 탭바 (D-6) */
  --side-w:236px;             /* 1024px+ 좌측 사이드바 (D-6) */
  --wrap:760px;

  --kr:'Pretendard Variable',Pretendard,-apple-system,BlinkMacSystemFont,
       'Apple SD Gothic Neo','Malgun Gothic','Noto Sans KR',sans-serif;

  /* ── 큰 글씨 보기 배율  [2026-09-07] ──────────────────────────────────
     ★★**«읽는 글»에만 건다.** 화면 전체를 키우면 하단 탭바가 깨진다 —
       `--tab-h`(60px)는 고정 토큰인데 `.tabs a` 에는 white-space 도 overflow 도 없어서,
       라벨이 커지면 375px 5분할(칸 ≈75px)에서 두 줄로 접히고 탭바 실제 높이가 토큰을 넘는다.
       그러면 그 높이를 빼서 계산하는 라운지 입력바가 화면 밖으로 밀린다(에러 0으로 조용히).
     ★그래서 이 변수를 쓰는 곳은 **본문(.body-text)·라운지 말풍선·AI 답변 세 곳뿐**이다.
       버튼·탭·배지·목록 제목은 그대로 둔다. 늘리려면 그 화면을 실측하고 늘릴 것.
     ★값은 `<html data-fs>` 가 정한다. 그 속성은 서버(mk_shell_open)가 쿠키를 보고 미리 박는다 —
       JS 로만 하면 «작게 그렸다가 커지는» 깜빡임이 생긴다(대상이 40~70대다). */
  --fs:1;
}
html[data-fs="2"]{--fs:1.15}
html[data-fs="3"]{--fs:1.30}

/* ── 리셋 ─────────────────────────────────────────────────────────────── */
*{box-sizing:border-box;margin:0;padding:0}
/* ★★`[hidden]` 은 **무조건** 이겨야 한다.
   `display:inline-flex` 같은 값이 붙은 요소(.btn 등)에 `hidden` 을 걸면 **아무 일도 안 일어난다** —
   HTML 기본의 `[hidden]{display:none}` 이 나중 규칙에 지기 때문이다.
   2026-08-21 실측: 알림이 차단된 상태인데 「알림 켜기/끄기」가 둘 다 떠 있었다.
   규칙마다 `.x[hidden]` 을 덧붙여 막을 일이 아니다(한 번은 반드시 빠뜨린다). 여기서 한 번에 못박는다. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--bg); color:var(--tx); font-family:var(--kr);
  font-size:16px; line-height:1.7;                    /* D-3 */
  /* ★한글은 keep-all 이 없으면 "준비/가 끝나면" 처럼 단어 중간에서 끊긴다 */
  word-break:keep-all; overflow-wrap:break-word;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;display:block}
a{color:var(--navy)}
button,input,select,textarea{font:inherit;color:inherit}

/* ★D-7 — 포커스 표시를 지우지 않는다. 키보드 사용자의 유일한 위치 단서다. */
:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.on-navy :focus-visible{outline-color:#fff}

/* 스크린리더 전용 (라벨은 있어야 하지만 화면엔 안 보여야 할 때) */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
    clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--navy);color:#fff;
      padding:.7rem 1rem;border-radius:0 0 var(--r-btn) 0}
.skip:focus{left:0}

/* ── D-3 타이포 ───────────────────────────────────────────────────────── */
h1{font-size:28px;font-weight:700;letter-spacing:-.3px;line-height:1.35}
h2{font-size:22px;font-weight:700;letter-spacing:-.3px;line-height:1.4}
h3{font-size:18px;font-weight:700;letter-spacing:-.3px;line-height:1.45}
.sub{font-size:14px;color:var(--tx2)}
.cap{font-size:13px;color:var(--muted)}
.strong{font-weight:700}
.nowrap{white-space:nowrap}

/* ═══ 앱 셸 (조합원) ═══════════════════════════════════════════════════
   D-6: ~767 하단 탭바 / 768~1023 상단 / 1024~ 좌측 사이드바 */
.app{min-height:100svh;display:flex;flex-direction:column}

.hd{position:sticky;top:0;z-index:30;height:var(--hd-h);flex:0 0 var(--hd-h);
    background:var(--navy);color:#fff;display:flex;align-items:center;gap:12px;
    padding:0 max(14px,env(safe-area-inset-left)) 0 max(14px,env(safe-area-inset-right))}
.hd .bar{width:3px;height:20px;border-radius:2px;background:var(--accent);flex:0 0 3px}
/* [2026-08-26] 헤더 브랜드 마크(로고). .bar 를 대체한다 — 정사각 SVG 라 세로 기준으로 맞춘다 */
/* [2026-08-26] 헤더 브랜드 로고(가로형 심볼+로고타입). 높이를 기준으로 잡고 폭은 비율대로 둔다
   — 가로형이라 width 를 고정하면 기기 폭에 따라 찌그러진다. */
.hd .lgw{display:flex;align-items:center;height:26px;flex:0 0 auto;padding:0 2px}
.hd .lgw img{height:26px;width:auto;display:block}
.hd .adm-tag{font-size:13px;font-weight:600;color:#C9D6E6;letter-spacing:-.2px;white-space:nowrap;margin-left:8px}
.hd .nm{font-size:17px;font-weight:700;letter-spacing:-.3px;white-space:nowrap;
        overflow:hidden;text-overflow:ellipsis}
.hd .sp{margin-left:auto}
.hd a,.hd button{color:#fff;text-decoration:none;background:none;border:0;cursor:pointer;
  min-height:44px;min-width:44px;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  font-size:14px;border-radius:var(--r-btn);padding:0 10px}
.hd a:hover,.hd button:hover{background:rgba(255,255,255,.12)}
/* 로고(브랜드)를 홈 링크로 — 로고처럼 보이되(17px/700) 탭영역은 유지, 강조막대 옆에 붙임 (2026-08-24) */
.hd a.nm{min-width:auto;padding:0 8px 0 2px}
.hd svg{width:20px;height:20px;flex-shrink:0}

.body{flex:1;display:flex;min-height:0}
.side{display:none}
.main{flex:1;min-width:0;width:100%;padding:18px max(16px,env(safe-area-inset-left)) 24px}
.wrap{width:min(var(--wrap),100%);margin-inline:auto}
.wrap-wide{width:min(1120px,100%);margin-inline:auto}

/* 모바일 하단 탭바 — D-6
   ★sticky + z-index:30 를 건드리지 말 것 — 증상만 옮겨간다(2026-08-22 사고: 하단탭 링크가
     보내기 버튼 위에 올라탐).
   ★2026-08-26: 앱팀 요청으로 fixed 시도 → WebView 컴포지팅 레이어 리페인트 누락으로 탭바가
     떠 보이는 새 버그 발생(CDP 실측) → position 제거(순수 flex 자식) 시도 → 이번엔 탭바가
     문서 하단으로 가라앉고 그 위에 흰 여백이 남는 증상(사용자 실측 확인) 발생 → sticky+z-index
     로 되돌림. ★이후 앱팀이 `.tabs{background:red}` 로 정밀 측정: sticky 상태에서 탭바 하단은
     WebView 경계와 오차 0px — `.lounge` 높이 산수는 이 증상의 원인이 아니었다(오독 정정).
     실제 원인은 네이티브 쪽: 오늘 고친 nav bar 흰색이 탭바 흰색과 이어져 60dp+48dp 가 하나의
     108dp 흰 띠로 보이는 착시였다(edge-to-edge 미적용). 즉 세 포지션 값 중 무엇으로도
     이 증상은 못 고친다 — 웹 CSS 는 sticky 로 고정, 근본 해결은 네이티브 edge-to-edge. */
.tabs{position:sticky;bottom:0;z-index:30;display:flex;background:var(--surface);
  border-top:1px solid var(--line);padding-bottom:env(safe-area-inset-bottom)}
.tabs a{flex:1;min-height:var(--tab-h);display:flex;flex-direction:column;align-items:center;white-space:nowrap;
  justify-content:center;gap:3px;text-decoration:none;color:var(--muted);font-size:11px;font-weight:700}
.tabs a svg{width:22px;height:22px}
.tabs a[aria-current]{color:var(--navy)}
.tabs a[aria-current] svg{stroke-width:2.4}

/* ── 라운지 안 읽음 배지 (nav) [2026-08-24] ──────────────────────────────
   ★--accent(브랜드 레드). 라운지 화면에선 서버가 배지를 아예 렌더 안 함(mk_lounge_badge).
   ★탭바에선 절대배치라 흐름 높이에 영향 0 → --tab-h 초과·라벨 2줄 접힘 위험 없음(함정 회피). */
.nbadge{display:inline-flex;align-items:center;justify-content:center;
  min-width:16px;height:16px;padding:0 4px;box-sizing:border-box;border-radius:8px;
  background:var(--accent);color:#fff;font-size:10px;font-weight:800;line-height:1;letter-spacing:-.02em}
.tabs a{position:relative}
.tabs a .nbadge{position:absolute;top:5px;left:calc(50% + 3px);
  height:18px;min-width:18px;border-radius:9px;border:2px solid var(--surface)}

@media (min-width:1024px){
  .tabs{display:none}
  /* ★★[2026-08-28] 좌측 메뉴를 화면에 **붙여 고정**한다(대표 지시: 세로 스크롤이 길면 메뉴가 같이 올라가 불편).
     ★`position:fixed` 가 아니라 `sticky` 다 — fixed 로 빼면 문서 흐름에서 사라져 본문 폭을 손으로
       다시 잡아야 하고(`--side-w` 만큼 여백), 창 크기가 바뀔 때마다 어긋난다. sticky 는 자리를 그대로 지킨다.
     ★★**`align-self:flex-start` 가 없으면 sticky 가 아무 일도 하지 않는다.** flex 자식은 기본이 `stretch` 라
       사이드바가 `.body` 전체 높이(=문서 전체)로 늘어나 버리고, 그러면 **움직일 여지 자체가 없어** 그냥 같이 스크롤된다.
     ★`top` 은 헤더 높이다 — `.hd` 가 `position:sticky; top:0` 이라 그 아래에 붙어야 겹치지 않는다.
     ★메뉴가 화면보다 길어질 수 있으므로(관리자 메뉴는 항목이 많다) 자체 스크롤을 준다. */
  .side{display:block;flex:0 0 var(--side-w);background:var(--surface);
        border-right:1px solid var(--line);padding:16px 12px;
        position:sticky;top:var(--hd-h);align-self:flex-start;
        height:calc(100svh - var(--hd-h));overflow-y:auto;overscroll-behavior:contain}
  .side a{display:flex;align-items:center;gap:11px;min-height:48px;padding:0 12px;
    border-radius:var(--r-btn);text-decoration:none;color:var(--tx2);font-weight:700;font-size:15px}
  .side a svg{width:20px;height:20px;flex-shrink:0}
  .side a:hover{background:var(--bg)}
  .side a[aria-current]{background:var(--navy);color:#fff}
  .side a{position:relative}
  .side a .nbadge{margin-left:auto}
  .main{padding:26px 28px 40px}
}


/* ═══ 관리자 셸 ═══════════════════════════════════════════════════════ */
.adm .hd{background:var(--navy-l)}
.adm .main{padding-bottom:40px}
/* 모바일 햄버거로 여는 서랍 (D-5 "모바일은 햄버거")
   ★JS 없이 <details>/<summary> 로 만든다 — 스크립트가 죽어도 메뉴는 열린다.
     (관리자는 심사 업무를 못 하면 서비스 전체가 멈추므로 실패 지점을 줄인다.) */
.drawer{position:relative}
.drawer > summary{list-style:none;cursor:pointer;min-height:44px;min-width:44px;
  display:inline-flex;align-items:center;justify-content:center;border-radius:var(--r-btn);color:#fff}
.drawer > summary::-webkit-details-marker{display:none}
.drawer > summary:hover{background:rgba(255,255,255,.12)}
/* ★★열린 패널(.panel, z-index:40)이 **자기 형제인 summary 를 통째로 덮어** 햄버거를 다시 누를 수 없었다
   (26-08-22 실측: summary 44×44 전 픽셀 히트테스트 0, click 타임아웃). 스크림·뒤로가기·ESC 도 안 닫혀
   **닫는 포인터 경로가 하나도 없었다.** 라운지 뷰어의 X 가 막대에 덮인 것과 **똑같은 유형**이다.
   ★★배경 지정이 함께 없으면 안 된다 — summary 는 `color:#fff` 인데 위로 올라갈 nav 배경이 흰색이라
     **흰 아이콘이 흰 패널 위에 놓여 사라진다.** */
.drawer > summary{position:relative;z-index:41}
.drawer[open] > summary{background:var(--navy)}
.drawer > .panel{position:fixed;inset:0;z-index:40;display:flex}
.drawer > .panel > .scrim{position:absolute;inset:0;background:rgba(10,26,44,.5)}
/* ★위 수정으로 햄버거가 패널 **위로** 올라왔으므로, 그만큼 내용을 내려 첫 항목(「관리자」 그룹 제목)이
   버튼 뒤로 숨지 않게 한다. `--hd-h`(56px) = 헤더 높이 = 햄버거가 차지하는 띠. */
.drawer > .panel > nav{position:relative;width:min(280px,84vw);background:var(--surface);
  padding:12px 12px calc(12px + env(safe-area-inset-bottom));overflow:auto;box-shadow:var(--shadow-lg)}
.drawer[open] > .panel > nav{padding-top:calc(var(--hd-h) + 4px)}
.drawer > .panel nav a{display:flex;align-items:center;gap:11px;min-height:48px;padding:0 12px;
  border-radius:var(--r-btn);text-decoration:none;color:var(--tx2);font-weight:700;font-size:15px}
.drawer > .panel nav a[aria-current]{background:var(--navy);color:#fff}
.drawer > .panel nav svg{width:20px;height:20px;flex-shrink:0}
.drawer .grp{margin:14px 0 6px;padding:0 12px;font-size:12px;font-weight:700;color:var(--muted);letter-spacing:.04em}
@media (min-width:1024px){ .drawer{display:none} }

/* ═══ 카드 ════════════════════════════════════════════════════════════ */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);
      box-shadow:var(--shadow);overflow:hidden}
.card + .card{margin-top:14px}
.chead{display:flex;align-items:center;gap:9px;padding:13px 18px;background:#F2F5F9;
  border-bottom:1px solid var(--line);font-size:16px;font-weight:700;line-height:1.4;color:var(--tx)}
.chead::before{content:"";width:3px;height:16px;border-radius:2px;background:var(--navy);flex-shrink:0}
.chead .sp{margin-left:auto;font-weight:400}
.pad{padding:18px}
.pad-lg{padding:22px 20px}
@media (min-width:768px){ .pad{padding:20px 22px} }

.page-h{display:flex;align-items:flex-end;gap:12px;margin-bottom:16px;flex-wrap:wrap}
.page-h .sp{margin-left:auto}
.page-h p{margin-top:4px}

/* ═══ 버튼 (D-4) ══════════════════════════════════════════════════════ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-height:44px;padding:0 16px;border:1px solid var(--line);border-radius:var(--r-btn);
  background:var(--surface);color:var(--tx);font-size:15px;font-weight:700;
  text-decoration:none;cursor:pointer;white-space:nowrap}
.btn svg{width:18px;height:18px;flex-shrink:0}
.btn:hover{background:var(--bg)}
.btn:disabled,.btn[aria-disabled=true]{opacity:.5;cursor:not-allowed}
.btn-lg{min-height:52px;font-size:17px;padding:0 20px}     /* D-4 주요 52px */
.btn-block{width:100%}
.btn-pri{background:var(--navy);border-color:var(--navy);color:#fff}
.btn-pri:hover{background:#1B3A5E}
.btn-ok{background:var(--ok);border-color:var(--ok);color:#fff}
.btn-ok:hover{filter:brightness(1.08)}
.btn-danger{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-danger:hover{filter:brightness(1.08)}
/* ★D-5 — 개인정보 열람 버튼은 **별도 색**으로 구분한다(기록이 남는 행위임을 색으로 알린다) */
.btn-reveal{background:#F3EEF9;border-color:#C9B6E4;color:#5B3E86}
.btn-reveal:hover{background:#EBE2F5}
.btn-row{display:flex;gap:8px;flex-wrap:wrap}
.btn-row-end{justify-content:flex-end}

/* 본문 「듣기」 줄 (assets/js/ttsread.js 가 만든다) — 공지·투표·자료실·약관 공용.
   ★★여백을 **여기서** 준다. 처음엔 `mb-14` 유틸로 줬는데 **이 파일에 `.mb-*` 는 존재하지 않아서**
     (있는 것은 `.mt-*` 뿐) 아래쪽 여백이 0 이었고, 버튼이 본문 첫 줄에 붙어 보였다(대표 지적).
   ★위쪽은 바로 앞 `.hr`(margin 18px)과 **마진이 합쳐져** 18px 로 정리된다 — 두 배로 벌어지지 않는다.
   ★아래 18px 은 `.hr` 과 같은 리듬이다. 본문과 버튼이 다른 덩어리로 읽혀야 한다. */
.tr-ttsbar{display:flex;margin:calc(14px * var(--fs)) 0 calc(18px * var(--fs))}

/* 큰 글씨 보기 — 크기 고르는 버튼 3개 (fontsize.php).
   ★★**이 버튼들은 `--fs` 를 따르지 않는다.** 크기를 고르는 조작부가 고른 값에 따라 커지면
     「아주 크게」에서 3칸이 한 줄에 안 들어간다(320px 실측). 조작부는 늘 같은 크기여야 한다.
   ★`1fr` 3등분이라 320px 에서도 「아주 크게」(4글자)가 접히지 않는다. */
.fs-opts{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.fs-opt{min-height:52px;font-size:15px;white-space:nowrap;padding:0 6px}
.fs-opt.is-on{background:var(--navy);border-color:var(--navy);color:#fff;font-weight:700}

/* ═══ 입력 (D-4) ══════════════════════════════════════════════════════ */
.field + .field{margin-top:14px}
/* ★[2026-08-31 대표 지적 「다닥다닥 붙어 있다」] 경고 박스 바로 아래 입력칸이 **간격 0** 이었다.
   `.field + .field` 만 있어서 앞 형제가 `.alert` 면 규칙이 걸리지 않았다(실측: PC·모바일 모두 0px).
   ★관리자 화면 7곳이 같은 구조다(로그인·비밀번호·공지/자료 편집·재확인·전자서명·조합원 상세) —
     마크업을 한 곳씩 고치지 않고 여기서 한 번에 띄운다. */
.alert + .field{margin-top:14px}
/* ★`label.lb` 로 한정하지 않는다 — 라벨이 아닌 <span class="lb"> 로 쓰는 자리가 있고
   (파일 입력처럼 for= 를 걸 대상이 여럿일 때), 그때 필수 별표가 검게 나온다(실측). */
.lb{display:block;font-size:14px;font-weight:700;margin-bottom:6px}
.lb .req{color:var(--accent);margin-left:2px}
.inp{position:relative}
input[type=text],input[type=tel],input[type=password],input[type=search],
input[type=number],input[type=date],select,textarea{
  width:100%;min-height:52px;padding:13px 16px;background:var(--surface);color:var(--tx);
  border:1px solid var(--field-line);border-radius:var(--r-inp);font-size:16px;line-height:1.5}
textarea{min-height:150px;resize:vertical;line-height:1.7}
select{min-height:52px;padding-right:38px;appearance:none;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235C6672' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center}
input::placeholder,textarea::placeholder{color:var(--muted)}   /* 4.62:1 — D-7 통과 */
/* ★포커스 테두리를 border-width 로 굵히면 칸 내부 폭이 줄어 글자가 밀린다.
   inset 그림자로 만들면 D-4 규정(2px)을 지키면서 레이아웃이 1px 도 안 흔들린다. */
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--navy);
  box-shadow:inset 0 0 0 1px var(--navy)}
input.bad,textarea.bad,select.bad{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.help{margin-top:6px;font-size:13px;line-height:1.5;color:var(--tx2);min-height:18px}
.help.bad{color:#A93226;font-weight:700}
/* ★[2026-08-27] 전자서명 동의 의사표시 문구.
   주 이용자가 40~60대라 .help(13px)보다 키우고, 서명 버튼 바로 위에서 눈에 걸리게 테두리를 준다.
   ★CSP(style-src 'self' 'nonce-…')가 인라인 style 속성을 차단하므로 반드시 클래스로 둔다. */
.consent{font-size:15px;line-height:1.6;color:var(--tx);font-weight:700;
  background:#F5F7FA;border:1px solid #D8DEE7;border-left:4px solid var(--brand,#16304F);
  border-radius:8px;padding:12px 14px;margin:0}
.check{display:flex;align-items:flex-start;gap:11px;min-height:44px;padding:6px 0;
  font-size:15px;cursor:pointer;user-select:none}
.check input{width:22px;height:22px;margin-top:3px;accent-color:var(--navy);flex-shrink:0}
/* 끌 수 없는 항목(계정 처분 통지).
   ★★`disabled` 체크박스를 그대로 두면 **브라우저가 회색으로 죽여 「꺼짐」으로 읽힌다** —
     바로 옆에 "항상 받음" 이라고 적혀 있는데 체크는 흐리니 정면으로 모순된다(2026-08-21 캡처로 확인).
     그래서 input 은 **접근성 트리에만 남기고**(스크린리더는 "선택됨·사용 안 함" 을 읽는다)
     눈에 보이는 것은 켜진 체크박스와 같은 남색 배지로 그린다. */
.check.is-fixed{cursor:default}
.check.is-fixed input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.ck-fixed{width:22px;height:22px;margin-top:3px;flex-shrink:0;border-radius:4px;
  background:var(--navy);color:#fff;display:inline-flex;align-items:center;justify-content:center}
.ck-fixed svg{width:15px;height:15px;stroke-width:2.8}

/* ═══ 배지 (D-4 알약형) ═══════════════════════════════════════════════ */
.bg{display:inline-flex;align-items:center;gap:5px;padding:3px 11px;border-radius:var(--r-pill);
  font-size:13px;font-weight:700;line-height:1.6;white-space:nowrap}
.bg-ok{background:var(--ok-bg);color:var(--ok)}
.bg-wait{background:var(--warn-bg);color:var(--warn)}
.bg-bad{background:var(--bad-bg);color:#A93226}
.bg-info{background:var(--info-bg);color:var(--navy)}
.bg-off{background:#EEF0F3;color:var(--muted)}
.bg-staff{background:var(--navy);color:#fff}          /* 운영진 배지 (D-5 라운지) */

/* ═══ 알림 박스 ═══════════════════════════════════════════════════════ */
/* ★★[2026-09-01 대표 지적] `.alert` 에 **기본 위아래 여백**을 준다.
   why: 종전에는 margin 이 0 이라 쓰는 곳마다 `mt-14` 를 손으로 붙여야 했다.
     실측 74곳이 `mt-0`·`mt-14`·없음으로 제각각이었고, 빠뜨리면 위아래가 딱 붙는다
     (투표 상세의 안내 상자가 본문·선택지와 붙어 있었다 — 대표 지적 「이런 실수 많음」).
   ★유틸(`.mt-0`·`.mt-14`)이 이 규칙보다 **뒤에 정의**돼 있어 그대로 이긴다 —
     일부러 여백을 죽인 곳(`mt-0`)은 지금처럼 붙어 있는다. 안 붙인 곳만 여백이 생긴다.
   ★`margin-bottom` 은 덮는 유틸이 없으므로 전 사용처에 14px 이 붙는다. 실화면으로 확인했다. */
.alert{margin:14px 0;display:flex;align-items:flex-start;gap:11px;padding:14px 16px;border-radius:var(--r-inp);
  font-size:15px;line-height:1.6}
.alert svg{width:20px;height:20px;flex-shrink:0;margin-top:2px}
/* ★[2026-09-01] 8px → 10px. `.alert` 는 글자 15px·행간 1.6(=24px)이라 8px 이면
   **줄 간격(24px)보다 좁아** 두 문단이 한 덩어리로 읽힌다. 문단 사이는 줄 사이보다 넓어야 한다. */
.alert p + p{margin-top:10px}
/* ★D-5 조합원 인증 — 경고 박스는 배경 #FDF6F4 + 좌측 굵은 레드 바 */
.alert-warn{background:var(--bad-bg);border-left:4px solid var(--accent);color:#8C2B20}
.alert-info{background:var(--info-bg);border-left:4px solid var(--navy-l);color:#1B3A5E}
.alert-ok{background:var(--ok-bg);border-left:4px solid var(--ok);color:#155029}
/* ★★[2026-09-17] `.alert-bad` 는 **이름만 있고 규칙이 없었다** — 쓰는 곳 4군데
   (긴급 통지의 「전 조합원에게 나갑니다」 경고·발송 오류·관리자 로그인 오류·재확인 오류)가
   전부 무채색 글상자로 나왔다. 9/15 전체 오발송 뒤에 붙인 마지막 안전장치가 그 상태였다.
   ★`.alert-warn` 보다 **한 단계 세게** 둔다(테두리 전체 + 더 진한 글자색) — 둘이 같아 보이면
     「돌이킬 수 없는 일을 하려는 중」이 일반 주의와 구별되지 않는다.
   ★★`display` 를 **선언하지 않는다.** 아래 `.alert[hidden]{display:none}` 를 이기는 `display`
     선언이 붙으면 숨겨야 할 경고가 계속 떠서, 한정 발송인데도 「전 조합원」 경고가 뜬다. */
.alert-bad{background:var(--accent);border-left:5px solid #8C2B20;color:#fff;font-weight:500}
.alert-bad .strong,.alert-bad strong{color:#fff}
.alert[hidden]{display:none}   /* ★display:flex 가 [hidden] 을 이긴다 — 명시 필요 */

/* ═══ 목록 (공지·자료실) ══════════════════════════════════════════════ */
.list{list-style:none}
.list li + li{border-top:1px solid var(--line)}
.list a{display:flex;align-items:flex-start;gap:12px;padding:15px 18px;text-decoration:none;color:inherit}

/* ★★[2026-08-28] 공지 첨부 그림 미리보기 (대표 지시: 내려받기는 그대로 두고 미리보기를 더한다).
   ★JS 를 쓰지 않는다 — 펼치기 토글 대신 **누르면 원본이 새 탭**에 뜬다(`attach.php` 는 파라미터 없으면 inline).
     상태를 들고 있을 일이 없으니 스크립트를 만들 이유도 없다.
   ★★높이를 반드시 묶는다. 999904 첨부는 338×1600 이라 그냥 깔면 **화면 7개 분량**으로 늘어난다.
     `vh` 로 묶어야 기기 화면에 비례한다(고정 px 는 큰 화면에서 답답하고 작은 화면에서 여전히 길다). */
/* ★★셀렉터를 `.list .atp` 로 쓴다. `.atp` 만 쓰면 바로 위 `.list a`(0,1,1)가 이겨
     `display:flex` 와 좌우 패딩이 먹어 **미리보기가 통째로 찌그러진다**(특이도 0,1,0 < 0,1,1). */
.list .atp{display:block;position:relative;margin:10px 18px 16px;padding:0;border-radius:var(--r-inp);
  overflow:hidden;border:1px solid var(--line);background:var(--surface);line-height:0}
.list .atp img{display:block;width:100%;height:auto}
/* ★PDF 첨부 — 쪽 그림을 이어 붙인다. 쪽 사이에 얇은 틈을 둬야 '한 장이 잘린 것' 으로 안 읽힌다. */
.list .atp-pdf{margin:10px 18px 16px;border-radius:var(--r-inp);overflow:hidden;
  border:1px solid var(--line);background:var(--surface);line-height:0}
.list .atp-pdf img{display:block;width:100%;height:auto}
.list .atp-pdf img + img{border-top:1px solid var(--line)}
/* ★★[2026-08-28 2차] **자르지 않는다.** 처음엔 `56vh` 로 묶고 「전체 보기」 배지를 뒀는데
     대표 지시로 걷어냈다 — *"전체보기 안 눌러도 전체 보여주면 좋겠다, 흐릿흐릿한 것도 이상하다"*.
     공지 첨부는 조합 자료(자금 현황·공고문)라 **한눈에 다 보이는 편이 낫다**는 판단이다.
   ★그래서 `max-height` 도, 페이드도, 배지도 없다. 세로로 긴 그림은 그냥 길게 나온다.
     (짧게 묶고 싶어지면 페이드는 다시 쓰지 말 것 — 어두운 그림에서 김 서린 듯 뿌옇게 된다.) */
.list a:hover{background:var(--bg)}
.list .t{font-weight:700;font-size:16px;line-height:1.5}
.list .m{margin-top:5px;display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  font-size:13px;color:var(--muted)}
.list .m .dot{width:3px;height:3px;border-radius:50%;background:var(--line);flex-shrink:0}
/* ★D-5 — 새 글은 좌측에 레드 점 */
.list .new{width:7px;height:7px;border-radius:50%;background:var(--accent);flex-shrink:0;margin-top:9px}
.list .new-sp{width:7px;flex-shrink:0}

/* 카테고리 필터 칩 (D-5) */
.chips{display:flex;gap:8px;overflow-x:auto;padding:2px 0 10px;-webkit-overflow-scrolling:touch}
.chips a{flex:0 0 auto;min-height:38px;display:inline-flex;align-items:center;padding:0 15px;
  border:1px solid var(--line);border-radius:var(--r-pill);background:var(--surface);
  color:var(--tx2);font-size:14px;font-weight:700;text-decoration:none}
.chips a[aria-current]{background:var(--navy);border-color:var(--navy);color:#fff}

/* ═══ 표 (관리자) ═════════════════════════════════════════════════════ */
.tw{overflow-x:auto;-webkit-overflow-scrolling:touch}
table.tb{width:100%;border-collapse:collapse;font-size:15px;white-space:nowrap}
table.tb th,table.tb td{padding:12px 14px;text-align:left;border-bottom:1px solid var(--line)}
table.tb thead th{background:var(--navy-l);color:#fff;font-weight:700;font-size:14px;
  position:sticky;top:0;z-index:1}
table.tb tbody tr:hover{background:var(--bg)}
table.tb td.wrap-cell{white-space:normal;min-width:220px}

/* ── 표의 이름/제목 칸을 상세로 가는 링크로 쓴다  [2026-08-24] ────────────────
   why: 표는 `white-space:nowrap` 이라 제목이 길면 마지막 열의 [보기] 버튼이
        가로 스크롤 밖으로 밀린다. 휴대폰(390px)에서는 스크롤이 있다는 것조차
        모르는 경우가 많아 **상세로 들어갈 방법이 사실상 없어진다**
        (26-08-24 대표 지적: "모바일에서 상세 리스트 클릭 동작 안 함").
        [보기] 버튼은 PC 에서 익숙한 자리라 그대로 두고, 왼쪽 칸에 경로를 하나 더 낸다.
   ★display:block 으로 칸 높이 전체를 링크가 차지하게 한다 — 주 이용자가 40~60대라
     글자 높이(약 20px)만 눌리게 두면 "눌러도 안 된다"가 그대로 남는다.
   ★꺾쇠는 글꼴이 아니라 border 로 그린다 — 문자(›)·이모지는 기기마다 다르게 뜬다. */
table.tb a.rl{display:block;margin:-12px -14px;padding:12px 14px;
              color:var(--navy);text-decoration:none}
table.tb a.rl:hover,table.tb a.rl:focus-visible{text-decoration:underline}
/* ★`?id=…#edit` 로 편집폼에 내려갈 때 폼 제목이 **고정 헤더(.hd, sticky) 밑에 깔린다**
   — 26-08-24 실측. 앵커 대상에만 헤더 높이만큼 여백을 준다(표 링크 수정과 한 쌍). */
#edit{scroll-margin-top:calc(var(--hd-h) + 14px)}
table.tb a.rl::after{content:"";display:inline-block;width:6px;height:6px;margin-left:8px;
              vertical-align:2px;border-right:2px solid currentColor;
              border-bottom:2px solid currentColor;transform:rotate(-45deg);opacity:.45}
table.tb .num{text-align:right;font-variant-numeric:tabular-nums}

/* 정의 목록 (상세 보기) */
.dl{display:grid;grid-template-columns:auto 1fr;gap:0}
.dl dt{padding:11px 0;font-size:14px;font-weight:700;color:var(--tx2);white-space:nowrap;
  padding-right:18px;border-bottom:1px solid var(--line)}
.dl dd{padding:11px 0;font-size:15px;border-bottom:1px solid var(--line);min-width:0}
.dl dt:last-of-type,.dl dd:last-of-type{border-bottom:0}

/* ═══ 아바타 (D-8) ════════════════════════════════════════════════════ */
.av{border-radius:50%;background:var(--navy);color:#fff;display:inline-flex;
  align-items:center;justify-content:center;font-weight:700;overflow:hidden;flex-shrink:0}
.av img{width:100%;height:100%;object-fit:cover}
.av-32{width:32px;height:32px;font-size:14px}
.av-40{width:40px;height:40px;font-size:16px}
.av-56{width:56px;height:56px;font-size:24px}
.av-96{width:96px;height:96px;font-size:42px}

/* ═══ 빈 상태 ═════════════════════════════════════════════════════════ */
.empty{padding:52px 20px;text-align:center;color:var(--tx2)}
.empty svg{width:44px;height:44px;color:var(--line);margin:0 auto 14px}
.empty .t{font-size:17px;font-weight:700;color:var(--tx);margin-bottom:6px}

/* ═══ 페이지네이션 ════════════════════════════════════════════════════ */
.pg{display:flex;gap:6px;justify-content:center;align-items:center;margin-top:20px;flex-wrap:wrap}
.pg a,.pg span{min-width:44px;min-height:44px;display:inline-flex;align-items:center;
  justify-content:center;padding:0 10px;border:1px solid var(--line);border-radius:var(--r-btn);
  background:var(--surface);text-decoration:none;color:var(--tx2);font-weight:700;font-size:15px}
.pg [aria-current]{background:var(--navy);border-color:var(--navy);color:#fff}
.pg .off{opacity:.4;pointer-events:none}

/* ═══ 유틸 ════════════════════════════════════════════════════════════ */
.mt-0{margin-top:0}.mt-8{margin-top:8px}.mt-14{margin-top:14px}.mt-20{margin-top:20px}
.mt-28{margin-top:28px}
.tc{text-align:center}.tr{text-align:right}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.row .sp{margin-left:auto}
/* ★★[2026-09-04] 검색 폼의 입력칸 — 전역 `input{width:100%}` 때문에 `.row` 안에서도
   칸마다 한 줄을 통째로 먹어 **세로로 쌓였다**(라운지 관리 화면 실측 캡처로 발견).
   두 칸이 나란히 서야 «내용 / 이름» 이 한눈에 구분된다.
   ★`flex:1 1 200px` = 좁아지면 알아서 줄바꿈한다(폰에서는 종전처럼 세로로 쌓인다). */
.row-search{align-items:flex-end}
.row-search .fld{flex:1 1 200px;min-width:0}
.row-search .fld label{display:block;margin-bottom:5px;font-size:12.5px;font-weight:700;color:var(--tx2)}
.row-search .fld input{min-height:46px}
.grid-2{display:grid;gap:14px}
@media (min-width:768px){ .grid-2{grid-template-columns:1fr 1fr} }
/* ★★그리드 안에서는 **형제 여백을 주지 않는다.**
   `.field + .field{margin-top:14px}` 이 나란히 놓인 두 칸에도 걸려 **오른쪽 칸만 14px 내려가**
   라벨과 입력칸의 가로줄이 어긋난다(대표 지적 2026-08-21 — admins·staff·lounge 관리 3개 화면).
   ★★화면들이 `class="field mt-0"` 으로 막아 두려 했지만 **(0,1,0) 이라 (0,2,0) 에 진다.**
     유틸리티 클래스로는 이 규칙을 이길 수 없다 — 그래서 여기서 구조적으로 끊는다.
   ★좁은 화면에서 세로로 쌓일 때의 간격은 `.grid-2` 의 `gap:14px` 이 이미 준다.
     (그동안은 gap 14 + margin 14 = 28px 로 **이중 여백**이었다. 그것도 함께 사라진다.) */
.grid-2 > .field + .field{margin-top:0}
.grid-cards{display:grid;gap:14px;grid-template-columns:1fr}
@media (min-width:768px){ .grid-cards{grid-template-columns:1fr 1fr} }
@media (min-width:1024px){ .grid-cards{grid-template-columns:1fr 1fr 1fr} }
.hr{height:1px;background:var(--line);margin:18px 0}

/* ★D-7 접근성 — 움직임 최소화 설정을 존중한다 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
}

/* ═══ 안내 전면 화면 (준비중·심사중·반려 등) ═══════════════════════════
   ★why 앱 셸을 안 쓰나: 이 화면들은 **아직 서비스에 들어오지 못한 사람**이 본다.
     하단 탭바를 보여 주면 누를 수 있는 것처럼 보이고, 눌러도 다시 여기로 튕긴다. */
.intro{min-height:100svh;display:flex;flex-direction:column;justify-content:center;
  background:linear-gradient(180deg,var(--navy),var(--navy-l));color:#fff;
  padding:1.25rem max(1.25rem,env(safe-area-inset-left))}
.intro .box{width:min(430px,100%);margin-inline:auto;background:var(--surface);color:var(--tx);
  border-radius:var(--r-card);padding:1.75rem 1.375rem;box-shadow:var(--shadow-lg)}
.intro .box h1{font-size:22px;margin-bottom:.75rem}
.intro .box p{color:var(--tx2);white-space:pre-line}     /* 안내 본문의 줄바꿈을 살린다 */
.intro .box .btn{margin-top:1.5rem}
.intro .foot{text-align:center;font-size:12px;color:rgba(255,255,255,.62);
  margin-top:1.5rem;padding-bottom:env(safe-area-inset-bottom)}

/* ═══ 파일 끌어다 놓기 (계약서 제출) ══════════════════════════════════ */
.drop{border:2px dashed var(--field-line);border-radius:var(--r-card);background:var(--bg);
  padding:24px 16px;text-align:center;color:var(--tx2)}
.drop.over{border-color:var(--navy);background:var(--info-bg)}
.drop svg{margin:0 auto;color:var(--navy-l)}
.drop img#preview{max-height:280px;width:auto;margin:0 auto;border-radius:8px;border:1px solid var(--line)}
.drop [hidden]{display:none}
details > summary{cursor:pointer;list-style:none}
details > summary::-webkit-details-marker{display:none}

/* ═══ 유틸 (인라인 style 대신) ════════════════════════════════════════
   ★★CSP 가 `style="..."` **속성**을 막는다. nonce 는 <style> 태그에만 통한다.
     그래서 한 줄짜리 스타일도 여기에 클래스로 둔다 — 인라인으로 쓰면 **에러 없이 조용히
     무시**되어 화면만 깨진다(2026-08-21 이 서비스에서 두 번 겪었다). */
.center{justify-content:center}
.w-full{width:100%}
.sample{width:100%;max-width:420px;margin-inline:auto;border-radius:8px;display:block}
.pre-line{white-space:pre-line}

/* ═══ 게시글 본문 ═════════════════════════════════════════════════════ */
.body-text{font-size:calc(16px * var(--fs));line-height:1.8}
.body-text a{color:var(--navy);text-decoration:underline;word-break:break-all}
.body-text + .hr{margin-top:22px}

/* ═══ 운영진 카드 (D-5) ═══════════════════════════════════════════════ */
.staff-card .av{margin-inline:auto}
.staff-card h3{font-size:18px}

/* ═══ 아바타 선택 (D-8 관리자 UI) ═════════════════════════════════════ */
.av-pick{gap:14px}
.av-opt{display:flex;flex-direction:column;align-items:center;gap:5px;cursor:pointer;
  padding:8px;border:2px solid transparent;border-radius:var(--r-btn)}
.av-opt:has(input:checked){border-color:var(--navy);background:var(--info-bg)}
.av-opt:has(input:focus-visible){outline:2px solid var(--navy);outline-offset:2px}

/* 임시 비밀번호 — 옮겨 적기 좋게 큼직하게, 자간을 벌린다 */
.temp-pw{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:700;
  letter-spacing:.12em;background:#fff;border:1px solid var(--line);border-radius:var(--r-inp);
  padding:12px 14px;margin:10px 0;word-break:break-all;user-select:all}

/* ═══ 조합원 라운지 (D-5 — 카카오톡과 비슷한 익숙한 배치) ═══════════════
   ★why 고정 높이인가: 대화는 아래가 최신이라 **입력바가 항상 보여야** 한다.
     페이지 전체가 늘어나면 폰에서 쓸 수 없다. */
.lounge{display:flex;flex-direction:column;
  /* ★★상수는 "라운지 아래에 남길 여백" 이다. 26-08-22 하단 안내문구를 빼면서 92→40 으로 줄였다
     — 안 줄이면 문구가 있던 자리가 **빈 띠로 남는다**(실측 73px). 문구를 되살리면 92 로 되돌릴 것.
     ★실측으로 맞춘 값이다(폰 390px 기준 아래 여백 ≈20px). 눈대중으로 바꾸지 말고 다시 재라. */
  /* ★★[2026-08-28] 대표 지시로 **화면을 꽉 채운다** — 아래 40px 여백을 뺐다.
     실측(390×844): 위 18px(`.main` 패딩) + 아래 21px 이 그냥 비어 있었다. 둘을 걷어 **39px 을 대화에 돌린다**.
     ★카드 테두리·라운드도 없앤다 — 화면을 꽉 채우면 «카드» 로 보일 이유가 없다. */
  /* ★`--tab-h`(60px)는 탭바 «내용» 높이다 — 실제 탭바는 위 테두리 1px 을 더해 **61px** 이라
     그대로 빼면 입력바와 1px 겹친다. 지금은 버튼이 가려지지 않지만, 26-08-22 에 하단탭이
     보내기 버튼 위로 올라탄 사고가 있었으므로 **여유 1px 을 남긴다.** */
  height:calc(100svh - var(--hd-h) - var(--tab-h) - 1px);min-height:340px;
  background:var(--surface);border:0;border-radius:0;overflow:hidden}
/* ★라운지가 든 화면에서만 본문 여백을 없앤다 — 다른 화면(공지·자료실)의 여백은 그대로 둔다.
   ★`:has()` 를 쓴다. 안 먹는 구형 웹뷰에서는 예전처럼 여백이 남을 뿐이라 **깨지지 않는다**(안전한 실패). */
.main:has(> .wrap > .lounge),
.main:has(> .wrap-wide > .lounge){padding:0}
/* ★★낮은 화면(가로 폰·멀티윈도우)에서 `min-height:340px` 가 뷰포트보다 커져 입력바가 아래로 밀려
   **하단탭 링크가 보내기 버튼 위에 올라탔다** — 보이는 버튼을 눌렀는데 자료실로 이동했다(26-08-22 실측).
   ★`min-height` 자체를 지우지 말 것(아주 낮은 화면에서 대화영역이 0이 된다).
   ★`.tabs` 의 sticky·z-index 를 건드리지 말 것 — 증상만 옮겨간다.
   ★임계 520 은 안전한 상위집합이다(검증자별 실측 임계가 442~496 으로 갈렸다). 조이지 말 것. */
@media (max-height:520px){ .lounge{min-height:0} }
/* PC 는 하단 탭바가 없다(좌측 사이드바) — 그만큼 더 쓸 수 있다.
   ★[2026-08-28] 95px → 0. 위와 같은 이유로 아래 여백을 남기지 않는다. */
@media (min-width:1024px){ .lounge{height:calc(100svh - var(--hd-h))} }
.lg-note{padding:9px 14px;background:var(--info-bg);color:var(--navy);font-size:13px;
  border-bottom:1px solid var(--line)}
.lg-note[hidden]{display:none}
.lg-note.bad{background:var(--bad-bg);color:#8C2B20}
.lg-scroll{flex:1;overflow-y:auto;padding:14px;-webkit-overflow-scrolling:touch;background:var(--bg)}
.lg-more{text-align:center;margin-bottom:10px}
.lg-more[hidden]{display:none}
/* ★★[2026-08-28] 이름이 어느 메시지 것인지 헷갈린다는 지적(대표) — **간격 비율**이 원인이었다.
   실측: 이름이 위 메시지에서 10px, 자기 말풍선에서 4px = **2.5배**뿐이라 눈이 소속을 못 가른다.
   ★기본 간격을 **좁게** 두고(같은 사람이 잇달아 말한 줄), 사람이 바뀌는 줄에만 위 여백을 준다.
     → 묶음 안 6px / 묶음 사이 18px. 이름 위 18px : 아래 2px = **9배**라 한눈에 붙는다.
   ★`gap` 을 키우고 음수 마진으로 되돌리는 방식은 쓰지 않는다 — 규칙이 서로 싸워 읽기 어렵다. */
.lg-list{list-style:none;display:flex;flex-direction:column;gap:6px}
.lg-row:not(.is-cont){margin-top:12px}
/* ★같은 사람이 잇달아 말하면 이름을 숨긴다. 아바타는 **자리만 비워** 말풍선 왼쪽 줄이 흔들리지 않게 한다
   (`display:none` 으로 지우면 그 줄만 왼쪽으로 밀린다). */
.lg-row.is-cont .lg-who{display:none}
.lg-row.is-cont .lg-av{visibility:hidden}

/* 날짜 구분선 */
.lg-day{align-self:center;background:rgba(22,48,79,.08);color:var(--tx2);font-size:12px;font-weight:700;
  padding:4px 12px;border-radius:var(--r-pill);margin:6px 0}
/* 읽지 않은 메시지 구분선 (D-5) */
.lg-unread{display:flex;align-items:center;gap:9px;color:var(--accent);font-size:12px;font-weight:700;margin:4px 0}
.lg-unread::before,.lg-unread::after{content:"";flex:1;height:1px;background:var(--accent);opacity:.45}

.lg-row{display:flex;gap:9px;align-items:flex-end;max-width:88%}
/* ★★[2026-08-30] 메타행이 말풍선 아래로 내려오면서 필요해진 3줄.
   안 넣으면 짧은 말풍선(「네」)이 **메타행 폭까지 늘어난다** — col 이 기본 stretch 라서다.
   ★`.lg-col{min-width:0}`(아래 있음)은 **유지**할 것 — 사진 100% 축소의 짝이다. */
.lg-col{display:flex;flex-direction:column;align-items:flex-start}
.lg-row.me .lg-col{align-items:flex-end}

/* ★[2026-08-30] 복사 관련 2선언
   ①인용 버튼은 기계가 만든 「답장: 원문40자」 문구다. 손으로 드래그해 복사할 때 섞이면
     **발신자가 쓴 말로 오귀속**된다 — 실명 기록이 남는 공간이라 그냥 두면 안 된다.
     ★무접두 user-select 는 Safari 17 이전에서 무시되니 짝을 쓴다(선례 :1016).
   ②내 말풍선은 남색 배경이라 브라우저 기본 선택색이 안 읽힌다 — 검색 하이라이트 값을 재사용한다. */
.lg-quote{-webkit-user-select:none;user-select:none}
.lg-row.me .lg-bubble::selection{background:#FFD24D;color:#101820}

/* ★[2026-08-30] 공감(리액션)
   ★칩·고르기 버튼은 **이모지가 콘텐츠**다 — 「UI 아이콘에 이모지 금지」는 버튼·아이콘 규칙이고,
     콘텐츠로서의 이모지는 26-08-28 EMOJI_QUICK 로 이미 채택된 선례가 있다.
   ★터치 타깃 44px 는 고르기 버튼에서 확보한다(칩은 보조 조작이라 32px). */
.lg-rx{display:flex;flex-wrap:wrap;gap:4px;margin-top:3px}
.lg-row.me .lg-rx{justify-content:flex-end}
.lg-rxchip{display:inline-flex;align-items:center;gap:3px;min-height:26px;padding:2px 8px;
  border:1px solid var(--line);border-radius:var(--r-pill);background:var(--surface);
  font-size:12px;color:var(--tx2);cursor:pointer;line-height:1.4}
.lg-rxchip.on{border-color:var(--navy);color:var(--navy);font-weight:600}
/* ★[2026-08-31 전화면 UI 점검] 41×26 이라 기획서의 터치 최소 44px 에 못 미쳤다.
   ★★칩을 키우지 않는다 — 말풍선 아래 줄이 굵어져 대화가 밀린다.
     대신 `::after` 로 **보이지 않는 히트영역만** 44px 로 넓힌다(메타행 `.lg-x` 가 쓰는 것과 같은 어법).
     화면은 하나도 안 변하고 누르기만 쉬워진다.
   ★칩끼리 히트영역이 겹치지 않게 좌우는 4px 만 넓힌다(`.lg-list` 의 칩 간격이 6px 이다). */
.lg-rxchip{position:relative}
.lg-rxchip::after{content:"";position:absolute;inset:-9px -4px}
/* ★[2026-08-30 대표 요청] 「화나요」만 브랜드 빨강(--accent)으로 구분한다.
   다른 넷(좋아요·박수·응원·감사)과 성격이 반대라 한눈에 갈려야 한다.
   ★임의 색을 새로 만들지 않고 팔레트 안의 --accent 를 쓴다(#C0392B). */
.lg-rxchip.lg-rx-angry{color:var(--accent)}
.lg-rxchip.lg-rx-angry.on{border-color:var(--accent);color:var(--accent)}
/* 고르기 줄 — 「공감」을 누르면 열린다. 롱프레스를 쓰지 않으므로 네이티브 텍스트 선택을 안 덮는다 */
.lg-rxpick{display:flex;gap:6px;margin-top:4px;padding:5px 7px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-pill);align-self:flex-start}
.lg-row.me .lg-rxpick{align-self:flex-end}
.lg-rxopt{min-width:40px;min-height:40px;border:0;background:none;border-radius:50%;
  font-size:21px;line-height:1;cursor:pointer}
.lg-rxopt:hover,.lg-rxopt:focus-visible{background:var(--bg)}
/* 즉시 가리기 — 사유 고르기 줄  [2026-09-05 대표 지시]
   ★공감 고르기 줄(.lg-rxpick)과 **같은 자리·같은 모양**을 쓴다. 말풍선 안에 붙는 인라인 요소라
     fixed 오버레이의 함정(부모 transform 에 갇힘 · AI 도우미 버튼과 겹침)이 아예 없다.
   ★글자 버튼이다 — 이 프로젝트는 UI 에 이모지를 쓰지 않는다(기기마다 다르게 보인다).
   ★한 줄에 다 안 들어가면 접힌다(wrap) — 320px 에서 사유 4개 + 취소가 두 줄이 된다. */
.lg-blpick{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px;padding:6px 8px;background:var(--surface);
  border:1px solid var(--accent);border-radius:12px;align-self:flex-start;max-width:100%}
.lg-row.me .lg-blpick{align-self:flex-end}
.lg-blpick .lg-bltitle{flex:0 0 100%;font-size:12px;color:var(--muted);line-height:1.3}
.lg-blopt{min-height:36px;padding:0 10px;border:1px solid var(--line);background:var(--bg);
  border-radius:var(--r-pill);font-size:13px;color:var(--accent);cursor:pointer}
.lg-blopt:hover,.lg-blopt:focus-visible{border-color:var(--accent)}
.lg-blopt.lg-blcancel{color:var(--muted)}
/* 「가리기」 버튼 자체 — 메타행의 다른 글자 버튼(.lg-x)과 같되 색만 경고색이다 */
.lg-x.lg-blind{color:var(--accent)}
/* ★[2026-08-23] 라운지 발신자 아바타 — .av av-32 가 원형·크기, .lg-row align-items:flex-end 가 하단정렬. 사진은 눌러 확대. */
/* ★[2026-08-30 조합원 요청 「프로필 사진을 이름 옆으로」] `flex-end` → `flex-start`.
   why: 08-30 에 메타행을 말풍선 아래로 내리면서 `flex-end` 인 아바타가 **메타행 높이까지 따라 내려가**
        이름에서 두 줄 이상 멀어졌다. 누구 말인지 눈으로 잇기 어려웠다.
        `flex-start` 면 아바타가 이름과 **같은 줄**에 서서 「얼굴+이름」이 한 덩어리로 읽힌다
        (카카오톡·슬랙과 같은 관례). 3안(맨아래/이름높이/말풍선상단)을 실제로 렌더해 비교한 결과다.
   ★연속 메시지(.is-cont)에서 아바타를 감추는 규칙(:520)은 그대로 작동한다. */
.lg-av{align-self:flex-start}
.lg-av-zoom{cursor:zoom-in}
.lg-row.me{align-self:flex-end;flex-direction:row-reverse}
/* ★이름은 자기 말풍선에 **바짝** 붙인다 — 위와의 거리를 벌린 것과 짝이 되는 조치다 */
.lg-who{font-size:13px;color:var(--tx2);margin-bottom:2px;display:flex;align-items:center;gap:5px}
.lg-bubble{background:var(--surface);border:1px solid var(--line);border-radius:14px;
  padding:9px 13px;font-size:15px;line-height:1.6;white-space:pre-wrap;word-break:break-word}
.lg-row.me .lg-bubble{background:var(--navy);border-color:var(--navy);color:#fff}
/* ★[2026-08-30] 대화문 속 주소는 **관습적인 파랑**으로 준다.
   본문색 그대로(=inherit)면 밑줄만으로 구분해야 해서 «누를 수 있는 것»인지 알아보기 어렵다.
   ★내 말풍선은 배경이 네이비라 파랑이 묻힌다 → 거기서만 흰색(inherit)으로 되돌린다. */
/* ★★[2026-09-07] 큰 글씨 보기는 **글자 말풍선에만** 건다.
   첨부(사진·문서·음성·동영상)·스티커·큰이모지 말풍선은 `max-width` 가 px 로 고정돼 있어
   (has-img 250 · has-doc 242 · has-aud 276 · has-vid 250), 글자만 키우면 그 안에서 넘치거나 잘린다.
   읽기 힘든 것은 «긴 글»이지 첨부 카드가 아니다 — 그래서 아예 대상에서 뺀다. */
.lg-bubble:not(.has-img):not(.has-doc):not(.has-aud):not(.has-vid):not(.has-st):not(.is-jumbo){
  font-size:calc(15px * var(--fs))}
.lg-bubble a{color:#1D5FA8;text-decoration:underline}
.lg-row.me .lg-bubble a{color:inherit}
/* ★★[2026-08-30] `white-space:nowrap` 을 뺐다. 메타가 말풍선 **옆**에 있던 시절에는
   줄바꿈을 막아야 폭 계산이 성립했지만, 아래로 내려온 지금은 그게 **해가 된다** —
   320px 에서 「시각·듣기·복사·공감·답장」 5개가 한 줄을 넘겨(실측 191px > 컨테이너) 잘렸다.
   이제는 좁은 화면에서 **자연스럽게 접히게** 둔다. 간격 10px 는 그대로 둘 것(오터치 방지 균형). */
.lg-meta{font-size:11px;color:var(--muted);padding-bottom:2px;
  display:flex;flex-wrap:wrap;align-items:center;row-gap:2px}
.lg-row.me .lg-meta{justify-content:flex-end}
.lg-row.me .lg-meta{text-align:right}
.lg-del{font-style:italic;color:var(--muted);background:transparent;border-style:dashed}
.lg-row.me .lg-del{color:rgba(255,255,255,.72)}
.lg-reply{font-size:12px;color:var(--tx2);border-left:3px solid var(--line);padding-left:8px;margin-bottom:5px;
  display:block;max-height:2.8em;overflow:hidden}
/* ★★27×24px 이라 기획서 6-? 의 「터치 영역 최소 44×44px」에 미달했다(26-08-22 조사).
   ★크기를 직접 키우면 `.lg-replybar` 가 41→61px 로 커져 대화창이 밀린다 →
     **박스는 그대로 두고 `::after` 로 히트영역만** 넓힌다(레이아웃 변화 0).
   ★더 아픈 쪽은 크기가 아니라 **시인성**이었다: 색·글자크기가 옆의 시각 텍스트와 완전히 같아
     화면이 「오후 11:35답장」 한 덩어리로 읽혔다 → 글자 버튼에만 밑줄을 준다(아이콘 버튼 제외). */
.lg-x{background:none;border:0;color:var(--muted);font-size:11px;cursor:pointer;padding:2px 4px;min-height:24px;
  position:relative}
.lg-x::after{content:"";position:absolute;inset:-10px}
.lg-meta .lg-x{text-decoration:underline;text-underline-offset:2px}
/* ★★[2026-08-30] 읽어주기 버튼이 생기면서 메타행 버튼이 **둘**이 됐다(종전엔 삭제/답장 중 하나뿐).
   ①`.lg-x::after{inset:-10px}` 는 좌우로도 10px 씩 히트영역을 넓힌다. 버튼이 나란히 서면 그 영역이
     **서로 겹쳐** 「답장을 눌렀는데 듣기가 눌리는」 오터치가 난다.
     → 좌우만 4px 로 줄이고 **상하 10px 은 유지**한다(24+20=44px, 터치 최소치를 지킨다).
   ②사이를 10px 띄워 4+4 를 넘긴다 — 겹침이 수학적으로 생기지 않는다.
   ③`.lg-meta` 가 `white-space:nowrap` 이라 폭이 밀린다. 간격은 이 이상 넓히지 말 것. */
.lg-meta .lg-x::after{inset:-10px -4px}
.lg-meta .lg-x + .lg-x{margin-left:10px}
/* ★[2026-08-30] 「수정됨」 — 버튼이 아니라 **표시**다. 밑줄을 주면 누를 수 있는 것으로 보인다.
   ★★[2026-09-12 대표 지적] 자리를 **메타행 → 말풍선 안**으로 옮겼다.
     why: 메타행에 두면 `시각·수정됨·듣기·복사·스크랩·공감·가리기·답장` 이 넘쳐
       **「답장」만 다음 줄로 떨어진다**(360px 에서 필요 358 > 가용 334, 24px 초과).
       글자·간격을 줄이는 미세조정으로는 20px 안팎만 벌어 아슬아슬하고 버튼이 하나 더 늘면 또 터진다.
       말풍선으로 옮기면 **메타행 폭이 수정 여부와 무관하게 일정**해진다.
   ★본문 끝에 이어 붙는다 — 본문이 길면 자연스럽게 다음 줄로 흐른다(본문의 일부처럼 읽힌다).
   ★`white-space:nowrap` 으로 「수정됨」이 글자 사이에서 쪼개지지 않게 한다.
   ★내 말풍선(`.lg-row.me`)은 글자가 흰색이라 색을 따로 준다 — `--muted` 는 어두워 안 보인다. */
.lg-edited{margin-left:6px;font-size:11px;color:var(--muted);opacity:.85;white-space:nowrap}
.lg-edited::before{content:"· "}
.lg-row.me .lg-edited{color:rgba(255,255,255,.72)}
/* ★`.lg-meta` 가 flex 컨테이너라 자식의 `hidden` 이 UA 스타일에 밀릴 수 있다 — 명시한다.
   (듣기 버튼은 음성이 잡히기 전까지 숨겨져 있다가 refresh() 가 켠다) */
.lg-meta .lg-x[hidden]{display:none}

.lg-bar{display:flex;gap:8px;padding:10px;border-top:1px solid var(--line);background:var(--surface);
  align-items:flex-end}
/* ★★[2026-08-28] 입력창 최대 높이 130px(≈4줄) → 대표 지시로 늘렸다.
   ★고정 px 만 쓰면 낮은 화면(가로 폰·멀티윈도우)에서 입력창이 대화창을 다 먹는다 →
     **`min()` 으로 화면 비례 상한을 함께 건다.** 844px 기기는 252px(≈10줄), 480px 기기는 163px(≈6줄).
   ★★**이 값이 유일한 출처다.** `lounge.js` 는 여기서 계산된 값을 읽어 높이를 정한다 —
     예전처럼 JS 에 130 을 또 적으면 두 값이 어긋나 «CSS 는 늘렸는데 안 늘어나는» 일이 생긴다. */
.lg-bar textarea{flex:1;min-height:44px;max-height:min(252px,34vh);padding:10px 14px;border-radius:var(--r-pill);
  resize:none;line-height:1.5}
.lg-send{min-width:52px;min-height:44px;border-radius:var(--r-pill);padding:0 14px}

/* 라운지 — 답장 바 · 첨부 버튼 · 이미지 말풍선 */
/* ★[2026-08-28] 자주 쓰는 이모지 띠 — 입력창을 누르면 펴진다.
   ★가로 스크롤을 허용한다(24개가 좁은 폰에서 다 안 들어간다). 세로는 한 줄로 고정. */
.lg-emo{background:var(--surface);border-top:1px solid var(--line)}
.lg-emo[hidden]{display:none}
/* 탭 — 이모지(글에 끼움) / 스티커(그 자체가 한 통) */
.lg-emo-tab{display:flex;gap:4px;padding:6px 8px 0}
/* ★★[2026-08-28] `white-space:nowrap` 필수 — 없으면 「이모지」가 「이모/지」로 2줄 깨진다(실측 캡처).
   flex 자식이라 폭이 내용 최소치까지 눌리는데, 한글은 글자 단위로 줄바꿈되기 때문이다. */
.lg-emo-tab button{flex:0 0 auto;min-height:32px;padding:0 14px;border:0;border-radius:999px;
  background:transparent;color:var(--tx2);font-size:13px;font-weight:700;font-family:inherit;
  cursor:pointer;white-space:nowrap}
.lg-emo-tab button.on{background:var(--navy);color:#fff}
.lg-emo-row{display:flex;gap:2px;overflow-x:auto;overflow-y:hidden;padding:4px 8px;
  -webkit-overflow-scrolling:touch}
.lg-emo-row::-webkit-scrollbar{height:0}
/* ★스티커는 격자다 — 이모지처럼 한 줄로 흘리면 글자 스티커가 잘린다. 높이는 2줄로 제한하고 세로 스크롤. */
/* ★[2026-08-28] 스티커 분류 줄 — 212종이라 한 격자로는 못 찾는다.
   ★가로 스크롤. 6개가 좁은 폰에서 다 안 들어간다. */
/* ★★[2026-08-28] 26개 분류를 **한 줄로 흘리면 안 된다.** 실측: 탭 전체가 1,796px 인데
     412px 화면에서는 5개만 보이고 나머지는 가로로 밀어 찾아야 했다(대표 지적).
     주 이용자가 40~60대라 가로 스크롤로 22개를 뒤지게 두면 사실상 못 찾는다.
   ★그래서 **줄바꿈(wrap)** 으로 전부 펼치고, 대신 세로는 상한을 둬 대화창을 덜 먹게 한다.
     넘치면 세로 스크롤 — 가로보다 세로가 훨씬 익숙하다. */
.lg-st-cats{display:flex;flex-wrap:wrap;gap:4px;padding:4px 8px;max-height:76px;overflow-y:auto;
  -webkit-overflow-scrolling:touch;border-bottom:1px solid var(--line)}
/* ★★높이는 **줄 경계**에 정확히 맞춘다. 76·104px 로 두니 마지막 줄이 반쯤 잘려
     스크롤이 있는지조차 안 보였다(실측 캡처 2회).
     실측값: 버튼 28px · 줄간격 32px(gap 4) · 상하 패딩 4+4.
     N줄 = 4 + 32*(N-1) + 28 + 4 = 32N + 4  →  3줄 100px / 4줄 132px.
   ★3줄(100px)로 둔다. 412px 에서 15개가 한눈에 들어오고 잘린 줄이 안 생긴다. */
.lg-st-cats{max-height:100px}
.lg-st-cats[hidden]{display:none}
.lg-st-cats::-webkit-scrollbar{width:0}
.lg-st-cats button{flex:0 0 auto;min-height:28px;padding:0 10px;border:1px solid var(--line);
  border-radius:999px;background:var(--surface);color:var(--tx2);font-size:12px;font-weight:700;
  font-family:inherit;cursor:pointer;white-space:nowrap}
.lg-st-cats button.on{background:var(--info-bg);color:var(--navy);border-color:var(--navy)}
.lg-st-pane{display:grid;grid-template-columns:repeat(auto-fill,minmax(72px,1fr));gap:6px}
.lg-st-pane[hidden]{display:none}

/* ★그림만 남아 열폭을 좁혔다(글자 스티커 시절엔 104px 이 필요했다) */
.lg-st-grid{padding:6px 8px;max-height:196px;overflow-y:auto;-webkit-overflow-scrolling:touch}
.lg-st-grid[hidden]{display:none}
.lg-st-grid button{display:flex;align-items:center;justify-content:center;min-height:56px;padding:6px;
  border:1px solid var(--line);border-radius:12px;background:var(--bg);cursor:pointer;font-family:inherit}
.lg-st-grid button:active{background:var(--info-bg)}
.lg-st-grid button img{width:40px;height:40px;display:block}

/* ── 보낸 스티커 (말풍선 대신 그 자체로 그린다) ─────────────────────────── */
.lg-bubble.has-st{padding:0;background:transparent;border:0}
.lg-row.me .lg-bubble.has-st{background:transparent;border:0}
.lg-st-img{display:block;width:96px;height:96px}
/* ★목록에서 내려간 스티커를 과거 메시지가 참조할 때만 쓰는 대체 표시(그림 없음) */
.lg-st-text{display:inline-block;padding:10px 14px;border-radius:14px;font-size:14px;font-weight:700;
  background:#5B6B7D;color:#fff;word-break:keep-all}
/* ★44px = 손가락 최소 타깃(주 이용자가 40~60대다). 이모지는 22px — 더 키우면 한 줄에 몇 개 안 보인다.
   ★★셀렉터를 `.lg-emo-row` 로 **좁혀야 한다.** `.lg-emo button` 으로 두면 같은 상자 안의
     탭 버튼과 스티커 격자 버튼까지 44px 정사각형으로 눌러, 탭 글자가 서로 겹치고
     격자 버튼의 테두리·배경이 사라진다(26-08-28 실측 캡처로 확인). */
.lg-emo-row button{flex:0 0 auto;width:44px;height:44px;border:0;background:transparent;
  font-size:22px;line-height:1;border-radius:10px;cursor:pointer;padding:0}
.lg-emo-row button:active{background:var(--info-bg)}

/* ★★[2026-08-28] 이모지만 보낸 메시지는 크게 — 카톡·왓츠앱·슬랙이 다 하는 방식이다.
   대표가 말한 「스티커처럼」에 가장 가까우면서 다운로드 0바이트다.
   ★말풍선 배경·테두리를 지운다 — 큰 그림에 상자를 두르면 스티커가 아니라 큰 글자로 보인다. */
.lg-bubble.is-jumbo{font-size:44px;line-height:1.15;padding:2px 4px;background:transparent;border:0}
.lg-row.me .lg-bubble.is-jumbo{background:transparent;border:0}

/* ★[2026-08-28] 답장 점프 되돌아오기 버튼 — `.lg-note` 와 같은 톤(같은 자리에 번갈아 뜬다).
   ★아이콘은 새로 만들지 않고 `back`(왼쪽 꺾쇠)을 **-90° 돌려 아래 꺾쇠**로 쓴다 —
     원문은 위에 있고 답장 글은 아래에 있으므로 방향이 아래여야 맞다. */
.lg-back{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;
  padding:10px 12px;border:0;border-top:1px solid var(--line);background:var(--info-bg);
  color:var(--navy);font-size:14px;font-weight:700;font-family:inherit;cursor:pointer;
  min-height:44px}
.lg-back[hidden]{display:none}
.lg-back-ico{display:flex;transform:rotate(-90deg)}
.lg-replybar{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--info-bg);
  border-top:1px solid var(--line);font-size:13px;color:var(--navy)}
.lg-replybar[hidden]{display:none}
/* ★[2026-08-30] 「답장」/「수정 중」 라벨 — 굵게 해서 뒤따르는 원문과 갈라 놓는다.
   평문이면 «수정 중 총회 안건…» 이 한 덩어리로 읽힌다(실화면 캡처로 확인). */
.lg-rl{font-weight:700;flex-shrink:0}
.lg-rt{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lg-attach{min-width:44px;min-height:44px;border-radius:var(--r-pill);padding:0 12px;flex-shrink:0}
/* ★★[2026-08-27] 사진 말풍선 폭 — 두 번 고친 자리다. 손대기 전에 아래를 다 읽을 것.
   ┌ 1차 증상(모바일): 사진이 행 폭을 넘겨 대화창이 좌우로 스크롤됐다.
   │  `.lg-scroll` 은 `overflow-y:auto` 만 걸었지만 CSS 규칙상 그 순간 `overflow-x` 도 `auto` 가 되어
   │  안쪽이 넘치면 가로로도 스크롤된다. 넘긴 범인은 옛 `max-width:min(240px,60vw)` — 화면폭(vw)을
   │  기준 삼아 행 구조(아바타 32 + gap 9 + 사진 + gap 9 + 시각 71.8, 행 상한 88%)를 무시했다.
   └ 2차 증상(PC): 그 수정이 회귀를 만들었다. 내가 보낸 사진이 오른쪽 끝에 안 붙고
      대화창 가운데에 뜨고, 시각이 사진에서 372px 떨어진 곳에 놓였다(대표님 지적).

   ★★2차의 원인 — **퍼센트가 들어간 max-width 는 flex 기초크기 계산에서 무시된다.**
     `min(240px,100%)` 의 100% 는 부모 폭에 의존하는데 그 부모 폭이 지금 계산하려는 값이라
     순환이 된다. 브라우저는 이때 max-width 를 없는 셈 치고 **이미지 원본 폭**으로 칸을 잡는다.
     실측: 원본 591px 사진 → 칸 601px(= 591 + 패딩 10). 사진은 그 안에서 240px 로 그려지니
     오른쪽에 360px 빈자리가 남고, 시각은 그 빈자리 건너편으로 밀려났다.

   ★해법 = 말풍선에 **퍼센트가 아닌 확정 px 상한**을 준다. 확정값은 기초크기 계산에서 존중되므로
     칸이 사진만큼만 넓어진다. 250 = 사진 240 + 패딩 5×2 (전역 `box-sizing:border-box`).
     ★`width` 로 주면 안 된다 — 240px 보다 **작은 사진까지 240 으로 늘려** 흐려진다.
       `max-width` 라야 작은 사진은 원본 크기를 지킨다.
   ★`.lg-img` 의 `100%` 는 그대로 둔다: 모바일에서 칸이 줄면 사진도 따라 줄어드는 축이다.
     짝이 되는 `.lg-col{min-width:0}` 이 없으면 칸이 안 줄어들어 그 100% 가 소용없다. */
.lg-col{min-width:0}
/* 첨부(사진·문서·영상) 행만 88% 상한을 푼다 — 글은 좁으면 읽기 힘들지만 첨부는 그냥 작아질 뿐이다.
   ★★상한 해제 **하나만으로는 안 고쳐진다.** 카드가 '줄어들 수 있는 폭'(max-width)을 함께 가져야 한다
     — 320px 에서 100% 로 풀어도 말풍선에 허용되는 폭은 126px 뿐이라 228px 고정 카드는 여전히 안 들어간다.
     짝이 되는 규칙은 `.lg-doc`(문서 섹션)·`.lg-vid`(영상 섹션)에 있다. 셋은 한 세트다. */
.lg-row:has(.lg-bubble.has-img),
.lg-row:has(.lg-bubble.has-doc),
.lg-row:has(.lg-bubble.has-vid),
.lg-row:has(.lg-bubble.has-aud){max-width:100%}
/* ★[2026-08-27] 세로 상한 — 스크린샷처럼 세로로 긴 사진이 대화창을 통째로 먹던 것을 막는다
     (실측: 240×556 사진 하나가 PC 대화창 높이 700px 의 8할을 차지했다).
   ★값 300 은 새로 정한 게 아니라 **영상 썸네일(.lg-vid-img)과 같은 값**이다 — 같은 대화방에서
     사진과 영상의 세로 크기가 어긋나면 그것대로 눈에 거슬린다.
   ★★`object-fit:cover`(영상 썸네일 방식)로 **자르지 않는다.** 여기는 재건축 조합 라운지라
     공문·계약서·현장 사진이 올라온다. 잘라내면 정작 봐야 할 부분이 사라진다.
     대신 비율을 지키며 줄인다 — 작아서 안 보이면 눌러서 확대하면 된다(lounge.js 의 openView).
   ★★세로 상한은 **CSS 혼자서는 못 건다.** lounge.js 가 사진에 HTML `width`/`height` 속성을
     박아 넣기 때문이다(로드 전에 자리를 잡아 두어 화면이 튀지 않게 하는 장치). 실측한 조합:
       · `width:auto;height:auto` → 속성이 무력화돼 **로드 전 사진이 2×2px 로 접힌다**(스크롤 튐)
       · `height:auto` 만        → 자리는 잡지만 높이만 300 으로 눌려 **사진이 찌그러진다**(549:1280 → 240:300)
     그래서 **상한을 반영한 크기를 lounge.js 가 속성에 미리 계산해 넣는다**(`Math.min(240/w, 300/h, 1)`).
     여기 `max-height:300px` 는 그 계산이 없는 경우(구버전 캐시·크기 미상)를 받아 주는 **안전망**이고,
     `height:auto` 는 모바일에서 폭이 줄 때 높이가 따라 줄게 하는 축이다. 셋은 한 세트다. */
.lg-img{display:block;max-width:min(240px,100%);max-height:300px;height:auto;
  border-radius:12px;border:1px solid var(--line);cursor:zoom-in}
.lg-row.me .lg-img{border-color:rgba(255,255,255,.25)}
.lg-bubble.has-img{padding:5px;background:transparent;border:0;max-width:250px}
.lg-row.me .lg-bubble.has-img{background:transparent;border:0}
.lg-quote{font-size:12px;color:var(--tx2);background:rgba(22,48,79,.06);border-radius:8px;
  padding:5px 9px;margin-bottom:5px;line-height:1.45}
.lg-row.me .lg-quote{background:rgba(255,255,255,.16);color:rgba(255,255,255,.85)}
/* ★★[2026-08-27] 사진 말풍선만은 예외다 — 윗줄의 흰 글씨를 되돌린다.
   why: 내 말풍선은 남색이라 흰 글씨가 맞지만, `.lg-bubble.has-img` 는 **배경을 지운다**(:567).
        그래서 밝은 대화창 바탕에 흰 글씨가 얹혀 **대비 1.03:1** — 사실상 안 보였다
        (지금 라운지 id=131 에서 실제로 재현·확대 캡처로 확인).
   ★윗줄(`.lg-row.me .lg-quote`) 자체를 건드리면 **일반 텍스트 말풍선(남색)이 깨진다.**
     사진 말풍선에만 걸리도록 `.has-img` 를 끼워 좁힌다. */
.lg-row.me .lg-bubble.has-img .lg-quote{background:rgba(22,48,79,.06);color:var(--tx2)}
/* ★답장 인용은 **누르면 원문으로** 간다(2026-08-24 대표 지시, 카카오톡식) → button 이다.
   ★`font-family:inherit` 필수 — 안 넣으면 버튼 기본 글꼴로 떨어져 인용만 다른 폰트로 뜬다.
   ★`background` 는 여기서 건드리지 않는다 — 내 말풍선용 `.lg-row.me .lg-quote` 와 싸운다. */
button.lg-quote{width:100%;text-align:left;border:0;font-family:inherit;
  cursor:pointer;-webkit-appearance:none;appearance:none;display:block}
/* ★2줄 딱 자르고 말줄임(…). 예전 `max-height:2.6em` 은 줄 높이의 배수가 아니라
   **두 번째 줄을 반쯤 잘라** 글자 윗부분만 보였다(26-08-24 캡처로 확인).
   ★★버튼에 직접 걸면 안 된다 — 크롬이 button 의 display 를 `flow-root` 로 바꿔 clamp 가 죽는다. */
.lg-quote .lg-qtext{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* 원문에 도착하면 잠깐 흔들어 알린다.
   ★흔들림만으로는 놓치기 쉬워 붉은 링을 함께 준다(주 이용자 40~60대) — 링은 스스로 옅어진다.
   ★`prefers-reduced-motion` 은 위 전역 블록이 자동으로 끈다. */
@keyframes mkShake{
  10%,90%{transform:translateX(-2px)} 20%,80%{transform:translateX(3px)}
  30%,50%,70%{transform:translateX(-5px)} 40%,60%{transform:translateX(5px)} }
@keyframes mkJumpRing{
  0%,50%{box-shadow:0 0 0 3px rgba(192,57,43,.60)} 100%{box-shadow:0 0 0 3px rgba(192,57,43,0)} }
.lg-row.is-jump .lg-bubble{animation:mkShake .5s both, mkJumpRing 1.6s ease-out both}
.lg-act{display:flex;gap:2px;justify-content:inherit}

/* ═══ 홈 히어로 — 밤 아파트 풍경 (D-1 확장, 2026-08-21) ═══════════════
   ★why: 자동 로그인이 걸리면 조합원은 **로그인 화면을 거의 못 본다.** 공들인 풍경을
     아무도 안 보게 되므로 홈 첫 화면으로 옮겼다(대표 지시 26-08-21).
   ★그림 자체(별·창문·아파트·산책)는 로그인과 **같은 소스**를 쓴다 → include/view/_scene.php.
     여기에는 **무대 크기와 배치만** 둔다.
   ★★풍경 위에 글자를 올리므로 대비를 직접 책임진다 — 하늘 위쪽이 가장 어두워
     흰 글자가 앉을 자리다. 아래쪽(스카이라인)에는 글자를 두지 않는다. */
.hero{position:relative;overflow:hidden;border-radius:var(--r-card);isolation:isolate;
  --sky-h:104px;                         /* 스카이라인 높이(무대) */
  --walk-from:-70px; --walk-to:470px;    /* ★산책 이동거리 — vw 가 아니라 이 띠의 폭 기준 */
  min-height:236px;display:flex;flex-direction:column;justify-content:flex-start;
  /* ★[2026-08-26] 하늘을 4단으로 깊게 깔았다. 종전 3색 선형 그라데이션은 위아래 대비가 얕아
     '남색 판때기' 로 읽혔다. 천정을 더 어둡게(#0E2340) 눌러 **위가 깊고 아래가 트인** 실제 밤하늘의
     명도 분포를 만들고, 지평선 쪽에 따뜻한 도시광(주황 15%)을 아주 옅게 섞어 색온도 대비를 준다.
     ★주황은 브랜드 포인트색(#FFC17B) 계열이다 — 공식 사이트 색(#EC6627) 이 아니다. */
  background:
    radial-gradient(120% 62% at 50% 104%, rgba(255,193,123,.16), transparent 58%),
    radial-gradient(128% 74% at 50% 100%, rgba(90,150,225,.28), transparent 62%),
    linear-gradient(180deg,#0E2340 0%,#16304F 34%,#1B3A5E 68%,#26476E 100%)}

/* ── 히어로 하늘 소품(달·구름·미스트) ─────────────────────────────────
   ★건물(z-index:3)·별(2) 보다 아래(1)에 둔다 — 달이 건물 앞에 오면 원근이 깨진다.
   ★전부 transform/opacity 만 움직인다(리플로우 0). 40~60대 사용자의 보급형 단말을 고려해
     blur 는 큰 면적 하나(헤일로)에만 쓰고 나머지는 그라데이션으로 흐림을 흉내낸다. */
.hero .sky-art{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}

/* 달 — 씬의 초점. 오른쪽 위 삼분할 지점에 둔다(정중앙은 표적처럼 보인다) */
/* ★★[2026-08-28] 달을 움직인다(대표 지시: *"실제 달은 시간에 따라 느리지만 움직인다"*).
   ★★[같은 날 2차] 대표 지시로 **경로를 대각선으로 넓히고 속도를 올렸다** —
     *"위아래로만이 아니라 좌우로 같이 움직여야", "실시간으로 천천히 움직이는 걸 눈으로 볼 수 있어야"*.
     1차(고도 96px·x 8px·편도 300초)는 **분당 19px** 이라 응시해도 움직임이 안 보였다.

   ★경로: **왼쪽 아래(동쪽에 떠오른 참) → 오른쪽 위(남중)**. 실제 달이 동에서 떠 남중하는 방향과 같다.
     중간 지점을 직선보다 위에 두어 **위로 볼록한 호**를 그린다(직선이면 레일 위를 미끄러지는 것처럼 보인다).
   ★★**달이 글자 뒤를 지나간다 — 그래도 된다.** 달은 `z-index:1`, 본문은 `4` 이고
     `.hero-in h1/.hero-sub` 에 `text-shadow` 가 이미 걸려 있어 글자가 묻히지 않는다.
     버튼은 불투명 흰 배경이라 아예 가려 준다. (26-08-26 의 "글자와 겹치지 않게" 는 달이 **멈춰서**
     인사말 옆에 붙어 있던 때 이야기다. 스쳐 지나가는 것과는 다르다.)
   ★아래 한계는 스카이라인이다. y 89px 내려도 360px 에서 여유 22px, 1280px 에서 24px 남는다.
     ★★**오른쪽으로는 넓히지 말 것** — 히어로 모서리까지 12px 뿐이라 **둥근 모서리에 잘린다**(1차 때 실제로 잘렸다).
       그래서 남중을 오른쪽 끝으로 두고 **왼쪽으로만** 벌린다.
   ★속도: 경로 120px 를 편도 **30초** = **초당 4.5px**. 3초만 봐도 달 반지름만큼 움직인다.
     ★90초(초당 1.5px)로 뒀다가 대표 지시로 **3배 올렸다**(26-08-28). 더 조정할 땐 여기 초와
       main.php 의 왕복 주기(`time() % 60`)를 **반드시 함께** 바꿀 것 — 한쪽만 바꾸면 시작 위치가 어긋난다.
   ★★**`ease-in-out` 을 쓰지 말 것.** 1차 때 그렇게 뒀더니 남중 근처에서 **분당 3.9px** 로 떨어져
     그때 들어온 사람에게는 멈춰 있는 것과 같았다(실측). 실제 달의 각속도도 균일하므로 `linear` 가 맞다. */
.hero .moon{position:absolute;top:19px;right:30px;width:34px;height:34px;
  animation:moonArc 30s linear infinite alternate}
@keyframes moonArc{
  0%  {transform:translate(-80px,89px)}  /* 동쪽에 낮게 떠오른 참 */
  50% {transform:translate(-46px,30px)}  /* ★직선이면 (-40,44.5) — 위로 띄워 호를 만든다 */
  100%{transform:translate(0,0)}         /* 남중 — CSS 에 적힌 원래 자리 */
}
.hero .moon i{position:absolute;border-radius:50%;display:block}
.hero .moon .disc{inset:0;
  background:radial-gradient(circle at 36% 34%, #FFF6E2 0%, #F7E7C6 46%, #E9D2A6 78%, #D9BE8C 100%);
  box-shadow:0 0 14px rgba(255,236,200,.34), inset -5px -4px 10px rgba(120,96,58,.26)}
/* 헤일로 — 달 주변 대기 산란. 이것 하나로 하늘이 '공기' 를 갖는다 */
.hero .moon .halo{left:-40px;top:-40px;width:114px;height:114px;
  background:radial-gradient(circle, rgba(255,238,205,.22) 0%, rgba(255,231,190,.10) 38%, transparent 70%);
  filter:blur(3px);animation:moonBreath 9s ease-in-out infinite}
@keyframes moonBreath{0%,100%{opacity:.78;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}

/* 구름띠 — 아주 옅게, 아주 느리게. 보이는 게 아니라 '느껴지는' 정도가 맞다.
   ★속도를 다르게 줘 층이 어긋나 흐르면 시차(parallax)가 생겨 하늘이 깊어진다. */
.hero .clouds{position:absolute;left:0;right:0;top:0;height:72%}
.hero .clouds i{position:absolute;display:block;height:26px;border-radius:50%;
  background:linear-gradient(90deg,transparent,rgba(196,220,250,.10) 22%,rgba(210,230,255,.16) 50%,rgba(196,220,250,.09) 78%,transparent);
  filter:blur(6px)}
.hero .clouds .c1{top:22%;left:-40%;width:64%;animation:drift 72s linear infinite}
.hero .clouds .c2{top:44%;left:-55%;width:78%;height:20px;opacity:.72;animation:drift 104s linear infinite;animation-delay:-38s}
.hero .clouds .c3{top:9%;left:-30%;width:46%;height:16px;opacity:.55;animation:drift 88s linear infinite;animation-delay:-64s}
@keyframes drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(230%,0,0)}}

/* 원경 미스트 — 스카이라인 바로 위에 깔리는 옅은 안개.
   ★이 한 겹이 '먼 동' 과 '가까운 동' 사이에 공기를 넣어 깊이를 만든다(대기 원근). */
/* ★위치가 중요하다. 아래로 내리면 **근경 건물 발치를 덮어** 건물이 공중에 뜬 것처럼 보인다
   (26-08-26 캡처로 확인). 원경 지붕선 언저리에만 얇게 걸치게 둔다. */
.hero .mist{position:absolute;left:0;right:0;bottom:calc(var(--sky-h) * .86);height:46px;
  background:linear-gradient(180deg,transparent,rgba(150,190,240,.10) 50%,rgba(170,205,245,.13));
  filter:blur(6px)}
/* 접지 그림자 — 띠 바닥을 어둡게 눌러 건물이 땅에 붙어 보이게 한다.
   ★건물(z-index:3) 위에 얹어야 발치가 잠긴다. 그래서 .city 가 아니라 히어로 바닥에 둔다. */
.hero::after{content:"";position:absolute;left:0;right:0;bottom:0;height:26px;z-index:4;
  background:linear-gradient(180deg,transparent,rgba(6,18,34,.34) 62%,rgba(4,13,26,.58));
  pointer-events:none}

/* ★좁은 화면(360px 안팎)에서는 인사말이 2줄이 되며 달과 겹친다(26-08-26 실측).
   달을 위로 올리고 한 단계 줄여 **글자와 겹치지 않게** 한다 — 배경이 본문을 방해하면 안 된다. */
@media (max-width:390px){
  .hero .moon{top:11px;right:20px;width:28px;height:28px}
  .hero .moon .halo{left:-34px;top:-34px;width:96px;height:96px}
}
/* ★움직임을 줄이도록 설정한 사용자에게는 흐름을 멈춘다(어지럼 방지) */
@media (prefers-reduced-motion:reduce){
  /* ★달 자체의 이동도 멈춘다 — 배경이 계속 움직이면 어지럼을 느끼는 사용자가 있다.
     멈추면 `transform` 이 사라져 CSS 에 적힌 원래 자리(남중)에 선다. */
  .hero .clouds i,.hero .moon .halo,.hero .moon{animation:none}
}
/* 도시는 띠 바닥에 붙인다. z-index 3 → 별(2)보다 위라 건물이 별을 가린다(하늘이 뒤에 있어야 맞다) */
.hero .city{position:absolute;left:0;right:0;bottom:0;z-index:3}
/* ★★띠의 **폭**을 채운다. 원본 SVG 는 `preserveAspectRatio="xMidYMax meet"` 라
   높이에 맞춰 축소되는데, 낮은 띠(126px)에서는 그림이 485px 로 줄어
   **760px 짜리 띠 가운데만 건물이 서고 양옆이 텅 빈다**(2026-08-21 캡처로 발견).
   → 폭을 100% 로 주고 높이를 비율대로(×0.26) 늘린 뒤, `.city` 의 overflow 로 **위를 잘라낸다.**
     사진의 object-fit:cover 와 같은 처리다. 잘리는 건 먼 건물의 꼭대기라 자연스럽다.
   ★`xMidYMax` 라 아래쪽 정렬이므로 잘림은 항상 위에서 생긴다 — 지면은 절대 잘리지 않는다. */
.hero .city > svg{left:0;transform:none;width:100%;height:auto}
.hero .stars,.hero .shoot{position:absolute;inset:0}
/* ★★아래 padding 이 **스카이라인 높이만큼**이다 — 이게 이 히어로의 핵심 규칙이다.
   글이 길어지거나(320px 폰에서 설명이 3줄) 글꼴이 커지면 버튼이 건물 위로 올라탄다.
   실제로 1280px 에서 한 번, 320px 에서 또 한 번 그렇게 겹쳤다.
   브레이크포인트마다 높이를 손으로 맞추면 **다음 화면 크기에서 또 겹친다** —
   글 블록이 항상 하늘 안에 머물도록 아래를 비워 두면 히어로가 알아서 늘어난다. */
.hero-in{position:relative;z-index:4;padding:22px 20px calc(var(--sky-h) + 6px);color:#fff}
.hero-in h1{font-size:22px;font-weight:800;line-height:1.35;color:#fff;
  /* ★그림자는 흐리게 넓게 — 선명한 그림자는 촌스럽고, 없으면 별 위에서 글자가 흔들린다 */
  text-shadow:0 1px 12px rgba(4,16,27,.55)}
.hero-in .hero-sub{margin-top:6px;font-size:14px;line-height:1.6;color:#D7E4F5;
  text-shadow:0 1px 10px rgba(4,16,27,.5)}
/* ★풍경 위의 주 버튼은 흰색이다 — 남색 버튼(.btn-pri)은 남색 하늘에 묻힌다 */
.hero-cta{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  margin-top:16px;min-height:48px;padding:0 22px;border-radius:var(--r-btn);
  background:#fff;color:var(--navy);font-weight:800;font-size:16px;text-decoration:none;
  box-shadow:0 6px 20px rgba(4,16,27,.32);transition:transform .12s ease,box-shadow .12s ease}
.hero-cta:hover{transform:translateY(-1px);box-shadow:0 9px 26px rgba(4,16,27,.4)}
.hero-cta:active{transform:none}
.hero-cta svg{width:20px;height:20px}
/* ★★[2026-08-28] 스카이라인이 **위에서 잘려** 옥상이 사라지고 담벼락처럼 보이던 것을 고친다(대표 지적).
   ★원인: `.hero .city > svg{width:100%;height:auto}` 라 **폭에 맞춰 높이가 정해지는데**,
     담는 칸(`--sky-h`)은 고정이라 넘치는 위쪽이 `overflow:hidden` 에 잘려 나갔다.
     실측(잘리는 양): 480w 12.5px · 768w 65.4px · 1280w **71.6px**. 390w 만 유일하게 여유가 있었다
     — 대표는 «PC» 라 하셨지만 실제로는 **480px 이상 전 구간**이 잘리고 있었다.
   ★해법은 **칸을 그림에 맞춰 키우는 것**이다(모바일이 예뻤던 이유가 바로 이 상태였다).
     그림 비율 1000:260 이고 히어로 폭이 최대 760px 이라 필요 높이는 197.6px → **200px** 로 잡는다.
   ★★`min-height` 를 **같이** 올려 «하늘»(= min-height − sky-h)을 **166px 그대로** 유지한다.
     이 값이 달 궤적·별똥별 하강폭의 기준이다 — 하늘이 줄면 둘 다 건물에 처박힌다(여유가 15~17px 뿐이다).
     **sky-h 만 올리는 실수를 하지 말 것.** */
@media (min-width:480px){
  .hero{--sky-h:200px;min-height:366px}
}
@media (min-width:768px){
  /* ★넓은 화면에서는 띠를 조금 더 높인다 — 폭이 넓어지면 건물도 함께 커져
     min-height 262px 에서는 「라운지 들어가기」 버튼이 건물 위로 올라탄다(캡처로 확인). */
  .hero{--walk-to:840px}
  .hero-in{padding:28px 26px calc(var(--sky-h) + 6px)}
  .hero-in h1{font-size:26px}
  .hero-in .hero-sub{font-size:15px}
}
/* ★움직임 최소화 — 불빛을 켜두고 움직임만 끄는 규칙은 _scene.php 가 그림과 함께 들고 온다.
   여기서는 **사람의 정지 위치**만 정한다(무대 폭이 로그인 화면과 다르다). */
@media (prefers-reduced-motion:reduce){
  .hero .w1{transform:translateX(60px)} .hero .w2{transform:translateX(230px) scaleX(-1)}
  .hero .w3{transform:translateX(360px)}
  .hero-cta{transition:none}
}

/* ═══ 바로가기 설치 안내 (2026-08-21) ═══════════════════════════════════
   ★★`hidden` 으로 시작해 JS 가 판정 후 연다. 전역 리셋의 `[hidden]{display:none!important}`
     가 없으면 아래 `display:flex` 가 이겨 **판정 전에 먼저 보인다** — 이 코드베이스에서 이미
     같은 함정을 밟은 적이 있다(알림 켜기/끄기 버튼이 둘 다 떴던 건). */
.ins-in{display:flex;align-items:center;gap:13px}
.ins-ico{flex-shrink:0;width:44px;height:44px;border-radius:12px;display:inline-flex;
  align-items:center;justify-content:center;background:var(--info-bg);color:var(--navy)}
.ins-ico svg{width:24px;height:24px}
.ins-tx{flex:1;min-width:0}
.ins-tx .strong{font-size:15px}
/* ★한글은 keep-all 이 없으면 단어 중간에서 끊긴다("받을 수 / 있습니다") */
.ins-tx .cap{margin-top:2px;word-break:keep-all}
.ins-in .btn{flex-shrink:0}
/* 닫기 — 눌러야 할 것이 둘(설치/닫기)이라 닫기는 확실히 약하게 그린다 */
/* ★[2026-08-31] 32×32 → 44×44. 잘못 누르면 배너가 사라지는 버튼이라 오터치 비용이 크다.
   ★아이콘 크기는 그대로다(`inline-flex` 가운데 정렬) — 버튼 상자만 커진다. */
.ins-x{flex-shrink:0;width:44px;height:44px;border:0;background:none;color:var(--muted);
  border-radius:8px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.ins-x:hover{background:#EEF1F5;color:var(--tx2)}

/* ★★[2026-09-03] 좁은 화면에서 **글자가 세로로 한 자씩** 떨어지던 것 수정 (대표 지적).
   원인: 한 줄에 아이콘(44)·버튼(89)·닫기(44)가 전부 `flex-shrink:0` 인데 gap 이 13×3 이라
   **고정으로 먹는 폭만 216px** 이다. 320px 폰의 실제 내용 폭은 250px 라 글자 칸에 **34px** 만 남았고,
   그 폭에서는 `word-break:keep-all` 도 소용이 없다 — 한 글자가 34px 보다 좁으니 브라우저는
   «맞다» 고 보고 한 자씩 쌓는다(실측: 320px 에서 배너 높이 313px, 360px 에서도 177px 로 깨졌다).
   ★고칠 곳은 글자 쪽이 아니라 **버튼**이다. 버튼을 아랫줄 전체 폭으로 내리면 글자 칸이 136px 로 늘어난다.
   ★★`order` 로 닫기(×)를 버튼보다 앞에 둔다 — 안 그러면 닫기가 버튼을 따라 아랫줄로 내려가
     «설치» 옆에 «닫기» 가 나란히 붙어 오터치가 는다.
   ★400px 기준: 412px 은 지금도 두 줄로 정상이라 건드리지 않는다(실측 확인). */
@media (max-width:400px){
  /* ★`align-items:flex-start` — 줄바꿈 뒤에는 첫 줄이 2줄이 되는데, 가운데 정렬로 두면
     아이콘·닫기가 «글자 두 줄의 한가운데» 로 떠서 제목과 눈높이가 안 맞는다(실측 캡처).
     윗줄 기준으로 맞춘다. 닫기는 아이콘 상자(44px)와 같은 높이라 저절로 제목 줄에 선다. */
  .ins-in{flex-wrap:wrap;align-items:flex-start}
  .ins-in .btn{order:3;flex:1 0 100%;margin-top:2px}
  .ins-x{order:2}
}

/* ── 아이폰 안내 시트 — 설치 프롬프트가 없는 유일한 대안 ─────────────── */
.ins-sheet{position:fixed;inset:0;z-index:60;display:flex;align-items:flex-end;justify-content:center;
  background:rgba(10,26,44,.55);padding:0}
.ins-sheet-in{width:min(430px,100%);background:var(--surface);
  border-radius:18px 18px 0 0;padding:22px 20px calc(20px + env(safe-area-inset-bottom))}
.ins-sh{font-size:18px;font-weight:800;color:var(--tx)}
.ins-steps{margin-top:14px;padding:0;list-style:none;counter-reset:s}
/* ★단계 목록과 아래 보충설명이 붙어 있으면 설명문이 5번째 단계처럼 읽힌다(26-08-27 캡처로 확인) */
.ins-steps + .cap{margin-top:16px}
.ins-steps li{counter-increment:s;position:relative;padding-left:34px;margin-top:11px;
  font-size:15px;line-height:1.65;color:var(--tx2);word-break:keep-all}
.ins-steps li::before{content:counter(s);position:absolute;left:0;top:1px;width:24px;height:24px;
  border-radius:50%;background:var(--navy);color:#fff;font-size:13px;font-weight:800;
  display:flex;align-items:center;justify-content:center}
/* 버튼 이름을 그대로 보여 준다 — "공유 버튼" 이라고만 쓰면 어떤 아이콘인지 못 찾는다 */
.ins-k{display:inline-flex;align-items:center;gap:4px;padding:1px 8px;margin:0 1px;
  border:1px solid var(--line);border-radius:7px;background:#F7F9FC;
  font-weight:700;color:var(--tx);white-space:nowrap}
.ins-k svg{width:17px;height:17px}
@media (min-width:768px){
  .ins-sheet{align-items:center}
  .ins-sheet-in{border-radius:var(--r-card);max-width:460px}
}
@media (prefers-reduced-motion:reduce){ .ins-x{transition:none} }

/* ═══ 미투표 안내 모달 [2026-09-03 대표 지시] ═══════════════════════════════
   ★★why 시트(`.ins-sheet`)를 그대로 안 쓰고 별도 클래스를 두는가: 저건 «설치 방법 안내» 전용이라
     JS(install.js)가 그 클래스를 잡아 열고 닫는다. 재사용하면 두 기능이 서로의 시트를 여닫는다.
   ★생김새는 `.ins-sheet` 를 그대로 따른다(폰=아래에서 올라오는 시트 / PC=가운데 카드).
     조합원이 이미 학습한 형태라 새 형태를 만들 이유가 없다.
   ★★**z-index 는 85 다(60 아님).** `.ins-sheet` 를 그대로 베껴 60 을 줬더니 **AI 챗봇 FAB
     (`#mw-chat` z-index:84)이 「투표하러 가기」 버튼 위에 겹쳤다**(실측 캡처로 발견 — 코드로는 안 보인다).
     `_ai_widget.php` 주석이 층 규약을 명시한다: 상시 콘텐츠 ≤80 · AI FAB 84 · **전체화면 모달 ≥85**.
     이건 화면 전체를 덮는 모달이므로 85 가 맞다(탭바가 열릴 때 쓰는 `.tabs-raise` 와 같은 층).
   ★`.ins-sheet`(60)는 왜 그대로 두나: 그건 **버튼이 하나뿐**이고 FAB 이 겹치는 자리에 없다.
     지금 고칠 이유가 없고, 건드리면 설치 안내 쪽을 다시 검증해야 한다. */
.pmd{position:fixed;inset:0;z-index:85;display:flex;align-items:flex-end;justify-content:center;
  background:rgba(10,26,44,.55);padding:0}
.pmd-in{width:min(430px,100%);background:var(--surface);
  border-radius:18px 18px 0 0;padding:22px 20px calc(20px + env(safe-area-inset-bottom))}
/* 아이콘 + 제목 한 줄 — 「투표」임을 글자보다 먼저 알린다 */
.pmd-h{display:flex;align-items:center;gap:9px}
.pmd-h svg{width:22px;height:22px;color:var(--accent);flex-shrink:0}
.pmd-t{font-size:18px;font-weight:800;color:var(--tx)}
.pmd-sub{margin-top:8px;font-size:14.5px;line-height:1.65;color:var(--tx2);word-break:keep-all}
/* 안건 목록 — 제목이 길어도 카드를 세로로 늘리지 않는다(2줄에서 자른다) */
/* 투표 전 확인창 본문 (2026-09-05). ★`.pmd` 를 그대로 쓰고 본문 타이포만 더한다 —
   내용이 길고 «※※※» 같은 강조가 섞여 있어 줄간격이 넉넉해야 읽힌다.
   ★길면 스크롤되게 둔다(모달 자체가 화면 밖으로 자라면 버튼을 못 누른다). */
.pcf-body{margin-top:10px;font-size:14.5px;line-height:1.7;color:var(--tx);
  word-break:keep-all;max-height:46vh;overflow-y:auto;-webkit-overflow-scrolling:touch}
.pmd-list{margin:14px 0 0;padding:0;list-style:none}
.pmd-list li{border:1px solid var(--line);border-radius:10px;padding:11px 13px;margin-top:8px;
  background:#F7F9FC}
.pmd-nm{display:block;font-size:15px;font-weight:700;color:var(--tx);line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pmd-dl{display:block;margin-top:3px;font-size:12.5px;color:var(--muted)}
/* ★버튼 2개는 세로로 쌓는다 — 가로로 두면 320px 에서 「나중에 하기」가 2줄로 접힌다.
   ★주 동작(투표하러 가기)이 위다. 아래는 약하게 — 실수로 닫는 비용이 크지 않지만
     매번 뜨는 모달이라 «닫는 길» 이 분명해야 한다. */
.pmd-go{margin-top:16px}
.pmd-later{width:100%;margin-top:8px;border:0;background:none;padding:12px;
  font-size:14.5px;color:var(--muted);cursor:pointer;border-radius:8px}
.pmd-later:hover{background:#EEF1F5;color:var(--tx2)}
@media (min-width:768px){
  .pmd{align-items:center}
  .pmd-in{border-radius:var(--r-card);max-width:460px}
}

/* ── 제보함 안내 모달 (`.pmd` 위에 얹는 변형)  [2026-09-14] ─────────────────
   ★★why 별도 변형인가: 투표 모달(`.pmd`)은 «안 한 일이 있다»는 **독촉**이고, 이건
     «새로 생겼다»는 **소개**다. 같은 얼굴로 띄우면 조합원은 또 독촉으로 읽고 닫는 법부터 쓴다.
     그래서 상단에 네이비 판을 얹어 성격을 먼저 구분시킨다(글을 읽기 전에 구분된다).
   ★★색은 브랜드색만 쓴다 — `--navy`/`--navy-l`. 공식 홈페이지 색(#001244·#EC6627)은 금지다.
   ★아이콘은 자물쇠 하나로 고정한다. 제보함의 판매점은 기능이 아니라 «아무도 못 본다» 이고,
     그 약속을 글보다 먼저 전하는 것이 이 그림의 일이다. 이모지는 쓰지 않는다(기기마다 다르게 보인다). */
/* ★★작은 화면(360x640)에서는 내용이 화면보다 길어 **상단이 잘려 나갔다**(실측: top=-25px —
   자물쇠 배지 윗부분과 둥근 모서리가 화면 밖). 시트 높이를 화면 안으로 묶고, **가운데 목록만**
   스크롤시킨다 — 통째로 스크롤시키면 「제보함 열어보기」가 아래로 밀려 보이지 않는다.
   ☆`min-height:0` 이 빠지면 flex 자식이 줄지 않아 스크롤이 안 생긴다(flex 기본 min-height:auto). */
.tipad .pmd-in{padding:0;overflow:hidden;max-height:92vh;max-height:92dvh;
  display:flex;flex-direction:column}
.tipad-hero{flex:0 0 auto}
.tipad-body{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
/* 상자 자체에 초점을 주므로(main.php 참조) 초점테는 지운다 — 조작 대상이 아니라 «읽을 곳» 표시다.
   ★키보드 사용자의 탈출구는 그대로다: ESC·닫기 버튼·바깥 클릭 셋 다 살아 있다. */
.tipad .pmd-in:focus{outline:none}
/* ★그라데이션 폭을 좁게 잡는다 — `--navy`→`--navy-l` 로 끝까지 벌리면 브랜드 네이비가 아니라
   «흐린 파랑» 으로 읽힌다(좌측 사이드바의 단색 네이비와 나란히 놓고 비교해 고른 값이다). */
.tipad-hero{position:relative;padding:24px 20px 20px;
  background:linear-gradient(152deg,#142B47 0%,#1B3758 100%);color:#fff}
/* 오른쪽 위에서 스며드는 빛 — 단색 네이비는 인쇄물처럼 납작하게 보인다.
   ★`pointer-events:none` 필수: 이 층이 글자 위를 덮으므로 없으면 제목 선택·탭이 막힌다. */
.tipad-hero::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 88% 0%,rgba(255,255,255,.07) 0%,rgba(255,255,255,0) 58%)}
.tipad-hero > *{position:relative;z-index:1}
/* 오른쪽 위 닫기 — ★터치 표적 44px 을 지킨다(아이콘은 18px 이지만 누르는 칸은 그보다 커야 한다).
   ★네이비 위 흰 아이콘은 그냥 두면 장식처럼 보인다 — 옅은 원판을 깔아 «누르는 것»으로 읽히게 한다. */
.tipad-x{position:absolute;top:10px;right:10px;z-index:2;width:44px;height:44px;padding:0;
  display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;
  background:rgba(255,255,255,.08);color:#fff;cursor:pointer}
.tipad-x svg{width:18px;height:18px}
.tipad-x:hover{background:rgba(255,255,255,.2)}
.tipad-badge{width:52px;height:52px;border-radius:16px;display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.34)}
.tipad-badge svg{width:26px;height:26px;color:#fff}
/* 작은 머리말 — 「새로 생겼다」를 제목보다 먼저 알린다.
   ★★자간은 거의 주지 않는다(.02em). 한글은 자간을 벌리면 낱글자가 떨어져 「새 로 생 긴 메 뉴」로
     읽힌다 — 영문 eyebrow 관습을 그대로 가져오면 안 되는 자리다(실제 캡처에서 확인). */
.tipad-eyebrow{margin:14px 0 0;font-size:11.5px;font-weight:800;letter-spacing:.02em;color:var(--muted-on-navy)}
.tipad-t{margin:5px 0 0;font-size:21px;font-weight:800;line-height:1.35;letter-spacing:-.01em}
.tipad-sub{margin:9px 0 0;font-size:14.5px;line-height:1.65;color:#D7E2EF;word-break:keep-all}
.tipad-body{padding:16px 20px calc(18px + env(safe-area-inset-bottom))}
/* 약속 세 줄. ★칸(테두리 박스)으로 만들지 않는다 — 모달 안에 카드가 또 들어가면
   화면이 복잡해지고, 세 줄이 각각 «눌러야 하는 것»처럼 보인다. 얇은 구분선이면 충분하다. */
.tipad-pts{margin:0;padding:0;list-style:none;flex:1 1 auto;min-height:0;
  overflow-y:auto;-webkit-overflow-scrolling:touch}
.tipad-pts li{display:flex;gap:11px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line)}
.tipad-pts li:first-child{border-top:0;padding-top:2px}
.tipad-pts svg{width:19px;height:19px;flex:0 0 19px;margin-top:1px;color:var(--navy)}
.tipad-pt-t{display:block;font-size:14.5px;font-weight:700;color:var(--tx);line-height:1.45}
.tipad-pt-d{display:block;margin-top:3px;font-size:13px;line-height:1.6;color:var(--tx2);word-break:keep-all}
.tipad-go{margin-top:18px}
/* 「오늘 하루 보지 않기」 — ★일부러 작고 흐리다(main.php 주석 참조). 그래도 **찾을 수는 있어야** 하므로
   밑줄을 남긴다: 회색 글씨만 두면 고령 사용자에게는 «눌리는 것»으로 보이지 않는다.
   ★터치 표적 높이는 지킨다(padding 으로 40px 이상) — 작게 보이는 것과 못 누르는 것은 다르다. */
.tipad-day{display:block;margin:2px auto 0;border:0;background:none;padding:11px 8px;
  font-size:12.5px;color:var(--muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.tipad-day:hover{color:var(--tx2)}
@media (min-width:768px){
  .tipad .pmd-in{border-radius:var(--r-card)}
}
/* ★낮은 화면(360x640 같은 구형 폰)에서는 머리판을 줄인다.
   why: 머리판이 그대로면 목록 셋째 줄이 **한 픽셀도 안 보여** 「두 줄짜리 안내」로 읽힌다 —
   스크롤이 되는 줄을 모른다. 조금 줄여 셋째 줄이 걸치게 하면 그 자체가 «더 있다» 는 신호다. */
@media (max-height:700px){
  .tipad-hero{padding:16px 20px 14px}
  .tipad-badge{width:44px;height:44px;border-radius:13px}
  .tipad-badge svg{width:22px;height:22px}
  .tipad-eyebrow{margin-top:10px}
  .tipad-t{font-size:19px}
  .tipad-sub{margin-top:7px;font-size:13.5px}
}

/* ★★기기 알림이 꺼져 있을 때의 「받을 소식 고르기」 목록.
   why: 체크가 전부 켜져 있으면 사람은 "알림 켜짐" 으로 읽는다. 26-08-21 대표님이 정확히 그렇게
   읽고 저장까지 누르셨는데, 그 시점 기기 구독은 0건이라 알림은 한 통도 오지 않는 상태였다.
   ★끄지 않고 **흐리게만** 한다 — 설정 자체는 여전히 유효하다(다른 기기·나중에 켤 때 적용된다).
     `pointer-events:none` 을 주면 저장도 못 하게 되어 오히려 손해다. */
#noti_list.is-noti-off .check{opacity:.45}
#noti_list.is-noti-off .check + .check{margin-top:0}

/* ── 파일 선택 필드 (2026-08-22) ─────────────────────────────────────
   문제: 브라우저 기본 렌더가 **"Choose File / No file chosen"** 영문을 그린다.
   ★그 문구는 CSS 로 못 바꾼다(색만 칠해도 영문 그대로 — 실측). 그래서 입력을 숨기고
     `<label>` 을 버튼으로 쓴다. 마크업은 `mk_file_field()`(_layout.php)가 낸다.
   ★`verify.php` 가 쓰던 기존 패턴을 공용화한 것이라 새 방식이 아니다. */
.filepick{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.filepick-name{font-size:13px;color:var(--tx2);word-break:break-all}
/* 숨김 입력이 레이아웃을 차지하지 않게(.sr 은 기존 정의를 그대로 쓴다) */

/* ── 가로 스크롤 힌트 (2026-08-22) ───────────────────────────────────
   문제: 모바일(390px)에서 관리자 표와 필터 칩이 화면 밖으로 넘어가는데
         **잘린 것처럼만 보이고 스크롤된다는 신호가 없다**(캡처로 확인 —
         조합원 관리 '최근접속/조치' 열, 로그 '행위' 열, 자료실 칩 등).
   ★스크롤 자체는 이미 됐다(.tw/.chips 에 overflow-x:auto). 없던 건 **어포던스**다.
   ★★배경 그라디언트 방식은 버렸다 — 표는 헤더가 진한 남색이고 본문은 흰색이라
     같은 색 페이드가 한쪽에서 반드시 묻힌다(실제로 캡처에서 안 보였다).
     대신 **컨테이너에 그림자 오버레이**를 얹는다. 색과 무관하게 보인다.
   ★`position:sticky` 로 스크롤을 따라다니게 하지 않는다 — 스크롤 끝에서도 계속 떠 있으면
     거짓 신호가 된다. 대신 컨테이너 우측에 고정하고, 내용이 넘칠 때만 의미를 갖는다.
   ★모바일에서만 건다(데스크톱 1440 캡처에서는 안 잘린다). */
@media (max-width: 720px){
  .tw, .chips{ position:relative; }
  .tw::after, .chips::after{
    content:""; position:absolute; top:0; right:0; bottom:0; width:18px;
    pointer-events:none;
    background:linear-gradient(to left, rgba(22,48,79,.20), rgba(22,48,79,0));
  }
  /* 표는 카드가 overflow:hidden 이라 ::after 가 잘린다 → 스크롤 컨테이너 자체에 그림자 */
  .tw{ box-shadow:inset -14px 0 12px -12px rgba(22,48,79,.35); }
  .chips::after{ bottom:10px; }   /* 칩 아래 여백(padding)만큼 띄운다 */
}

/* ═══ 라운지 알림 종 (2026-08-22) ═══════════════════════════════════════
   ★.lounge 는 고정 높이 flex 컬럼이고 .lg-scroll{flex:1} 이 남는 높이를 흡수한다 —
     여기 줄을 하나 더해도 대화 영역이 알아서 줄어든다(--tab-h 토큰 계산과는 무관한 축이다). */
/* ★안내줄이 숨으면 종만 남는다 — 그때 헤더가 텅 빈 띠가 되지 않도록 오른쪽 정렬 */
/* ★★[2026-09-07] `flex-wrap:wrap` + 안내문 전용 줄.
   why: 종전에는 한 줄짜리 flex 라 안내문(`#push_state`)이 버튼들 사이에 끼어 **한 줄에 한 단어씩**
     접혔고, 「알림 켜기」 버튼과 겹쳐 보였다(390px 실캡처). 알림을 안 켠 사람에게 늘 보이는 자리라
     그냥 두면 라운지 첫인상이 깨진 화면이다.
   ★★**늘어나도 안전하다** — `.lounge` 는 높이가 `calc(100svh - …)` 로 고정이고 `overflow:hidden`,
     그 안에서 `.lg-scroll{flex:1}` 이 남는 높이를 먹는다. 즉 상단바가 두꺼워지면 **대화 영역이
     그만큼 줄 뿐** 입력바가 밀려나지 않는다(바로 아래 `.lg-bell` 주석의 판단과 같다).
     ★단 «두꺼워져도 된다»는 것이지 «두꺼워도 좋다»는 뜻은 아니다 — 문구는 짧게 유지한다
       (push.js 가 라운지 상단바에서는 **짧은 문구**를 쓴다). */
.lg-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px;padding:6px 10px;
  border-bottom:1px solid var(--line);background:var(--surface);min-height:44px}
/* ★★push.js 가 className 을 'alert mt-0 alert-warn' 등으로 **통째로 갈아끼운다.**
   그래서 클래스를 더 붙여 봐야 지워진다 — 자식 선택자(0,2,0)로 이겨야 한다. */
.lg-head .alert{flex:1 1 100%;min-width:0;margin:0;padding:0;background:none;border:0;
  font-size:12.5px;line-height:1.45;color:var(--tx2);word-break:keep-all}
.lg-head .alert.alert-warn{color:#8C2B20}
/* ★[2026-08-31] 높이 32 → 44(기획서 터치 최소). 상단바는 콘텐츠 높이로 늘어나므로
   막대가 12px 두꺼워진다 — 대화창이 그만큼 줄지만 늘 보이는 막대가 아니라 영향이 작다. */
.lg-bell{flex-shrink:0;min-height:44px;padding:0 12px;font-size:13px;gap:6px;
  border-radius:var(--r-pill);white-space:nowrap}
.lg-bell.is-off{color:var(--muted)}
.lg-bell.is-off svg{opacity:.55}

/* ═══ 라운지 사진 뷰어 (2026-08-22) ═══════════════════════════════════
   ★★`hidden` 으로 시작한다 — 전역 리셋의 `[hidden]{display:none !important}` 가 아래 flex 를 이긴다.
     그 한 줄이 없으면 판정 전에 검은 화면이 먼저 덮인다(이 코드베이스에서 이미 겪은 함정). */
.lg-view{position:fixed;inset:0;z-index:80;display:flex;align-items:center;justify-content:center;
  background:rgba(4,16,27,.92);padding:calc(12px + env(safe-area-inset-top)) 12px calc(12px + env(safe-area-inset-bottom))}
.lg-view-img{max-width:100%;max-height:100%;object-fit:contain;border-radius:6px}
.lg-view-x{position:absolute;top:calc(8px + env(safe-area-inset-top));right:8px;
  width:44px;height:44px;border:0;border-radius:50%;cursor:pointer;   /* ★44px = 손가락 최소 크기 */
  color:#fff;display:inline-flex;align-items:center;justify-content:center;
  /* ★★z-index 를 반드시 준다. 문서 뷰어의 상단 막대(.lg-view-bar)가 z-index:2 인 형제라
     이 값이 없으면 **막대가 닫기 버튼을 덮어 44px 중 아래 3px 만 눌린다**(26-08-22 대표 신고·실측 재현:
     X 정중앙을 elementFromPoint 로 찍으면 .lg-view-bar 가 잡혔다). 사진 뷰어는 막대를 감추므로
     증상이 문서에서만 나타나 원인을 찾기 어렵다. */
  z-index:3;
  /* ★★배경이 **흰색일 수 있다.** 원래는 `rgba(255,255,255,.14)` 였는데, 그건 "뒤가 항상 어둡다"는
     가정에 기대고 있었다. 문서 뷰어는 **흰 페이지가 이 버튼 밑으로 스크롤해 올라오고**(26-08-22 대표 신고),
     사진 뷰어도 흰 사진이면 같은 일이 난다. → 뒤가 무엇이든 스스로 보이도록
     **어두운 알약 + 밝은 테두리 + 그림자**로 바꾼다. 어두운 배경 위에서는 테두리가, 밝은 배경 위에서는
     알약이 형태를 만든다. 둘 중 하나에만 기대지 않는다. */
  background:rgba(0,0,0,.58);border:1px solid rgba(255,255,255,.45);
  box-shadow:0 2px 8px rgba(0,0,0,.45)}
.lg-view-x:hover{background:rgba(0,0,0,.74)}
/* 뷰어가 열리면 뒤 화면이 따라 움직이지 않게 */
html.is-view,html.is-view body{overflow:hidden}

/* ═══ 프로필 사진 자르기 (2026-08-22) ═══════════════════════════════════════
   ★★`hidden` 으로 시작한다 — 전역 리셋 `[hidden]{display:none !important}`(app.css:57)이
     아래 `display:flex` 를 이긴다. 라운지 사진 뷰어 `.lg-view`(app.css:613)와 같은 이유다.
   ★이름은 전부 `mkc-`/`js-mkc-`. 26-08-22 실측으로 코드베이스에 `crop`·`mkc` 가 0건임을 확인했다
     (장식용 클래스가 폼을 흔든 `.pw` 사고 예방).
   ★스크롤 잠금은 새로 만들지 않고 기존 `html.is-view`(app.css:621)를 그대로 쓴다. */
.mkc{position:fixed;inset:0;z-index:80;display:flex;flex-direction:column;
  background:rgba(4,16,27,.95);padding-top:env(safe-area-inset-top)}

/* 무대 — 사진 **전체**가 보이고 동그라미 안만 저장된다.
   ★why 동그라미 밖에도 사진을 보여주나: 얼굴이 창 밖으로 나갔을 때 **어느 쪽으로 끌어야 하는지**
     단서가 남아야 한다. 밖을 완전히 지우면 고령 사용자는 길을 잃는다(어둡게만 한다).
   ★★`touch-action:none` 이 없으면 브라우저가 스크롤·핀치를 먼저 먹어 **끌기가 아예 안 된다.**
     app.css 에 touch-action 규칙은 지금 한 줄도 없다 — 선례가 없으니 빠뜨리기 쉽다. */
.mkc-stage{position:relative;flex:1;min-height:150px;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.mkc-cv{display:block;width:100%;height:100%}

/* 저장되는 자리. 크기는 JS 가 style **프로퍼티**로 넣는다 —
   CSP(style-src 'self' 'nonce-…')는 인라인 style *속성* 을 막지만 CSSOM 대입은 막지 않는다. */
.mkc-ring{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  pointer-events:none;border-radius:50%;border:2px solid #fff;
  box-shadow:0 0 0 9999px rgba(4,16,27,.6)}

/* 안내문은 무대 위에 얹는다. ★why: 조작판에 두면 320px 기기에서 조작판이 438px 를 먹어
   동그라미가 110px 로 짜부라진다(26-08-22 실측). 무대로 올리면 282px 가 된다. */
.mkc-say{position:absolute;left:0;right:0;top:0;padding:12px 16px;pointer-events:none;
  background:linear-gradient(rgba(4,16,27,.78),rgba(4,16,27,0));transition:opacity .15s}
.mkc-say.is-dim{opacity:.12}          /* 손가락이 닿는 동안엔 얼굴을 가리지 않는다 */
.mkc-t{color:#fff;font-size:17px;font-weight:800;line-height:1.4;text-align:center;word-break:keep-all}
.mkc-hint{margin-top:3px;color:#E3ECF6;font-size:13px;line-height:1.45;text-align:center;word-break:keep-all}

/* 조작판 — 앱의 다른 화면과 같은 흰 바탕. 전체 반전 화면은 노안에서 읽는 속도가 느려진다. */
.mkc-ctl{flex-shrink:0;background:var(--surface);
  border-radius:var(--r-card) var(--r-card) 0 0;
  padding:14px 16px calc(14px + env(safe-area-inset-bottom))}
.mkc-zoom{display:flex;align-items:center;gap:9px}
.mkc-step{flex:0 0 auto;padding:0 12px}          /* .btn-lg(52px, app.css:181) 유지 */
/* ★`input[type=range]` 는 app.css:202~204 의 타입 열거에 없어 브라우저 기본 렌더다.
   **일부러 그대로 둔다** — 보이스오버·톡백이 읽고 좌우 방향키가 동작한다.
   ::-webkit-slider-thumb 을 키우려면 -webkit-appearance:none 이 필요하고 그 순간
   트랙까지 전부 직접 그려야 한다. 그 교환은 하지 않는다. */
.mkc-range{flex:1;min-width:0;height:44px;background:none;border:0;accent-color:var(--navy)}
.mkc-mid{display:flex;align-items:center;gap:10px;margin-top:12px}
.mkc-prev{flex-shrink:0;width:56px;height:56px;border-radius:50%;
  background:#fff;border:1px solid var(--line)}
.mkc-midtx{flex:1;min-width:0;font-size:14px;font-weight:700;line-height:1.35;word-break:keep-all}
.mkc-mid .btn{flex-shrink:0}
.mkc-esc .btn{flex:1;min-width:0}
.mkc-ok[aria-disabled="true"]{opacity:.55;pointer-events:none}
/* ── 라운지 대화 검색줄 [2026-08-23] ──────────────────────────────────────────
   ★막대형이다(전면 오버레이 아님) — `.lg-scroll{flex:1}` 이 높이를 흡수하므로 줄이 하나 늘어도
     입력바가 밀리지 않는다. `.lg-head` 안에 우겨넣지 않은 이유: 거긴 `#push_state{flex:1}` 이
     폭을 다 먹고, push.js 가 그 className 을 통째로 갈아끼운다(app.css:624).
   ★★낮은 화면(가로 폰) 회귀 주의 — `@media (max-height:520px){.lounge{min-height:0}}`(app.css:616)의
     임계 520 을 조이지 말 것. 증상만 하단탭으로 옮겨간다(26-08-22 실측). */
.lg-find{flex-shrink:0;background:var(--surface);border-bottom:1px solid var(--line);
  padding:8px 10px;display:flex;flex-direction:column;gap:6px}
.lg-find-row{display:flex;align-items:center;gap:8px}
.lg-find-q{flex:1;min-width:0;height:44px;padding:0 12px;font-size:16px;   /* ★16px 미만이면 iOS 가 확대한다 */
  border:1px solid var(--field-line);border-radius:10px;background:#fff;color:var(--ink)}
.lg-find-q:focus{outline:2px solid var(--navy);outline-offset:-1px}
.lg-find-nav{justify-content:flex-end}
.lg-find-cnt{flex:1;min-width:0;font-size:14px;color:var(--muted);word-break:keep-all}
.lg-find-cnt.bad{color:#8C2B20}
/* ★44px = 손가락 최소 크기(app.css:641 과 같은 근거). 아이콘만 두지 않고 글자를 함께 둔다. */
.lg-find-b{min-height:44px;padding:0 12px;gap:4px;flex-shrink:0}
.lg-find-b[disabled]{opacity:.45;pointer-events:none}
/* 검색어가 걸린 말풍선.
   ★★처음엔 `.me` 만 흰 테두리로 뒤집었는데 **안 보였다**(실측): outline 은 말풍선 **바깥**에
     그려지고 그 바깥은 흰 페이지라 흰 테두리가 묻힌다. 남색으로 두면 남색 말풍선과 붙어 구분이 안 된다.
     → 두 경우 모두 브랜드 강조색으로 그린다. 흰 말풍선·남색 말풍선 어디에서도 페이지 배경과 대비된다. */
.lg-row.is-hit .lg-bubble{outline:2px solid var(--accent);outline-offset:2px}
/* 검색 입력의 **브라우저 기본 지우기(×)** 를 끈다 — 옆에 둔 닫기(×)와 나란히 놓여
   "어느 쪽이 검색을 닫는 건가"를 헷갈리게 한다(실측 캡처에서 X 가 두 개로 보였다). */
.lg-find-q::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
/* 본문 안 일치 글자 강조. ★`mark` 기본 노랑은 브랜드와 겉돌아 직접 지정한다. */
.lg-hl{background:#FFE9A8;color:inherit;border-radius:3px;padding:0 1px}
.lg-row.me .lg-hl{background:#FFD24D;color:#101820}

/* 가로화면 폰 — 세로로 쌓으면 무대가 150px 로 짜부라진다 */
@media (orientation:landscape) and (max-height:520px){
  .mkc{flex-direction:row}
  .mkc-ctl{width:min(58%,380px);border-radius:0;overflow:auto}
  /* ★★여기 있던 `.mkc-say{position:static;background:none;padding:0 0 8px}` 을 뺐다(26-08-22).
     `.mkc-stage` 가 flex 라 `static` 이 되는 순간 안내문이 **캔버스의 flex 형제**가 되고,
     넘친 만큼을 `justify-content:center` 가 양쪽으로 나눠 **캔버스만 왼쪽으로 29.4px 밀렸다.**
     링은 무대 기준 `left:50%` 라 안 밀리는데 저장은 캔버스 중심 기준이라(crop.js) →
     **동그라미에 맞춘 것과 저장되는 것이 640px 출력에서 51px(약 8%) 어긋났다.**
     에러도 로그도 없이 틀린 결과가 저장되는 유형이라 세로와 같은 처리(absolute + 그라디언트 스크림)로 되돌린다.
     ★`background:none` 만 남기는 부분수정은 하지 말 것 — 스크림이 사라져 사진 위 흰 글씨가 안 읽힌다. */
}
/* ★★넓은 화면(PC) — 26-08-22 대표 보고 "PC에서 이상함".
   위 가로화면 규칙은 `max-height:520px` 이라 1440x900 데스크톱에는 **안 걸린다.**
   그래서 폰 세로 배치가 그대로 펴져 조작판이 화면 폭을 다 먹었다
   (1440px 실측: 「이 사진으로 하기」 1408px · 슬라이더 1200px · 미리보기와 「돌리기」가 양 끝으로 갈라짐).
   무대와 조작판을 같은 폭의 가운데 카드로 묶는다. 폰 배치는 건드리지 않는다.
   ★`.mkc-stage` 의 `flex:1` 을 basis 로 바꿔야 세로로 무한히 늘어나지 않는다. */
@media (min-width:760px) and (min-height:620px){
  .mkc{align-items:center;justify-content:center;padding:28px 16px}
  .mkc-stage,.mkc-ctl{width:min(520px,100%)}
  /* ★높이는 동그라미(RMAX 400) + 위아래 여백 20px 씩 = 440. 520 으로 두면 사진 아래에
     **빈 띠**가 남는다(1440x900 캡처로 확인) — 사진은 동그라미에 맞춰 그려지므로
     무대가 그보다 크면 그만큼이 빈다. */
  .mkc-stage{flex:0 1 440px;min-height:240px;
    border-radius:var(--r-card) var(--r-card) 0 0}
  .mkc-ctl{border-radius:0 0 var(--r-card) var(--r-card);padding-bottom:14px}
}
@media (prefers-reduced-motion:reduce){ .mkc-say{transition:none} }

/* ═══ 라운지 문서(PDF) 첨부 [2026-08-22] ═══════════════════════════════════
   ★★`.lg-bubble.has-img` 를 **문서에는 붙이지 않는다.** 그 규칙은
     `padding:5px;background:transparent;border:0` 이라(app.css:447) 사진용이다 —
     문서 카드에 붙으면 배경과 테두리를 잃어 글자가 대화창에 그냥 떠 있게 된다.
   ★대신 `has-doc` 으로 여백만 줄인다: **말풍선 자체가 카드**이고, 안에 미리보기와 이름을 담는다.
   ★★미리보기 높이를 세로 원본 비율(1:1.3)로 두면 카드가 260×338 이 되어 **대화창을 통째로 먹는다**
     (26-08-22 첫 캡처에서 실제로 그랬다). 1쪽 **윗부분만** 잘라 보여준다 — 제목이 거기 있다. */
/* ★★[2026-08-27] 242 = 카드 228 + 좌우 패딩 7×2 (전역 box-sizing:border-box) */
.lg-bubble.has-doc{padding:6px 7px 7px;max-width:242px}
/* ★★옛 `width:min(228px,58vw)` 는 **화면 폭**을 기준 삼아 '행에 남은 자리'를 몰랐다.
   `.lg-col{min-width:0}` 로 말풍선은 줄어드는데 카드는 고정폭이라 같이 안 줄어 밖으로 삐져나갔고,
   시각·답장 버튼 위에 그대로 겹쳐 그려졌다(실측 412px 폰에서 50px 삐져나감·41px 겹침, 480px+ 만 정상).
   ★vw 계수를 조정해 맞추려 하지 말 것 — 화면 폭과 남는 자리는 비례하지 않아 어느 구간에서 또 어긋난다.
   ★★`width:228px` + `max-width:100%` 순서가 중요하다. 반대로 `width:100%;max-width:228px` 로 쓰면
     **카드에 고유폭이 없어져** 말풍선이 내용만큼 쪼그라들고(실측 34px) 카드도 18px 로 딸려 줄었다.
     확정 px 를 `width` 에 둬야 말풍선이 242px 로 잡히고, `max-width:100%` 가 좁을 때만 줄여 준다. */
.lg-doc{display:block;width:228px;max-width:100%;background:transparent;border:0;padding:0;
  cursor:pointer;text-align:left;color:inherit}
.lg-doc-thumb{display:block;width:100%;aspect-ratio:1/0.62;object-fit:cover;object-position:top center;
  background:#fff;border:1px solid var(--line);border-radius:8px}
.lg-row.me .lg-doc-thumb{border-color:rgba(255,255,255,.28)}
.lg-doc-info{display:flex;align-items:center;gap:8px;padding:7px 2px 0}
.lg-doc.no-thumb .lg-doc-info{padding-top:0}
.lg-doc-ico{flex:0 0 auto;color:var(--accent)}
.lg-row.me .lg-doc-ico{color:rgba(255,255,255,.9)}
.lg-doc-txt{min-width:0;flex:1 1 auto}
/* ★파일명은 한 줄로 자른다 — 「2026년_정기총회_안건자료_최종_수정본.pdf」 가 카드를 세로로 늘린다 */
.lg-doc-name{display:block;font-size:13.5px;font-weight:700;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lg-doc-sub{display:block;font-size:11.5px;color:var(--muted);margin-top:1px}
.lg-row.me .lg-doc-sub{color:rgba(255,255,255,.75)}

/* ── 문서 뷰어 — 사진 뷰어(.lg-view)를 함께 쓴다 ─────────────────────────
   ★why 세로 스크롤인가: 이전/다음 버튼보다 손가락 스크롤이 빠르고, 쪽수가 몇 장이든
     같은 조작이다. `loading="lazy"` 라 보이는 쪽만 서버가 렌더한다. */
.lg-view-doc{width:100%;height:100%;overflow-y:auto;overflow-x:hidden;
  -webkit-overflow-scrolling:touch;padding:56px 8px calc(16px + env(safe-area-inset-bottom))}
.lg-view-doc img{display:block;width:100%;max-width:820px;margin:0 auto 10px;
  background:#fff;border-radius:4px;min-height:120px}
/* 상단 막대 — 파일명·내려받기. ★닫기 버튼(.lg-view-x)과 겹치지 않게 오른쪽을 비워 둔다 */
/* ★★막대 자체는 **그라디언트 장식**이다 — 화면 폭 전체 × 49px 를 차지하면서 탭을 먹으면
   ①닫기 버튼을 가리고 ②**손가락을 화면 위쪽에서 시작하는 스크롤이 통째로 막힌다**(문서는 세로로 넘긴다).
   그래서 막대는 `pointer-events:none` 으로 통과시키고, **실제 컨트롤만** 되살린다. */
.lg-view-bar{position:absolute;top:0;left:0;right:0;z-index:2;display:flex;align-items:center;gap:10px;
  padding:calc(8px + env(safe-area-inset-top)) 64px 20px 12px;pointer-events:none;
  /* ★★원래 `linear-gradient(rgba(0,0,0,.62), transparent)` 였다 — **흰 문서 위에서 무너진다.**
     그라디언트가 49px 에서 투명해지는데 닫기 버튼은 52px 까지 내려오고, 그 밑으로 **흰 페이지가
     스크롤해 올라온다** → 흰 글씨·흰 아이콘이 흰 바탕에 놓인다(26-08-22 대표 신고, 캡처로 확인).
     → 컨트롤이 놓이는 구간(88%)까지는 **불투명**하게 깔고, 마지막 12%만 부드럽게 푼다.
     ★문서 뷰어는 세로 스크롤이 조작의 전부라 이 막대가 늘 보이는 편이 낫다(닫는 법이 항상 눈에 있다). */
  background:linear-gradient(180deg,rgba(10,20,30,.92) 0,rgba(10,20,30,.92) 88%,rgba(10,20,30,0) 100%);
  color:#fff}
.lg-view-bar .lg-view-dl{pointer-events:auto}
/* ★막대가 사라지는 경우를 대비한 2차 방어 — 글자 자체도 흰 바탕에서 읽히게 */
.lg-view-name{text-shadow:0 1px 3px rgba(0,0,0,.75)}
.lg-view-name{min-width:0;flex:1 1 auto;font-size:13px;font-weight:700;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ★닫기 버튼과 같은 이유로 어둡게 — 흰 페이지가 밑으로 지나가도 읽혀야 한다 */
.lg-view-dl{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;
  background:rgba(0,0,0,.58);color:#fff;border:1px solid rgba(255,255,255,.45);border-radius:999px;
  padding:6px 12px;font-size:12.5px;font-weight:700;cursor:pointer;text-decoration:none;
  box-shadow:0 2px 8px rgba(0,0,0,.45)}
.lg-view-dl:hover{background:rgba(0,0,0,.74)}
@media (max-width:380px){ .lg-view-dl span{display:none} }

/* ═══ 라운지 음성 [2026-09-01] ═══════════════════════════════════════════
   ★브라우저 기본 `<audio controls>` 를 그대로 쓴다 — 직접 만들면 재생·탐색·배속·잠금화면 제어를
     전부 다시 만들어야 한다. 여기서는 **폭만** 잡아 준다.
   ★★`width:228px` + `max-width:100%` 순서를 지킨다. 반대로 쓰면 카드에 고유폭이 없어져
     말풍선이 내용만큼 쪼그라든다 — `.lg-doc` 주석의 실측 사례와 같은 함정이다.
   ★★크롬은 `<audio>` 가 좁아지면 **탐색 막대부터 줄인다** — 236px 에서는 막대가 몇 px 짜리
     실선이 돼 손가락으로 잡을 수가 없었다(실측). 그래서 문서·동영상 카드보다 넓은 262px 을 준다.
     320px 화면에서도 넘치지 않는다(실측: 말풍선 오른쪽 끝 306px, 가로 스크롤 없음).
     회의 녹음은 되감기가 핵심이라 이 폭을 줄이지 말 것. */
.lg-bubble.has-aud{padding:6px 7px 7px;max-width:276px}
.lg-aud{display:block;width:262px;max-width:100%}
.lg-aud-el{display:block;width:100%;height:36px;margin:5px 0 3px}
/* 파일명은 한 줄로 자른다 — 「2026-08-30 조합 임원회의 녹음.m4a」 가 카드를 세로로 늘린다 */
.lg-aud-name{display:block;font-size:13.5px;font-weight:700;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lg-aud-sub{display:block;font-size:11.5px;color:var(--muted)}
/* ★★320px 폰(iPhone SE)에서 **받은** 말풍선만 잘린다 — 내 말풍선과 달리 왼쪽에 아바타(36px)와
   간격(9px)이 붙어 시작점이 55px 이기 때문이다(실측: 오른쪽 끝 331px > 화면 320px).
   ★`max-width:100%` 로는 안 줄어든다 — 퍼센트가 들어간 max-width 는 flex 기초크기 계산에서
     무시된다(이 파일 `.lg-img` 주석의 실측 사례와 같은 함정). **확정 px 로만** 줄일 수 있다.
   ★360px 이상은 그대로 262px 을 쓴다(오른쪽 끝 331px < 360px). 탐색 막대는 넓을수록 좋다.
   ★★남은 한계: **320px 에서는 탐색 막대가 20px 남짓한 토막**이 된다(크롬이 스스로 접는다).
     아바타·간격이 55px 을 가져가는 한 이 폭에서 둘 다 만족시킬 수 없다 — 잘리는 쪽을 버렸다.
     360px 이상(요즘 폰 대부분)에서는 정상 폭이다. 되감기가 안 된다는 신고가 오면 기종부터 물을 것. */
@media (max-width:359px){
  .lg-bubble.has-aud{max-width:246px}
  .lg-aud{width:232px}
}
/* ★내 말풍선(남색)에서는 부가정보가 묻힌다 — 대비를 되돌린다 */
.lg-row.me .lg-aud-sub{color:rgba(255,255,255,.78)}

/* ═══ 라운지 동영상 [2026-08-22] ═══════════════════════════════════════════
   ★말풍선은 **첫 장면 + 재생버튼 + 길이 배지** 세 개다(카카오톡과 같은 구성).
   ★`has-img`(배경·테두리 제거)를 붙이지 않는다 — 문서 카드와 같은 이유. `has-vid` 로 여백만 줄인다. */
/* ★250 = 카드 240 + 좌우 패딩 5×2. 사유는 `.lg-doc` 주석 참조(같은 문제·같은 해법) */
.lg-bubble.has-vid{padding:5px;max-width:250px}
.lg-vid{position:relative;display:block;width:240px;max-width:100%;border:0;padding:0;background:transparent;cursor:pointer}
/* ★세로 영상(요즘 휴대폰 기본)이 카드를 세로로 길게 늘이지 않게 최대 높이를 둔다 */
.lg-vid-img{display:block;width:100%;max-height:300px;object-fit:cover;border-radius:9px;
  background:#0B1622;border:1px solid var(--line)}
.lg-row.me .lg-vid-img{border-color:rgba(255,255,255,.25)}
/* 썸네일을 못 뽑았을 때도 카드가 무너지지 않게 자리를 잡아 준다 */
.lg-vid.no-thumb .lg-vid-img{aspect-ratio:16/9;object-fit:none}
/* ★★재생버튼·배지는 `pointer-events:none` — 카드 전체가 누르는 곳이라
   이것들이 탭을 가로채면 "가운데만 안 눌리는" 이상한 카드가 된다. */
.lg-vid-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.55);border:1px solid rgba(255,255,255,.5);color:#fff;
  box-shadow:0 2px 10px rgba(0,0,0,.45);pointer-events:none}
.lg-vid-dur{position:absolute;right:7px;bottom:7px;padding:2px 7px;border-radius:999px;
  background:rgba(0,0,0,.66);color:#fff;font-size:11.5px;font-weight:700;pointer-events:none}

/* ── 업로드 진행 막대 — 입력바 바로 위 ────────────────────────────────
   ★★why 별도 줄인가: 기획서가 "진행률을 반드시 보여 준다"고 못박았다(조합원 다수가 40~70대,
     300MB 를 올리는 몇 분 동안 아무 표시 없는 화면을 견디지 못한다).
   ★`note()` 줄에 쓰지 않는다 — 그 한 줄은 연결상태·쓰기정지와 공유되고 이미 덮어쓰기 사고를 처리한 자리다. */
.lg-up{display:flex;align-items:center;gap:10px;padding:9px 12px;
  background:var(--surface);border-top:1px solid var(--line)}
.lg-up-tx{flex:1 1 auto;min-width:0}
.lg-up-name{display:block;font-size:12.5px;font-weight:700;line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lg-up-bar{margin-top:5px;height:6px;border-radius:999px;background:var(--line);overflow:hidden}
.lg-up-bar > i{display:block;height:100%;width:0;background:var(--navy);transition:width .25s}
.lg-up-pct{flex:0 0 auto;min-width:40px;text-align:right;font-size:12.5px;font-weight:700;color:var(--tx2)}
/* 취소는 44px 손가락 크기를 지킨다 */
.lg-up-x{flex:0 0 auto;width:44px;height:44px;border:0;background:none;color:var(--muted);
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border-radius:50%}
.lg-up-x:hover{background:rgba(22,48,79,.08)}

/* ── 뷰어 안 재생기 ──────────────────────────────────────────────────── */
.lg-view-vid{max-width:100%;max-height:100%;border-radius:6px;background:#000}
/* 뷰어 안 재생실패 안내 [2026-08-22] — 대화창 알림줄은 뷰어(z-index:80)가 덮어 안 보인다 */
.lg-view-err{position:absolute;left:16px;right:16px;top:50%;transform:translateY(-50%);
  margin:0;padding:16px 18px;border-radius:12px;text-align:center;line-height:1.65;
  background:rgba(12,22,33,.92);border:1px solid rgba(255,255,255,.28);color:#fff;font-size:14.5px}
.lg-view-err strong{color:#fff}

/* ═══ @멘션 [2026-08-22] ═══════════════════════════════════════════════════
   ★목록은 입력바 **바로 위**에 뜬다 — 손가락이 닿는 자리다. 최대 높이를 두어 화면을 덮지 않는다. */
.lg-at{max-height:210px;overflow-y:auto;background:var(--surface);
  border-top:1px solid var(--line);box-shadow:0 -6px 16px rgba(22,48,79,.10)}
.lg-at button{display:flex;align-items:center;gap:10px;width:100%;min-height:48px;
  padding:0 14px;border:0;background:none;cursor:pointer;text-align:left;
  font-size:15px;font-weight:700;color:var(--tx)}
.lg-at button:hover,.lg-at button[aria-selected="true"]{background:rgba(22,48,79,.07)}
.lg-at .at-x{flex:0 0 auto;color:var(--muted);font-weight:800}
.lg-at .at-none{padding:14px;color:var(--muted);font-size:14px;text-align:center}
/* 말풍선 안에서 부른 이름을 눈에 띄게 — 내 이름이 불렸는지 훑어보며 알 수 있어야 한다 */
.lg-at-tag{font-weight:800;color:var(--navy);background:rgba(22,48,79,.10);
  border-radius:4px;padding:0 3px}
.lg-row.me .lg-at-tag{color:#fff;background:rgba(255,255,255,.22)}

/* ── 회원 콘텐츠 푸터 (2026-08-24) — 법정문서 접근성(개인정보처리방침 상시 노출).
   ★하단 탭바(sticky) 위 스크롤 영역에 온다. 라운지(풀스크린)엔 mk_shell_close(['nofoot'=>1]) 로 미표시. */
/* ★★[2026-09-05] 아래 여백은 **장식이 아니라 AI 버튼(#mw-chat)을 피하려고 둔 것**이다.
   그 버튼은 `position:fixed` 라 스크롤을 끝까지 내리면 푸터 마지막 줄 위에 그대로 얹힌다.
   실측(320px): 버튼은 화면 아래에서 82~144px 을 차지한다(PC 는 24~86px).
   조합사무실 줄이 늘면서 「운영진 자율 운영(조합 비공식)」이 버튼에 가려 안 읽혔다.
   → 마지막 줄이 버튼 **위쪽**에서 끝나도록 아래 여백을 그 높이만큼 준다.
   ★줄이지 말 것. 줄이면 그 자리에서 다시 가려진다. 값을 바꿀 거면 `#mw-chat` 의 bottom 과 함께 잰다. */
.mfoot{margin-top:28px;padding:16px 4px calc(150px + env(safe-area-inset-bottom));
  border-top:1px solid var(--line);text-align:center}
@media (min-width:1024px){          /* PC 는 탭바가 없어 버튼이 더 아래에 앉는다 */
  .mfoot{padding-bottom:calc(96px + env(safe-area-inset-bottom))}
}
/* 푸터의 「글씨 크기」 줄  [2026-09-07 대표 지시로 상시 노출]
   ★★이 버튼들은 `--fs` 를 **따르지 않는다** — 크기를 고르는 조작부가 고른 값을 따라 커지면
     「아주 크게」에서 한 줄에 안 들어간다(`.fs-opt` 와 같은 이유).
   ★좁은 폭에서는 라벨과 버튼이 자연스럽게 다음 줄로 접힌다(`flex-wrap`) — 푸터는 세로로 늘어도
     아래 콘텐츠를 밀지 않는다(문서 끝이다). 그래서 여기서는 wrap 이 안전한 선택이다. */
.mfoot-fs{display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap;
  margin-bottom:14px}
.mfoot-fs .mfoot-lb{font-size:13px;font-weight:600;color:var(--tx);white-space:nowrap;margin-right:2px}
.mfoot-fsb{min-height:40px;padding:0 14px;font-size:14px;font-weight:600;white-space:nowrap;
  border:1px solid var(--line);border-radius:var(--r-pill);background:var(--surface);color:var(--tx2)}
.mfoot-fsb.is-on{background:var(--navy);border-color:var(--navy);color:#fff}
.mfoot-links{display:flex;gap:8px;justify-content:center;align-items:center;flex-wrap:wrap;
  font-size:13px;line-height:1.6}
.mfoot-links a{color:var(--tx2);text-decoration:none}
.mfoot-links a:hover{text-decoration:underline}
.mfoot-links span{color:var(--line)}
/* 조합사무실 위치·연락처 (2026-09-05 대표 지시).
   ★`<address>` 의 브라우저 기본 기울임을 끈다 — 안 끄면 여기만 혼자 이탤릭으로 뜬다.
   ★flex+wrap: 320px 에서는 주소가 길어 줄이 바뀐다. 「조합사무실」 라벨과 전화번호는
     nowrap 으로 묶어 **가운데서 끊기지 않게** 한다 — 전화번호가 두 줄로 갈리면 못 읽는다.
   ★전화는 눌러서 거는 링크라 본문(11px)보다 키우고 색을 살린다. */
/* ★★[2026-09-05 대표 지적] 주소·버튼·전화를 **한 줄에 늘어놓지 않는다.** 그러면
   「지도 보기」가 전화번호에 붙어 전화에 딸린 버튼처럼 읽힌다. 두 줄(`.mfoot-arow`)로 나눈다.
   ★버튼은 주소와 **같은 줄**에 남긴다 — 둘 다 주소를 다루는 것이라 붙어 있어야 뜻이 통한다. */
.mfoot-addr{margin-top:10px;font-style:normal;
  font-size:12px;color:var(--tx2);line-height:1.6}
.mfoot-arow{display:flex;flex-wrap:wrap;gap:4px 8px;
  justify-content:center;align-items:center}
.mfoot-arow + .mfoot-arow{margin-top:6px}
.mfoot-addr .mfoot-lb{white-space:nowrap;font-weight:600;color:var(--tx)}
.mfoot-addr a{white-space:nowrap;color:var(--navy);text-decoration:none;font-weight:600}
.mfoot-addr a:hover{text-decoration:underline}
/* 주소 복사·지도 보기 — 작지만 **손가락으로 눌러야 한다.** 글자는 11px 로 줄이되
   상하 패딩으로 높이를 24px 이상 확보한다(고령 조합원이 많다).
   ★`.mfoot-map` 은 `<a>` 라 바로 위 `.mfoot-addr a`(전화번호용 남색 굵은 글씨)를 물려받는다 —
     여기서 되돌리지 않으면 버튼이 아니라 파란 글씨 링크로 보인다. 그래서 한 묶음으로 적는다. */
.mfoot-copy,.mfoot-map{flex:none;border:1px solid var(--line);background:var(--surface);
  color:var(--tx2);font:inherit;font-size:11px;font-weight:600;line-height:1;
  padding:6px 9px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;
  text-decoration:none}
.mfoot-copy:hover,.mfoot-map:hover{border-color:var(--field-line);color:var(--tx);
  text-decoration:none}
.mfoot-copy:active,.mfoot-map:active{background:var(--bg)}
.mfoot-note{margin-top:8px;font-size:11px;color:var(--tx2);line-height:1.5}

/* ══ 은은한 고급 폴리시 (2026-08-24, 대표 지시: 회원 화면을 동적·인터랙티브하게) ══
   ★회원 화면 공통 모션. prefers-reduced-motion 은 위 전역 블록(*{animation/transition .01ms !important})이
     자동으로 끄므로 개별 대응 불필요. ★관리(.adm) 화면은 제외 — 차분하게 둔다.
   ★CSS 만으로 구현(외부 라이브러리 CSP 차단·성능). transform/opacity 라 GPU 친화적. */
@keyframes mkRise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* 콘텐츠 블록이 진입 시 아래서 살짝 떠오르며 순차 등장 = 매끄러운 화면 전환감 */
.app:not(.adm) .wrap > *{animation:mkRise .42s cubic-bezier(.22,.61,.36,1) both}
.app:not(.adm) .wrap > *:nth-child(2){animation-delay:.05s}
.app:not(.adm) .wrap > *:nth-child(3){animation-delay:.10s}
.app:not(.adm) .wrap > *:nth-child(4){animation-delay:.15s}
.app:not(.adm) .wrap > *:nth-child(5){animation-delay:.20s}
.app:not(.adm) .wrap > *:nth-child(n+6){animation-delay:.24s}
/* 눌림 피드백(미세 스케일) — 마우스·터치 공통. :disabled 은 제외 */
.btn{transition:transform .1s ease,background .12s ease,border-color .12s ease}
.btn:active:not(:disabled):not([aria-disabled=true]){transform:scale(.97)}
.tabs a{transition:transform .12s ease,color .12s ease}
.tabs a:active{transform:scale(.9)}
.list a{transition:background .12s ease,transform .1s ease}
.list a:active{transform:scale(.99)}

/* ══ 조합원 목록 [2026-08-30] ═══════════════════════════════════
   ★237명을 한 화면에 쭉 내린다 — 무한스크롤·가상스크롤을 만들지 않는다(그 규모가 아니다).
   ★터치 타깃 최소치를 행 높이로 확보한다(고령 사용자). */
.mb-wrap{padding:12px 14px 20px}
.mb-search{display:flex;gap:6px;margin-bottom:10px}
.mb-search input{flex:1;min-height:44px;padding:0 12px;border:1px solid var(--line);
  border-radius:var(--r-pill);background:var(--surface);font-size:15px}
.mb-search button{min-height:44px;padding:0 16px;border-radius:var(--r-pill);
  background:var(--navy);color:#fff;border:0;font-size:14px;white-space:nowrap}
.mb-clear{display:flex;align-items:center;padding:0 10px;color:var(--tx2);font-size:13px;white-space:nowrap}
.mb-count{margin:0 2px 8px;font-size:13px;color:var(--muted)}
.mb-empty{margin:28px 0;text-align:center;color:var(--muted);font-size:14px}
.mb-list{list-style:none;margin:0;padding:0;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden}
.mb-item{display:flex;align-items:center;gap:10px;min-height:56px;padding:8px 12px;
  border-top:1px solid var(--line)}
.mb-list .mb-item:first-child{border-top:0}
.mb-name{flex:1;min-width:0;font-size:15px;color:var(--tx);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-noname{color:var(--muted)}
/* 「나」 표시 — 목록에서 자기를 빨리 찾게 */
.mb-me{margin-left:6px;padding:1px 6px;border-radius:var(--r-pill);
  background:var(--bg);color:var(--tx2);font-size:11px;vertical-align:middle}

/* ══ 1:1 채팅 (2026-08-30) ═══════════════════════════════════════
   ★대화창(dm_room.php)은 **라운지 CSS 를 그대로 쓴다** — 여기 있는 건 목록·머리줄뿐이다. */
.dm-empty{padding:40px 16px;text-align:center;color:var(--tx2);line-height:1.7}
.dm-list{list-style:none;margin:0;padding:0}
.dm-list li + li{border-top:1px solid var(--line)}
.dm-item{display:flex;align-items:center;gap:11px;padding:12px 14px;text-decoration:none;color:inherit;
  min-height:64px}
.dm-item:active{background:var(--bg)}
.dm-av{flex:0 0 auto}
.dm-body{flex:1;min-width:0}
.dm-top{display:flex;align-items:baseline;gap:8px}
.dm-name{font-size:15px;color:var(--tx);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dm-at{margin-left:auto;font-size:11px;color:var(--muted);white-space:nowrap;flex:0 0 auto}
.dm-prev{display:block;font-size:13px;color:var(--tx2);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dm-tag{font-size:11px;color:var(--muted);font-weight:400}
.dm-badge{flex:0 0 auto;min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--accent);
  color:#fff;font-size:11px;line-height:20px;text-align:center;font-weight:600}
/* 대화창 머리줄 — 상대 이름과 차단 버튼 */
.dm-head{display:flex;align-items:center;gap:9px;padding:8px 12px;border-bottom:1px solid var(--line);
  background:var(--surface)}
/* ★[2026-08-31] 36px 이라 기획서의 **터치 최소 44px** 에 미달했다. 자주 누르는 버튼이라 44px 로 올린다.
   ★같은 줄의 `.lg-bell`(검색)이 이미 min-height:44px 라 머리줄 높이는 그대로다 — 레이아웃 안 밀린다. */
.dm-back{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;
  color:var(--tx2);text-decoration:none}
.dm-head-name{font-size:15px;font-weight:600;color:var(--tx);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;flex:1;min-width:0}
.dm-block{margin-left:auto;flex:0 0 auto}
.dm-blocked{padding:14px;text-align:center;color:var(--tx2);font-size:13px;background:var(--bg);
  border-top:1px solid var(--line);line-height:1.6}
/* ★[2026-08-31 전화면 UI 점검] 34px 이라 기획서의 **터치 최소 44px** 에 미달했다(60곳에 쓰인다).
   ★높이만 키우고 글자·테두리·색은 그대로 둔다 — 행 높이(57px)에 44px 이 들어가 레이아웃은 안 밀린다.
   ★`inline-flex` 로 글자를 세로 가운데 둔다. 세로 padding 을 없애야 44px 이 정확히 맞는다. */
.mb-dm{margin-left:auto;flex:0 0 auto;font-size:12px;padding:0 14px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:var(--r-pill);color:var(--navy);background:var(--surface)}

/* ══ 프로필 사진 크게 보기 (공용 — assets/js/photoview.js) ═══════════
   ★라운지 첨부 뷰어(.lg-view 계열)와 **별개**다. 저건 동영상·PDF·히스토리까지 얽힌 큰 장치이고
     이건 사진 한 장만 본다. 역할이 다르므로 클래스도 섞지 않는다. */
.av-zoom{cursor:zoom-in}
.av-zoom:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.pv{position:fixed;inset:0;z-index:1200;background:rgba(16,24,32,.92);
  display:flex;align-items:center;justify-content:center;padding:24px}
.pv-img{max-width:100%;max-height:100%;border-radius:10px;object-fit:contain}
.pv-x{position:absolute;top:14px;right:14px;min-width:60px;min-height:44px;padding:0 14px;
  border:0;border-radius:var(--r-pill);background:rgba(255,255,255,.16);color:#fff;
  font-size:14px;cursor:pointer}
.pv-x:active{background:rgba(255,255,255,.28)}
/* 배경이 뒤에서 스크롤되지 않게 — 모달이 열린 동안만 */
html.pv-on,html.pv-on body{overflow:hidden}

/* ── 「나 관련」 필터  [2026-08-31] ─────────────────────────────────────────
   ★필터 중임을 **버튼 색으로** 알린다. 목록이 갈아끼워지므로 «지금 전체가 아니다» 가
     보이지 않으면 조합원이 «대화가 사라졌다» 고 오해한다. */
.lg-bell[aria-pressed="true"]{background:var(--navy);color:#fff;border-color:var(--navy)}
.lg-bell[aria-pressed="true"] svg{stroke:#fff}
/* 왜 걸렸는지 — 말풍선 위 작은 표시. 색은 배지(--accent)와 구분되게 남색 계열. */
.lg-why{display:inline-flex;align-items:center;gap:3px;margin-bottom:3px;padding:1px 7px;
  border-radius:9px;background:#E8EDF4;color:#16304F;font-size:11px;font-weight:700;line-height:1.6}
.lg-row.me .lg-why{background:#DCE4EE}

/* ── 스크랩(담아두기)  [2026-08-31] ────────────────────────────────────────
   ★담긴 상태를 **글자(담기/담김) + 굵기 + 색** 셋으로 알린다. 색만으로 가르면 색각 이상 사용자가
     구분하지 못한다(이 프로젝트는 UI 에 이모지를 안 써서 아이콘 대비도 쓸 수 없다).
   ★`.lg-x` 를 그대로 상속하므로 히트영역(::after inset:-10px)과 밑줄은 다른 메타 버튼과 같다. */
.lg-scrap.is-on{color:var(--navy);font-weight:700}

/* 머리줄의 「담아둠」 — 아이콘만 두는 버튼. 글자 라벨이 없어 좌우 여백을 줄여야 44px 정사각이 된다.
   ★★`min-height:44px` 는 `.lg-bell` 에서 상속받는다(터치 최소치). 여기서 덮어쓰지 말 것. */
.lg-bell.lg-ico{padding:0 11px;gap:0}
/* 담긴 목록을 보는 중에는 책갈피를 **채워서** 보여준다 — 눌린 상태(남색 배경)와 겹쳐 읽힌다.
   ★`aria-pressed` 를 선택자로 쓴다: 상태의 정본이 하나여서 JS 가 클래스를 따로 관리할 필요가 없다. */
.lg-bell.lg-ico[aria-pressed="true"] svg{fill:#fff}


/* ══ 투표  [2026-09-01] ═══════════════════════════════════════════════════
   ★★**인라인 `style=` 을 쓸 수 없다** — 이 사이트 CSP 는 `style-src 'self' 'nonce-…'` 라
     속성 스타일을 **조용히 차단**한다(에러도 안 나고 막대만 사라진다·실측). 그래서 막대 폭을
     5% 단위 클래스로 미리 만들어 둔다. 5% 단위인 이유 = 101개 클래스는 낭비이고,
     한 칸(5%)은 320px 화면에서 약 13px 라 눈으로 구분되는 최소 단위다. */
.poll-opts{display:flex;flex-direction:column;gap:8px}
/* 선택지 — 터치 최소 44px. 글자만이 아니라 **칸 전체**가 눌린다(손가락이 큰 이용자 대비). */
.poll-opt{display:flex;align-items:center;gap:10px;min-height:52px;padding:0 14px;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);cursor:pointer}
.poll-opt:has(input:checked){border-color:var(--navy);background:#EEF2F8}
.poll-opt input{width:20px;height:20px;flex:0 0 auto;accent-color:var(--navy)}
.poll-opt span{font-size:15px;color:var(--tx)}

.poll-res{display:flex;flex-direction:column;gap:12px}
.poll-bar-top{display:flex;align-items:baseline;gap:8px;margin-bottom:5px}
.poll-bar-lb{font-size:14px;color:var(--tx);font-weight:600}
.poll-bar-n{margin-left:auto;font-size:13px;color:var(--tx2);white-space:nowrap}
.poll-bar-track{height:10px;border-radius:5px;background:#E8EDF4;overflow:hidden}
.poll-bar-track i{display:block;height:100%;border-radius:5px;background:var(--navy)}
/* ★내가 고른 것은 색을 달리한다. 단 「내 선택」 글자 배지가 이미 붙어 있어 **색만으로 가르지 않는다**. */
.poll-bar.is-mine .poll-bar-track i{background:var(--accent)}
.poll-bar-track i.w0{width:0%}
.poll-bar-track i.w5{width:5%}
.poll-bar-track i.w10{width:10%}
.poll-bar-track i.w15{width:15%}
.poll-bar-track i.w20{width:20%}
.poll-bar-track i.w25{width:25%}
.poll-bar-track i.w30{width:30%}
.poll-bar-track i.w35{width:35%}
.poll-bar-track i.w40{width:40%}
.poll-bar-track i.w45{width:45%}
.poll-bar-track i.w50{width:50%}
.poll-bar-track i.w55{width:55%}
.poll-bar-track i.w60{width:60%}
.poll-bar-track i.w65{width:65%}
.poll-bar-track i.w70{width:70%}
.poll-bar-track i.w75{width:75%}
.poll-bar-track i.w80{width:80%}
.poll-bar-track i.w85{width:85%}
.poll-bar-track i.w90{width:90%}
.poll-bar-track i.w95{width:95%}
.poll-bar-track i.w100{width:100%}

/* ═══════════════════════════════════════════════════════════════════════════
   출석체크  [2026-09-03]
   ★도장·메달·순위는 전부 **CSS 도형 + inline SVG** 다. 이모지를 쓰지 않는다 —
     기기·OS 이모지 폰트마다 다르게 그려지고 브랜드 색을 못 준다([[ui-emoji-device-dependent]]).
     트로피/불꽃/메달을 이모지로 넣고 싶어지는 자리가 여럿인데 전부 SVG 로 갔다.
   ★애니메이션은 `prefers-reduced-motion` 전역 블록(파일 상단)이 자동으로 끈다.
     ★단 그 블록은 `animation-duration:.01ms` 로 «끝 상태»를 즉시 만든다 —
       그래서 모든 키프레임은 **끝 상태가 정상 화면**이어야 한다(both/forwards).
       시작 상태에 opacity:0 을 두고 끝에서 1로 가는 식은 안전하지만,
       반대로 끝에서 사라지는 연출은 모션을 끈 사람에게 «영영 안 보임»이 된다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 출석 도장 버튼 ──────────────────────────────────────────────────────── */
.at-stamp-wrap{display:flex;flex-direction:column;align-items:center;gap:14px;padding:8px 0 4px}

/* 도장 버튼 = 원형. ★44px 최소 터치영역을 한참 넘는 132px — 주 이용자가 40~60대다.
   button 이라 키보드 포커스·엔터가 그냥 된다(div 로 만들지 말 것). */
.at-stamp{position:relative;width:132px;height:132px;border-radius:50%;border:0;cursor:pointer;
  background:radial-gradient(circle at 32% 28%,var(--navy-l),var(--navy) 62%);
  color:#fff;font-family:var(--kr);font-size:19px;font-weight:800;letter-spacing:2px;
  box-shadow:0 10px 26px rgba(22,48,79,.28), inset 0 -3px 10px rgba(0,0,0,.18);
  transition:transform .12s, box-shadow .12s}
.at-stamp:active{transform:scale(.94);box-shadow:0 4px 12px rgba(22,48,79,.3)}
.at-stamp:disabled{cursor:default}
/* 버튼 안 글자가 2줄(「출석/하기」)이라 자간·행간을 좁힌다 */
.at-stamp span{line-height:1.15;letter-spacing:1px}

/* ★★[2026-09-03] 「뭘 눌러야 하는지 헷갈린다」 대응 — 아직 안 찍은 도장.
   ★맥동 «고리»만 퍼뜨린다. 버튼 자체를 깜빡이면 글자가 읽기 어려워지고,
     40~60대에게는 «고장난 화면» 으로 보인다(이 코드베이스의 이모지 사고와 같은 결).
   ★고리는 `::after` 가 아니라 **별도 레이어**가 필요해 box-shadow 로 그린다 —
     `.at-stamp::before/::after` 는 이미 인장 이중 링이 쓰고 있다. */
@keyframes atCallout{
  0%{box-shadow:0 10px 26px rgba(22,48,79,.28), inset 0 -3px 10px rgba(0,0,0,.18), 0 0 0 0 rgba(192,57,43,.42)}
  70%{box-shadow:0 10px 26px rgba(22,48,79,.28), inset 0 -3px 10px rgba(0,0,0,.18), 0 0 0 16px rgba(192,57,43,0)}
  100%{box-shadow:0 10px 26px rgba(22,48,79,.28), inset 0 -3px 10px rgba(0,0,0,.18), 0 0 0 0 rgba(192,57,43,0)}}
.at-stamp.is-todo{animation:atCallout 2.1s ease-out infinite}
/* ★모션을 끈 사람에게는 **정지된 테두리**를 남긴다 — 전역 reduced-motion 블록이
   애니메이션을 죽이면 «누르라는 신호»까지 함께 사라지기 때문이다. */
@media (prefers-reduced-motion:reduce){
  .at-stamp.is-todo{box-shadow:0 10px 26px rgba(22,48,79,.28), inset 0 -3px 10px rgba(0,0,0,.18), 0 0 0 4px rgba(192,57,43,.35)}
}

/* 버튼 «위» 지시문 — 종전엔 아래 흐린 글씨라 누른 뒤에야 읽혔다 */
.at-cta{font-size:16px;font-weight:800;color:var(--tx);text-align:center;
  letter-spacing:-.3px;margin-bottom:2px}
/* 버튼 아래 보조 힌트 — 화살표가 위를 가리킨다 */
.at-hint{display:flex;align-items:center;justify-content:center;gap:4px}
.at-hint svg{width:14px;height:14px;color:var(--accent)}

/* 도장 안쪽 이중 링 — 인장 느낌. 순수 CSS 라 이미지 요청이 없다 */
.at-stamp::before{content:'';position:absolute;inset:9px;border-radius:50%;
  border:2px solid rgba(255,255,255,.42)}
.at-stamp::after{content:'';position:absolute;inset:16px;border-radius:50%;
  border:1px dashed rgba(255,255,255,.3)}
/* ★글자에 옅은 그림자 — 붉은 바탕 위에서 흰 글자가 뭉개지지 않게(실캡처로 확인) */
.at-stamp span{position:relative;z-index:1;text-shadow:0 1px 3px rgba(0,0,0,.35)}

/* 이미 찍은 상태 = 붉은 인장. ★색만 바꾸는 게 아니라 «기울여» 실제 찍힌 느낌을 준다 */
.at-stamp.is-done{background:radial-gradient(circle at 32% 28%,#D5503F,var(--accent) 62%);
  transform:rotate(-7deg);box-shadow:0 8px 22px rgba(192,57,43,.32), inset 0 -3px 10px rgba(0,0,0,.16)}
.at-stamp.is-done:active{transform:rotate(-7deg) scale(.97)}

/* 찍는 순간 — 위에서 «쿵» 내려와 박히고 살짝 튕긴다 */
@keyframes atStampHit{
  0%{transform:rotate(-7deg) scale(2.1);opacity:0}
  55%{transform:rotate(-7deg) scale(.88);opacity:1}
  72%{transform:rotate(-7deg) scale(1.06)}
  100%{transform:rotate(-7deg) scale(1);opacity:1}}
.at-stamp.is-hit{animation:atStampHit .52s cubic-bezier(.2,.8,.3,1) both}

/* 도장이 박힐 때 퍼지는 물결 — 잉크가 번지는 느낌 */
@keyframes atRipple{
  0%{transform:scale(.5);opacity:.55}
  100%{transform:scale(2.3);opacity:0}}
.at-ripple{position:absolute;inset:0;border-radius:50%;background:var(--accent);
  pointer-events:none;animation:atRipple .72s ease-out both}

/* ── 이달 요약 (일수·연속·순위) ──────────────────────────────────────────── */
.at-sum{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:16px}
.at-sum .b{background:var(--bg);border:1px solid var(--line);border-radius:var(--r-card);
  padding:13px 8px;text-align:center}
.at-sum .b .k{display:block;font-size:12px;color:var(--muted);margin-bottom:5px}
.at-sum .b .v{display:block;font-size:23px;font-weight:800;color:var(--navy);line-height:1.15}
.at-sum .b .v small{font-size:13px;font-weight:700;color:var(--tx2);margin-left:1px}
/* 순위 칸만 강조 — 이 화면에서 조합원이 가장 궁금해하는 값이다 */
.at-sum .b.hi{background:#FBF1EF;border-color:#F0D5D0}
.at-sum .b.hi .v{color:var(--accent)}

/* ── 달력 ────────────────────────────────────────────────────────────────── */
.at-cal{margin-top:18px}
.at-cal .hd7{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:6px}
.at-cal .hd7 span{text-align:center;font-size:12px;font-weight:700;color:var(--muted);padding:2px 0}
.at-cal .hd7 span.sun{color:var(--accent)}
.at-cal .grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
/* ★★[2026-09-03 재작업] 종전 시안은 «꽉 찬 빨간 네모» 였다 — 대표 지적:
     「출석 도장 찍힌 게 달력에 너무 디자인 구림」. 실제로 도장이 아니라 **에러 표시**처럼 보였다.
     원인 3가지를 전부 바꿨다:
       ① 사각형 = 도장이 아니다 → **원형 낙관**(전각 인장은 둥글다)
       ② 꽉 찬 면 = 인쇄물이 아니라 색칠이다 → **테두리 링 + 옅은 인주 바탕**
       ③ 칸을 꽉 채워 다닥다닥 → 칸 안에서 **한 겹 물러나** 숨 쉴 여백을 준다
     ★날짜 숫자를 지우지 않는다 — 며칠인지 계속 읽혀야 한다. 인장은 숫자 «둘레»에 찍힌다. */
.at-cal .d{position:relative;aspect-ratio:1;display:flex;align-items:center;justify-content:center;
  border-radius:10px;font-size:13px;font-weight:600;color:var(--tx2);background:var(--bg)}
.at-cal .d.pad{background:transparent}

/* 오늘 — 아직 안 찍은 날은 «여기를 찍으세요» 로 읽혀야 한다(점선이 빈 자리를 뜻한다) */
.at-cal .d.today{color:var(--navy);font-weight:800;background:#fff;
  box-shadow:inset 0 0 0 2px var(--navy)}

/* ── 출석한 날 = 붉은 낙관 ────────────────────────────────────────────────
   바탕은 아주 옅은 인주색만. 진한 것은 «링» 이 맡는다 — 그래야 인장으로 읽힌다. */
/* ★바탕을 «투명» 으로 둔다 — 옅은 분홍 사각형을 깔았더니 원형 인장 뒤로 네모가 비쳐
   테두리가 어른거렸다(실캡처). 인주 자국은 아래 ::before 의 그림자가 대신한다.
   ★★[대표 지시] 도장 안에 **「출석」 글자**가 들어간다 → 세로 2줄(날짜/출석)로 쌓는다. */
.at-cal .d.on{background:transparent;color:var(--accent);font-weight:800;
  flex-direction:column;gap:0;line-height:1}
/* 날짜 — 인장 위쪽. 작게 두어 「출석」이 주인공이 되게 한다 */
.at-cal .d.on .dd{position:relative;z-index:1;font-size:11px;font-weight:800;
  letter-spacing:-.3px;margin-bottom:1px}
/* 「출석」 — 도장의 본문. ★2글자가 원 안에 들어가야 하므로 자간을 좁힌다.
   ★★clamp 로 폭에 따라 줄인다 — 320px 에서 칸이 40px 남짓이라 고정 px 면 원 밖으로 삐져나온다. */
.at-cal .d.on .ss{position:relative;z-index:1;font-size:clamp(8.5px,2.6vw,10.5px);
  font-weight:800;letter-spacing:-.6px}
/* 인장 링 — 칸 안쪽으로 한 겹 물러나 찍힌다(위 ③) */
.at-cal .d.on::before{content:'';position:absolute;inset:2px;border-radius:50%;
  border:2.2px solid var(--accent);opacity:.92;
  /* 인주가 종이에 번진 자국 — 안쪽을 아주 옅게 채우고 바깥으로 옅은 그림자 */
  background:rgba(192,57,43,.055);box-shadow:0 1px 4px rgba(192,57,43,.18)}
/* 안쪽 가는 링 — 실제 낙관의 이중 테두리. 도장 버튼(.at-stamp)과 같은 어법이라 한 세트로 읽힌다 */
.at-cal .d.on::after{content:'';position:absolute;inset:5.5px;border-radius:50%;
  border:1px solid var(--accent);opacity:.42}
/* ★★오늘 찍은 칸 — 남색 후광을 둘렀더니 붉은 인장 옆에서 «탁하게» 보였다(실캡처).
   두 색을 겹치지 않는다: 오늘 표시는 지우고 **인장만** 남긴다.
   why 괜찮은가 — 오늘 칸은 달력에서 이미 «마지막 인장» 자리라 눈으로 찾을 수 있고,
   화면 위쪽 도장 버튼이 「오늘 출석이 기록되었습니다」로 이미 말해 준다. */
.at-cal .d.on.today{background:transparent;color:var(--accent);box-shadow:none}

/* 도장이 «쿵» 찍히는 연출 — 위에서 내려와 박히고 살짝 튕긴다(.at-stamp 와 같은 곡선).
   ★끝 상태가 정상 화면이다 — prefers-reduced-motion 이 .01ms 로 끝 상태만 남겨도 온전하다. */
@keyframes atPop{
  0%{transform:scale(2) rotate(-14deg);opacity:0}
  60%{transform:scale(.9) rotate(-4deg);opacity:1}
  80%{transform:scale(1.05) rotate(0deg)}
  100%{transform:scale(1) rotate(0deg);opacity:1}}
.at-cal .d.on::before{animation:atPop .42s cubic-bezier(.2,.8,.3,1) both}

/* ── 랭킹 목록 ───────────────────────────────────────────────────────────── */
.at-rank{list-style:none;margin:0;padding:0}
.at-rank li{display:flex;align-items:center;gap:11px;padding:11px 2px;border-bottom:1px solid var(--line)}
.at-rank li:last-child{border-bottom:0}
.at-rank .no{flex:0 0 30px;text-align:center;font-size:15px;font-weight:800;color:var(--muted)}
.at-rank .nm{flex:1 1 auto;font-size:15px;font-weight:700;color:var(--tx);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.at-rank .ct{flex:0 0 auto;font-size:14px;font-weight:800;color:var(--navy)}
.at-rank .ct small{font-size:12px;font-weight:700;color:var(--muted);margin-left:1px}
/* 내 줄 — 목록에서 나를 즉시 찾게 */
.at-rank li.me{background:#F1F5FA;border-radius:9px;margin:0 -8px;padding-left:10px;padding-right:10px}
.at-rank li.me .nm::after{content:'나';margin-left:7px;font-size:11px;font-weight:800;color:#fff;
  background:var(--navy);border-radius:9px;padding:1px 7px;vertical-align:1px}

/* 「상위 5명」과 「내 줄」 사이의 생략 표시 — 건너뛴 구간이 있음을 눈에 보이게.
   ★[2026-09-03] 이게 없어서 5위 다음 7위가 붙어 «6위가 없다» 로 읽혔다(대표 지적). */
.at-rank li.gap{justify-content:center;padding:3px 2px;border-bottom:0}
.at-rank li.gap .dots{color:var(--muted);font-size:15px;letter-spacing:3px;line-height:1}

/* 메달 — 1·2·3위. ★SVG 아이콘 컨테이너 색만 바꾼다(이모지 금지) */
/* ★메달은 «순위 숫자» 자리를 대신하므로 폭이 .no 와 같아야 한다(줄이 흔들리지 않게).
   ★첫 시안은 23px 원 두 개라 금/은/동 구분이 안 됐다 → 배경 원반 + 테두리로 키운다. */
.at-medal{flex:0 0 30px;display:flex;align-items:center;justify-content:center}
.at-medal svg{width:27px;height:27px;display:block;filter:drop-shadow(0 1px 1px rgba(0,0,0,.18))}
.at-medal.g{color:#D9A521} .at-medal.s{color:#93A1AF} .at-medal.b{color:#B87A4B}

/* ── 홈 하이라이트: 시상대 ───────────────────────────────────────────────
   ★대표 요청 「메인에서 1~5위를 더 하이라이트해서 멋지게」 → 상위 3명은 시상대, 4·5위는 아래 줄.
   ★★[2026-09-03 재작업] 대표 지적 「너무 허접」. 무엇이 문제였나:
       ① 이름·일수가 단상 **위 허공에 떠** 있어 누가 어느 단인지 눈으로 안 이어졌다
       ② **시상대인데 사람이 없었다** — 텅 빈 계단이었다
       ③ 왕관이 이름에서 멀리 떨어져 붕 떴다
       ④ 금·은·동 위계가 1위에만 있었다(2·3위가 같은 회색)
     → 아바타를 단 위에 세우고 이름·일수를 **그 아래 붙여** 한 덩어리로 만들었다.
       무대에는 조명(방사형 그라데이션)과 바닥 반사를 넣어 «무대» 로 읽히게 했다. */
.at-podium{position:relative;display:flex;align-items:flex-end;justify-content:center;gap:7px;
  padding:20px 12px 0;
  /* 밤하늘 무대 — 위에서 조명이 떨어지는 느낌(가운데가 밝다) */
  background:
    radial-gradient(120% 78% at 50% -8%, rgba(242,193,78,.20) 0%, rgba(242,193,78,0) 58%),
    linear-gradient(180deg,#1B3A5E 0%,#102539 100%);
  border-bottom:3px solid rgba(255,255,255,.30);overflow:hidden}
/* 무대 바닥의 옅은 빛 — 단상이 «서 있는» 면을 만든다 */
.at-podium::after{content:'';position:absolute;left:0;right:0;bottom:3px;height:34px;
  background:linear-gradient(180deg,rgba(255,255,255,0),rgba(255,255,255,.07));pointer-events:none}

.at-podium .p{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;
  position:relative;z-index:1}

/* ── 단 위에 선 사람 ─────────────────────────────────────────────────── */
/* ★사람 덩어리는 단상에 **붙여** 세운다 — 간격이 넓으면 «단 위에 선» 것이 아니라
   허공에 뜬 글자로 읽힌다(첫 시안의 문제가 정확히 이것이었다). */
.at-podium .who{display:flex;flex-direction:column;align-items:center;gap:2px;
  width:100%;padding-bottom:4px}
/* 2·3위는 단상이 낮아 그만큼 이름이 위로 뜬다 → 아래 여백을 더 줄여 붙인다 */
.at-podium .p2 .who,.at-podium .p3 .who{padding-bottom:3px}
.at-podium .face{position:relative;display:block;line-height:0}
/* 아바타에 테두리 링 — 남색 배경에서 얼굴이 «떠» 보이게 */
.at-podium .face .av{border:2px solid rgba(255,255,255,.34);
  box-shadow:0 3px 10px rgba(0,0,0,.28)}
.at-podium .p1 .face .av{border-color:#F2C14E;box-shadow:0 0 0 3px rgba(242,193,78,.22),0 4px 14px rgba(0,0,0,.34)}
.at-podium .p2 .face .av{border-color:#C6D2DE}
.at-podium .p3 .face .av{border-color:#C79766}
/* 1위 아바타만 조금 크게 — 시선이 가운데로 모인다 */
.at-podium .p1 .face .av{width:52px;height:52px;font-size:21px}

/* 이름 — 좁은 폭에서 반드시 한 줄(2줄이면 시상대 높이가 들쭉날쭉해진다) */
.at-podium .p .nm{max-width:100%;font-size:12.5px;font-weight:800;color:#fff;letter-spacing:-.3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:3px}
.at-podium .p1 .nm{font-size:13.5px}
/* 일수 — 「18일」의 «일» 만 작게 해서 숫자가 주인공이 되게 */
.at-podium .p .ct{font-size:13px;font-weight:800;color:#F2C14E;line-height:1.2}
.at-podium .p2 .ct,.at-podium .p3 .ct{color:var(--muted-on-navy)}
.at-podium .p .ct i{font-style:normal;font-size:10.5px;font-weight:700;margin-left:1px;opacity:.85}

/* 왕관 — 아바타 «바로 위»에 붙인다(종전엔 멀리 떨어져 붕 떴다) */
.at-podium .crown{width:24px;height:24px;color:#F2C14E;display:block;margin-bottom:-2px;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.35))}

/* ── 단상 ────────────────────────────────────────────────────────────── */
.at-podium .bar{width:100%;border-radius:10px 10px 0 0;display:flex;align-items:flex-start;
  justify-content:center;padding-top:9px;position:relative;
  background:linear-gradient(180deg,rgba(255,255,255,.34),rgba(255,255,255,.10));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5)}
/* ★금·은·동을 **셋 다** 준다 — 종전엔 1위만 금색이고 2·3위가 같은 회색이라 위계가 반만 보였다 */
.at-podium .p1 .bar{background:linear-gradient(180deg,rgba(242,193,78,.92),rgba(242,193,78,.34));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.65)}
.at-podium .p2 .bar{background:linear-gradient(180deg,rgba(198,210,222,.72),rgba(198,210,222,.20))}
.at-podium .p3 .bar{background:linear-gradient(180deg,rgba(199,151,102,.72),rgba(199,151,102,.20))}
.at-podium .p1 .bar{height:64px} .at-podium .p2 .bar{height:46px} .at-podium .p3 .bar{height:34px}
/* 등수 숫자 — 단상에 새긴 느낌 */
/* ★「1위」 — 숫자는 크게, 「위」는 작게. baseline 을 맞춰 한 덩어리로 읽히게 한다.
   ★`inline-flex`+`align-items:baseline` 이라 낮은 단상(3위)에서도 두 줄로 안 접힌다. */
.at-podium .bar .rk{display:inline-flex;align-items:baseline;gap:1px;
  font-size:19px;font-weight:800;color:#fff;line-height:1;
  text-shadow:0 1px 3px rgba(0,0,0,.32)}
.at-podium .bar .rk i{font-style:normal;font-size:11px;font-weight:700;opacity:.9}
.at-podium .p1 .bar .rk{font-size:22px;color:#3A2A06;text-shadow:0 1px 0 rgba(255,255,255,.35)}
.at-podium .p1 .bar .rk i{font-size:12px;opacity:.75}

/* 단상이 아래에서 솟아오르고, 사람은 뒤이어 내려앉는다 */
@keyframes atRise{0%{transform:scaleY(.2);opacity:0}100%{transform:scaleY(1);opacity:1}}
@keyframes atDrop{0%{transform:translateY(-10px);opacity:0}100%{transform:translateY(0);opacity:1}}
.at-podium .bar{transform-origin:bottom;animation:atRise .5s cubic-bezier(.2,.8,.3,1) both}
.at-podium .p2 .bar{animation-delay:.06s} .at-podium .p1 .bar{animation-delay:.13s}
.at-podium .p3 .bar{animation-delay:.2s}
.at-podium .who{animation:atDrop .42s cubic-bezier(.2,.8,.3,1) both}
.at-podium .p2 .who{animation-delay:.22s} .at-podium .p1 .who{animation-delay:.3s}
.at-podium .p3 .who{animation-delay:.38s}
/* 1위 왕관이 살짝 반짝 — 한 번만(계속 움직이면 피로하다) */
@keyframes atShine{0%{transform:translateY(-5px) scale(.8);opacity:0}
  60%{transform:translateY(1px) scale(1.06)}100%{transform:translateY(0) scale(1);opacity:1}}
.at-podium .crown{animation:atShine .6s ease-out .46s both}

/* 4·5위 줄 — 시상대 아래. ★칸을 나눠 위 시상대와 축을 맞춘다(종전엔 왼쪽으로 몰려 어긋났다) */
.at-rest{display:flex;gap:8px;padding:12px 0 10px;border-bottom:1px solid var(--line)}
.at-rest .r{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:7px;font-size:13px;
  background:var(--bg);border-radius:10px;padding:8px 10px}
.at-rest .r .no{flex:0 0 auto;font-weight:800;color:var(--muted);font-size:12px}
/* 「위」는 작게 — 시상대의 `.rk i` 와 같은 어법 */
.at-rest .r .no i{font-style:normal;font-size:10px;font-weight:700;margin-left:.5px;opacity:.85}
.at-rest .r .nm{flex:1 1 auto;font-weight:700;color:var(--tx);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.at-rest .r .ct{flex:0 0 auto;font-weight:800;color:var(--navy)}

/* 홈 카드의 내 현황 줄 */
.at-mine{display:flex;align-items:center;gap:8px;padding:11px 0 3px;font-size:14px}
.at-mine .lb{color:var(--muted)}
.at-mine .vv{font-weight:800;color:var(--navy)}
.at-mine .sp{flex:1 1 auto}

/* ═══════════════════════════════════════════════════════════════════════════
   탭바 「더보기」 토글  [2026-09-03]
   ★★8칸 실측(320px)에서 「전자서명」 여유가 **0.0px** 였다 — 칸 39.4px 에 글자 44px.
     6칸 + 더보기로 나눠 칸당 ≈53px 를 확보한다. 앞으로 메뉴가 늘어도 토글만 길어진다.
   ★`<details>` 라 **JS 없이** 열리고 닫힌다(라운지 서랍과 같은 어법).
   ═══════════════════════════════════════════════════════════════════════════ */
/* ★★[2026-09-03 대표 지적] 「더보기를 열면 AI 챗봇 아이콘이 시트를 덮는다」.
   원인: `.tabs` 가 `z-index:30` 으로 **쌓임 맥락**을 만들어, 그 안의 시트는 아무리 높여도
     30 을 못 넘는다. AI FAB 은 `#mw-chat` `z-index:84` 라 항상 이긴다.
   → 더보기가 **열려 있을 때만** `.tab-more` 자체를 위 층으로 올린다(`z-index:85`).
   ★85 인 근거: `_ai_widget.php` 주석이 층을 이렇게 정의해 뒀다 —
     «상시 콘텐츠 ≤80 · AI FAB 84 · 전체화면 오버레이/모달 ≥85».
     더보기 시트는 상시 UI 가 아니라 **열었을 때만 뜨는 오버레이**라 그 규약에 맞는다.
   ★★★**자식만 올려서는 안 된다.** `.tabs{z-index:30}` 이 쌓임 맥락을 만들므로 그 «안»의
     값은 아무리 커도 **부모의 30 이 상한**이다(실측: `.tab-more[open]{z-index:85}` 만으로는
     여전히 FAB 이 이겼다 — `elementFromPoint` 히트테스트로 확인).
     → **탭바 자체**를 열려 있는 동안만 올린다. 그래야 맥락 전체가 FAB 위로 간다.
   ★★닫히면 즉시 30 으로 돌아온다 — 상시로 85 면 탭바가 전자서명 동의 모달 같은
     전체화면 오버레이(≥85)까지 덮어 이번과 **반대 방향의 가림**이 생긴다. */
.tabs:has(.tab-more[open]){z-index:85}
/* ★`:has()` 미지원 브라우저용 — `tabmore.js` 가 이 클래스를 붙인다(그쪽 주석 참조).
   실측 미지원 0.02%(5,802건 중 1건)라 «있으면 좋은» 보완이다. */
.tabs.tabs-raise{z-index:85}
/* ★★[2026-09-13] `position:relative` 를 뺐다. 그게 있으면 시트의 기준이 **이 칸(탭바의 1/7)** 이라
   좌우로 펼 수가 없다. static 이면 기준이 `.tabs`(positioned: sticky)로 올라가
   `left:0;right:0` 이 곧 **탭바 전체 폭 = 화면 폭**이 된다.
   ★`left:50% + translateX(-50%)` 로 펴는 방법은 **쓰면 안 된다** — 펼침 애니메이션이 같은
     `transform` 속성을 덮어써 시트가 오른쪽으로 밀린다(실측으로 깨졌다).
   ★배지는 영향 없다: `.tab-more>summary{position:relative}` 가 따로 있어 그쪽이 기준이다.
   ★z-index 도 영향 없다: 실제로 FAB 을 이기는 것은 `.tabs:has(.tab-more[open]){z-index:85}` 이고
     `.tab-more[open]{z-index:85}` 는 보조였다(바로 위 주석의 실측 결론). */
.tab-more{flex:1;min-width:0}
.tab-more[open]{z-index:85}
/* summary 를 다른 탭과 «똑같이» 보이게 — 하나만 모양이 다르면 버튼으로 안 읽힌다 */
.tab-more>summary{min-height:var(--tab-h);display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:3px;color:var(--muted);font-size:11px;font-weight:700;
  white-space:nowrap;cursor:pointer;list-style:none;position:relative;
  transition:transform .12s ease,color .12s ease}
.tab-more>summary::-webkit-details-marker{display:none}   /* Safari 기본 삼각형 제거 */
.tab-more>summary::marker{content:''}
.tab-more>summary svg{width:22px;height:22px}
.tab-more>summary:active{transform:scale(.9)}
/* 열려 있거나, 지금 보는 화면이 토글 «안» 항목일 때 활성 표시 */
.tab-more[open]>summary,
.tab-more[data-active]>summary{color:var(--navy)}
.tab-more[open]>summary svg,
.tab-more[data-active]>summary svg{stroke-width:2.4}
/* 배지 — 접혀 있어 안 보이는 배지를 여기 모아 준다(위치는 .tabs a .nbadge 와 같게) */
.tab-more>summary .nbadge{position:absolute;top:5px;left:calc(50% + 3px);
  height:18px;min-width:18px;border-radius:9px;border:2px solid var(--surface)}

/* 펼쳐지는 목록 — 탭바 «위»로 올라온다(아래는 화면 밖이다) */
/* ★★[2026-09-13 대표 지시] 좁은 드롭다운(172px) → **화면 폭 시트**로 바꿨다.
   ★`position:absolute` 를 버리고 `fixed` 로 간다 — 종전 기준점이 `.tab-more`(탭바의 1/7 칸)라
     거기 붙어 있는 한 절대 넓어지지 않는다.
   ★★아래 여백은 `var(--tab-h) + safe-area` 다. `.tabs` 가 이미 `padding-bottom:safe-area` 를
     쓰고 있어 그 값을 빼면 아이폰에서 시트가 탭바에 깔린다.
   ★★`max-height` + `overflow-y:auto` 가 **필수**다 — 「아주 크게」 글씨(--fs)에서 프로필 블록과
     8개 항목이 화면을 넘어가고, 그러면 아래쪽 항목에 손이 닿지 않는다.
   ★모서리는 위쪽만 둥글린다(아래는 탭바에 붙는다). */
/* ★★[2026-09-13 실측 수정] `position:fixed` + `bottom:calc(var(--tab-h)+safe-area)` 는 **틀렸다.**
     `--tab-h` 는 고정값(60px)인데 「크게/아주 크게」에서는 라벨이 커져 **탭바가 실제로 더 높아진다**
     (`min-height` 는 최소값일 뿐이다). 그러면 시트 아래가 탭바에 깔린다 — 390px·「크게」에서 실측됐다.
   → `.tab-more` 에 `absolute` 로 붙이고 `bottom:100%` 를 쓴다. `.tab-more` 는 탭바 높이만큼
     늘어나 있으므로(flex stretch) **글씨 배율과 무관하게 언제나 탭바 바로 위**가 된다.
   ★좌우는 그 칸(탭바의 1/7)에 묶이므로 화면 가운데 기준으로 `100vw` 를 편다. */
.tab-more .sheet{position:absolute;bottom:100%;left:0;right:0;z-index:2;
  max-height:min(74vh,560px);overflow-y:auto;-webkit-overflow-scrolling:touch;
  background:var(--surface);border-top:1px solid var(--line);
  border-radius:18px 18px 0 0;box-shadow:var(--shadow-lg);padding:6px 10px 12px}

/* 프로필 블록. ★사진·이름·「내 정보」 한 줄. */
.ms-prof{display:flex;align-items:center;gap:13px;padding:16px 6px 18px;
  border-bottom:1px solid var(--line);margin-bottom:10px}
.ms-prof-txt{min-width:0;flex:1}
.ms-prof-nm{display:block;font-size:calc(16px * var(--fs));font-weight:800;color:var(--tx);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ms-prof-sub{display:block;margin-top:2px;font-size:calc(12px * var(--fs));color:var(--muted)}
/* ★★`.tabs a`(0,1,1)가 이 링크에도 먹는다 — 세로 정렬·11px·회색·min-height 가 전부 딸려 온다.
   `.tabs .tab-more .sheet` 를 앞에 붙여 (0,4,1)로 확실히 이긴다(이 파일이 이미 겪은 함정). */
.tabs .tab-more .sheet .ms-prof-edit{display:inline-flex;flex-direction:row;align-items:center;
  justify-content:center;gap:5px;flex:0 0 auto;min-height:0;padding:8px 12px;
  border:1px solid var(--line);border-radius:999px;background:var(--bg);
  font-size:calc(13px * var(--fs));font-weight:700;color:var(--tx2);white-space:nowrap}
.tabs .tab-more .sheet .ms-prof-edit svg{width:16px;height:16px;flex:0 0 16px;color:var(--tx2)}
.tabs .tab-more .sheet .ms-prof-edit:active{background:var(--line)}
.tabs .tab-more .sheet .ms-prof-edit[aria-current]{background:var(--navy);border-color:var(--navy);color:#fff}
.tabs .tab-more .sheet .ms-prof-edit[aria-current] svg{color:#fff}
/* 사진이 없는 분의 동그라미는 「사진 넣으러 가기」 링크가 된다 — 죽은 자리로 두지 않는다 */
.tabs .tab-more .sheet .ms-prof-avlink{display:inline-flex;min-height:0;padding:0;flex:0 0 auto}

/* 메뉴 두 칸 격자.
   ★★항목을 **연한 칸**으로 만든다 — 두 칸이 되면서 좌우는 찼는데 아이콘·글자만 떠 있어
     «어디까지가 누르는 곳인지»가 안 보였다(실화면 판단). 칸으로 두면 터치 영역이 곧 보인다.
   ★`.tabs .tab-more .sheet a`(0,2,1)가 padding 을 이미 잡고 있어 같은 무게로 덮는다. */
.ms-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.tabs .tab-more .sheet .ms-grid a{padding:14px 12px;background:var(--bg);
  border:1px solid var(--line);border-radius:12px}
.tabs .tab-more .sheet .ms-grid a[aria-current]{background:var(--info-bg);border-color:var(--navy)}
/* ★★`.tabs a{flex-direction:column}`(특정도 0,1,1)가 시트 안 링크까지 먹어 아이콘 아래로
   글자가 쌓였다(실캡처). `.tabs` 를 앞에 붙여 특정도를 (0,2,1)로 올려 이긴다 —
   이 코드베이스에서 특정도 때문에 스타일이 통째로 무시된 사고가 이미 여러 번 있었다.
   ★`flex-direction:row` 를 **명시**한다. 상속을 덮는 것이 목적이라 생략하면 안 된다. */
.tabs .tab-more .sheet a{display:flex;flex-direction:row;align-items:center;gap:11px;
  /* ★★`.tabs a{justify-content:center}` 를 함께 덮어야 한다 — flex-direction 만 바꾸면
     주축이 가로로 서면서 **가운데 정렬**이 그대로 살아 아이콘·글자가 몰린다(실캡처).
     방향을 바꾸는 규칙은 정렬 두 축을 **함께** 다시 지정한다. */
  justify-content:flex-start;
  padding:12px 13px;text-decoration:none;color:var(--tx);font-size:15px;font-weight:600;
  border-radius:9px;position:relative;min-height:0;white-space:nowrap}
.tabs .tab-more .sheet a svg{width:20px;height:20px;color:var(--muted);flex:0 0 20px}
.tab-more .sheet a[aria-current]{background:#F1F5FA;color:var(--navy);font-weight:800}
.tab-more .sheet a[aria-current] svg{color:var(--navy);stroke-width:2.4}
.tab-more .sheet a:active{background:var(--bg)}
/* 시트 안 배지는 절대배치가 아니라 **줄 끝**에 붙인다 — 줄이 넓어 자리가 있다.
   ★`.tabs a .nbadge{position:absolute}`(0,2,1)를 이기려면 여기도 같은 무게가 필요하다. */
.tabs .tab-more .sheet a .nbadge{position:static;margin-left:auto;border:0;
  top:auto;left:auto;height:18px;min-width:18px}

/* 바깥을 눌러 닫기 — summary 밖을 눌러도 닫히게 해야 «갇힌» 느낌이 안 난다 */
/* ★★[2026-09-03 조합원 민원] 「더보기를 연 뒤 옵션을 고르지 않으면 아래 탭이 눌리지 않는다.
     더보기를 한 번 더 눌러도 안 닫힌다」 — 실사용에서 접수됐다.
   원인: 스크림을 `inset:0` 으로 깔아 **탭바까지 덮었고**, `.tabs` 가 만든 쌓임 맥락 안에서
     `z-index:1` 이라 탭 링크(z-index auto)와 **「더보기」 버튼 자신보다 위**에 있었다.
     그래서 ①탭이 안 눌리고 ②더보기를 다시 눌러도 스크림이 클릭을 먹어 `<details>` 의
     기본 토글(다시 누르면 닫힘)마저 막혔다. **막기만 하고 닫지는 않는 스크림**이었다.
   → 스크림을 **탭바 «위» 영역만** 덮게 한다(`bottom:var(--tab-h)`). 탭바와 더보기 버튼은
     스크림 밖이라 항상 눌린다 = 한 번 더 누르면 닫힌다(브라우저 기본 동작, JS 불필요).
   ★스크림을 아예 지우지 않는 이유: 목록 밖을 눌러 닫는 것이 자연스럽고, 그건 아래 JS 가 맡는다.
     JS 가 죽어도 «더보기 재클릭»과 «항목 선택» 두 경로가 살아 있어 갇히지 않는다. */
.tab-more .scrim{display:none}
.tab-more[open] .scrim{display:block;position:fixed;left:0;right:0;top:0;
  bottom:calc(var(--tab-h) + env(safe-area-inset-bottom));z-index:1;
  /* ★[2026-09-13] 투명 → 옅은 딤. 시트가 화면 폭을 다 쓰게 되면서 뒤 본문과 구분이 필요해졌다.
     ★★**높이·위치는 한 글자도 바꾸지 않았다** — 탭바를 덮지 않는 그 geometry 가
       26-09-03 「더보기를 열면 탭이 안 눌린다」 민원의 수정 내용이다. 색만 얹는다. */
  background:rgba(12,22,32,.28);animation:tabMoreDim .16s ease-out both}
@keyframes tabMoreDim{from{opacity:0}to{opacity:1}}
/* ★스크림은 `.tab-more[open]`(85) 안의 지역 z-index 라 AI FAB(84)도 함께 덮는다 —
   그래서 «시트 밖 아무 데나 탭하면 닫힌다» 가 챗봇 위에서도 성립한다. */

/* 펼쳐질 때 살짝 떠오른다 */
@keyframes tabMoreIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.tab-more[open] .sheet{animation:tabMoreIn .16s ease-out both}

@media (min-width:1024px){ .tab-more{display:none} }  /* PC 는 사이드바가 전부 낸다 */

/* ── PC 사이드바 프로필 [2026-09-13 대표 지시] ─────────────────────────────
   ★모바일 시트와 **같은 내용**을 세로로 쌓는다(사이드바가 좁아 한 줄에 안 들어간다).
   ★★`.side` 는 관리자 셸도 쓰는 클래스다 — 그래서 구조 선택자가 아니라 전용 클래스로만 잡는다.
     관리자 셸은 `mk_shell_profile()` 을 부르지 않으므로 이 블록 자체가 안 그려진다. */
.sd-prof{display:none}
@media (min-width:1024px){
  .sd-prof{display:flex;flex-direction:column;align-items:center;gap:8px;
    padding:6px 10px 16px;margin-bottom:8px;border-bottom:1px solid var(--line);text-align:center}
  .sd-prof-txt{min-width:0;width:100%}
  .sd-prof-nm{display:block;font-size:15px;font-weight:800;color:var(--tx);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .sd-prof-sub{display:block;margin-top:2px;font-size:12px;color:var(--muted)}
  /* ★`.side a`(사이드바 링크)의 블록 스타일이 이 버튼에도 먹는다 — 전용 클래스로 덮는다. */
  .side a.sd-prof-edit{display:inline-flex;align-items:center;justify-content:center;gap:5px;
    padding:7px 14px;margin:0;border:1px solid var(--line);border-radius:999px;
    background:var(--bg);font-size:13px;font-weight:700;color:var(--tx2)}
  .side a.sd-prof-edit svg{width:16px;height:16px;margin:0;color:var(--tx2)}
  .side a.sd-prof-edit:hover{background:var(--line);color:var(--tx)}
  .side a.sd-prof-edit[aria-current]{background:var(--navy);border-color:var(--navy);color:#fff}
  .side a.sd-prof-edit[aria-current] svg{color:#fff}
  .side a.sd-prof-avlink{display:inline-flex;padding:0;margin:0;background:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   조합 퀴즈  [2026-09-03]
   ★랭킹·요약은 출석(`at-rank`·`at-sum`)을 그대로 재사용한다 — 같은 성격의 화면이
     서로 다르게 보이면 조합원이 «다른 기능»으로 인식한다. 여기선 «문제 풀이»만 새로 만든다.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ★★[2026-09-03 재작업] 「남은 문제 58개」는 **깎이는 숫자**라 부담으로 읽혔다.
   → 몇 번째 도전인가 + 채워지는 막대로 바꿨다. 게임의 «스테이지 표시»와 같은 자리다. */
.qz-head{display:flex;align-items:center;gap:11px;margin-bottom:13px}
.qz-step{flex:0 0 auto;font-size:20px;font-weight:800;color:var(--navy);
  letter-spacing:-.5px;line-height:1}
.qz-step i{font-style:normal;font-size:13px;font-weight:700;color:var(--muted);margin-left:1px}
.qz-track{flex:1 1 auto;height:7px;border-radius:4px;background:var(--bg);overflow:hidden;min-width:0}
.qz-track i{display:block;height:100%;border-radius:4px;
  background:linear-gradient(90deg,var(--navy-l),var(--navy));
  transition:width .6s cubic-bezier(.2,.8,.3,1)}

.qz-meta{display:flex;align-items:center;gap:8px;margin-bottom:14px}
.qz-meta .sp{flex:1 1 auto}

/* 문제 본문 — 읽기가 이 화면의 본업이라 크게, 넉넉하게 */
/* ★문제 본문 — 「지금 도전 중인 것」이라 살짝 들어올린 판 위에 얹는다.
   흰 배경에 검은 글씨만 두면 시험지로 읽힌다(대표 지적). */
.qz-q{font-size:17px;font-weight:700;line-height:1.55;color:var(--tx);
  letter-spacing:-.3px;margin:0 0 18px;word-break:keep-all;
  padding:16px 16px 17px;border-radius:var(--r-card);
  background:linear-gradient(160deg,#F4F7FB 0%,#EDF2F8 100%);
  border:1px solid #E2E9F2}

/* 보기 — 라디오+제출 2단계 대신 «누르면 제출». 고령 이용자의 단계를 하나 줄인다 */
.qz-choices{display:flex;flex-direction:column;gap:9px}
.qz-c{display:flex;align-items:flex-start;gap:11px;width:100%;text-align:left;
  padding:14px 14px;border:1.5px solid var(--line);border-radius:var(--r-btn);
  background:var(--surface);cursor:pointer;font-family:var(--kr);
  transition:border-color .12s, background .12s, transform .1s}
.qz-c:hover{border-color:var(--navy-l);background:#F7F9FC}
.qz-c:active{transform:scale(.99);background:#EEF3F9}
/* 번호 원반 — 정답 안내("정답: 2번")와 눈으로 이어지게 */
/* ★번호 원반 — 남색으로 채워 «누를 것»으로 보이게 한다. 회색이면 목록처럼 읽힌다. */
.qz-c .no{flex:0 0 27px;height:27px;border-radius:50%;background:var(--navy);
  color:#fff;font-size:13px;font-weight:800;display:flex;align-items:center;
  justify-content:center;margin-top:1px;transition:transform .12s}
.qz-c:active .no{transform:scale(.9)}
.qz-c .tx{flex:1 1 auto;font-size:15px;font-weight:600;line-height:1.5;
  color:var(--tx);word-break:keep-all}

/* 채점 결과 */
.qz-verdict{display:flex;align-items:center;gap:10px;padding:4px 0 12px}
.qz-verdict .ic{width:38px;height:38px;border-radius:50%;display:flex;
  align-items:center;justify-content:center;flex:0 0 38px}
.qz-verdict .tx{font-size:19px;font-weight:800;letter-spacing:-.3px}
.qz-verdict.ok .ic{background:var(--ok-bg);color:var(--ok)}
.qz-verdict.ok .tx{color:var(--ok)}
.qz-verdict.no .ic{background:var(--bad-bg);color:var(--accent)}
.qz-verdict.no .tx{color:var(--accent)}
/* 결과가 «나타나는» 느낌 — 끝 상태가 정상 화면이라 reduced-motion 에서도 온전하다 */
@keyframes qzIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}
.qz-verdict{animation:qzIn .28s ease-out both}

.qz-ans{font-size:15px;color:var(--tx2);margin-bottom:10px}
/* 해설 — 채점 뒤에만 나온다. 읽는 글이라 배경을 깔아 문제와 구분한다 */
.qz-exp{background:var(--bg);border-radius:var(--r-btn);padding:14px;
  font-size:15px;line-height:1.6;color:var(--tx);word-break:keep-all}
.qz-exp .cap{display:flex;align-items:center;gap:5px;color:var(--muted)}
.qz-exp .cap svg{width:13px;height:13px;flex:0 0 13px}

/* ── 조합 퀴즈: 「깨는 맛」 요소  [2026-09-03 대표 지시] ──────────────────────
   「공부하듯 지루하면 안 된다. 하나씩 깨가는 기분이 들어야 한다」
   → ①콤보(지금 몇 연속) ②분야별 진행 막대. 숫자 하나보다 «차오르는 것»이 진도로 읽힌다. */

/* 콤보 배지 — 문제 위에 작게, 채점 결과에는 크게 */
.qz-combo{display:inline-flex;align-items:center;gap:3px;padding:3px 9px;
  border-radius:var(--r-pill);background:#FFF4E5;color:#8A5A00;
  font-size:12px;font-weight:800;line-height:1.5;white-space:nowrap}
.qz-combo svg{width:13px;height:13px}
.qz-combo.big{margin-left:auto;font-size:14px;padding:5px 12px}
/* ★3연속부터 «불붙은» 색 — 숫자만 오르면 특별한 줄 모른다 */
.qz-combo.hot{background:linear-gradient(135deg,#FFE0B2,#FFCC80);color:#7A4100;
  box-shadow:0 1px 6px rgba(224,140,38,.28)}
/* 신기록 — 금색으로 바뀐다. 남과 겨루지 않아도 이길 상대(내 기록)가 생긴다 */
.qz-combo.rec{background:linear-gradient(135deg,#F2C14E,#E0A526);color:#3A2A06;
  box-shadow:0 2px 8px rgba(224,165,38,.35)}
/* 콤보가 «붙는» 느낌 — 끝 상태가 정상이라 reduced-motion 에서도 온전하다 */
@keyframes qzPop{0%{transform:scale(.6);opacity:0}70%{transform:scale(1.12)}100%{transform:scale(1);opacity:1}}
.qz-combo.big{animation:qzPop .34s cubic-bezier(.2,.8,.3,1) both}

/* 분야별 진행 — 5칸이 차오르는 것이 «지도»가 된다 */
.qz-prog{list-style:none;margin:16px 0 0;padding:0}
.qz-prog li{display:flex;align-items:center;gap:10px;padding:8px 0}
.qz-prog .lb{flex:0 0 74px;font-size:13px;font-weight:700;color:var(--tx2)}
.qz-prog .bar{flex:1 1 auto;height:10px;border-radius:5px;background:var(--bg);
  overflow:hidden;min-width:0}
.qz-prog .bar i{display:block;height:100%;border-radius:5px;
  background:linear-gradient(90deg,var(--navy-l),var(--navy));
  transition:width .5s cubic-bezier(.2,.8,.3,1)}
.qz-prog .ct{flex:0 0 auto;font-size:12px;font-weight:800;color:var(--muted);
  min-width:38px;text-align:right}
/* 그 분야를 다 깬 줄 — 색이 바뀌어 «클리어»가 눈에 띈다 */
.qz-prog li.done .lb{color:var(--ok)}
.qz-prog li.done .bar i{background:linear-gradient(90deg,#2E9E5B,var(--ok))}
.qz-prog li.done .ct{color:var(--ok)}
/* 막대 폭 — CSP 가 인라인 style 을 막아 클래스로 낸다(투표 결과 막대와 같은 어법) */
/* 상단 진행 막대 — 5% 단위(문제를 풀 때마다 눈에 띄게 움직이려면 촘촘해야 한다) */
.qz-track i.w0{width:0}
.qz-track i.w5{width:5%}    .qz-track i.w10{width:10%}   .qz-track i.w15{width:15%}
.qz-track i.w20{width:20%}  .qz-track i.w25{width:25%}   .qz-track i.w30{width:30%}
.qz-track i.w35{width:35%}  .qz-track i.w40{width:40%}   .qz-track i.w45{width:45%}
.qz-track i.w50{width:50%}  .qz-track i.w55{width:55%}   .qz-track i.w60{width:60%}
.qz-track i.w65{width:65%}  .qz-track i.w70{width:70%}   .qz-track i.w75{width:75%}
.qz-track i.w80{width:80%}  .qz-track i.w85{width:85%}   .qz-track i.w90{width:90%}
.qz-track i.w95{width:95%}  .qz-track i.w100{width:100%}

.qz-prog .bar i.w0{width:0}
.qz-prog .bar i.w10{width:10%}   .qz-prog .bar i.w20{width:20%}
.qz-prog .bar i.w30{width:30%}   .qz-prog .bar i.w40{width:40%}
.qz-prog .bar i.w50{width:50%}   .qz-prog .bar i.w60{width:60%}
.qz-prog .bar i.w70{width:70%}   .qz-prog .bar i.w80{width:80%}
.qz-prog .bar i.w90{width:90%}   .qz-prog .bar i.w100{width:100%}

/* ── 조합 퀴즈: 홈 카드 · 분야 클리어 · 틀린 문제  [2026-09-03] ─────────────── */

/* 홈 카드의 진행 줄 */
.qzh{display:flex;align-items:center;gap:11px;margin-bottom:4px}
.qzh-step{flex:0 0 auto;font-size:19px;font-weight:800;color:var(--navy);letter-spacing:-.5px;line-height:1}
.qzh-step i{font-style:normal;font-size:12px;font-weight:700;color:var(--muted);margin-left:1px}

/* ★★분야 클리어 배너 — 「하나씩 깨는 기분」의 완성.
   카드 밖에 두어 «화면을 뚫고 나온» 느낌을 준다. 금색은 시상대 1위와 같은 어법이다. */
.qz-clear{position:relative;overflow:hidden;text-align:center;padding:20px 16px 18px;
  border-radius:var(--r-card);margin-bottom:14px;
  background:linear-gradient(160deg,#1B3A5E 0%,#12283F 100%)}
/* 위에서 떨어지는 빛 */
.qz-clear::before{content:'';position:absolute;left:50%;top:-60%;width:150%;height:150%;
  transform:translateX(-50%);pointer-events:none;
  background:radial-gradient(closest-side,rgba(242,193,78,.28),rgba(242,193,78,0) 70%)}
.qz-clear .ic{position:relative;display:block;color:#F2C14E;margin-bottom:6px;
  filter:drop-shadow(0 3px 8px rgba(0,0,0,.35))}
.qz-clear .ic svg{width:34px;height:34px;display:inline-block}
.qz-clear .t{position:relative;font-size:19px;font-weight:800;color:#fff;letter-spacing:-.4px}
.qz-clear .s{position:relative;font-size:13px;font-weight:600;color:var(--muted-on-navy);margin-top:3px}
.qz-clear .s .strong{color:#F2C14E}
/* 솟아오르는 등장 — 끝 상태가 정상이라 reduced-motion 에서도 온전하다 */
@keyframes qzClear{0%{transform:scale(.9);opacity:0}60%{transform:scale(1.02)}100%{transform:scale(1);opacity:1}}
.qz-clear{animation:qzClear .45s cubic-bezier(.2,.8,.3,1) both}

/* 틀린 문제 — 보기를 «읽는 목록»으로. `.qz-c` 를 재사용하고 상태 색만 바꾼다 */
.qz-c.is-static{cursor:default;background:var(--surface)}
.qz-c.is-static:hover{border-color:var(--line);background:var(--surface)}
.qz-c.is-static:active{transform:none}
.qz-c.is-static .no{background:var(--bg);color:var(--muted)}
/* 정답 줄 — 초록 */
.qz-c.is-ans{border-color:#BFE0CC;background:var(--ok-bg)}
.qz-c.is-ans .no{background:var(--ok);color:#fff}
/* 내가 고른(틀린) 줄 — 붉은색 */
.qz-c.is-mine{border-color:#F0D5D0;background:var(--bad-bg)}
.qz-c.is-mine .no{background:var(--accent);color:#fff}
.qz-c .tag{flex:0 0 auto;align-self:center;font-size:11px;font-weight:800;
  padding:2px 8px;border-radius:var(--r-pill);white-space:nowrap}
.qz-c .tag.ok{background:var(--ok);color:#fff}
.qz-c .tag.no{background:var(--accent);color:#fff}

/* ── 조합 퀴즈: 월 선택 · 마감 안내  [2026-09-03] ───────────────────────────── */
/* ★월간 랭킹인데 지난달을 볼 방법이 없었다 — 10월이면 9월 1등이 사라진다. */
.qz-months{display:flex;gap:6px;padding:12px 18px 0;overflow-x:auto;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.qz-months::-webkit-scrollbar{display:none}
.qz-m{flex:0 0 auto;padding:6px 13px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:var(--surface);
  font-size:13px;font-weight:700;color:var(--tx2);text-decoration:none;white-space:nowrap}
.qz-m.on{background:var(--navy);border-color:var(--navy);color:#fff}
.qz-m:active{transform:scale(.97)}

/* 마감 안내 — 7일 이하일 때만. 월초부터 떠 있으면 잔소리가 된다 */
.qz-dday{margin-left:8px;padding:2px 9px;border-radius:var(--r-pill);
  background:var(--warn-bg);color:var(--warn);font-size:12px;font-weight:800;
  white-space:nowrap;vertical-align:1px}

/* 퀴즈 문항 제보 안내 — 작게. 문제 푸는 화면이라 주인공이 되면 안 된다 [2026-09-03] */
.qz-report{margin-top:14px;text-align:center;font-size:12px;color:var(--muted);line-height:1.5}

/* ══ 투표 본문 서식 (2026-09-05 대표 지시 「안내나 강조는 부각」) ═══════════════════
   ★`mk_poll_body_render()` 가 내는 마크업 전용. 공지·자료실 본문(.body-text)에는 영향이 없다.
   ★HTML 을 입력으로 받는 것이 아니라, 정해진 표기(■■ / [ ] / ※ / ·)를 이 요소들로 바꾼 것이다. */
.pb > :first-child{margin-top:0}
.pb-p{margin:12px 0 0;line-height:1.75;word-break:keep-all}

/* 최상위 경고 — 가장 먼저 눈에 들어와야 한다. 붉은 테두리 + 굵은 글자. */
.pb-warn{margin:0 0 4px;padding:11px 13px;border:1.5px solid var(--accent);
  border-radius:10px;background:var(--bad-bg);color:var(--accent);
  font-size:14.5px;font-weight:800;line-height:1.5;text-align:center;letter-spacing:-.2px}

/* 소제목 — 구획을 나눈다. 왼쪽 세로 막대로 «여기부터 새 이야기»를 표시. */
.pb-h{margin:22px 0 0;padding-left:10px;border-left:3px solid var(--navy);
  font-size:16px;font-weight:800;color:var(--tx);line-height:1.4;word-break:keep-all}
.pb-h:first-child{margin-top:0}

/* ※ 참고 — 본문보다 한 단 낮게. 배경으로 «단서»임을 알린다. */
.pb-note{margin:12px 0 0;padding:11px 13px;border-radius:10px;background:var(--bg);
  font-size:13.5px;line-height:1.7;color:var(--tx2);word-break:keep-all}
.pb-note .pb-mark{font-weight:800;color:var(--warn)}
/* ★참고 박스 안의 `**굵게**` 는 **붉게** 낸다 — 그 박스에서 가장 중요한 낱말이라는 뜻이다.
   (대표 지시: 「"라운지" 내에서도 이부분 대화 "금지"」 처럼 낱말만 튀게) */
.pb-note b{color:var(--accent);font-weight:800}
/* ★보통 문단의 `**굵게**` 도 붉게 — 본문에서 굵게 한 것은 «강조»이지 «제목»이 아니다.
   (맨 위 보안 안내문의 「라운지」·「금지」가 이 경우다) */
.pb-p b{color:var(--accent);font-weight:800}

/* · 목록 — 두 갈래를 나란히 보여 준다(어느 쪽을 보고 있는지 포함). */
.pb-ul{margin:12px 0 0;padding:0;list-style:none}
.pb-ul li{position:relative;padding:9px 12px 9px 26px;margin-top:6px;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);
  font-size:14px;line-height:1.55;word-break:keep-all}
.pb-ul li::before{content:'';position:absolute;left:12px;top:16px;
  width:5px;height:5px;border-radius:50%;background:var(--muted)}
/* 지금 보고 있는 쪽 — 목록에서 바로 구분되게 */
.pb-ul li:has(.pb-now){border-color:var(--navy);background:var(--info-bg)}
.pb-now{color:var(--navy);font-weight:800;white-space:nowrap}
/* 관리자 — 투표 본문 표기 안내 목록 (2026-09-05).
   ★인라인 `style=` 은 CSP 가 조용히 막는다. 이런 소소한 서식도 반드시 클래스로 둔다. */
.pb-help{margin:6px 0 0;padding-left:18px;list-style:disc}
.pb-help li{margin-top:3px}
.pb-help code{padding:1px 5px;border-radius:5px;background:var(--bg);
  border:1px solid var(--line);font-size:12px}

/* ═══ 만화 [2026-09-07] ═══════════════════════════════════════════════════
   ★★비율이 편마다 다르다(실측 1073×1280 · 1200×896). 그래서 고정 높이를 주지 않고
     `height:auto` 로 둔다 — 고정하면 세로형이 잘리거나 가로형에 빈 공간이 생긴다.
     서버가 `<img width height>` 를 박아 주므로 내려받기 전에도 자리는 잡힌다.
   ★`--fs`(큰 글씨 보기)를 걸지 않는다 — 그림이라 글자 배율과 무관하고,
     걸면 20쪽짜리에서 화면이 통째로 흔들린다. */
/* 목록 표지 · 관리자 쪽 미리보기.
   ★★고정 폭 + `object-fit:cover` 로 «칸»을 만든다 — 비율이 편마다 달라서(0.84 ~ 1.34)
     자연 크기로 두면 줄 높이가 제각각이 되어 목록이 들쭉날쭉해진다.
   ★`aspect-ratio` 로 칸을 고정하므로 이미지가 늦게 와도 줄이 튀지 않는다. */
.mw-cover{flex-shrink:0;width:56px;aspect-ratio:3/4;object-fit:cover;object-position:top;
  border-radius:8px;border:1px solid var(--line);background:var(--surface);margin-right:10px}
.mw-thumb{flex-shrink:0;width:48px;aspect-ratio:3/4;object-fit:cover;object-position:top;
  border-radius:6px;border:1px solid var(--line);background:var(--surface);margin-right:10px}

.mw-pages{display:flex;flex-direction:column;gap:10px;margin-top:14px}
.mw-page{display:block;width:100%;height:auto;border-radius:var(--r-card);
  border:1px solid var(--line);background:var(--surface);cursor:zoom-in}

/* 크게 보기 — 전체화면.
   ★★z-index 는 **85 이상**이어야 한다. 라운지 AI 버튼(FAB)이 화면을 가린 사고가 두 번 있었고
     그때 정해진 경계가 이 값이다. 낮추지 말 것.
   ★확대는 브라우저 기본 핀치줌에 맡긴다(`touch-action`) — 직접 구현하면 기기마다 어긋나고
     시스템 돋보기와 충돌한다. */
.mw-zoom{position:fixed;inset:0;z-index:90;background:#000;overflow:auto;
  -webkit-overflow-scrolling:touch;touch-action:pan-x pan-y pinch-zoom;padding:0}
/* ★★**원본 크기로 띄운다**(`width:auto`). 화면 폭에 맞추면 상세 화면과 똑같은 크기라
     「눌렀는데 그대로」가 된다 — 실화면에서 확인했다. 가로로 긴 편은 375px 폭에 4컷이 들어가
     말풍선 글자가 원본의 1/3 이 되어 **읽을 수가 없다**. 그게 이 뷰어의 존재 이유다.
   ★넘치는 만큼은 좌우로 밀어서 본다(부모가 `overflow:auto`). 핀치줌도 그대로 된다. */
.mw-zoom img{display:block;width:auto;max-width:none;height:auto;margin:0 auto}
/* ★닫기 버튼은 **아래쪽 가운데**에 둔다. 위쪽 모서리에 두면 만화 제목·첫 컷을 가린다(실화면 확인).
   ★`position:fixed` 라 스크롤해도 따라오고, 배경을 진하게 줘 밝은 그림 위에서도 보인다. */
.mw-zoom-x{position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(16px + env(safe-area-inset-bottom));z-index:91;
  min-height:48px;padding:0 26px;font-size:16px;font-weight:700;
  border:1px solid rgba(255,255,255,.5);border-radius:var(--r-pill);
  background:rgba(0,0,0,.82);color:#fff;cursor:pointer;box-shadow:0 2px 12px rgba(0,0,0,.6)}

/* ★★★[2026-09-07 대표 지시] 캡처 유출 추적용 워터마크.
   why: 조합원 전용 자료가 캡처돼 밖으로 돌 때 **누가 찍었는지** 알 수 있어야 한다.
     조합원번호와 날짜를 화면 전체에 옅게 깔아 캡처 이미지에 함께 남게 한다.
   ★`z-index:2000` — 사진·문서 뷰어(`.pv`, z-index 1200)보다 위다. 유출은 대개 그 화면에서
     일어나므로 거기를 못 덮으면 의미가 없다.
   ★`pointer-events:none` 필수 — 안 넣으면 화면 전체가 클릭을 먹어 앱이 죽는다.
   ★색은 중간 회색(#8a8a8a)이다. 밝은 배경(#F5F7FA)에서도, 뷰어의 검은 배경에서도
     양쪽 다 보이는 유일한 구간이다. 흰색이나 검은색은 한쪽에서 사라진다.
   ★배경 이미지(조합원번호·날짜가 든 SVG)는 사람마다 달라 `_layout.php` 가 인라인으로 준다.
     CSP 가 style **속성**을 막으므로 `<style nonce>` 로 나간다. */
.mk-wm{position:fixed;inset:0;z-index:2000;pointer-events:none;
       background-repeat:repeat;opacity:.2}
/* ★인쇄에도 남긴다 — 화면 캡처만 막고 인쇄로 새면 같은 구멍이다. */
@media print{.mk-wm{opacity:.22}}

/* ── 만화 좋아요·싫어요 · 댓글  [2026-09-08] ─────────────────────────────────
   ★버튼은 44px 높이를 지킨다(주 이용자가 40~70대다). 댓글의 「삭제」만 작게 두되
     `::after` 로 **보이지 않는 히트영역**을 넓혀 44px 를 맞춘다(`.lg-x` 와 같은 어법).
   ★싫어요가 눌린 상태만 강조색(--accent)을 쓴다 — 안 누른 상태까지 빨갛게 두면
     화면이 «경고»처럼 읽힌다. */
.mw-rx{display:flex;gap:10px;flex-wrap:wrap}
.mw-rxb{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 16px;
        border:1px solid var(--line);border-radius:var(--r-pill);background:var(--surface);
        color:var(--tx2);font-size:15px;cursor:pointer}
.mw-rxb .mw-rxc{font-weight:700;font-variant-numeric:tabular-nums}
.mw-rxb.on{border-color:var(--navy);color:var(--navy);font-weight:600;background:#F2F5F9}
.mw-rxb[data-mw-rx="dislike"].on{border-color:var(--accent);color:var(--accent);background:#FCF1EF}

.mw-cmts{list-style:none;margin:0;padding:0}
.mw-cmt{display:flex;gap:10px;padding:13px 0;border-top:1px solid var(--line)}
.mw-cmt:first-child{border-top:0;padding-top:0}
.mw-cmt-b{flex:1;min-width:0}                      /* ★min-width:0 이 없으면 긴 낱말이 카드를 밀어낸다 */
.mw-cmt-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin:0 0 4px}
.mw-cmt-t{margin:0;font-size:calc(15px * var(--fs));line-height:1.7;overflow-wrap:anywhere}
.mw-cmt-act{margin-top:6px}
/* ★★★[2026-09-12 대표 지적 3차] 신고 사유를 **라운지와 같은 알약 버튼**으로 바꿨다.
   종전의 `<select>` + 「보내기」(`.mw-cmt-rsn`·`.mw-cmt-act.is-rp`)는 **이 변경으로 쓰는 곳이
   0 이 되어 함께 지웠다** — 남겨 두면 다음 사람이 둘 중 어느 쪽이 살아 있는지 알 수 없다.
   ★패널 자체는 `.lg-blpick.lg-rppick`(라운지 신고 시트와 **같은 컴포넌트**)을 그대로 쓴다.
     여기서는 그 패널을 «댓글 아래에 놓을 때의 간격»만 정한다.
   ★접힘/펼침 글자 교체(신고↔취소)는 아래 두 줄이 전부다. `content` 가 아니라 실제 글자를
     숨기고 보이는 방식이라 화면낭독기·복사·검색에 잡힌다. */
.mw-cmt-rp{margin-top:6px}
.mw-cmt-rp>summary{display:inline-block}
.mw-cmt-rp>.lg-blpick{margin-top:6px}
.mw-cmt-rp>summary .mw-rp-oc{display:none}
.mw-cmt-rp[open]>summary .mw-rp-cl{display:none}
.mw-cmt-rp[open]>summary .mw-rp-oc{display:inline}
.mw-cmt-x{position:relative;min-height:32px;padding:0 6px;border:0;background:none;
          color:var(--muted);font-size:13px;text-decoration:underline;cursor:pointer}
.mw-cmt-x::after{content:"";position:absolute;inset:-6px -8px}
.mw-cmt-form textarea{min-height:88px}
/* ★앵커 착지 보정 — `#cmt`(조합원)·`#cmts`(관리자)로 되돌아올 때 제목줄이 sticky 헤더(.hd) 밑에 깔린다.
   `#edit` 규칙(app.css 위쪽)과 같은 어법. */
#cmt,#cmts{scroll-margin-top:calc(var(--hd-h) + 14px)}
/* 싫어요 엄지는 **CSS 로만 뒤집는다** — 같은 SVG 하나를 재사용한다(좌우까지 도는 rotate 는 쓰지 않는다) */
.mw-rxb[data-mw-rx="dislike"] svg{transform:scaleY(-1)}
/* 관리자 「가리기」 사유칸 — 한 줄에 버튼과 나란히 놓되 좁은 화면에서는 접힌다 */
.mw-cmt-reason{max-width:320px;height:34px;padding:0 10px;border:1px solid var(--line);
  border-radius:var(--r-inp);background:var(--surface);font-size:13px;margin-right:6px}

/* ══ 신고 · 차단  [2026-09-09 대표 지시 · 애플 심사 요구] ═══════════════════
   ★★공개 라운지의 «차단» 은 **감추기가 아니라 접기** 다(대표 결정).
     글은 그대로 오고 덮개를 눌러 펼 수 있다 — 공개방이 하나뿐이라 조합 안건을
     못 보게 하면 나중에 「나는 못 봤다」는 분쟁이 되기 때문이다.
   ★시트·사유줄은 운영진 「가리기」(`.lg-blpick`)와 **같은 생김새를 재사용**한다.
     새 모달을 들이면 좁은 폰에서 또 자리를 다투게 된다. */
.lg-nameBtn{
  /* ★버튼 기본 생김새를 지운다 — 이름은 «이름처럼» 보여야 한다. `.lg-name` 의
     글꼴·색은 그대로 두고, 눌린다는 것만 밑줄로 알린다. */
  appearance:none;-webkit-appearance:none;background:none;border:0;padding:0;
  font:inherit;color:inherit;cursor:pointer;
  text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px;
}
.lg-nameBtn:hover{text-decoration-style:solid}

.lg-foldcover{
  /* 접힌 줄의 덮개. ★말풍선을 지우는 것이 아니라 **위에 한 줄을 얹는다** —
     원문은 DOM 에 그대로 있고 펼치면 바로 보인다. */
  appearance:none;-webkit-appearance:none;cursor:pointer;
  display:block;width:100%;margin:2px 0 4px;padding:9px 12px;
  border:1px dashed #b9c0cc;border-radius:10px;background:#f2f4f8;
  color:#5a6270;font-size:13px;text-align:left;line-height:1.4;
}
.lg-foldcover:hover{background:#e9edf4}
/* ★접힘은 **감추기(display:none)가 아니라** 접기다. 높이만 0 으로 만들고
   내용은 남긴다 — 읽어주기·복사 같은 기능이 지워진 글을 붙들지 않게 한다. */
.lg-row.lg-folded .lg-col > *:not(.lg-foldcover){display:none}
.lg-row.lg-folded .lg-avatar{opacity:.35}
/* ★★접힌 줄은 **폭을 넓게** 준다. `.lg-row{max-width:88%}` 안에서 덮개가 100% 를 먹으면
   좁은 폰에서 「차단한 조합원의 / 메시지입니다 · 눌러서 / 보기」 로 **3줄이 된다**(실측).
   덮개는 말풍선이 아니라 «안내 줄» 이므로 폭을 아끼는 이유가 없다. */
.lg-row.lg-folded{max-width:100%}
/* ★`.lg-row` 는 flex 다 — 덮개는 그 안의 **아이템**이라 `width:100%` 만으로는 안 늘어난다.
   `flex:1 1 100%` 로 줄 전체를 차지하게 해야 한 줄에 들어간다(실측: 안 주면 3줄). */
.lg-row.lg-folded .lg-foldcover{flex:1 1 100%;width:auto}

/* ★★신고 시트는 **경고색을 쓰지 않는다.** `.lg-blpick` 은 운영진 「가리기」용이라 테두리가
   경고색(`--accent`)인데, 그대로 두면 조합원이 신고 메뉴를 열 때마다 붉은 상자를 본다 —
   «내가 뭘 잘못했나» 로 읽힌다. 생김새(줄·간격)만 재사용하고 색은 중립으로 되돌린다. */
.lg-rpsheet,.lg-rppick{border-color:var(--line)}
.lg-rpsheet .lg-blopt,.lg-rppick .lg-blopt{color:var(--fg)}

/* ══ 동영상  [2026-09-12 대표 지시] ═════════════════════════════════════════
   ★★좋아요·싫어요와 댓글은 **만화의 부품(`.mw-rx*`·`.mw-cmt*`)을 그대로 쓴다.**
     같은 행동이 제품 안에서 두 모양이면 어느 쪽도 완성돼 보이지 않고, 복사해 두면
     한쪽만 고친 상태가 반드시 생긴다. 여기에는 **동영상에만 있는 것**만 둔다.
   ★목록은 격자다 — 영상은 그림이 곧 내용이라 한 줄 목록으로는 고를 수가 없다.
     `auto-fill minmax(220px,1fr)` 라 360px 폰에서는 한 칸(=썸네일이 화면 폭)이 된다.
     ★★`%` 상한을 쓰지 않는다 — 이 코드베이스에서 퍼센트 max-width 가 flex 를 부순 전례가 있다. */
.vd-grid{list-style:none;margin:14px 0 0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px}
.vd-grid>li{min-width:0}
.vd-grid>li>a{display:block;color:inherit;text-decoration:none}

/* 썸네일 칸. ★`aspect-ratio` 로 자리를 먼저 잡는다 — 그림이 늦게 와도 줄이 튀지 않는다.
   ★★그림이 아예 없는 편도 있다(썸네일 추출 실패). 그때 이 칸이 «회색 네모»로 남아야
     제목만 덩그러니 남는 것보다 낫다 — 그래서 배경·테두리를 칸 쪽에 준다. */
.vd-th{position:relative;display:block;aspect-ratio:16/9;overflow:hidden;
  border-radius:var(--r-card);border:1px solid var(--line);background:#0C1620}
.vd-th img{display:block;width:100%;height:100%;object-fit:cover}
/* 재생 표식. ★이모지 금지 규칙에 따라 inline SVG(`mk_icon('play')`)를 쓴다.
   ★어두운 알약 + 밝은 테두리 — 밝은 썸네일 위에서도 사라지지 않는다. */
.vd-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  display:flex;align-items:center;justify-content:center;width:46px;height:46px;
  border-radius:50%;background:rgba(0,0,0,.55);border:1px solid rgba(255,255,255,.6);color:#fff}
.vd-play svg{width:22px;height:22px;margin-left:2px;fill:currentColor;stroke:none}
/* 길이 표시. ★`tabular-nums` 로 자리를 고정해 목록에서 좌우로 흔들리지 않게 한다. */
.vd-dur{position:absolute;right:8px;bottom:8px;padding:2px 7px;border-radius:6px;
  background:rgba(0,0,0,.72);color:#fff;font-size:12px;font-variant-numeric:tabular-nums}
/* 아직 «안 본» 편 표시. ★길이 표시(`.vd-dur`)와 **대각선으로** 둔다 — 같은 모서리에 두면 겹친다.
   ★`--fs`(큰 글씨 보기)를 걸지 않는다: `.vd-dur` 과 한 쌍으로 보이는 표식이라 같이 고정폭이어야
     썸네일 위에서 크기가 어긋나지 않는다.
   ★색은 배지와 같은 `--accent` — 「안 읽음」을 뜻하는 이 앱의 색이다(공지 목록 점·nav 배지와 같은 말). */
.vd-new{position:absolute;left:8px;top:8px;padding:2px 7px;border-radius:6px;
  background:var(--accent);color:#fff;font-size:12px;font-weight:700;line-height:1.5}
/* ★제목은 두 줄까지. 한 줄로 자르면 비슷한 제목을 구분할 수 없고, 무제한이면 칸 높이가 들쭉날쭉해진다. */
.vd-t{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  margin-top:8px;font-size:calc(15px * var(--fs));font-weight:600;line-height:1.45;
  color:var(--tx);word-break:keep-all}
.vd-s{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  margin-top:3px;font-size:calc(13px * var(--fs));line-height:1.5;color:var(--tx2);word-break:keep-all}
.vd-m{display:block;margin-top:4px;font-size:calc(12px * var(--fs));color:var(--muted)}

/* 재생기.
   ★★`--fs`(큰 글씨 보기)를 걸지 않는다 — 영상은 글자가 아니고, 걸면 화면이 통째로 흔들린다.
   ★검은 배경을 깔아 «아직 첫 프레임이 안 온» 순간에도 빈 흰 칸이 보이지 않게 한다.
   ★`display:block` 필수 — 인라인이면 아래에 줄간격만큼 흰 띠가 생긴다. */
/* ★`outline:0` 을 주지 않는다 — 전역 `:focus-visible` 포커스 링까지 지워져
   키보드로 재생기에 닿았을 때 어디에 있는지 안 보인다(2026-09-12 리뷰). */
.vd-player{display:block;width:100%;aspect-ratio:16/9;background:#000;
  border-radius:var(--r-card)}

/* 관리자 업로드 진행 막대. ★라운지(`.js-up`)와 같은 생김새지만 그쪽은 라운지 화면에만 있다. */
.vd-up{margin-top:10px;padding:10px 12px;border:1px solid var(--line);
  border-radius:var(--r-card);background:var(--surface)}
.vd-up-h{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--tx2)}
.vd-up-h .sp{flex:1}
.vd-up-bar{margin-top:8px;height:8px;border-radius:999px;background:var(--line);overflow:hidden}
.vd-up-fill{height:100%;width:0;background:var(--navy);transition:width .2s linear}
/* 관리자 목록의 썸네일 — 만화(`.mw-thumb`)와 달리 가로형이다 */
.vd-athumb{flex-shrink:0;width:96px;aspect-ratio:16/9;object-fit:cover;border-radius:6px;
  border:1px solid var(--line);background:#0C1620;margin-right:10px}
/* ★수정 화면의 「지금 이 그림이 썸네일이다」 자리 — 96px 로는 무엇인지 분간이 안 된다(실화면 확인) */
.vd-athumb.is-lg{width:160px;border-radius:8px}

/* ══ 제보함  [2026-09-13, 대표 지시] ═══════════════════════════════════════
   ★★고령 조합원이 주 사용자다 — 글자를 키우고 줄간격을 넉넉히 둔다.
     여기 수치는 «읽는 글»이라 `--fs`(큰 글씨 보기)를 함께 건다.
   ★안내·예시가 화면의 절반을 차지하는 것이 의도다. 그게 없으면
     「총무가 해먹는 것 같다」 같은 확인 불가능한 글만 쌓인다(착수 때 확인한 목적). */

/* 작성 가이드 — 접히는 카드. ★기본 펼침(`open`)이라 요약줄은 «접기» 버튼처럼 보여야 한다. */
.tip-guide > summary{display:flex;align-items:center;gap:9px;padding:14px 16px;
  font-size:calc(15px * var(--fs));font-weight:800;color:var(--navy);
  border-radius:var(--r-card);transition:background .12s ease}
.tip-guide > summary svg{width:20px;height:20px;flex:0 0 20px;color:var(--navy-l)}
.tip-guide > summary:hover{background:var(--info-bg)}
.tip-guide[open] > summary{border-bottom:1px solid var(--line);border-radius:var(--r-card) var(--r-card) 0 0}
/* ★펼침 표시. 삼각형은 기기마다 다르게 보여 직접 그린다(이모지 금지 규칙과 같은 이유). */
.tip-guide > summary::after{content:'';margin-left:auto;width:9px;height:9px;flex:0 0 9px;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .15s ease}
.tip-guide[open] > summary::after{transform:rotate(-135deg) translate(-2px,-2px)}

/* 다섯 가지 항목. ★번호를 직접 그린다 — 기본 `ol` 마커는 작고 색을 못 준다. */
.tip-ol{list-style:none;margin:10px 0 0;padding:0;counter-reset:tipn}
.tip-ol li{position:relative;counter-increment:tipn;padding:0 0 0 34px;margin-top:10px;
  font-size:calc(14.5px * var(--fs));line-height:1.65;color:var(--tx);word-break:keep-all}
.tip-ol li::before{content:counter(tipn);position:absolute;left:0;top:2px;
  width:23px;height:23px;border-radius:50%;background:var(--navy);color:#fff;
  font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center}

/* 예시 상자. ★좋은 예/나쁜 예를 **색과 왼쪽 띠**로 가른다 — 글자만으로는 훑을 때 구분이 안 된다. */
.tip-ex{margin-top:8px;padding:13px 15px;border-radius:10px;
  font-size:calc(14.5px * var(--fs));line-height:1.7;word-break:keep-all}
.tip-ex-ok{background:var(--ok-bg);border-left:4px solid var(--ok);color:#17402A}
.tip-ex-no{background:var(--bad-bg);border-left:4px solid var(--accent);color:#5E241D}

/* 본문 칸 — 「충분히 입력할 수 있어야 한다」가 요구사항이라 넉넉히 두되,
   PC 에서 빈 상자가 화면 1/3 을 먹지 않게 최소높이로 잡는다. */
#content{min-height:200px;line-height:1.7}
/* 도움말 줄바꿈. ★괄호만 다음 줄로 떨어지는 것을 막는다(390px 실캡처에서 확인). */
.tip-help{word-break:keep-all}
.tip-nb{white-space:nowrap}

/* 올리는 중 막대 — 동영상(`.vd-up`)과 같은 생김새다. 화면이 달라도 뜻이 같으면 모양도 같아야 한다. */
.tip-up{margin-top:12px;padding:10px 12px;border:1px solid var(--line);
  border-radius:var(--r-card);background:var(--bg)}
.tip-up-h{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--tx2)}
.tip-up-h .sp{flex:1}
.tip-up-h .js-tip-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tip-up-bar{margin-top:8px;height:8px;border-radius:999px;background:var(--line);overflow:hidden}
.tip-up-fill{height:100%;width:0;background:var(--navy);transition:width .2s linear}

/* 올린 파일 목록. ★지우는 버튼이 없다 — 첨부에 DELETE 권한 자체가 없다(설계). */
.tip-files{list-style:none;margin:12px 0 0;padding:0}
.tip-files li{display:flex;align-items:center;gap:9px;padding:11px 13px;margin-top:8px;
  border:1px solid var(--line);border-radius:10px;background:var(--bg);min-width:0}
.tip-files li svg{width:16px;height:16px;flex:0 0 16px;color:var(--muted)}
.tip-files li .t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:calc(14px * var(--fs));color:var(--tx);font-weight:600}
.tip-files li .m{flex:0 0 auto;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
/* 빼기(X). ★터치 타깃을 32px 로 잡는다 — 고령 사용자가 옆 글자를 누르지 않게.
   ★평소엔 회색, 누를 때만 붉게. 삭제 버튼이 상시 빨가면 화면이 «위험해» 보인다. */
.tip-x{flex:0 0 auto;width:32px;height:32px;margin:-6px -6px -6px 2px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:0;background:none;border-radius:50%;color:var(--muted);cursor:pointer;
  transition:background .12s ease,color .12s ease}
.tip-x svg{width:15px;height:15px}
.tip-x:hover{background:var(--bad-bg);color:var(--accent)}
.tip-x:active{background:var(--bad-bg);color:var(--accent)}
.tip-x[disabled]{opacity:.4;cursor:default}

/* 상세 제목. ★인라인 `style` 을 못 쓴다 — CSP(style-src 'self' 'nonce-…')가 조용히 죽인다. */
.tip-h2{margin:0;font-size:calc(18px * var(--fs));line-height:1.45;word-break:keep-all}

/* ── 관리자 제보 목록·상세 ───────────────────────────────────────────── */
/* 상태 알약. ★«아직 아무도 안 봤다»가 한눈에 보여야 한다 — 그게 이 표의 존재 이유다. */
.tip-st{display:inline-flex;align-items:center;padding:2px 9px;border-radius:999px;
  font-size:12px;font-weight:800;white-space:nowrap}
.tip-st-n{background:var(--accent);color:#fff}                       /* 접수 — 미열람 */
.tip-st-r{background:var(--info-bg);color:var(--navy)}               /* 열람함 */
.tip-st-c{background:var(--line);color:var(--tx2)}                   /* 종료 */
/* 본문 — 줄바꿈을 그대로 살린다(제보자가 문단을 나눠 적는다). */
.tip-body{white-space:pre-wrap;word-break:keep-all;line-height:1.75;
  font-size:calc(15px * var(--fs));color:var(--tx)}

/* 인쇄용 — 「모아서 변호사에게 전달합니다」를 빈 약속으로 두지 않기 위한 화면이다.
   ★화면 장식(카드 테두리·그림자·버튼·네비)을 전부 걷어내고 글만 남긴다. */
@media print{
  .hd, .tabs, .side, .mfoot, .btn, .btn-row, .tip-noprint, .ai-fab, .mwc-fab{display:none !important}
  .card{border:0 !important;box-shadow:none !important;break-inside:avoid}
  .main, .wrap, .wrap-wide{margin:0 !important;padding:0 !important;max-width:none !important}
  .tip-body{font-size:12pt}
  .tip-print-item{break-after:page}
  .tip-print-item:last-child{break-after:auto}
}

/* ═══ 비용 납부 관리 (admin/poll_voters.php) · 입금 안내 (pay.php)  [2026-09-14] ═══ */
.pay-on{font-size:13px;font-weight:800;color:#fff;background:var(--accent);
  padding:3px 10px;border-radius:var(--r-pill)}
.pay-stat{display:flex;gap:10px;flex-wrap:wrap;margin:0}
.pay-stat>div{flex:1 1 110px;border:1px solid var(--line);border-radius:var(--r-btn);padding:10px 12px}
.pay-stat dt{font-size:13px;color:var(--tx2);margin-bottom:4px}
.pay-stat dd{margin:0;font-size:20px;font-weight:800}
.pay-stat dd.ok{color:var(--ok)}
.pay-stat dd.no{color:var(--accent)}

/* ── 거르개 + 찾기 한 줄 ──────────────────────────────────────────────
   ★★295명을 눈으로 훑게 두면 그게 곧 오조작이다(한 칸 옆의 버튼을 누른다).
     운영진의 실제 일은 «통장 내역에 적힌 그 사람을 찾는» 것이라, 찾기가 이 화면의 주기능이다. */
.pay-tools{display:flex;gap:12px;flex-wrap:wrap;align-items:center;padding-bottom:12px}
.pay-segs{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-btn);overflow:hidden}
.pay-seg{display:inline-flex;align-items:center;min-height:38px;padding:0 14px;
  font-size:14px;font-weight:700;color:var(--tx2);text-decoration:none;background:var(--surface)}
.pay-seg + .pay-seg{border-left:1px solid var(--line)}
.pay-seg:hover{background:var(--bg)}
.pay-seg.on{background:var(--navy);color:#fff}
.pay-find{flex:1 1 220px;display:flex;align-items:center;gap:8px;min-width:0}
.pay-find input{flex:1;min-width:0;min-height:38px;padding:0 12px;
  border:1px solid var(--line);border-radius:var(--r-btn);background:var(--surface);font-size:14px}
.pay-find .cap{flex:0 0 auto;white-space:nowrap}

/* ── 명단 표 ──────────────────────────────────────────────────────────
   ★★★처음엔 «미납» 줄을 분홍으로 칠했다. 295명이 전부 미납인 상태에서는 화면이 통째로
     분홍이 되어 강조가 아무 뜻도 없고 보기만 사납다(26-09-14 대표 지적).
     → **바뀐 쪽(납부함)만** 칠한다. 소수가 눈에 띄어야 «몇 명 처리했는지»가 읽힌다.
   ★줄 높이를 줄인다. 버튼이 44px 면 295줄이 끝없이 길어져 찾기가 더 어려워진다 —
     터치 목표는 38px 로 두되 이 화면은 PC 운영 화면이라 허용 범위다. */
.pay-tb td{padding-top:8px;padding-bottom:8px}
.pay-tb .row-paid td{background:#F1F8F4}
.pay-tb .row-paid td:first-child{box-shadow:inset 3px 0 0 var(--ok)}
.pay-td{display:flex;align-items:center;gap:8px;justify-content:flex-end}
.pay-chip{display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;
  font-size:12.5px;font-weight:700;color:var(--ok);white-space:nowrap}
.pay-chip svg{width:15px;height:15px}
.pay-cell{display:inline-block;flex:0 0 auto}
.pay-b{min-height:38px;padding:0 14px;font-size:14px}
/* ★해제는 «되돌리기» 라 주 버튼처럼 보이면 안 된다 — 평소엔 조용히 있다가 눌릴 때만 반응한다. */
.pay-b-off{background:var(--surface);border-color:var(--line);color:var(--tx2);font-weight:700}
.pay-b-off:hover{background:var(--bg);color:var(--accent);border-color:var(--accent)}

/* ★계좌번호 옆 부연(카톡 모임통장) — 숫자보다 작고 흐리게. 숫자와 같은 크기면 계좌번호의 일부로 읽힌다.
   ★★복사 대상(#payAcct)과 **다른 요소**여야 한다 — 안에 넣으면 클립보드에 괄호까지 들어간다. */
.pay-acct dd.num .pay-acct-sub{font-size:12.5px;font-weight:600;color:var(--tx2);
  white-space:nowrap;margin-left:4px}

/* ★★★[2026-09-14 실측] 좁은 화면에서 «납부» 칸이 표 밖으로 밀려, 버튼을 누르려면 표를 가로로
   밀어야 했다(390px). 이 화면에서 버튼은 목적 그 자체라 안 보이면 기능이 없는 것과 같다.
   → 마지막 칸을 오른쪽에 **고정**한다. 이름·번호·동호는 그 아래로 스크롤되고 버튼은 늘 보인다.
   ★배경색을 반드시 준다 — 투명이면 스크롤되는 글자가 버튼 밑으로 비쳐 지나간다.
   ★납부한 줄은 초록 배경이라 같은 색을 다시 칠한다(상속이 안 된다). */
@media (max-width:760px){
  .pay-tb th:last-child,
  .pay-tb td.pay-td{position:sticky;right:0;z-index:1;background:var(--surface);
    box-shadow:-6px 0 6px -6px rgba(0,0,0,.18)}
  .pay-tb thead th:last-child{background:var(--navy)}
  .pay-tb .row-paid td.pay-td{background:#F1F8F4}
  /* ★칩(납부 09-14)과 버튼이 한 칸에 들어가면 고정 폭이 너무 넓어진다 — 좁은 화면에선 세로로 쌓는다 */
  .pay-td{flex-direction:column;align-items:flex-end;gap:4px;padding-left:10px}
}

/* ═══ 라운지 사진 묶음(앨범) · 뷰어 넘기기  [2026-09-14 대표 지시] ═══════════════
   연달아 보낸 사진을 한 말풍선 안 격자로 보여준다. 묶는 판단은 JS(`regroupAlbums`)가 하고
   여기서는 «칸을 어떻게 그리나» 만 정한다.
   ★★칸 크기는 **확정 px** 다. 퍼센트 상한은 flex 기초크기 계산에서 무시돼 행이 601px 로
     벌어진 사고가 이 파일 826-840 에 실측으로 적혀 있다(.lg-bubble.has-img 가 250px 인 이유).
   ★말풍선 자체는 `.has-img` 규칙(250px)을 그대로 쓴다 — 격자는 그 안에 들어간다. */
.lg-album{display:grid;grid-template-columns:repeat(3,76px);gap:4px}
/* 2장이면 두 칸을 크게 — 3열 격자에 2장만 있으면 오른쪽이 휑하다 */
.lg-album.n2{grid-template-columns:repeat(2,118px)}
.lg-album .lg-tile{width:100%;height:76px;object-fit:cover;border-radius:4px;display:block;
  max-width:none;max-height:none}          /* ★`.lg-img` 의 min()/max-height 상한을 칸 안에서는 푼다 */
.lg-album.n2 .lg-tile{height:118px}
/* 묶여서 감춘 행 — `hidden` 속성이 아니라 클래스로 감춘다(행은 DOM 에 남아야 뷰어의 「삭제」가 그 버튼을 누른다) */
.lg-row.is-alb{display:none}

/* 뷰어 좌우 넘기기 — JS 가 만들어 붙인다(마크업이 lounge.php·dm_room.php 두 곳이라) */
.lg-view-nav{position:absolute;top:50%;transform:translateY(-50%);
  width:44px;height:44px;border:0;border-radius:50%;cursor:pointer;   /* ★44px = 손가락 최소 크기 */
  background:rgba(0,0,0,.42);color:#fff;font-size:26px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;z-index:3}
.lg-view-nav:disabled{opacity:.28;cursor:default}
.lg-view-prev{left:8px}
.lg-view-next{right:8px}
/* 뷰어 아래 버튼 묶음 — 삭제·신고·가리기.  [2026-09-15]
   ★★버튼마다 `left:` 고정 px 을 주던 것을 **그릇 하나로 바꿨다**(규칙 교체이지 추가가 아니다).
     라벨 글자수가 달라(삭제·신고·가리기) 개별 배치로는 반드시 겹친다. 폭은 flex 가 잡는다.
   ★확정 px 만 쓴다 — 퍼센트 상한은 flex 기초크기 계산에서 무시돼 행이 벌어진 사고가 이 파일에 있다.
   ★★그릇에 `pointer-events:none` 이 **반드시** 있어야 한다. 없으면 그릇이 `ev.target` 이 되어
     뷰어의 배경 탭 닫기(`if (ev.target === view)`)가 아래쪽 띠 전체에서 죽는다. 버튼만 손을 받는다. */
.lg-view-acts{position:absolute;left:8px;bottom:calc(10px + env(safe-area-inset-bottom));
  display:flex;gap:8px;z-index:3;pointer-events:none}
.lg-view-act{pointer-events:auto;min-height:36px;padding:0 14px;border:0;border-radius:18px;
  cursor:pointer;background:rgba(0,0,0,.42);color:#fff;font-size:14px;font-weight:600}
.lg-view-del{background:rgba(192,57,43,.92)}   /* 삭제만 붉게 — 되돌릴 수 없는 동작 */
