/* ============================================================
   카리스 예배팀 허브 — "SEASIDE" 스킨 v5
   레퍼런스: 히로시 나가이(永井博) 80년대 시티팝 아트워크 (사용자 제공 이미지,
   _archive/refs/nagai.jpg. translate, don't copy)
   가져온 것: 위에서 아래로 깊은 하늘 → 수평선 → 물가로 읽히는 화면,
     그림자 없는 평면 색면, 딱 떨어지는 하드 엣지, 후투라 계열 라틴 트래킹,
     정오·노을·아침·땅거미로 갈리는 하늘.
   두고 온 것: 수영장 그림 자체(1:1 복사 금지)와 어두운 본문.
   유지: v4의 확신(잉크 2px 아웃라인 + 블러 0 하드 오프셋 섀도)과
     컬러코딩 IA(방송 바다 / 음향 잔디 / 찬양 붉은꽃 / 앨범 라일락 / 해).
   시그니처: ① 상단 하늘 밴드  ② 스포트라이트 카드 머리 = 예배 커버(96차부터. 유튜브 썸네일과 같은 얼굴,
                주일 하늘 · 브뚜/리허설 검정 테두리. 특별예배만 계절 풍경이 남았다)
             ③ 계절마다 갈리는 하늘  ④ 카드 바닥의 풀 데크 색 밴드
             ⑤ 본문 = 물가 (얕은 물빛 바탕 + 화면 바닥에 고정된 그 계절의 물가 그림)

   ── 색 규율 (2026-09-12, 사용자: "색 조합이 뒤죽박죽. 디테일까지 신경 써 줘") ──
   한 화면에 채도색은 **세 벌**만 선다: ① 잉크 ② 그 계절의 강조색 하나(--accent) ③ 의미색(역할 = 찬양·방송·음향 / 예배 = 주일·브뚜·리허설).
   · 단추는 두 종류뿐: 잉크 외곽선(기본) / 잉크 채움(카드의 주 동작 = 전체 재생). **색 단추 없음.**
   · «있다/켜짐» 상태는 전부 --accent-soft 한 가지(악보 있음·결단 있음·리허설 녹화·TODAY). 의미색으로 상태를 말하지 않는다.
   · 의미색은 **딱지와 머리띠에서만**(rlab·카드 머리·테이프·4px 띠). 키 배지·검색·팀 B 칩 같은 보조 요소는 무채(잉크 계열).
   · 홈의 구역 아이콘 타일은 계절 강조 하나. 도메인 색(섬김표 바다·찬양 붉은꽃·팀 모래·자료 잔디·앨범 라일락)은 **그 탭 안에서만**.
   · --deck(카드 바닥 띠·상단바 밑줄)은 --accent 와 같다. 계절색이 둘이면 그 자체로 뒤죽박죽이다.
   · 라일락은 앨범 탭 밖으로 나오지 않는다. 모래는 팀 탭 밖으로 나오지 않는다. 버터(#F5C63C)는 직접 쓰지 않고 --accent 를 거친다.

   never (v5):
   - 그라디언트는 하늘과 물에만. 카드·버튼·칩에 그라디언트 금지
   - 배경 그림은 **화면 바닥에만**, 글자 뒤로는 안 올라온다. 위쪽은 마스크로 지워 바탕색에 녹인다
   - 배경 색은 손으로 고르지 않는다. `tools/_sky_src/palette.json`(그림에서 뽑은 값)만 쓴다
   - 블러 섀도 금지. 그림자는 블러 0 하드 오프셋만
   - 본문 카드에 어두운 배경 금지 (딥 네이비는 상단바·탭바·히어로 같은 크롬에만)
   - 이모지 아이콘 금지. 야자수도 이모지 말고 SVG 실루엣
   - 모노폰트에 한글 금지 (Plex Mono 는 라틴·숫자 전용, 한글은 .ko)
   - 이름표 색을 이름 해시로 뿌리지 않는다. 색은 곧 역할이다 (.rl-*)
   - 역할 색은 계절을 타지 않는다 (계절이 바뀌면 색으로 역할을 못 읽는다)
   - transition:all 금지 · radius 12/16/20/28 스케일만

   ── 누르는 것만 단추 모양 (UX 130, 2026-09-27, 사용자: "이름도 버튼처럼 보이고, 버튼이 너무 많아. 머리가 아프거든") ──
   정보(이름 · 역할 · 키 · 딱지 · 날짜)는 테두리 · 그림자 없는 글자. 카드마다 볼록한 단추는 주 동작 하나(채움).
   줄마다 붙는 동작은 조용하게(테두리 없는 글자 · 아이콘). 가끔 쓰는 도구는 카드 맨 아래 한 줄.
   고르는 칩은 안 고른 것이 가볍고 고른 것만 볼록하다.
   ⚠ 이 규칙의 CSS 는 **파일 맨 끝 «UX 130» 블록**이 앞의 같은 선택자를 덮는 방식이다. 앞쪽 옛 규칙을 고치기 전에 끝 블록부터 볼 것.
   ============================================================ */
/* ── 폰트 ─────────────────────────────────────
   전부 **네이버 무료폰트**다 (사용자 지시 2026-09-01: "네이버 무료폰트에서 가장 적절한 폰트로,
   한 가지만 쓰지 말고 적절하게 최대한 다양하게").
   역할을 나눠 여섯 벌을 쓴다 — 아래 --f-* 토큰 참조.
   (여섯째 = 나눔스퀘어라운드, 2026-09-04 가사 전용으로 추가)
   ⚠ 나눔스퀘어 네오는 구글 폰트에 없다. 네이버가 주는 woff2 는 한 굵기당 11,172자 전부라 380KB 인데,
      `tools/make_fonts.py` 가 KS X 1001 2,350자 + 앱이 쓰는 글자로 줄여 113KB 로 굽는다.
      서브셋에 없는 희귀 글자는 두부가 되지 않고 **스택 다음의 나눔고딕**으로 떨어진다.
      그래서 스택에서 'Nanum Gothic' 을 빼면 안 된다. */
@font-face{font-family:'NanumSquareNeo'; font-weight:400; font-display:swap;
  src:url('/fonts/nsn-400.woff2') format('woff2');}
@font-face{font-family:'NanumSquareNeo'; font-weight:700; font-display:swap;
  src:url('/fonts/nsn-700.woff2') format('woff2');}
@font-face{font-family:'NanumSquareNeo'; font-weight:900; font-display:swap;
  src:url('/fonts/nsn-900.woff2') format('woff2');}
/* 나눔스퀘어라운드 — **가사 한 자리에만** 쓴다(--f-lyric).
   .lyrbody 는 곡 상세 시트 안에만 생기니 원래는 가사를 열 때 받아졌는데, 그러면 글자가 한 번
   갈아 끼워진다 → index.html 에서 **미리 받는다**(fetchpriority=low). */
@font-face{font-family:'NanumSquareRound'; font-weight:400; font-display:swap;
  src:url('/fonts/nsr-400.woff2') format('woff2');}

:root{
  /* 잉크 = 밤바다 네이비. 선을 없애지는 않는다 (선을 없앤 v3 가 "클로드로 딸깍"이었다) */
  --ink:#0B2A44;
  --on-ink:#fff;     /* 잉크로 채운 칩 · 띠 위 글자. 어두운 시간대엔 잉크가 밝아지니 이건 어두워진다(133차-e) */
  --top-safe:env(safe-area-inset-top, 0px);   /* 화면 맨 위에서 비워 둘 높이. 아이폰 홈 화면 앱만 유리 흐림 띠(40px)를 더한다(133차-g) */
  --ink2:#2E5878;
  --faint:#5E8299;   /* 2026-09-12: #8AAABF 는 흰 카드 위 2.45:1 이라 폰 야외에서 안 읽혔다(검토). 4.6:1 로. */
  --muted:var(--faint);
  /* 본문 바탕 = 그림 속 물빛을 얕게 푼 것. 위가 옅고 아래로 갈수록 조금 깊어진다.
     값은 전부 palette.json 에서 왔다 — 손으로 고른 파랑을 섞으면 그림과 따로 논다. */
  --sea:#005DD6;                  /* 수평선 아래 물빛 (그림 원색) */
  --paper:#E8F0FB;                /* 얕은 물 — 화면 위쪽 */
  --paper2:#D1E2F8;               /* 조금 깊은 물 — 화면 아래쪽 */
  --shore:url("/sky/church-summer-shore.webp?v=3");   /* 화면 바닥에 고정하는 교회 그림 (폰, 하늘 투명) */
  --scene:url("/sky/church-summer-scene.webp?v=3");   /* 같은 장면 폭 그대로 (넓은 화면 바닥, 2026-09-16) */
  --bg:var(--paper);
  /* 홈 화면 앱(iOS) 흰 상태바 → 종이색. `hold` = 흰색 그대로 두는 길이(상단바가 84~97px 이라 그 밑까지),
     `fade` = 그 아래로 번지는 길이. 아래 «상태바» 절 */
  --sbhold:100px;
  --sbfade:160px;
  /* 흰색 덮개 한 장. 멈춤 자리는 smoothstep(3t²-2t³) 을 따라간다 — 양 끝에서 기울기가 안 꺾여야 거기가 선으로 안 보인다 */
  --sbveil:linear-gradient(180deg,
    #fff 0 var(--sbhold),
    rgba(255,255,255,.96) calc(var(--sbhold) + var(--sbfade) * .12),
    rgba(255,255,255,.78) calc(var(--sbhold) + var(--sbfade) * .30),
    rgba(255,255,255,.43) calc(var(--sbhold) + var(--sbfade) * .55),
    rgba(255,255,255,.11) calc(var(--sbhold) + var(--sbfade) * .78),
    rgba(255,255,255,0)  calc(var(--sbhold) + var(--sbfade)));
  --card:#FFFFFF;
  --gridline:rgba(11,42,68,.05);

  /* 하늘 — 값은 전부 **실제 그림에서 뽑았다**(tools/_sky_src/palette.json).
     코드가 그림과 다른 색을 쓰면 그 순간 둘이 따로 논다. 기본값은 여름. */
  --sky1:#0045E4; --sky2:#0061EB; --sky3:#0294F5;
  --skyart:url("/sky/church-summer-bar.webp?v=2");     /* 상단바에 까는 하늘 조각 */
  --mini:url("/sky/church-summer-mini.webp?v=2");      /* 상단바 빈자리의 작은 교회 (넓은 화면, 나무까지) */
  --minic:url("/sky/church-summer-minic.webp?v=2");    /* 같은 그림에서 교회만 (폰) */
  --hero:url("/sky/church-summer-hero.webp?v=2");      /* 스포트라이트 카드 머리의 계절 그림 */
  --deck:var(--accent);                     /* 카드 바닥 띠·상단바 밑줄 = 계절 강조색과 같다 (2026-09-12 색 규율) */

  /* 팀 의미색 — IA 는 그대로 두고 채도만 나가이 쪽으로 옮겼다 */
  --praise:#D6452F; --praise-soft:#FFDED4;
  --praise2:#A93A6E; --praise2-soft:#FBDCEB;   /* 찬양 B팀 */
  --bcast:#1668A8;  --bcast-soft:#D7EAF8;
  --sound:#0A7A40;  --sound-soft:#D2EFDC;
  --lilac:#6B4BBE;  --lilac-soft:#E7DDFB;
  --sand:#8A6A3A;   --sand-soft:#F2E7D0;      /* '팀' 탭 색. 토요일에서는 손을 뗐다 */
  /* 토요일(리허설) = 풀색. 사용자 요청으로 모래 → 초록.
     ⚠ 음향 잔디(#0A7A40)와 **다른 초록**이어야 한다 — 토요일 칸 배경 위에 음향 이름표가 얹히는데
        둘이 같은 초록이면 그 칸에서만 역할 색을 못 읽는다. 이건 **노란기가 도는 풀색**이고,
        음향은 푸른기가 도는 잔디색이라 색차가 난다.
     ⚠ 흰 글자를 얹는 색이라 대비 4.5:1 을 넘겨야 한다(never 규칙: 채도 필 위 작은 흰 글자 금지).
        실측 5.1:1. 더 밝고 예쁜 초록(#2F8F3E 4.1:1)은 이 문턱을 못 넘어서 버렸다. */
  --sat:#3A7D22;    --sat-soft:#E3F4D9;
  --praise-fill:var(--praise); --praise2-fill:var(--praise2); --bcast-fill:var(--bcast); --sound-fill:var(--sound);
  --sand-fill:var(--sand); --sat-fill:var(--sat); --lilac-fill:var(--lilac);
  --butter:#F5C63C; --butter-soft:#FFEFC0; --butter-ink:#5F4405;

  --accent:var(--butter); --accent-soft:var(--butter-soft);
  --accent-ink:var(--butter-ink); --accent-line:var(--butter);

  /* ── 역할 색 ────────────────────────────────
     예전엔 이름을 해시해서 파스텔 여섯 개를 돌려 썼다. 알록달록하기만 하고 뜻이 없었다
     (사용자: "이름표 색깔이 너무 무작위로 알록달록한데"). 이제 색 하나가 곧 역할이다.
     리더 해 · 싱어 붉은꽃 · 세션 라일락 · 방송 바다 · 음향 잔디.
     ⚠ 계절 토큰과 분리해 고정한다. 계절 따라 흔들리면 색으로 역할을 못 읽는다. */
  --rl-lead:#8A6208;    --rl-lead-soft:#FFD75E;
  --rl-vocal:#D6452F;   --rl-vocal-soft:#FFDCD1;
  --rl-session:#6B4BBE; --rl-session-soft:#E7DDFB;
  --rl-bcast:#1668A8;   --rl-bcast-soft:#D7EAF8;
  --rl-sound:#0A7A40;   --rl-sound-soft:#D2EFDC;

  /* 생일 촛불 — 한 카드 안에서 겹치지 않게 순서대로 집어 쓴다 */
  --cd1:#E8543C; --cd1s:#FFDACF;
  --cd2:#0E96A0; --cd2s:#D0EFF2;
  --cd3:#2E9E5B; --cd3s:#D6F0DF;
  --cd4:#2E82D8; --cd4s:#D8E9FB;
  --cd5:#8B5CD6; --cd5s:#EADFFA;
  --cd6:#D6478F; --cd6s:#FBDCEA;

  --r-s:12px; --r-m:16px; --r-l:20px; --r-xl:28px;
  /* ⭐⭐ 카드 안쪽 좌우 여백 **한 값**. 라벨의 왼쪽 끝과 모서리 단추의 오른쪽 끝이 여기서 같이 나온다.
     ⚠ 86차에 이걸 안 묶어 뒀다가 실측 2~3px 어긋났다(사용자: "리허설 녹화 버튼이랑 무대배치 세로줄이 안 맞아").
     흐름에 있는 단추(padding 기준)와 띄워 놓은 단추(right 기준)는 **같은 수를 봐야** 한 줄로 선다. */
  --card-gut:16px;
  --bw:2px;
  /* 다섯 벌을 역할로 나눠 쓴다. 굵기가 아니라 **일이 다르면** 폰트를 바꾼다.
     · disp  나눔스퀘어 네오 900 — 제목·날짜·예배 이름·사람 이름. 기하학적이라 나가이/후투라 방향과 맞는다
     · body  나눔스퀘어 네오 400/700 — 본문. 같은 가족이라 화면이 안 흔들린다
     · serif 나눔명조 — **사람 목소리가 나는 자리**에만 (한 줄 소개, 권유 문장). 남발하면 뜻이 죽는다
     · hand  나눔손글씨 펜 — 축하 한마디 하나. 여기 말고는 쓰지 않는다
     · mono  나눔고딕코딩 — 시계·숫자·라틴 라벨
     · lyric 나눔스퀘어라운드 — **가사 상자 하나**. 부르려고 읽는 글이라 획 끝이 둥글어야 눈이 안 걸린다
             (명조로 두면 성경 본문처럼 읽힌다. 가사는 낭독이 아니라 노래다)
     ⚠ 'Nanum Gothic' 은 장식이 아니라 **서브셋 안전망**이다 (위 @font-face 주석 참조). 빼지 말 것.
     ⚠ 모노·라틴 폰트에 한글을 얹지 않는다. 한글은 .ko 로 본문 폰트에 넘긴다. */
  --f-disp:'NanumSquareNeo','Nanum Gothic',sans-serif;
  --f-body:'NanumSquareNeo','Nanum Gothic',-apple-system,'Apple SD Gothic Neo','Malgun Gothic',sans-serif;
  --f-serif:'Nanum Myeongjo','NanumSquareNeo',serif;
  --f-hand:'Nanum Pen Script','NanumSquareNeo',cursive;
  --f-latin:'Jost',system-ui,sans-serif;      /* 후투라 계열. 라틴 대문자 + 넓은 자간 전용 */
  --f-mono:'Nanum Gothic Coding',ui-monospace,monospace;
  --f-lyric:'NanumSquareRound','NanumSquareNeo','Nanum Gothic',sans-serif;
  --sh:0 4px 0 var(--ink);        /* 카드: 잉크 하드 섀도 */
  --sh-sm:0 2px 0 var(--ink);     /* 칩/버튼: 얕은 잉크 단 */
  --tabbar-h:66px;
  /* ── 움직임의 말투 ────────────────────────────
     ⚠ 41차에 "닌텐도 느낌"으로 스쿼시&스트레치 + 오버슛을 넣었다가 **사용자가 물렸다**
       ("탱글거리는 느낌보다 스륵하고 나타나는 게 더 좋아", 42차).
       이 앱의 말투는 **튀는 게 아니라 미끄러지는 것**이다.
     ① 빨리 나가서 길게 감속한다(--e-glide). 같은 시간이라도 훨씬 부드럽게 읽힌다.
     ② **목표를 지나치지 않는다.** 오버슛·스쿼시는 쓰지 않는다.
     ③ transform·opacity 만 쓴다. */
  /* ⚠ 42차의 --e-glide(.16,.84,...)는 **너무 앞으로 쏠린 커브**였다.
     시작 25% 만에 거리의 77% 를 가 버려서, 부드럽다기보다 "툭 나타났다"로 읽혔다
     (사용자: "너무 갑자기 pop out 하는 느낌", 44차). 실측으로 확인한 값이다.
     지금은 easeOutQuad — 25% 에 42%, 절반에 72%. 골고루 나눠 가서 눈이 따라갈 수 있다. */
  --e-glide:cubic-bezier(.25,.46,.45,.94);  /* 천천히 붙잡았다 놓는다 = "스륵" */
  --e-snap:cubic-bezier(.2,.9,.25,1);       /* 짧은 반응(누름·전환) */
  /* 필름 천공 한 칸. 영상 칸 위아래에 가로로 반복해 깐다 (.photogrid .isvid) */
  --film:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='9'%3E%3Crect x='3.2' y='2.4' width='6.6' height='4.2' rx='1.6' fill='%23FFFFFF' fill-opacity='.9'/%3E%3C/svg%3E");
  /* 섹션 제목 밑 = 파도 두 줄.
     ⚠ 예전엔 세 줄이었는데 맨 윗줄이 **제목 아이콘 밑동을 파고들었다**
        (사용자: "이 세 줄 바로 위에 아이콘 아래 부분을 살짝 깎아먹어").
        아이콘은 -4도 기울고 2px 잉크 단까지 있어서 글자 상자보다 3.4px 아래로 내려온다.
        줄을 둘로 줄이고(무게도 가벼워졌다) 아래로 더 내렸다. */
  --squig:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='84' height='12' viewBox='0 0 84 12'%3E%3Cg fill='none' stroke='%230B2A44' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M2 3h66'/%3E%3Cpath d='M2 9h38'/%3E%3C/g%3E%3C/svg%3E");
}

/* ── 계절 ─────────────────────────────────────
   ⚠ 1차 시도는 CSS 그라디언트로 하늘을 흉내냈다가 **신스웨이브**가 나왔다
   (사용자: "히로시 아트가 아니라 무슨 레트로 miami 스타일, 그 특유의 청량함이 없어").
   범인 = 마젠타에서 보라로 가는 그라디언트 · 수평선에 걸린 큰 해 · 검은 야자수 실루엣 ·
   하늘 위 가로 줄무늬(CRT 스캔라인). 전부 레트로웨이브의 어휘지 나가이의 어휘가 아니다.
   그래서 하늘은 손으로 안 만든다. `tools/gen_season_art.py`(GPT Image 2)로 그린
   그림 네 장을 그대로 깔고, 아래 색값도 **그 그림에서 뽑아 온다**.

   계절 상징: 봄 벚꽃 · 여름 바다 · 가을 낙엽 · 겨울 눈.
   ⚠ 그래도 네 계절 **전부** 맑은 파란 하늘 + 눈부신 흰색 + 청록 물을 유지한다.
   청년부가 쓰는 화면이라 계절이 뭐든 청량해야 한다(사용자 지시). */
/* ⭐⭐ 2026-09-16: 바닷가 그림 → **실제 새한장로교회 건물**(사용자: "교회랑 연관 없는 배경이라 이상해").
   그림 문법(나가이 평면 과슈)과 계절마다 갈리는 것은 그대로, 장면만 교회 앞마당이다. `tools/gen_church_scene.py`.
   봄 산딸나무 꽃·진달래 · 여름 배롱나무·짙은 초록 · 가을 단풍 · 겨울 눈. 하늘색은 그 그림에서 뽑았다(palette.json church-*).
   ⚠⚠ 주소 끝 `?v=2` 는 판 번호다. 그림을 다시 그리면 **올린다.** 파일 이름이 같으면 /sky 캐시(하루)와 서비스워커(먼저 옛것)가
      옛 그림을 계속 보여 준다. 1판(안 닮은 건물)을 본 폰이 2판을 못 받을 뻔했다(2026-09-16).
   --skyart 상단바 하늘 · --mini·--minic 상단바 빈자리의 작은 교회 · --shore 폰 바닥 교회 · --scene 넓은 화면 바닥 교회 · --hero 특별예배 카드 머리 */
[data-theme="spring"]{           /* 3~5월 · 산딸나무 꽃 */
  --sky1:#2091DD; --sky2:#30A4E5; --sky3:#55A9B8;
  --skyart:url("/sky/church-spring-bar.webp?v=2"); --hero:url("/sky/church-spring-hero.webp?v=2"); --mini:url("/sky/church-spring-mini.webp?v=2"); --minic:url("/sky/church-spring-minic.webp?v=2");
  --sea:#02C2E3; --paper:#E8FAFC; --paper2:#D1F4FA; --shore:url("/sky/church-spring-shore.webp?v=3"); --scene:url("/sky/church-spring-scene.webp?v=3");
  --accent:#F384AE; --accent-soft:#FDE0EB; --accent-ink:#7C1F44; --accent-line:#F384AE;
}
[data-theme="summer"]{           /* 6~8월 · 짙은 초록 */
  --sky1:#0045E4; --sky2:#0061EB; --sky3:#0294F5;
  --skyart:url("/sky/church-summer-bar.webp?v=2"); --hero:url("/sky/church-summer-hero.webp?v=2"); --mini:url("/sky/church-summer-mini.webp?v=2"); --minic:url("/sky/church-summer-minic.webp?v=2");
  --sea:#005DD6; --paper:#E8F0FB; --paper2:#D1E2F8; --shore:url("/sky/church-summer-shore.webp?v=3"); --scene:url("/sky/church-summer-scene.webp?v=3");
  --accent:#12A9C4; --accent-soft:#D2F0F6; --accent-ink:#07505E; --accent-line:#12A9C4;
}
[data-theme="autumn"]{           /* 9~11월 · 단풍 */
  --sky1:#0059BB; --sky2:#0171D0; --sky3:#109EE6;
  --skyart:url("/sky/church-autumn-bar.webp?v=2"); --hero:url("/sky/church-autumn-hero.webp?v=2"); --mini:url("/sky/church-autumn-mini.webp?v=2"); --minic:url("/sky/church-autumn-minic.webp?v=2");
  --sea:#02ABD1; --paper:#E8F7FB; --paper2:#D1F0F7; --shore:url("/sky/church-autumn-shore.webp?v=3"); --scene:url("/sky/church-autumn-scene.webp?v=3");
  --accent:#F09A16; --accent-soft:#FFEBC6; --accent-ink:#6B3E02; --accent-line:#F09A16;
}
[data-theme="winter"]{           /* 12~2월 · 눈 */
  --sky1:#2688EA; --sky2:#2A99F2; --sky3:#49B6F8;
  --skyart:url("/sky/church-winter-bar.webp?v=2"); --hero:url("/sky/church-winter-hero.webp?v=2"); --mini:url("/sky/church-winter-mini.webp?v=2"); --minic:url("/sky/church-winter-minic.webp?v=2");
  --sea:#04BFE3; --paper:#E8F9FC; --paper2:#D2F3FA; --shore:url("/sky/church-winter-shore.webp?v=3"); --scene:url("/sky/church-winter-scene.webp?v=3");
  --accent:#3FADE4; --accent-soft:#DCEFFA; --accent-ink:#0B3F63; --accent-line:#3FADE4;
}

/* ── 시각 (계절 위에 얹는 두 번째 축) ──────────────
   ⚠ 계절은 **무엇이 있는가**를 정한다(벚꽃·바다·낙엽·눈 그림, 강조색, 앱 아이콘).
      시각은 **그게 지금 어떻게 보이는가**를 정한다(하늘·물빛·그림의 빛).
      그래서 24개 조합을 쓰지 않고, 시각 블록이 하늘·물만 덮어쓴다.
   ⚠⚠ **본문 바닥(--paper/--paper2)은 어느 시각에도 읽을 수 있게 유지한다.**
      카드 밖 글자(제목·hint·grptitle)가 전부 잉크색이라, 바닥이 어두워지면 그대로 안 읽힌다.
      밤을 통째로 어둡게 하려면 잉크·카드까지 다 뒤집는 진짜 다크 테마가 필요하다 — 그건 별개 작업이다.
   ⭐⭐ 그래서 **밝기는 지키고 색조를 옮긴다**(2026-09-18, 103차-b). 사용자: *"완전 꺼멓게 만들라는 게 아니라, 밑에 그 사진하고 색깔을 조금 맞춰줘."*
      `--paper`(위) · `--paper2`(아래)는 **그 시각 교회 그림의 진짜 하늘색**을 흰색 쪽으로 눕힌 것이다
      (`tools/_church_src/church-<계절>-<시각>.png` 의 윗하늘·중간하늘 평균 → 밝기 .80 / .62 로. 뽑는 법은 `tools/gen_sky_palette.py`).
      손으로 고른 파랑을 섞으면 그림과 따로 논다 — palette.json 을 만든 것과 같은 원칙이다.
      ⚠ 값을 바꿀 땐 `tools/qa/skycontrast.mjs` 로 **글자 대비를 다시 재고** 바꾼다. 눈으로는 안 보인다.
   ⚠ 바닥 교회 그림은 시각마다 **빛을 다시 그린 그림**으로 바꾼다(아래 ⭐⭐, 2026-09-17). `--veil`(덮개)은 특별예배 카드 머리 같은 곳이 쓴다.
      상단바(엽서 카드·우표)는 시각을 **안 입는다**(2026-09-17, 우표만 어두워지는 게 글리치 같았다).
   ⚠ 네 계절 내내 지켜 온 "청량함"은 시각이 바뀌어도 지킨다 — 탁하게 만들지 않는다.
   ⭐ 133차-e(2026-10-02): 새벽 · 저녁 · 밤은 화면 전체가 어둡다(맨 끝 «시간대 옷» 절). 그래서 세 시각의 종이색은 어두운 바탕색이다
      (index.html 첫 스크립트 표와 같아야 한다, skyboot.mjs). */
[data-tod="dawn"]{               /* 새벽 05–07 · 동트기. 해가 왼쪽에서 막 오른다 */
  --sky1:#1E3A6E; --sky2:#4A6BA8; --sky3:#E3A68F;
  --sea:#4A79C4; --paper:#172950; --paper2:#132343;
  --sk0:rgba(161,162,220,0); --sk1:rgba(161,162,220,.5); --sk2:#A1A2DC; --sk3:#BC9DAE;
  --sun:radial-gradient(58px 58px at 10% 46%, rgba(255,224,190,.98) 0 36%, rgba(255,184,138,.5) 58%, rgba(255,184,138,0) 74%),
        radial-gradient(280px 210px at 10% 50%, rgba(255,174,126,.42) 0, rgba(255,174,126,0) 70%);
  --starop:.3; --moonop:0; --shoreop:.66; --skp1:34%; --skp2:70%; --skp3:94%;
  --veil:linear-gradient(180deg, rgba(26,44,92,.42) 0, rgba(224,150,120,.20) 100%);
}
[data-tod="morning"]{            /* 아침 07–11 · 맑고 신선. 해가 동쪽에서 올라왔다 */
  --sky1:#0B78E0; --sky2:#2F9BEE; --sky3:#7FD3F6;
  --sea:#12A0DC; --paper:#F3F8F4; --paper2:#EBF3ED;
  --sk0:rgba(108,189,249,0); --sk1:rgba(108,189,249,.5); --sk2:#6CBDF9; --sk3:#8BC3D7;
  --sun:radial-gradient(40px 40px at 26% 26%, rgba(255,253,232,1) 0 40%, rgba(255,240,182,.55) 60%, rgba(255,240,182,0) 76%),
        radial-gradient(240px 220px at 26% 30%, rgba(255,244,192,.40) 0, rgba(255,244,192,0) 68%);
  --starop:0; --moonop:0; --shoreop:.58; --skp1:34%; --skp2:70%; --skp3:94%;
  --veil:linear-gradient(180deg, rgba(255,255,255,.10) 0, transparent 100%);
}
[data-tod="midday"]{             /* 낮 11–15 · 가장 쨍하다. 해는 머리 위 — 화면 밖이라 빛만 넓게 */
  --sky1:#0165D8; --sky2:#0A8FEC; --sky3:#4FD0F5;
  --sea:#02BEE0; --paper:#F3F8F4; --paper2:#EBF3ED;
  --sk0:rgba(39,155,237,0); --sk1:rgba(39,155,237,.42); --sk2:#279BED; --sk3:#3FA9CC;
  --sun:radial-gradient(360px 240px at 50% 2%, rgba(255,255,236,.6) 0, rgba(255,255,236,0) 70%);
  --starop:0; --moonop:0; --shoreop:.56; --skp1:38%; --skp2:74%; --skp3:96%;
  --veil:none;
}
[data-tod="afternoon"]{          /* 오후 15–18 · 해가 서쪽으로 기울고 금빛이 돈다 */
  --sky1:#0A6BCB; --sky2:#3E97D6; --sky3:#F0C98A;
  --sea:#2C9FC0; --paper:#F3F8F4; --paper2:#EBF3ED;
  --sk0:rgba(140,181,200,0); --sk1:rgba(140,181,200,.5); --sk2:#8CB5C8; --sk3:#CAB883;
  --sun:radial-gradient(54px 54px at 72% 26%, rgba(255,242,198,1) 0 38%, rgba(255,214,132,.55) 58%, rgba(255,214,132,0) 76%),
        radial-gradient(300px 240px at 72% 30%, rgba(255,204,128,.38) 0, rgba(255,204,128,0) 70%);
  --starop:0; --moonop:0; --shoreop:.60; --skp1:34%; --skp2:70%; --skp3:94%;
  --veil:linear-gradient(180deg, transparent 0, rgba(246,186,96,.22) 100%);
}
[data-tod="evening"]{            /* 저녁 18–20:30 · 해가 서쪽 지평선에 걸리고 첫 별이 뜬다 */
  --sky1:#3A2F6E; --sky2:#A85480; --sky3:#F3A05E;
  --sea:#B0708F; --paper:#1F1B40; --paper2:#1A1736;
  --sk0:rgba(190,131,166,0); --sk1:rgba(190,131,166,.5); --sk2:#BE83A6; --sk3:#CA6C63;
  --sun:radial-gradient(66px 66px at 88% 46%, rgba(255,216,152,.96) 0 34%, rgba(255,152,92,.55) 56%, rgba(255,152,92,0) 74%),
        radial-gradient(340px 230px at 88% 52%, rgba(255,140,80,.46) 0, rgba(255,140,80,0) 72%);
  --starop:.45; --moonop:.55; --shoreop:.74; --skp1:32%; --skp2:68%; --skp3:92%;
  --veil:linear-gradient(180deg, rgba(58,44,110,.44) 0, rgba(240,140,80,.30) 100%);
}
[data-tod="night"]{              /* 밤 20:30–05 · 해는 졌고 달이 동쪽(왼쪽)에 떴다 */
  --sky1:#0B1F4D; --sky2:#153A73; --sky3:#2E6BA8;
  --sea:#2B558F; --paper:#0E1F3D; --paper2:#0B1A34;
  --sk0:rgba(131,149,185,0); --sk1:rgba(131,149,185,.5); --sk2:#8395B9; --sk3:#0C3A82;
  --sun:none;
  --starop:1; --moonop:1; --shoreop:.92; --skp1:24%; --skp2:58%; --skp3:88%;
  --veil:linear-gradient(180deg, rgba(6,18,48,.56) 0, rgba(6,18,48,.30) 100%);
}
/* ⭐⭐ 바닥 교회도 시간대마다 **다시 비춘 그림**으로 바꾼다 (2026-09-17). 사용자: *"교회 배경이 시간대 영향을 받게 해 줘.
   이른 아침, 아침, 점심, 오후, 저녁 이런 식으로 시간에 맞춰서 적절하게."*
   ⚠ 필터(`--artfx`)로는 빛의 방향·광원을 못 만든다. 그림 전체를 한 방향으로 눌러서 칙칙하게 어두워질 뿐이다(우표에서 «부자연스럽다» 지적).
   → 낮 그림을 Kie 로 **빛만 바꿔 다시 그렸다**(`tools/gen_church_tod.py`). 노을이 첨탑 끝에만 걸리고, 저녁·밤엔 출입문 유리에 불이 켜진다.
   ⚠ 그림 크기·자리가 낮 그림과 같다(어긋남을 재서 맞췄다) → 시간대가 바뀌는 순간 교회가 안 튄다.
   ⚠ 네 계절 스무 장 모두 있다(2026-09-17). 예전 필터(`--artfx`)는 지웠다. 그림을 다시 그리면 주소의 `?v=` 를 올린다(같은 이름이면 캐시가 옛 그림을 준다). */
[data-theme="spring"][data-tod="dawn"]    {--shore:url("/sky/church-spring-dawn-shore.webp?v=2"); --scene:url("/sky/church-spring-dawn-scene.webp?v=2");}
[data-theme="spring"][data-tod="morning"] {--shore:url("/sky/church-spring-morning-shore.webp?v=2"); --scene:url("/sky/church-spring-morning-scene.webp?v=2");}
[data-theme="spring"][data-tod="afternoon"]{--shore:url("/sky/church-spring-afternoon-shore.webp?v=2"); --scene:url("/sky/church-spring-afternoon-scene.webp?v=2");}
[data-theme="spring"][data-tod="evening"] {--shore:url("/sky/church-spring-evening-shore.webp?v=2"); --scene:url("/sky/church-spring-evening-scene.webp?v=2");}
[data-theme="spring"][data-tod="night"]   {--shore:url("/sky/church-spring-night-shore.webp?v=2"); --scene:url("/sky/church-spring-night-scene.webp?v=2");}
[data-theme="summer"][data-tod="dawn"]    {--shore:url("/sky/church-summer-dawn-shore.webp?v=2"); --scene:url("/sky/church-summer-dawn-scene.webp?v=2");}
[data-theme="summer"][data-tod="morning"] {--shore:url("/sky/church-summer-morning-shore.webp?v=2"); --scene:url("/sky/church-summer-morning-scene.webp?v=2");}
[data-theme="summer"][data-tod="afternoon"]{--shore:url("/sky/church-summer-afternoon-shore.webp?v=2"); --scene:url("/sky/church-summer-afternoon-scene.webp?v=2");}
[data-theme="summer"][data-tod="evening"] {--shore:url("/sky/church-summer-evening-shore.webp?v=2"); --scene:url("/sky/church-summer-evening-scene.webp?v=2");}
[data-theme="summer"][data-tod="night"]   {--shore:url("/sky/church-summer-night-shore.webp?v=2"); --scene:url("/sky/church-summer-night-scene.webp?v=2");}
[data-theme="autumn"][data-tod="dawn"]    {--shore:url("/sky/church-autumn-dawn-shore.webp?v=2"); --scene:url("/sky/church-autumn-dawn-scene.webp?v=2");}
[data-theme="autumn"][data-tod="morning"] {--shore:url("/sky/church-autumn-morning-shore.webp?v=2"); --scene:url("/sky/church-autumn-morning-scene.webp?v=2");}
[data-theme="autumn"][data-tod="afternoon"]{--shore:url("/sky/church-autumn-afternoon-shore.webp?v=2"); --scene:url("/sky/church-autumn-afternoon-scene.webp?v=2");}
[data-theme="autumn"][data-tod="evening"] {--shore:url("/sky/church-autumn-evening-shore.webp?v=2"); --scene:url("/sky/church-autumn-evening-scene.webp?v=2");}
[data-theme="autumn"][data-tod="night"]   {--shore:url("/sky/church-autumn-night-shore.webp?v=2"); --scene:url("/sky/church-autumn-night-scene.webp?v=2");}
[data-theme="winter"][data-tod="dawn"]    {--shore:url("/sky/church-winter-dawn-shore.webp?v=2"); --scene:url("/sky/church-winter-dawn-scene.webp?v=2");}
[data-theme="winter"][data-tod="morning"] {--shore:url("/sky/church-winter-morning-shore.webp?v=2"); --scene:url("/sky/church-winter-morning-scene.webp?v=2");}
[data-theme="winter"][data-tod="afternoon"]{--shore:url("/sky/church-winter-afternoon-shore.webp?v=2"); --scene:url("/sky/church-winter-afternoon-scene.webp?v=2");}
[data-theme="winter"][data-tod="evening"] {--shore:url("/sky/church-winter-evening-shore.webp?v=2"); --scene:url("/sky/church-winter-evening-scene.webp?v=2");}
[data-theme="winter"][data-tod="night"]   {--shore:url("/sky/church-winter-night-shore.webp?v=2"); --scene:url("/sky/church-winter-night-scene.webp?v=2");}

*{box-sizing:border-box;}
/* ⚠⚠ 고무줄 스크롤(iOS)에서 드러나는 자리는 **루트(html)의 배경**이 칠한다.
   맨 위에서 더 당기면 본문이 통째로 내려오고 sticky 상단바도 같이 내려오는데,
   그 위에 남는 자리는 **문서 바깥**이라 요소가 아니라 캔버스가 그린다
   (사용자: "탭까지 같이 쓸려 내려와서 위에 하얀 공백이 나온다").
   ⚠ 28차에 `.topbar` 의 box-shadow 로 덮으려 했는데 **안 먹었다.** 그림자는 요소가 그리는 것이라
      문서 위쪽 바깥까지 안 간다. (헤드리스에서 body 에 transform 을 걸어 흉내 낸 게 잘못된 검증이었다 —
      transform 은 문서를 화면 안에서 밀 뿐이라 진짜 고무줄과 다르다.)
   ⚠ `overscroll-behavior-y:none` 으로 고무줄 자체를 없앨 수도 있지만 **당겨서 새로고침까지 죽는다.**
   그래서 캔버스를 위=하늘 / 아래=물빛으로 칠한다. 화면에 고정이라(fixed) 위로 당기면 하늘이,
   아래로 당기면 물빛이 나온다. 본문은 body 가 따로 칠하므로 평상시에는 보이지 않는다.
   ⚠ html 에 배경을 주면 **body 배경이 더는 캔버스로 전파되지 않는다.** 그래서 body 쪽 규칙을 지우면 안 된다. */
html{-webkit-text-size-adjust:100%;
  /* ⚠⚠ 결국 **고무줄을 없앴다**(3차). 칠하는 쪽으로 두 번 시도했는데 두 번 다 사용자 폰에서 틀렸다:
     1차 상단바 box-shadow → 흰 공백 그대로(그림자는 문서 바깥까지 안 간다).
     2차 루트 배경 → 이번엔 **물결 줄무늬가 위로 계속 이어져 나왔다**
        (사용자: "이젠 dash line 들이 계속 이어서 나오네").
        고무줄 자리를 iOS 가 무엇으로 채우는지는 **엔진이 정한다** — 배경색일 때도 있고
        맨 윗줄 픽셀을 늘리거나 고정 레이어를 이어 붙이기도 한다. 여기 `body::before`(수면 잔물결)가
        `position:fixed` 라 그 레이어에 얹혀 있었다. **칠해서 맞히는 싸움은 이길 수 없다.**
     그래서 현상 자체를 없앤다. 드러나는 자리가 없으면 무엇으로 칠할지도 문제가 안 된다.
     ⚠ 잃는 것 = **당겨서 새로고침**. 다만 이 앱은 홈 화면(standalone)으로 여는 게 기본이고,
        방문할 때마다 `autoPullIfStale` 이 데이터를 당기며 sw 가 앱 파일을 캐시하지 않아
        "다시 열면 최신"이 이미 보장된다. 그래서 손해가 거의 없다. */
  overscroll-behavior-y:none;
  background-color:var(--paper);
  background-image:linear-gradient(180deg, var(--paper) 0 34%, var(--paper2) 34%);   /* 위 = 상단바 바깥 틈과 같은 종이색 (2026-09-16 엽서) */
  background-attachment:fixed; background-repeat:no-repeat;}
html,body{margin:0;}
body{
  /* 물가. 화면 위는 얕은 물, 아래로 갈수록 깊어진다.
     ⚠ fixed 다 — 바닥의 물가 그림도 화면에 고정이라, 둘이 같이 붙어 있어야 한 장면으로 읽힌다.
     문서 길이를 따라가면 긴 페이지에서 물빛만 혼자 흘러내린다. */
  /* ⚠ `background` 한 줄로 쓰면 **배경색이 투명으로 되돌아간다**(그림만 남는다). 색을 따로 적는다 —
     브라우저·웹뷰 가운데 상태바나 고무줄 자리를 «body 의 배경색» 으로 칠하는 것들이 있어서, 투명이면 흰색으로 떨어진다. */
  background-color:var(--paper);
  background-image:linear-gradient(180deg, var(--paper) 0, var(--paper2) 100%);
  background-attachment:fixed;
  min-height:100vh; min-height:100dvh;
  color:var(--ink); font-family:var(--f-body); font-size:15px; line-height:1.55;
  word-break:keep-all; overflow-wrap:anywhere;   /* '섬김 / 표를' 처럼 낱말이 글자 단위로 끊기지 않게 */
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;
  overscroll-behavior-y:contain;
  padding-bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  /* ⚠⚠ 2026-09-12 실측: 아래 `body::before`(잔물결)와 `body::after`(물가 그림)가 **한 번도 보인 적이 없었다.**
     z-index:-1 인 가상요소는 body 가 쌓임 맥락이 아니면 **루트 맥락**으로 올라가고, 거기서는 body 의 배경보다 먼저 칠해진다
     (음수 z 는 루트 배경 다음, 블록 배경 전). body 배경이 불투명한 물빛이라 둘 다 그 밑에 깔려 있었다.
     시그니처 ⑤(물가)가 라이브에서 안 보였던 이유가 이것이다 — 사용자가 "비어 보인다"고 한 바닥이 실제로 비어 있었다.
     `isolation:isolate` 로 body 를 쌓임 맥락으로 만들면 가상요소가 body 배경 **위**, 본문 **아래**에 놓인다. */
  isolation:isolate;
}
/* ══ 상태바 = 홈 화면 앱(iOS)에서만 다른 것 (2026-09-18, 107차) ═══════════════════════════
   사용자: *"아이폰 맨 위 시간·배터리·다이나믹 아일랜드 있는 그 띠하고 앱 배경 색깔이 안 맞아.
   데스크탑으로 보면 경계선이 안 보이는데 폰은 너무 잘 보여. 아이패드도 마찬가지."*

   ⭐ **애플은 홈 화면 웹앱의 상태바 색을 코드로 못 정하게 한다.** `apple-mobile-web-app-status-bar-style` 의
      세 가지(흰색 · 검정 · 비치는 것)뿐이고 `theme-color` 는 **홈 화면 앱에서는 아예 안 본다**
      (사파리·크롬·카톡 안 브라우저·안드로이드·데스크톱 앱은 theme-color 가 먹는다. 거기는 이미 맞는다).
   ⭐ 셋 중 «비치는 것» 을 쓰면 색은 완벽히 이어지는데 **시계·배터리 글자가 흰색으로 고정**이라
      우리 종이색(밝다) 위에서 안 읽힌다(대비 1.2:1). 그래서 흰 상태바(검은 글자)를 쓰고,
      **앱 쪽이 그 흰색에서 시작해 그 시각 종이색으로 번지게** 한다. 선이 안 보이면 «안 맞는다» 가 사라진다.
   ⚠ 안드로이드 홈 화면 앱은 theme-color 로 이미 맞는다 → 여기 걸리면 안 된다.
      그래서 `display-mode:standalone` 이 아니라 **iOS 에만 있는 `navigator.standalone`** 으로 가른다(index.html 의 첫 스크립트).
   ⚠⚠ **34px 로는 모자랐다**(2026-09-18 사용자: *"경계가 여전히 보이거든. 너무 조금 넣은 것 같아. 아예 안 보이게 넓게."*).
     까닭 둘: ① 상단바 카드(19~78px)가 그 34px 를 거의 다 덮어서, 카드 **위 19px 띠만** 살짝 물들었다 →
     흰 상태바 · 물든 띠 · 흰 카드 가 이어지며 그 띠가 선으로 읽힌다. ② 34px 안에서 색이 다 바뀌면 한 줄에 1.3 씩 변한다(눈에 보이는 계단).
   ⭐ 그래서 **상단바가 끝나는 곳까지는 흰색 그대로**(`--sbhold` 100px, 상단바는 폭에 따라 84~97px) 두고,
     그 아래로 `--sbfade` 만큼 푼다. 한 줄에 0.3 도 안 변한다(눈이 못 잡는다).
   ⭐ 색을 섞지 않고 **흰색 덮개의 투명도**로 푼다 — 그래야 계절·시각이 바뀌어도 밑의 종이색을 그대로 따라간다.
   ⚠ 멈춤 자리는 직선이 아니라 **부드러운 곡선**(smoothstep)이다. 직선으로 두면 시작과 끝에서 기울기가 꺾여 거기가 선으로 보인다. */
html.iosapp{background-image:var(--sbveil), linear-gradient(180deg, var(--paper) 0 34%, var(--paper2) 34%);}
html.iosapp body{background-image:var(--sbveil), linear-gradient(180deg, var(--paper) 0, var(--paper2) 100%);}
/* 상단바는 제 높이(84~97px)가 통째로 «흰색 그대로» 구간 안에 든다 → 그냥 흰색이면 밑의 덮개와 정확히 이어진다 */
html.iosapp .topbar{padding-top:19px; background:linear-gradient(180deg, #fff 0 74%, rgba(255,255,255,0));}
/* 무대 배치처럼 종이색으로 화면을 다 쓰는 것도 맨 위가 흰 상태바에 닿는다. 같은 문법으로 번지게 한다.
   ⚠ 사진·악보 보기(`#layer.photo`)는 일부러 짙은 남색이다(사진에 집중하는 자리). 거기는 안 건드린다. */
html.iosapp:not(.sp) .stagewrap{background-image:var(--sbveil), linear-gradient(180deg, var(--paper), var(--paper));}   /* 133 에서는 안 쓴다(133차-f) */
/* (2026-09-16) 수면 잔물결(`body::before`, 흰 가로줄)은 지웠다. 바다 그림의 물결이었고 교회 앞마당에는 물이 없다. */
/* ⑤ 교회 — 화면 **바닥에 고정**한 그 계절의 새한장로교회 (시그니처, 2026-09-16 바닷가에서 바꿨다).
   ⭐ 그림에서 **하늘을 빼 두었다**(`gen_church_scene.py` key_sky). 교회·소나무·잔디만 바탕 위에 선다.
      예전 물가 그림은 하늘까지 네모로 칠해져 있어서 위쪽 절반을 마스크로 지웠는데, 이제 지울 것이 없다.
      그래서 첨탑 꼭대기 십자가까지 온전히 보인다.
   ⚠ 폰은 그림 오른쪽 60%(교회가 통째로 들어온다), 가로를 꽉 채운다. 왼쪽 끝은 그림 안에서 흐려 두었다.
   ⚠ 폰은 아래 탭바가 바닥 66px 을 덮는다 → 그 위에 세운다. 안 그러면 교회 출입문이 탭바 밑으로 들어간다.
   ⚠ 카드는 불투명이라 그림은 카드 사이·페이지 끝에서 보인다. 글자 뒤로 비치는 곳이 있어 한 단 옅게 둔다. */

/* ⭐⭐ 하늘 = 화면에 고정된 **그 시각의 하늘** (2026-09-17, 103차). 교회 그림 뒤(z -3)에 깔린다.
   사용자: *"교회 이미지가 아니라 뒤에 배경 색깔이 고정이라서 그냥 교회 이미지만 저녁으로 바뀌고 뒤의 배경은 그냥 똑같이 하얀색이야.
   이러면 구별이 안 되지 않을까? 제일 쉬운 걸 안 해놨어. 아침에 해 뜨는 그 위치도 좀 표현해주고, 저녁 되면 별들도 좀 보이게끔."*
   ⚠ 예전엔 `--paper`/`--paper2` 만 시각마다 조금씩 달랐는데 여섯 값이 전부 흰색에 가까워서(L .75~.86) **눈으로는 같은 색**이었다.
      교회 그림만 저녁으로 바뀌니 오려 붙인 스티커로 보였다.
   ⭐ 그래서 두 갈래로 나눴다:
      ① **종이(`--paper`·`--paper2`)는 밝기를 지키고 색조만 옮긴다** — 카드 밖 글자가 전부 잉크색이라 어두워지면 안 읽힌다(옛 주석 그대로).
         라벤더(새벽) · 물빛(아침) · 청록(낮) · 금빛(오후) · 살구(저녁) · 푸른 재(밤). 밝기는 여섯 다 L .70 위로 잡았다.
      ② **하늘은 화면 아래쪽에서 진해진다** — 글자가 없는 자리다(바닥 교회 그림과 탭바가 덮는다). 여기서 해·달·별이 산다.
   ⚠ 첫 색 멈춤은 `transparent` 가 아니라 **같은 색의 알파 0**(`--sk0`)이다. `transparent` 로 두면 섞이는 동안 회색이 낀다.
   ⚠ 해·달·별은 그림이 아니라 그라디언트와 도형이다. 파일을 더 받지 않는다(폰이 주 사용처). */
.sky{position:fixed; left:0; right:0; bottom:0; height:52%; z-index:-3; pointer-events:none; overflow:hidden;
  background:var(--sun, none), linear-gradient(180deg, var(--sk0) 0, var(--sk1) var(--skp1, 40%), var(--sk2) var(--skp2, 72%), var(--sk3) var(--skp3, 92%));}
.sky > i{position:absolute; display:block; pointer-events:none;}
/* 별 — 두 겹이라 한꺼번에 깜빡이지 않는다. 밤에만 다 보이고 저녁엔 옅게 몇 개만 */
.skst{left:0; right:0; top:6%; height:48%; opacity:var(--starop, 0); transition:opacity .8s ease; background-repeat:no-repeat;}
.skst.a{background-image:
  radial-gradient(3.4px 3.4px at 7% 16%, rgba(255,255,255,.98) 0 34%, rgba(255,255,255,.30) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.4px 2.4px at 18% 7%, rgba(255,255,255,.95) 0 36%, rgba(255,255,255,.26) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(3px 3px at 29% 24%, rgba(255,255,255,.96) 0 34%, rgba(255,255,255,.28) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.2px 2.2px at 41% 11%, rgba(255,255,255,.92) 0 36%, rgba(255,255,255,.24) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(3.2px 3.2px at 52% 21%, rgba(255,255,255,.98) 0 34%, rgba(255,255,255,.30) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.2px 2.2px at 62% 6%, rgba(255,255,255,.90) 0 36%, rgba(255,255,255,.24) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(3.6px 3.6px at 73% 15%, rgba(255,255,255,1) 0 34%, rgba(255,255,255,.32) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.4px 2.4px at 85% 26%, rgba(255,255,255,.94) 0 36%, rgba(255,255,255,.26) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(3px 3px at 94% 9%, rgba(255,255,255,.96) 0 34%, rgba(255,255,255,.28) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.2px 2.2px at 12% 37%, rgba(255,255,255,.88) 0 36%, rgba(255,255,255,.22) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(2.6px 2.6px at 36% 42%, rgba(255,255,255,.90) 0 36%, rgba(255,255,255,.24) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(2.2px 2.2px at 58% 38%, rgba(255,255,255,.86) 0 36%, rgba(255,255,255,.22) 60%, rgba(255,255,255,0) 76%);}
.skst.b{background-image:
  radial-gradient(2.6px 2.6px at 3% 28%, rgba(255,255,255,.95) 0 36%, rgba(255,255,255,.26) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(2.2px 2.2px at 24% 33%, rgba(255,255,255,.90) 0 36%, rgba(255,255,255,.24) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(3px 3px at 46% 30%, rgba(255,255,255,.98) 0 34%, rgba(255,255,255,.30) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.2px 2.2px at 67% 34%, rgba(255,255,255,.88) 0 36%, rgba(255,255,255,.22) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(3.4px 3.4px at 80% 41%, rgba(255,255,255,1) 0 34%, rgba(255,255,255,.32) 58%, rgba(255,255,255,0) 74%),
  radial-gradient(2.4px 2.4px at 89% 18%, rgba(255,255,255,.92) 0 36%, rgba(255,255,255,.26) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(2.2px 2.2px at 15% 22%, rgba(255,255,255,.86) 0 36%, rgba(255,255,255,.22) 60%, rgba(255,255,255,0) 76%),
  radial-gradient(2.8px 2.8px at 97% 31%, rgba(255,255,255,.94) 0 36%, rgba(255,255,255,.28) 60%, rgba(255,255,255,0) 76%);
  animation:twink 7.5s ease-in-out infinite alternate;}
@keyframes twink{from{opacity:calc(var(--starop, 0) * .4);} to{opacity:var(--starop, 0);}}
/* 달 — 알맹이가 빈 원에 **안쪽 그림자를 비켜 넣으면** 초승달이 된다(그림 파일이 필요 없다) */
.skmoon{left:11%; top:19%; width:30px; height:30px; border-radius:50%;
  box-shadow:inset -8px -4px 0 0 rgba(255,250,228,.95), 0 0 20px rgba(255,246,214,.4);
  opacity:var(--moonop, 0); transition:opacity .8s ease;}
@media (prefers-reduced-motion:reduce){ .skst.b{animation:none;} }
body::after{content:''; position:fixed; left:0; right:0; z-index:-2; pointer-events:none;
  bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  height:min(calc(100vw * .66), 420px, 60vh);
  opacity:var(--shoreop, .58);
  background:var(--shore) right bottom/min(100%, 640px) auto no-repeat;
  transition:transform .24s ease;}
/* 내려 읽을 때 탭바가 비키면(body.tabhide) 교회도 같이 내려와 화면 바닥에 선다. 안 그러면 잔디 밑에 빈 띠가 남는다(실측) */
body.tabhide::after{transform:translateY(calc(var(--tabbar-h) + env(safe-area-inset-bottom)));}
body.pwa::after{transform:none;}
/* 손가락으로 쓰는 화면. 탭 지연·길게 눌러 생기는 파란 선택은 웹 티만 낸다 */
a,button,summary,[role="button"]{touch-action:manipulation;}
.topbar,.tabbar,.subtabs,.deskNav{-webkit-user-select:none; user-select:none;}
button{font-family:inherit; color:inherit;}
a{color:inherit;}
.ic{width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; flex:none;}
:focus-visible{outline:3px solid var(--bcast); outline-offset:2px; border-radius:8px;}
::selection{background:var(--butter);}

/* ── 상단 바 = 엽서 카드 (시그니처 ①) ─────────
   2026-09-16 다시 짰다. 사용자: *"배너 디자인 지금 마음에 안 들어. 그냥 클로드 기본 디자인만 살짝 바꾼 느낌이랄까? 안 이뻐.
   디자인 랩에서 인사이트 얻을 수는 없어?"* → 방향 셋(지평선·엽서·스티커)을 라이브에서 `?bar=` 로 넘겨 보게 했고 *"엽서가 나아"*.
   ⚠ 예전 판은 파란 하늘 띠 + 흰 글자였다. 밑 화면이 쓰는 말(잉크 2px 테두리·하드 그림자·테이프·기울임)을 띠만 안 써서
      «흔한 앱 머리»로 읽혔다. 이제 띠는 **밑의 카드들과 같은 종이 카드**이고, 교회는 테이프로 붙인 우표 안에 있다.
   ⚠ 카드 바깥 틈은 바탕색으로 칠하고 아래쪽만 투명하게 풀었다. 스크롤한 본문이 카드 뒤로 스며든다(칼로 자른 선이 안 생긴다).
   (옛 하늘 띠의 그림 덮개 층 두 장은 지웠다. 하늘 그림 `--skyart` 는 이제 우표 안에서만 쓴다.) */
.topbar{position:sticky; top:0; z-index:40; padding:13px 10px 6px;
  background:linear-gradient(180deg, var(--paper) 0 74%, transparent);}
.topbar .in{position:relative; max-width:960px; margin:0 auto; padding:7px 12px;
  display:flex; align-items:center; gap:10px;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:18px; box-shadow:0 4px 0 var(--ink);}
/* ⚠ 마크(`.tile`)는 이름 링크(`.logo`) 밖의 형제다. 폰 격자에서 마크가 두 줄을 다 쓰고 이름 밑에 날씨·시각이 서려면
   둘이 따로 칸을 받아야 한다. 시안 때는 링크에 display:contents 를 걸었는데, 그러면 링크가 접근성 트리에서 빠지는 브라우저가 있다.
   마크도 홈으로 가는 링크지만 탭 순서·읽기에서는 뺐다(같은 곳으로 가는 링크가 둘이 되지 않게). */
.logo{display:flex; align-items:center; text-decoration:none; min-width:0;}
/* 마크는 상자에 안 넣는다(사용자: "상자 안에 들어있는 디자인"). 종이 위에 그냥 얹는다 */
.topbar .tile{width:42px; height:42px; flex:none; display:flex; align-items:center; justify-content:center;}
.topbar .tile img{width:42px; height:42px; display:block;}
.logo .nm{font-family:var(--f-disp); font-weight:900; font-size:17.5px; letter-spacing:-.2px; line-height:1.15;
  display:flex; flex-direction:column; color:var(--ink); min-width:0;}
.logo .nm small{font-family:var(--f-body); font-weight:600; font-size:10px; letter-spacing:.01em;
  color:var(--ink2); margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
/* 폰(519px 까지)은 로고 밑 설명글을 접는다. 2026-09-16: 430 폰에서 설명글이 자리를 다 먹어 상단 띠의 작은 교회가 0px 로 사라졌다(실측) */
@media (max-width:519px){ .logo .nm small{display:none;} .logo .nm{font-size:19px;} }
/* 좁은 폰(399px 까지)은 띠 안 간격을 조금 줄여 작은 교회 자리를 만든다(390 에서 45 → 63px) */
@media (max-width:399px){ .topbar .tile, .topbar .tile img{width:38px; height:38px;} }
/* 시계 — 엣지 서버 시각에 맞춘다. 폰 시계가 틀어져 있어도 여기 뜨는 시간은 맞다.
   ⚠ 예전엔 **반투명 남색 알약 + 1.5px 흰 헤어라인 보더**였다(사용자: "전체적인 디자인이랑 안 어울려").
      맞는 지적이었다. 이유 셋:
      ① 저대비 헤어라인 보더 = v3 가 기각당한 바로 그 지문이다. 이 스킨의 선은 **잉크 2px** 하나뿐이다.
      ② 바로 옆 자물쇠 버튼은 흰 채움 + 잉크 2px + 하드 섀도인데, 둘이 나란히 서서 서로 다른 언어를 썼다.
      ③ 상단바는 **끊기지 않는 하늘 밴드**다. 불투명한 상자를 얹으면 하늘에 구멍이 뚫린다.
   그래서 상자를 없앴다. 로고와 같은 처리 — 하늘 위에 그냥 얹고 잉크 그림자만 한 단
   (로고도 같은 이유로 흰 상자를 뺐다: "상자 안에 들어있는 디자인").
   크기도 내렸다. 시계는 상단바에서 **가장 안 중요한 정보**인데 가장 컸다. */
/* ⭐ 알파레타 날씨 (2026-09-16). 날짜 줄 앞에 아이콘 하나 + 화씨 온도. 시계와 같은 크기 문법(작은 글자 · 잉크 그림자) */
.nowtop{display:flex; align-items:center; gap:7px;}
.nowwx{display:inline-flex; align-items:center; gap:3px; font-family:var(--f-mono); font-weight:600; font-size:10.5px;
  letter-spacing:0; white-space:nowrap;}
.nowwx b{font-weight:600;}
/* ° 는 모노 폰트에서 한 칸을 통째로 먹어 «78 °» 로 떨어져 보였다 → 라틴 글꼴로 붙인다 */
.nowwx i{font-family:var(--f-latin); font-style:normal; font-weight:500; margin-left:-2px;}
/* ⭐ 우표 속 교회 (2026-09-16). 바닥 그림과 같은 새한장로교회(`--mini`, 소나무·계절 나무까지)를 하늘 그림(`--skyart`) 위에 얹고
   흰 종이 테두리 + 점선 톱니 + 기울임 + 테이프로 «카드에 붙인 우표» 를 만든다.
   지나온 길: 첨탑 끝(*"꽁다리만 나왔어"*) → 작은 교회(*"조금만 더 크게, 배너가 안 이뻐"*) → 우표(엽서 시안).
   ⚠ 바 배경 그림에 박지 않고 **흐름 안의 칸 하나**로 세운다. 폭마다 글자 자리가 달라서 박으면 시계·메뉴 밑으로 들어간다.
   ⚠ 카드 위아래로 조금 삐져나오게 음수 여백을 준다(붙인 우표). 폰은 이름 밑으로 시계를 내려서 자리를 만들었다(위 599px 규칙).
   ⚠⚠ 시각의 빛(옛 `--artfx` 필터)을 **안 입는다**(2026-09-17). 입혔더니 저녁·밤에 우표만 필터로 칙칙하게 어두워져서 글리치처럼 보였다
   (사용자: *"엽서 배너는 냅둬야지. 왜 아이콘만 껌껌해지는 거야? 원래대로 돌려놔"*). 시간은 바닥의 교회 장면이 말한다. */
.bartip{position:relative; flex:none; box-sizing:border-box; width:100px; height:70px; margin:-13px 6px -19px auto; padding:0;
  background:var(--mini) center calc(100% + 3px)/88% auto no-repeat, var(--skyart) center/cover no-repeat, var(--sky2);
  border:4px solid #fff; border-radius:2px; outline:1.5px solid var(--ink);
  box-shadow:0 3px 0 rgba(11,42,68,.55); transform:rotate(4deg); pointer-events:none;}
/* 톱니: 흰 테두리 바깥을 점선으로 뚫는다 */
.bartip::before{content:''; position:absolute; inset:-6px; border:3px dotted var(--card); pointer-events:none;}
/* 우표에 찍힌 이름 (2026-09-16, 사용자: *"우표 위에 '새한장로교회'라고 넣어 줘"*). 진짜 우표의 나라 이름 자리(위 가운데).
   하늘 위 흰 글자에 잉크 그림자 한 단(봄·겨울 하늘이 밝다). 교회 그림은 88% 로 줄여 첨탑 끝이 글자에 안 닿게 했다 */
.bartip b{position:absolute; left:0; right:0; top:3px; text-align:center; white-space:nowrap;
  font-family:var(--f-disp); font-weight:900; font-size:9px; line-height:1; letter-spacing:.06em;
  color:#fff; text-shadow:0 1px 0 rgba(4,24,54,.55);}
/* 우표를 붙인 테이프. 카드 테이프(`.teamcard::before`)와 같은 줄무늬 가면, 색은 계절 강조색 */
.bartip::after{content:''; position:absolute; top:-6px; left:-16px; width:42px; height:14px; transform:rotate(-34deg);   /* ⚠ -9 이면 폰 화면 윗끝에 테이프 끝이 1~2px 잘렸다 */
  border-radius:2px; opacity:.88; background:var(--accent);
  -webkit-mask:repeating-linear-gradient(90deg,#000 0 5px,rgba(0,0,0,.78) 5px 10px);
  mask:repeating-linear-gradient(90deg,#000 0 5px,rgba(0,0,0,.78) 5px 10px);}
/* ⭐ 날씨 아이콘은 **날씨마다 제 색**이다 (2026-09-16). 사용자: *"햇살 아이콘이 파래서 난 눈꽃 아이콘인 줄 알았어.
   햇살이면 햇살답게."* 글자색(파란 잉크)을 따라 칠했더니 해의 빛살이 눈 결정으로 읽혔다.
   → 색은 `wxIcon` 이 도형마다 직접 준다(해 = 노란 원 + 주황 빛살, 비 = 파란 빗줄기, 구름 = 회색 테두리 흰 구름).
   여기서는 크기와 선 모양만. ⚠ fill·stroke 를 여기서 주면 도형의 색 속성을 덮으니 주지 않는다. */
.wxi{width:16px; height:16px; stroke-linecap:round; stroke-linejoin:round; flex:none;}
/* 좁은 폰은 연도를 접는다 — 날씨 칸이 들어갈 자리. 월·일·요일은 남는다 */
@media (max-width:519px){ .nowy{display:none;} }
/* 메뉴가 상단바에 올라오는 좁은 데스크톱(900~1099)도 연도를 접는다. 안 접으면 메뉴 글자가 두 줄로 꺾였다(실측 900px) */
@media (min-width:900px) and (max-width:1099px){ .nowy{display:none;} .topbar .deskNav a{padding-left:9px; padding-right:9px;} }
/* 효과 판 = 바탕 그림 위, 본문 아래. 누를 수 없고 글자를 안 가린다 */
.fxlayer{position:fixed; inset:0; width:100%; height:100%; z-index:-1; pointer-events:none;}
.fxlayer[hidden]{display:none;}
.nowplate{margin-left:0; flex:none; display:flex; flex-direction:column; align-items:flex-end;   /* auto 는 우표(.bartip)가 갖는다. index.html 첫 그림 CSS 의 auto 를 덮는다 */
  line-height:1; color:var(--ink2); padding:2px 0 1px;}
.nowdate{font-family:var(--f-latin); font-weight:500; font-size:9.5px; letter-spacing:.13em;
  opacity:.8; white-space:nowrap;}
/* 요일만 한글. 라틴 폰트(Jost)에는 한글이 없어서 섞어 쓰면 폰트가 갈린다 */
.nowdate i{font-family:var(--f-body); font-style:normal; font-weight:700; font-size:9px;
  letter-spacing:0; margin-left:5px;}
.nowtime{font-family:var(--f-mono); font-weight:500; font-size:13px; letter-spacing:.01em;
  margin-top:5px; font-variant-numeric:tabular-nums;}
/* 시 칸은 폭을 잡아 둔다 — 9시에서 10시로 넘어갈 때 판이 흔들리면 안 된다 */
.nowtime .nowh{display:inline-block; min-width:2ch; text-align:right;}
/* AM/PM 은 후투라 계열 라틴으로 작게. 숫자와 같은 크기면 시각보다 눈에 먼저 들어온다 */
.nowtime i{font-family:var(--f-latin); font-style:normal; font-weight:500; font-size:9px;
  letter-spacing:.14em; margin-left:5px; opacity:.72;}
.adminBtn{flex:none; position:relative; width:38px; height:38px; border-radius:12px;
  border:var(--bw) solid var(--ink); background:var(--card); box-shadow:var(--sh-sm);
  display:flex; align-items:center; justify-content:center; cursor:pointer;}
.adminBtn .ic{width:18px; height:18px; color:var(--ink);}
.adminBtn:active{transform:translateY(2px); box-shadow:none;}
/* 로그인 상태는 **잉크 채움**이다. 예전엔 라일락이었는데 그건 앨범 탭의 색이고,
   상단바에 나오면 색 규율이 깨진다("라일락은 앨범 탭 밖으로 나오지 않는다"). 2026-09-12 */
.adminBtn.on{background:var(--ink);}
.adminBtn.on .ic{color:#fff;}
.rolebadge{position:absolute; top:-9px; right:-9px; background:var(--ink); color:#FFD75E;
  font-size:9.5px; font-weight:800; border-radius:999px; padding:3px 8px; border:2px solid var(--card);}

/* ⚠ 이 폰 규칙은 시계·우표·자물쇠 기본 규칙 **뒤에** 둔다. 앞에 두면 `.nowplate{flex-direction:column}`·`.nowtime{margin-top}` 이 도로 덮는다(실측: 시각이 두 줄로 서서 카드가 87px) */
/* ⭐ 폰(599px 까지): 날씨·시각을 **이름 밑 한 줄**로 내린다(날짜·초는 접는다). 시계가 오른쪽 두 줄을 먹으면
   교회가 360 폰 33px · 390 폰 63px 밖에 못 섰다. 격자 = [마크][이름 / 날씨·시각][우표][자물쇠]. */
@media (max-width:599px){
  .topbar .in{display:grid; grid-template-columns:auto auto minmax(0,1fr) auto; grid-template-rows:auto auto;
    column-gap:8px; row-gap:3px;}
  .topbar .tile{grid-column:1; grid-row:1 / 3;}
  .logo{grid-column:2; grid-row:1; align-self:end;}
  .nowplate{grid-column:2; grid-row:2; align-self:start; flex-direction:row; align-items:center; gap:7px; padding:0;}
  .nowdate, .nows{display:none;}
  .nowtime{margin-top:0; font-size:11.5px;}
  .bartip{grid-column:3; grid-row:1 / 3; justify-self:end;}
  .adminBtn{grid-column:4; grid-row:1 / 3;}
}

.deskNav{display:none;}

/* ── 하단 탭바 ────────────────────────────── */
.tabbar{position:fixed; left:0; right:0; bottom:0; z-index:40;
  background:var(--card); border-top:var(--bw) solid var(--ink);
  box-shadow:0 -3px 0 var(--deck);
  transition:transform .24s ease;
  display:flex; justify-content:space-around; align-items:stretch;
  height:calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding:7px 6px calc(env(safe-area-inset-bottom) + 7px); gap:3px;}
.tabbar a{flex:1; max-width:92px; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; text-decoration:none; color:var(--faint); font-size:10.5px; font-weight:700; border-radius:13px;
  border:var(--bw) solid transparent;
  transition:transform .26s var(--e-snap), background .18s ease, color .18s ease, box-shadow .18s ease;}
.tabbar a:active{transform:scale(.94);}
.tabbar a .ic{width:22px; height:22px;}
/* 아이콘은 고르는 순간 한 번 부풀었다 가라앉는다. 튀지는 않는다 (.on 이 붙는 순간 재생된다) */
.tabbar a.on .ic{animation:tabpop .42s var(--e-glide);}
@keyframes tabpop{
  from{transform:scale(.9);}
  50%{transform:scale(1.06);}
  to{transform:scale(1);}
}
/* 폰 브라우저는 자기 하단 바를 그린다. 그 위에 이 바까지 고정이면 바가 두 겹이 된다.
   내려 읽을 땐 비키고, 조금만 올리면 돌아온다. 홈 화면에서 연 경우엔 가릴 바가 없으니 안 접는다. */
body.tabhide .tabbar{transform:translateY(calc(100% + 8px));}
body.pwa .tabbar{transform:none;}
.tabbar a.on{font-weight:800; color:var(--ink); border-color:var(--ink); box-shadow:var(--sh-sm);
  transform:rotate(-1.5deg) scale(1.03);}
.tabbar a[data-nav="#/home"].on{background:var(--accent-soft);}
.tabbar a[data-nav="#/plan"].on{background:var(--bcast-soft);}
.tabbar a[data-nav="#/praise"].on{background:var(--praise-soft);}
.tabbar a[data-nav="#/team"].on{background:var(--sand-soft);}
.tabbar a[data-nav="#/docs"].on{background:var(--sound-soft);}
.tabbar a[data-nav="#/album"].on{background:var(--lilac-soft);}
.tabbar a.on[data-nav="#/plan"] .ic{color:var(--bcast);}
.tabbar a.on[data-nav="#/praise"] .ic{color:var(--praise);}
.tabbar a.on[data-nav="#/team"] .ic{color:var(--sand);}
.tabbar a.on[data-nav="#/docs"] .ic{color:var(--sound);}
.tabbar a.on[data-nav="#/album"] .ic{color:var(--lilac);}

/* ── 본문 공통 ────────────────────────────── */
.view{max-width:960px; margin:0 auto; padding:20px 16px 44px;}
.sec{margin-top:34px;}
.sec:first-child{margin-top:10px;}
.sec>h2, .secrow h2{font-family:var(--f-disp); font-weight:900; font-size:23px; letter-spacing:-.3px;
  margin:0 0 3px; display:flex; align-items:center; gap:10px; color:var(--ink);
  /* 물결은 배경이 아니라 ::after 다. 배경이면 그어지는 연출이 background-size 를 늘리는 꼴이라
     선이 가로로 눌렸다 펴진다. 별도 상자로 두면 scaleX 로 깔끔하게 그어진다(합성만 쓴다).
     ⚠⚠ **그리는 순서로 풀려고 하지 말 것.** 배경은 언제나 자식 뒤지만 절대배치 가상요소는 자식 위다.
        42차에 `isolation:isolate` + `z-index:-1` 로 뒤로 보냈는데 **폰에서는 그게 안 통했다**
        (사용자: "여전히 잘려, 애니메이션이 끝날 때까지"). 조상(#view)이 transform 애니메이션 중이면
        합성 레이어로 올라가고, 그 안의 음수 z-index 는 앞으로 튀어나올 수 있다.
        애니메이션이 끝나면 제자리로 돌아가니 **끝날 때까지만** 잘려 보였다.
        → 43차: **겹칠 수 없게 띄운다.** 여유 3.6px 이 아니라 **9px**. 순서가 어떻든 닿지 않는다.
        (아이콘은 -4도 기울고 2px 잉크 단이 있어 글자 상자보다 3.6px 아래로 내려온다.
         물결 첫 줄은 padding-bottom 22px 기준으로 그보다 9px 아래에서 시작한다.) */
  position:relative; padding-bottom:22px;}
.sec>h2::after, .secrow h2::after{content:''; position:absolute; left:0; bottom:0;
  width:74px; height:11px; background:var(--squig) left bottom/74px 11px no-repeat;
  transform-origin:left center;}
/* ⚠⚠⚠ **기울인 아이콘 타일에 `filter` 를 쓰지 않는다** (2026-09-12 뒤집음).
   46차에는 `box-shadow` 가 «곧게 아래로» 밀려 모서리가 어긋난다고 보고 `filter:drop-shadow` 로 바꿨는데,
   **그 진단이 틀렸다.** box-shadow 는 요소가 다 그려진 뒤 **통째로** 변형되므로 그림자도 같이 기운다.
   -4도에서 어긋나는 양은 0.14px 다(실측, 6배 확대 비교에서 두 판이 구별되지 않는다).
   반대로 `filter` 는 그 요소만 **따로 래스터화**해서 합성하는데, 그 표면이 다시 회전하면
   가장자리가 계단으로 남는다 — 아이패드에서 그렇게 보였다
   (사용자 2026-09-12: *"아이콘 외곽이 깨져 보여, 계단 현상처럼. 이전에는 없었거든"*).
   ⭐ **그림자 하나 때문에 레이어를 하나 더 만들 이유가 없다.** 한 화면에 이 타일이 예닐곱 개다.
   ⚠ 단, **배경이 없는 그림**(로고 png)은 여전히 `filter` 여야 한다 — box-shadow 는 네모를 그린다.
   (2026-09-16) 제목 옆 네모 타일(`.sec>h2 .ic`)은 지웠다. 이 교훈은 기울인 그림 아이콘에도 그대로다. */
/* ⭐ (2026-09-16) 제목 옆은 이제 네모 타일이 아니라 **그림 아이콘**(`hico`)이다. 제목에 선 아이콘을 다시 넣지 말 것(타일 규칙이 없다).
   그림에 이미 남색 테두리가 있어서 타일·그림자를 안 두른다. 기울임만 살짝(스티커처럼).
   ⚠ 기울인 그림에 filter 그림자를 걸지 않는다(위 주석, 아이패드 계단 현상). */
.sec>h2 .hic, .secrow h2 .hic{width:40px; height:40px; flex:none; transform:rotate(-4deg); margin-right:-2px;}
/* ⭐ 영어를 나란히 (75차, 사용자: *"영어권 있어서 '다음 섬김' 같은 건 잘 못 알아듣는 것 같아.
   옆에 작은 폰트로 영어도 같이, 한글하고 자연스럽게 섞이게"*).
   ⚠ 라틴 전용 글꼴(Jost)로 두고 **아래쪽에 맞춰** 앉힌다 — 한글 제목이 23px 이라 가운데로 맞추면 뜬다. */
.sec>h2 i, .secrow h2 i{font-family:var(--f-latin); font-style:normal; font-weight:700;
  font-size:11.5px; letter-spacing:.08em; color:var(--faint); align-self:flex-end;
  margin:0 0 4px -4px; white-space:nowrap;}
/* ⭐ 바탕 위에 바로 앉는 글자(구역 제목·영어 부제·안내·발)에 **바탕색 테두리** (2026-09-16).
   스크롤하다 제목이 바닥 교회 그림(첨탑·소나무) 위를 지나가면 작은 영어 부제가 나무에 묻혔다(실측, 폰·1440).
   테두리 색이 바탕과 같아서 **평소엔 안 보이고**, 그림 위를 지날 때만 글자를 받친다. 블러 0(이 스킨의 그림자 규칙).
   ⚠ 상자(알약)를 깔지 않는다. 제목이 스티커처럼 떠 보이고 화면 모양이 바뀐다. */
:root{
  --halo:1.5px 0 0 var(--paper), -1.5px 0 0 var(--paper), 0 1.5px 0 var(--paper), 0 -1.5px 0 var(--paper),
         1px 1px 0 var(--paper), -1px -1px 0 var(--paper), 1px -1px 0 var(--paper), -1px 1px 0 var(--paper);
  --halo-sm:1px 0 0 var(--paper), -1px 0 0 var(--paper), 0 1px 0 var(--paper), 0 -1px 0 var(--paper);
}
.sec>h2, .secrow h2, .grptitle, .rsghd{text-shadow:var(--halo);}
.sec>h2 i, .secrow h2 i, .sec>.hint, .srcnote, .rsghd b, .rsmore, .hubfoot .hf1, .hubfoot .hf2{text-shadow:var(--halo-sm);}
/* 75차엔 홈 구역 타일마다 도메인 색을 줬다(그때는 그림까지 다 같아서 구별이 안 됐다). 지금은 그림이 구역마다 다르고
   (확성기·별·달력·유튜브·집), 색까지 여섯 가지면 한 화면에 채도색이 열 벌이 된다(사용자 2026-09-12: "뒤죽박죽").
   → 홈 타일은 **계절 강조 하나**(기본값). 도메인 색은 아래 뷰 단위 규칙대로 **그 탭 안에서만**. */
/* (2026-09-16) 뷰마다 타일 바탕색을 칠하던 여섯 줄은 지웠다. 제목 옆은 이제 그림 아이콘이라 바탕이 없다 */
.sec>.hint{font-size:12.5px; font-weight:500; color:var(--ink2); margin:6px 0 15px;}
.secrow{display:flex; align-items:center; gap:10px;}
.secrow .more{margin-left:auto; font-size:12.5px; font-weight:800; color:var(--ink); text-decoration:none;
  white-space:nowrap; background:var(--card); border:var(--bw) solid var(--ink); border-radius:999px;
  padding:6px 13px; box-shadow:var(--sh-sm);}
.secrow .more:active{transform:translateY(2px); box-shadow:none;}
/* 섹션 머리의 단추 묶음(앨범 머리의 사진 올리기·앨범 삭제). `.more` 의 알약 옷을 벗긴다. 안 벗기면 단추를 알약이 한 겹 더 두른다 */
.secrow .more.acts{background:none; border:0; box-shadow:none; padding:0; display:inline-flex; align-items:center; gap:8px;}
.secrow .more.acts:active{transform:none;}

.card{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-l);
  padding:16px 18px; box-shadow:var(--sh);}
.empty{border:2.5px dashed var(--faint); border-radius:var(--r-l); background:rgba(255,255,255,.65);
  padding:26px 18px; text-align:center; color:var(--ink2); font-size:13.5px; font-weight:500; line-height:1.7;}
.empty b{color:var(--ink);}

/* ── 큐카드 = 워시테이프 티켓 (시그니처) ────── */
/* 옆으로 넘기면 카드가 화면 한가운데 선다.
   양옆 여백 = (레일폭 - 카드폭)/2. 레일은 margin:0 -16px 로 화면 끝까지 나가 있으니 +16px 로 되돌린다.
   첫 카드·마지막 카드까지 가운데로 올 수 있어야 mandatory 스냅이 튀지 않는다. */
/* ⚠ 예전엔 가로로 넘기는 레일이었다(카드 폭 84vw, 스냅). 폰에서 두 번째 카드부터는 오른쪽 끝만 살짝 보여
   "넘길 수 있다"는 걸 아무도 몰랐고, 9/6 주일 콘티가 첫 화면에 없었다(62차 화면 점검). 넘김 자체를 없앤다:
   폰은 세 장을 세로로, 넓은 화면은 격자(아래 미디어 쿼리). */
.rail{display:flex; flex-direction:column; align-items:stretch; gap:22px; margin:0; padding:16px 0 6px;}
.qcard{position:relative;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh); display:flex; flex-direction:column;}
.qcard:nth-child(even){--tilt:.5deg;}
.qcard:nth-child(odd){--tilt:-.4deg;}
.qcard{transform:rotate(var(--tilt,0deg));}
/* 워시테이프 조각 — 카드마다 색이 다른 진짜 테이프 */
.qcard::before{content:''; position:absolute; top:-11px; left:50%; width:96px; height:22px;
  transform:translateX(-50%) rotate(-3deg); border-radius:3px; opacity:.85;
  background:var(--sand-soft);
  -webkit-mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);
  mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);}
.qcard.sun::before{background:var(--praise-fill);}
.qcard.fri::before{background:var(--bcast-fill);}
.qcard.sat::before{background:var(--sat-fill);}
.qcard.ev::before{background:var(--accent);}
.qcard.today{--tilt:-.8deg; border-width:3px; box-shadow:0 5px 0 var(--ink); z-index:1;}
.stamp{position:absolute; top:-14px; right:12px; font-family:var(--f-mono); font-weight:600; font-size:10px;
  letter-spacing:.14em; background:var(--accent); color:var(--ink);
  border:var(--bw) solid var(--ink); border-radius:9px; padding:3.5px 10px;
  transform:rotate(4deg); box-shadow:var(--sh-sm); z-index:2;}
/* 카드 머리 = 두 칸. **왼쪽이 무엇인지, 오른쪽이 언제인지.**
   ⚠ 예전엔 `날짜 ····· [작은 알약]` 한 줄이었다. 알약을 오른쪽 끝으로 밀어 놓으니
      가운데가 통째로 죽은 자리였고(사용자: "그 많은 공간에 콩알만하게 박아넣은 거 같다",
      "남는 공간을 최대한 활용하라고 한 건데 아직 공백이 많이 남아 보인다"),
      정작 "무슨 예배인가"가 그 줄에서 가장 작은 글자였다.
      시각·장소를 아래 별도 줄(.qmeta)로 빼 둔 것도 빈 자리를 더 벌리고 있었다.
   이제 왼쪽 칸이 `예배 이름(크게) / 시각·장소(작게)`, 오른쪽 칸이 `날짜 / 요일`.
   두 칸이 양 끝을 잡아 주니 가운데 빈 자리가 없어지고 줄 하나도 줄었다. */
.qhead{display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
  padding:12px 16px 13px;
  border-bottom:var(--bw) solid var(--ink);
  border-radius:calc(var(--r-m) - 3px) calc(var(--r-m) - 3px) 0 0;}
.qhl{min-width:0; display:flex; flex-direction:column; align-items:flex-start; gap:5px;}
.qhr{flex:none; display:flex; align-items:baseline; gap:2px; padding-top:2px;}
/* 카드 머리 바탕 = 요일 색. 목록 줄(.svrow)도 같은 문법을 쓴다 */
.qcard.sun .qhead,.svrow.sun .qhead{background:var(--praise-soft);}
.qcard.fri .qhead,.svrow.fri .qhead{background:var(--bcast-soft);}
.qcard.sat .qhead,.svrow.sat .qhead{background:var(--sat-soft);}
.qcard.ev .qhead,.svrow.ev .qhead{background:var(--accent-soft);}
.qdate{font-family:var(--f-disp); font-weight:900; font-size:25px; letter-spacing:-.5px; line-height:1;}
.qdow{font-family:var(--f-body); font-weight:700; font-size:10.5px; color:var(--ink2); margin-left:-3px; align-self:flex-end; padding-bottom:2px;}
/* 예배 이름(브뚜·주일예배·리허설) = 이 카드가 **무엇인지** 말하는 한마디. 카드의 제목이다.
   ⚠ **상자를 없앴다** (사용자: "그 상자 꼭 써야 해?"). 알약에 가둬 두니 아무리 키워도 딱지로 읽혔고,
      머리 안에 잉크 테두리가 두 겹(카드 + 알약)이 되어 시끄러웠다.
      색만으로 충분하다 — 예배별 의미색은 이미 카드 머리 바탕·워시테이프·탭까지 다 쓰고 있는 규칙이다.
   ⚠ 상자를 지웠으니 **글자 색이 유일한 신호**다. 소프트 바탕 위 진한 의미색이라 큰 글자 대비는 넉넉하다. */
.qsvc{font-family:var(--f-disp); font-weight:900; font-size:30px; letter-spacing:-.8px;
  line-height:1; white-space:nowrap;}
.qcard.sun .qsvc,.spot.sun .qsvc,.svrow.sun .qsvc{color:var(--praise);}
.qcard.fri .qsvc,.spot.fri .qsvc,.svrow.fri .qsvc{color:var(--bcast);}
.qcard.sat .qsvc,.spot.sat .qsvc,.svrow.sat .qsvc{color:var(--sat);}
.qcard.ev .qsvc,.spot.ev .qsvc,.svrow.ev .qsvc{color:var(--accent-ink);}
/* 시각·장소 = 예배 이름 바로 아래 붙는 부제. 이제 머리 안에 산다(예전엔 아래 별도 줄) */
.qmeta{font-size:11.5px; font-weight:600; color:var(--ink2); font-variant-numeric:tabular-nums;
  line-height:1.45;}
.qsec{padding:10px var(--card-gut) 14px;}
/* 신청 폼 머리. 예전엔 큰카드 딜지(`.qlab`)를 빌려 쓰고 있었는데, 그건 71차에 없어졌다.
   여긴 다르다 — 아래 칸이 무엇을 쓰는 곳인지 말해 주는 유일한 줄이라 남긴다. */
.formlab{display:flex; align-items:center; gap:6px; font-family:var(--f-body); font-weight:800;
  font-size:11px; color:var(--praise); margin-bottom:10px;}
.formlab .ic{width:13px; height:13px; stroke-width:2.6;}
/* 영어는 섹션 머리와 같은 규칙 — 라틴 전용 글꼴, 작게, 흐리게 (75차) */
.formlab i, .btn i, .en{font-family:var(--f-latin); font-style:normal; font-weight:700;
  letter-spacing:.06em; color:var(--faint);}
.formlab i{font-size:10px; margin-left:1px;}
.btn i{font-size:10.5px; margin-left:5px; opacity:.85; color:inherit;}
.hint .en{display:inline-block; font-size:11px; margin-top:2px;}
/* ⭐ 익명 = **스위치 하나**. 라벨 줄 오른쪽 끝에 붙여, 이름칸 바로 위에서 켜고 끈다. */
.formlab .anonchip{margin:0 0 0 auto; padding:3px 10px; font-size:10.5px; display:inline-flex;
  align-items:center; gap:4px;}
.formlab .anonchip .ic{width:11px; height:11px;}
.formlab .anonchip i{color:inherit; opacity:.75;}
.field[hidden]{display:none;}
/* ⚠ 여기 있던 `.qlab`(찬양·방송음향 딱지 줄)은 71차에 통째로 뺐다 — 바로 아래 줄이 같은 말을 한다. */
/* 절취선 — 무대(STAGE)와 뒤(CREW)가 만나는 곳 */
.cut{position:relative; border-top:2.5px dashed var(--ink); opacity:.9; margin:2px 12px;}
/* 구멍 가운데 = 점선(2.5px) 가운데: top = -1.25 - (16 + 테두리 둘)/2. 예전 -9px 는 구멍이 점선보다 2px 아래였다(10-03, 티켓 절취선과 같이 잼) */
.cut::before,.cut::after{content:''; position:absolute; top:calc(-9.25px - var(--bw)); width:16px; height:16px;
  border-radius:999px; background:var(--paper); border:var(--bw) solid var(--ink);}
.cut::before{left:-24px;} .cut::after{right:-24px;}
.qcard .cut::before{left:-21px;} .qcard .cut::after{right:-21px;}

/* 인도자·팀·곡 수·단추가 한 줄에 다 안 들면 단추가 다음 줄로. 이름이 글자 단위로 쪼개지던 것(인/도 지/혜) 수리 */
.leadrow{display:flex; align-items:center; gap:8px; font-size:14px; flex-wrap:wrap; row-gap:8px;}
.leadrow .leadwho{white-space:nowrap;}
.leadrow b, .leadrow .qnm{font-size:15.5px; font-weight:800;}
.teamchip{font-family:var(--f-mono); font-weight:600; font-size:11px; width:24px; height:24px;
  border-radius:999px; display:inline-flex; align-items:center; justify-content:center; border:var(--bw) solid var(--ink);}
.teamchip.A{background:var(--accent); color:var(--ink);}
.teamchip.B{background:var(--ink); color:var(--on-ink);}   /* A = 강조색 · B = 잉크. 자홍은 이 화면에 다른 식구가 없었다 */
.songs{margin:9px 0 0; padding:0; list-style:none; display:flex; flex-direction:column; gap:9px;}
.songs li{display:flex; align-items:flex-start; gap:8px; font-size:13.5px; font-weight:500; line-height:1.45;}
.songs li .no{margin-top:9px;}   /* 단추가 32px 이라 번호·제목을 단추 세로 가운데에 맞춘다 */
.songs li .sbody{padding-top:6px;}
.songs li .key{margin-top:6px;}
.songs .no{font-family:var(--f-mono); font-weight:600; font-size:10px; color:var(--faint); width:12px; flex:none; text-align:right;}
.songs .t{min-width:0;}
/* 곡 한 줄 — 제목은 누를 수 있고, 무슨 곡인지 한 줄이 항상 붙는다 */
.songrow{align-items:flex-start !important;}
.songrow .sbody{flex:1; min-width:0; display:flex; flex-direction:column; gap:1px;}
.stitle{display:inline-flex; align-items:center; gap:5px; padding:0; border:0; background:none; cursor:pointer;
  font-family:var(--f-body); font-size:13.5px; font-weight:700; color:var(--ink); text-align:left;
  line-height:1.45;
  /* ⚠⚠ 밑줄은 **없앴다** (79차). 67차에 빨강 → 잉크로 눅였는데도, 제목이 두 줄로 접히면
     선이 두 번 그어져 **제목 자체가 읽기 어려워졌다**(사용자: "밑줄까지 들어가니까 읽기가 더 힘들어").
     누를 수 있다는 신호는 이미 있다 — 옆의 ▶ 아이콘 · `상세` 단추 · 눌리는 느낌.
     ⚠⚠ **낱말 가운데서 쪼개지지 않게 한다.** 전역 `overflow-wrap:anywhere` 탓에
     `이 날은 주가 지 / 으신 날` 처럼 음절 안에서 끊겼다 — 그러면 대충 만든 것처럼 읽힌다.
     ⚠ `normal` 이 아니라 `break-word` 인 이유: 띄어쓰기가 아예 없는 긴 제목은 `normal` 이면
     줄을 넘어 **상자 밖으로 흘러나간다**. `break-word` 는 띄어쓰기를 먼저 쓰고,
     한 낱말이 통째로 안 들어갈 때만 쪼갠다. */
  overflow-wrap:break-word; word-break:keep-all;}
.stitle:hover{color:var(--praise);}
.stitle .ic.tiny{width:11px; height:11px; fill:currentColor; stroke:none; color:var(--praise); flex:none;}
.smeta{font-size:11px; font-weight:600; color:var(--faint);}
.infobtn{flex:none; width:32px; height:32px; padding:0; border-radius:10px; cursor:pointer;
  background:var(--card); border:1.5px solid var(--faint); color:var(--ink2);
  display:inline-flex; align-items:center; justify-content:center;}
.infobtn .ic{width:14px; height:14px;}
.infobtn:hover{border-color:var(--ink); color:var(--ink);}

/* 결단찬양 = 당일에 들어오는 곡. 콘티 안에서 한눈에 구분되어야 한다 */
.songrow.role .no .ic.tiny{width:11px; height:11px; fill:var(--accent); stroke:var(--ink); stroke-width:1.6;}
/* ⭐ 딱지 한 줄 — 한영 · 결단 · 악보가 **옆으로** 선다 (72차). 자리가 모자라면 접힌다.
   ⚠ 템포·키는 여기 안 넣는다 — 테두리 없는 맨 글이라 딱지들과 같은 줄에 서면 혼자 옷을 안 입은 꼴이다.
   ⚠ 안이 비면 줄 자체를 없앤다(`:empty`). 안 그러면 곡마다 빈 3px 이 깔린다. */
.songrow .stags{display:flex; align-items:center; gap:7px; flex-wrap:wrap; margin-top:3px;}
.songrow .stags:empty{display:none;}
.songrow .stags > *{align-self:center; margin:0;}
.rchip{align-self:flex-start; margin-top:2px; font-size:9.5px; font-weight:800; border-radius:999px;
  padding:2px 8px; background:var(--accent-soft); color:var(--accent-ink); border:1.5px solid var(--accent);}
/* «콘티에서» = 시트 곡 목록엔 없지만 콘티에 있는 곡 (104차). 새 색을 만들지 않는다 — 팀 탭의 모래색을 쓴다 */
.rchip.ct{background:var(--sand-soft); color:var(--sand); border-color:var(--sand);}
.setfoot{display:flex; flex-wrap:wrap; gap:9px; align-items:center;}
.setfoot .btn.playall{margin-top:11px;}
/* 콘티 한 편치 악보를 한 권으로 여는 단추. 재생(붉은꽃) 옆에 서니 **다른 색**이어야 한다 → 잔디 */
.btn.scoreall{margin-top:11px; font-size:12px; padding:7px 13px;
  background:var(--card); border-color:var(--ink); color:var(--ink);}
.btn.scoreall .ic{width:13px; height:13px;}
/* 악보(세션) 옆에 가사(싱어). 예전엔 색으로 갈랐는데(라일락) 아이콘과 글자가 이미 가른다 — 2026-09-12 색 규율로 잉크 외곽선 */
.btn.lyrbookbtn{margin-top:11px; font-size:12px; padding:7px 13px;
  background:var(--card); border-color:var(--ink); color:var(--ink);}   /* 라일락은 앨범 탭 밖으로 안 나온다 (색 규율) */
.btn.lyrbookbtn .ic{width:13px; height:13px;}
/* ⚠ 가사 슬라이드(Drive 링크)도 **같은 몸**이다 (108차-c). CSS 가 없어서 혼자 기본 `.btn`(14px · 10/17) 으로
   커 보였다. 콘티 카드 발의 단추는 전부 한 치수다 — 하나만 크면 그것만 중요한 것으로 읽힌다. */
.btn.slidefile{margin-top:11px; font-size:12px; padding:7px 13px;
  background:var(--card); border-color:var(--ink); color:var(--ink);}
.btn.slidefile .ic{width:13px; height:13px;}

/* ── 가사 한 권 (싱어용) ────────────────────────
   ⚠ 뿌리 클래스를 .pv 가 아니라 .lb 로 쓴다. .pv 는 `touch-action:none` 이라 **세로 스크롤이 죽는다** —
     여기서는 세로가 곧 글 읽기다. 가로로 미는 것만 우리가 가로챈다(JS). */
.lb{position:relative; width:100%; height:100%; overflow:hidden;}
.lbwait{position:absolute; inset:0; display:grid; place-items:center; color:#fff; font-size:13px; font-weight:700;}
.lbstage{position:absolute; inset:0; overflow:auto; overscroll-behavior:contain; touch-action:pan-y;
  padding:calc(74px + var(--top-safe)) 18px calc(92px + env(safe-area-inset-bottom));
  -webkit-overflow-scrolling:touch;}
/* ⚠ 사진 위에 쓰던 옅은 그늘로는 **흰 가사가 그대로 비친다** — 곡 이름이 안 읽혔다(실측).
   글이 지나가는 자리라 버튼 줄 뒤는 **불투명하게** 덮고 바깥으로만 흐려 준다. */
.lb .pvtop{background:linear-gradient(180deg,#050f1c 0 62%,rgba(5,15,28,0));}
.lb .pvnav{background:linear-gradient(0deg,#050f1c 0 62%,rgba(5,15,28,0));}
.lbtext{margin:0; white-space:pre-wrap; word-break:keep-all; font-family:var(--f-lyric); font-weight:400;
  line-height:1.85; letter-spacing:-.1px; color:#fff; text-shadow:0 1px 0 rgba(0,0,0,.35);}
.lbtabs{display:flex; width:fit-content; margin:0 0 14px; border:var(--bw) solid var(--ink);
  border-radius:999px; overflow:hidden; box-shadow:var(--sh-sm);}
/* ⚠⚠ display 를 준 요소는 `[hidden]` 이 안 먹는다(52차의 `.pvstage iframe` 과 똑같은 함정).
   이게 빠져 있어서 **한글 곡에도 언어 탭이 그대로 떠 있었다** — 누르면 그 곡의 영어 줄
   (감탄사·반복 표시)만 남아 가사가 사라진 것처럼 보였다. */
.lbtabs[hidden]{display:none;}
.lbtabs button{border:0; background:var(--card); cursor:pointer; padding:6px 15px;
  font-family:var(--f-body); font-size:11.5px; font-weight:800; color:var(--ink2);}
.lbtabs button + button{border-left:var(--bw) solid var(--ink);}
.lbtabs button.on{background:var(--praise-fill); color:#fff;}
/* 글자 크기 단추 — 아이콘이 아니라 글자다(무대에서 뜻이 바로 읽혀야 한다) */
#lbSmall, #lbBig{font-family:var(--f-disp); font-weight:900; font-size:13px; line-height:1;}
#lbSmall small, #lbBig small{font-size:10px; margin-left:1px;}
.btn.resp{margin-top:11px; font-size:12px; padding:7px 13px;
  background:var(--card); border-color:var(--ink); color:var(--ink); border-style:dashed;}
.btn.resp .ic{width:13px; height:13px;}
.btn.resp.has{background:var(--accent-soft); border-style:solid; border-color:var(--accent);}
.qsec .btn.resp{margin:0; padding:5px 10px; font-size:11px;}

/* ══ 결단찬양 창 (97차, `openRespSheet` 주석) ══════════════════════════════════
   ① 팀 코드(로그인 안 됐을 때만) ② 시트·노션 본 결과 한 줄 ③ 올라와 있는 곡 ④ 곡 이름 칸 + 유튜브 후보.
   ⚠ 후보는 **세로 한 줄씩**, 썸네일은 작게(112×63). 폰에서 한 화면에 셋은 보여야 고를 수 있다.
   ⚠ 후보 줄 전체가 단추다(짧게 누르면 그 영상으로 올라간다). 잉크 외곽선은 누를 때만 — 여섯 줄이 다 굵으면 시끄럽다. */
.rsnote{margin:0 0 10px; font-size:13px; color:var(--ink2); line-height:1.6;}
.rsnow{display:flex; align-items:center; gap:8px; margin:0 0 10px; padding:9px 12px;
  font-size:12.5px; font-weight:700; color:var(--ink2); line-height:1.45;
  background:var(--paper); border:1.5px dashed var(--faint); border-radius:var(--r-s);}
.rsnow .ic{width:15px; height:15px; flex:none;}
.rsnow.hit{background:var(--accent-soft); border:1.5px solid var(--accent); color:var(--ink);}
.rslist{list-style:none; margin:0 0 12px; padding:0; display:flex; flex-direction:column; gap:6px;}
.rslist:empty{display:none;}
.rsitem{display:flex; align-items:center; gap:8px; padding:8px 10px 8px 9px;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-s);}
.rsitem > .ic{width:15px; height:15px; flex:none; color:var(--accent-ink);}
.rsin{flex:1; min-width:0; display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 8px;}
.rsin b{font-weight:800; font-size:14px;}
.rsin i{font-style:normal; font-size:11px; font-weight:700; color:var(--ink2);}
.rsitem .linkbtn.del{flex:none; color:var(--praise); font-size:12px; font-weight:800;}
.rsrow{display:flex; gap:8px; align-items:center;}
.rsrow .field{flex:1; margin:0;}
.rsrow .field.rskey{flex:none; width:68px;}
.rsrow .btn{flex:none; margin:0;}
.rslib{margin:6px 2px 0; font-size:11.5px; font-weight:700; color:var(--accent-ink);}
.rsres{display:flex; flex-direction:column; gap:6px; margin-top:10px;}
.rsvid{display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
  padding:6px; background:var(--card); border:1.5px solid var(--faint); border-radius:var(--r-s);
  font-family:var(--f-body); color:var(--ink);}
.rsvid:hover{border-color:var(--ink); background:var(--accent-soft);}
.rsvid:active{transform:translateY(1px);}
.rsvid img{flex:none; width:112px; height:63px; object-fit:cover; border-radius:8px; background:var(--paper2);}
.rsvt{min-width:0; display:flex; flex-direction:column; gap:3px;}
.rsvt b{font-size:13px; font-weight:700; line-height:1.35;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
.rsvt i{font-style:normal; font-size:11px; font-weight:600; color:var(--faint);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.rswait{display:flex; align-items:center; gap:8px; padding:8px 2px; font-size:12.5px; color:var(--ink2);}
.rswait .ic{width:15px; height:15px; flex:none;}
#rsPlain{display:block; margin:10px 2px 0; font-size:12.5px; font-weight:800; color:var(--ink2); text-decoration:underline;}
#rsPlain[hidden]{display:none;}

/* 악보 */
.scorebtn{align-self:flex-start; margin-top:3px; display:inline-flex; align-items:center; gap:5px;
  font-family:var(--f-body); font-size:10.5px; font-weight:800; cursor:pointer;
  background:var(--sound-soft); color:var(--sound); border:1.5px solid var(--sound);
  border-radius:999px; padding:3px 9px;}
.scorebtn .ic{width:11px; height:11px;}
.infobtn.soon{border-style:dashed; color:var(--faint);}
/* (옛 .scoreview / .scorepages 는 51차-c 에 없앴다 — 악보도 사진과 같은 전체화면 뷰어를 쓴다) */
.scorehd{display:flex; align-items:center; gap:7px; font-size:13px; font-weight:800; margin-bottom:10px;}
.scorehd .ic{width:15px; height:15px; color:var(--sound);}
.scorehd .d{font-size:11px; font-weight:600; color:var(--faint);}
.scorethumbs{display:flex; flex-wrap:wrap; gap:9px; margin-bottom:10px;}
.scorethumb{position:relative; width:76px; height:76px; border:var(--bw) solid var(--ink);
  border-radius:var(--r-s); overflow:hidden; background:#fff;}
.scorethumb img{width:100%; height:100%; object-fit:cover; display:block;}
.scorethumb .iconbtn{position:absolute; top:2px; right:2px; width:24px; height:24px; border-radius:8px;}
.scorethumb .iconbtn .ic{width:11px; height:11px;}
.scoreadd{cursor:pointer;}

/* 점검 — 빨간 줄만 보면 되게.
   등급 셋을 **색으로** 가른다: 빨강 = 오늘 손대야 함 · 노랑 = 며칠 안에 · 그냥 = 알고만 있으면 됨. */
.mgcard.chk{border-color:var(--ink);}
.chklist{display:flex; flex-direction:column; gap:7px; margin-top:4px;}
.chkrow{display:flex; flex-direction:column; align-items:stretch; gap:3px; padding:9px 12px; text-decoration:none;
  background:var(--paper); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh-sm); color:var(--ink);}
.chktop{display:flex; align-items:center; gap:9px;}
.chkrow.bad{background:var(--praise-soft); border-color:var(--praise); box-shadow:0 2px 0 var(--praise);}
.chkrow.warn{background:var(--butter-soft); border-color:var(--butter); box-shadow:0 2px 0 var(--butter);}
.chkdot{flex:none; width:20px; height:20px; border-radius:999px; display:inline-flex;
  align-items:center; justify-content:center; background:var(--sound-fill); border:1.5px solid var(--ink);}
.chkrow.bad .chkdot{background:var(--praise-fill);}
.chkrow.warn .chkdot{background:var(--butter);}
.chkrow.info .chkdot{background:var(--faint);}
.chkdot .ic{width:11px; height:11px; color:#fff; stroke-width:3;}
.chkrow.warn .chkdot .ic{color:var(--butter-ink);}
.chkwhat{font-size:12.5px; font-weight:800; flex:none;}
.chkdetail{flex:1; min-width:0; font-size:11.5px; font-weight:600; color:var(--ink2);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:right;}
/* ⚠ 괜찮은 줄은 한 줄로 잘라도 되지만 **빨강·노랑은 그 내용이 용건 자체다** —
   `홈은 "이태영", 실제 오늘은 …` 이 말줄임으로 잘리면 무엇이 틀렸는지가 사라진다. 여긴 접어서 다 보여 준다. */
.chkrow.bad .chkdetail, .chkrow.warn .chkdetail{white-space:normal; overflow:visible; line-height:1.45;}
.chkrow.bad .chkdetail{color:var(--praise); font-weight:700;}
.chkrow.warn .chkdetail{color:var(--butter-ink); font-weight:700;}
/* 무엇을 하면 되는지. **빨강·노랑에만** 붙는다 — 괜찮은 줄에 설명이 붙으면 목록이 읽기 힘들어진다. */
.chkhint{font-size:11px; font-weight:600; line-height:1.45; color:var(--ink2); opacity:.9;
  padding-left:29px; white-space:normal;}
.chkgo{flex:none;} .chkgo .ic{width:13px; height:13px; color:var(--faint);}
.chksum{margin-top:11px; font-size:12px; font-weight:700; color:var(--ink2);
  display:flex; align-items:center; gap:9px; flex-wrap:wrap;}
.chksum b{color:var(--praise); font-family:var(--f-disp); font-weight:900; font-size:14px;}
.chkwhen{color:var(--faint); font-weight:600; font-size:11.5px; margin-left:auto;}

/* 자동 백업 상태 = 단추 **아래 제 줄**. 옆에 붙여 두면 390 폰에서 «구글 드라이브» 가 혼자 아랫줄로 떨어진다. */
/* 창 맨 아래 «내리기» (109차-c). 지우는 것은 맨 아래 작은 글씨 — 95차-g 의 층 규율 그대로다.
   저장 단추와 나란히 서면 실수로 누른다. */
/* ⭐ 모임 «참여하기» 는 **날짜 줄의 빈자리**에 앉는다 (109차-d). 새 줄을 만들면 카드가 46px 커진다.
   ⚠ `.nmeta` 는 흐린 작은 글씨 줄이라 단추도 그 치수에 맞춘다(xs). 줄 높이를 키우지 않는 게 요점이다. */
.btn.xs{font-size:11.5px; font-weight:800; padding:3px 9px; border-radius:999px; border-width:1.5px; margin:0;}
.btn.xs .ic{width:13px; height:13px; margin-right:3px;}
.nmeta .jbtn{margin-left:auto;}
.nmeta .jbtn + .jbtn{margin-left:5px;}

/* ⭐ «새 글» — 새 공지일 때만, 보고 나면 사라진다 (109차-e). 늘 켜져 있는 강조는 곧 배경이 된다. */
.newdot{display:inline-block; vertical-align:2px; margin-right:5px; padding:0 5px; border-radius:999px;
  background:var(--accent); color:#fff; font-size:9.5px; font-weight:900; letter-spacing:-.3px;
  line-height:1.55; border:1.5px solid var(--ink);}
.notice.fresh{border-color:var(--ink);}
.notice.fresh::before{width:9px;}

/* 차례 바꾸기 단추는 **한 묶음**으로 세운다 (109차-i). 낱개로 두면 핀·연필·휴지통과 섞여 무슨 짝인지 안 보인다. */
/* 「내가 서는 날만」 칩 (109차-i). 안내 줄에 얹히는 작은 알약이라 줄 높이를 안 키운다. */
.minechip{margin-left:7px; vertical-align:1px;}
.minechip .ic{width:13px; height:13px; margin-right:3px;}
/* ⚠ 켜진 모양은 손대지 않는다 — 이 앱의 칩은 `.fchip.on` 한 규칙으로 켜진다(곡 찾기 키·템포와 같은 옷). */

.ordbtns{display:flex; flex-direction:column; gap:2px; margin-right:2px;}
.ordbtns .iconbtn{width:28px; height:22px; border-radius:7px;}
.ordbtns .ic{width:14px; height:14px;}

/* ⭐ 공지 제목 (109차-e). 레퍼런스 셋(Carbon · Atlassian · Polaris)이 다 «아이콘 + 제목 + 본문» 이다.
   제목이 있어야 훑다가 걸리고, 두 줄로 접어도 요지가 남는다. */
.nhead{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  font-size:15px; font-weight:900; line-height:1.4; margin-bottom:2px; letter-spacing:-.2px;}
/* ⚠ 좁은 폰(360·344)에서는 제목이 두 줄로 꺾인다. 한 치수 줄여 한 줄 확률을 높이되,
   두 줄이 되는 것 자체는 막지 않는다 — 제목을 잘라 버리면 요점이 사라져서 제목을 둔 뜻이 없어진다. */
@media (max-width:380px){ .nhead{font-size:14px; letter-spacing:-.4px;} }
.nhead + .nbody{font-size:13px; color:var(--ink2);}

/* ⭐ 왼쪽 색 띠 = **모임 카드와 같은 문법**(`.notice.meet::before`). 공지만 띠가 없어서
   같은 자리에 선 모임 카드보다 약해 보였다(사용자: "배경에 묻혀 버리는 느낌"). 색은 그 공지의 팀 색이다. */
.notice.nt-all, .notice.nt-praise, .notice.nt-av{position:relative; overflow:hidden; padding-left:20px;}
.notice.nt-all::before, .notice.nt-praise::before, .notice.nt-av::before{
  content:''; position:absolute; left:0; top:0; bottom:0; width:7px; background:var(--nc);}
.notice.nt-all{--nc:var(--sand);}
.notice.nt-praise{--nc:var(--praise);}
.notice.nt-av{--nc:var(--bcast);}
/* 핀 공지는 한 겹 더 — 맨 위에 둔 것은 맨 위에 둔 티가 나야 한다. */
.notice.pin{box-shadow:var(--sh);}

/* 긴 공지는 석 줄까지 (109차-d). 글은 그대로 있고 보이는 줄만 줄인다. */
/* 모임 안내도 두 줄까지 — 긴 글이 오면 카드가 그만큼 길어진다. 전문은 «고치기» 창에 있다. */
.mnote{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
.nbody.clamp{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
.morebtn{display:block; margin-top:3px; padding:0; background:none; border:0; cursor:pointer;
  font:inherit; font-size:12px; font-weight:800; color:var(--ink2); text-decoration:underline;}
/* ⚠ 색 규율(이 파일 머리): 초록·파랑 같은 의미색은 **딱지와 머리띠에서만** 쓴다.
   «더 보기» 는 그냥 더 읽겠다는 말이라 흐린 잉크 + 밑줄이면 족하다. */

/* 신청한 사람 (리더만 본다). 날짜와 지우기는 각자 칸을 차지한다.
   절대 위치로 위/아래에 붙이면 메모 없는 짧은 줄에서 둘이 겹친다(123차). */
.jlist{display:flex; flex-direction:column; gap:9px;}
.jrow{display:grid; grid-template-columns:minmax(0,1fr) auto 34px; align-items:center; gap:3px 8px;
  background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-s); padding:10px 13px; box-shadow:var(--sh-sm); font-size:13.5px;}
.jwho{grid-column:1; grid-row:1; display:flex; flex-wrap:wrap; align-items:center; gap:4px 7px; min-width:0;}
.jwho b{min-width:0; overflow-wrap:anywhere; font-weight:800;}
.jwho .tbadge{max-width:100%; white-space:normal; overflow-wrap:anywhere;}
.jnote{grid-column:1/-1; grid-row:2; min-width:0; overflow-wrap:anywhere; font-size:12.5px; color:var(--ink2);}
.jwhen{grid-column:2; grid-row:1; white-space:nowrap; font-size:11px; font-weight:700; color:var(--ink2);}
.jrow .jdel{grid-column:3; grid-row:1; width:34px; height:34px; margin:0;}


.expwhen{display:block; margin:7px 0 0; font-size:11.5px; font-weight:700; color:var(--faint);}
.expwhen.warn{color:var(--praise);}
.infobtn.up{border-style:dashed;}          /* 리더용 악보 올리기 = "넣는 자리"는 점선으로(색이 아니라 형태) */
.infobtn.up.has{border-style:solid;}
.infobtn.has{border-color:var(--accent); color:var(--accent-ink); background:var(--accent-soft);}   /* 악보 «있다» = 상태색 하나 */
.scoreblk{margin-bottom:16px;}
.scorehd.alt .ic{color:var(--praise);}
.scorenone{font-size:11.5px; font-weight:600; color:var(--faint); margin-bottom:10px;}


/* 곡 상세 시트 */
.sdchips{display:flex; gap:7px; flex-wrap:wrap; margin-bottom:13px;}
.sdchip{font-size:12px; font-weight:800; border-radius:999px; padding:4px 12px;
  background:var(--praise-soft); color:var(--praise); border:1.5px solid var(--praise);}
.sdchip.none{background:transparent; color:var(--faint); border-color:var(--faint); border-style:dashed;}
/* 결단찬양 = 시트가 아니라 허브에서 들어온 곡. 콘티 줄의 버터 칩과 같은 색으로 맞춘다 */
.sdchip.resp{background:var(--accent-soft); color:var(--accent-ink); border-color:var(--accent);}
.sdrow{display:flex; gap:9px; flex-wrap:wrap; margin-bottom:6px;}
.sdhint{font-size:12px; font-weight:500; color:var(--ink2); margin:6px 0 0;}
.sdhist{margin-top:16px; padding-top:14px; border-top:2px dashed var(--faint);}
.sdhtitle{font-family:var(--f-disp); font-weight:900; font-size:15px; margin-bottom:9px;}
.sdhlist{display:flex; flex-direction:column; gap:7px;}
/* ⭐ 부른 날 한 줄 = **단추**다 (108차). 예전엔 콘티 화면으로 옮겨 가는 링크였는데 같은 클릭이 창도 닫아
   서로 싸웠다(`openSongSheet` 주석). 이제 누르면 그날 콘티 카드가 이 위에 뜬다 — 모양은 그대로 둔다. */
.sdh{display:flex; width:100%; align-items:center; gap:9px; text-decoration:none; background:var(--card);
  font:inherit; color:inherit; text-align:left; cursor:pointer;
  border:1.5px solid var(--ink); border-radius:11px; padding:9px 12px; box-shadow:var(--sh-sm);}
/* 손가락 크기(44px). 예전 링크는 42px 이었는데, 이제 창을 여는 단추다 */
.sdh:active{transform:translateY(2px); box-shadow:none;}
.sdhd{font-family:var(--f-disp); font-weight:900; font-size:15px; min-width:44px;}
.sdhl{font-size:12px; font-weight:600; color:var(--ink2); margin-left:auto;}
/* 꺾쇠 = «누르면 열린다». 인도자 이름이 있으면 그 옆에, 없으면 혼자 오른쪽 끝으로 */
.sdhgo{flex:none; width:14px; height:14px; margin-left:auto; color:var(--ink2);}
.sdhl + .sdhgo{margin-left:7px;}
.key{font-family:var(--f-mono); font-weight:700; font-size:10.5px; color:var(--ink2);
  background:var(--paper); border:1.5px solid var(--faint);   /* 키는 정보지 경고가 아니다. 붉은 배지가 줄마다 서 있었다 (색 규율) */
  border-radius:7px; padding:1.5px 7px; margin-left:auto; white-space:nowrap; flex:none; text-decoration:none;}
.crow{display:flex; align-items:center; gap:8px; font-size:13.5px;}
.rlab{flex:none; width:44px; text-align:center; font-size:10.5px; font-weight:800;
  border-radius:8px; padding:3px 0; border:1.5px solid var(--ink);}
.rlab.b{color:#fff; background:var(--bcast-fill);}
.rlab.s{color:#fff; background:var(--sound-fill);}
/* 교제는 섬김이 아니다. 채운 라벨(섬김) 대신 옅은 라벨로 구분한다 */
.rlab.o{color:var(--ink2); background:var(--paper2); border-color:var(--faint);}   /* 모래는 팀 탭 밖으로 안 나온다 */
.offrow{display:flex; align-items:center; gap:8px; padding:9px var(--card-gut); flex-wrap:wrap;}
.offnote{font-size:11.5px; font-weight:600; color:var(--ink2);}
/* 방음 조가 같이 가는 교제 (2026-09-25, app.js `avFellow`). 이름 줄은 문장 밑으로, «교제» 이름표 폭만큼 들여서 */
.offrow.fellow .avwho{flex-basis:100%; display:flex; align-items:center; gap:7px; flex-wrap:wrap;
  padding-left:52px; font-size:13.5px; font-weight:800;}
.offrow.fellow .avwho i{font-style:normal; color:var(--faint); font-weight:600;}
/* 예배팀 전체 모임 날: 문장이 길어서 «교제» 이름표 옆 칸 안에서 접는다(밑으로 떨어지면 이름표와 따로 논다) */
.offrow.all .offnote{flex:1; min-width:0;}
.avgchip{font-size:10.5px; font-weight:800; color:var(--bcast); background:var(--bcast-soft);
  border-radius:999px; padding:2px 7px; white-space:nowrap;}
.teamcard.av .avghd{display:flex; align-items:baseline; gap:4px 8px; flex-wrap:wrap;
  margin:20px 0 0; padding-top:14px; border-top:2px solid var(--paper2);}
.teamcard.av .avghd b{font-family:var(--f-disp); font-weight:900; font-size:13px; color:var(--bcast);}
.teamcard.av .avghd i{font-style:normal; font-size:10.5px; font-weight:700; color:var(--faint);}

.svrow .offrow{padding:7px 0 0; gap:7px;}
.qsec .offrow{padding:9px 0 0;}
/* ⭐ 리허설 = 내일 준비 (67차). 명단 대신 **못 오는 사람**과 **내일 콘티**를 보여준다.
   '빠짐'은 없으면 줄 자체가 안 뜬다 — 아무도 안 빠지는 게 기본이라, 늘 뜨는 줄이면 신호가 아니라 장식이다. */
.rlab.a{color:var(--praise); background:var(--praise-soft);}
.awaywho{display:flex; align-items:center; gap:7px; flex-wrap:wrap; font-size:14px; font-weight:800;}
.awaywho i{font-style:normal; color:var(--faint); font-weight:600;}
.contiblk{padding:8px var(--card-gut); border-top:1.5px dashed var(--faint);}
.spot .contiblk{border-top:0;}
/* 119: 점선 사이 위아래 여백은 같은 값, 단추 줄에는 별도 아래 여백을 두지 않는다.
   알약과 단추는 28px를 최소 높이로 공유한다. 줄이 접혀도 알약만 납작해지지 않는다.
   각 줄의 높이를 함께 맞추고 글자는 가운데 둔다. 글자가 커져도 같은 줄의 키는 같다. */
.contihd{display:flex; align-items:stretch; gap:7px; flex-wrap:wrap; margin:0;}
/* ⚠ 이 줄의 단추 크기·여백 규칙은 **파일 아래쪽 `.btn.playall` 다음**에 있다.
   여기 두면 `.btn.playall{margin-top:11px}`(같은 무게, 더 뒤)에 져서 전체 재생만 11px 내려앉는다(실측). */
.contilab{display:inline-flex; align-items:center; font-family:var(--f-mono); font-weight:700; font-size:12px;
  color:var(--ink2); background:var(--card); border:var(--bw) solid var(--ink2); border-radius:999px;
  min-height:28px; line-height:normal; padding:0 14px; text-decoration:none; white-space:nowrap; box-shadow:var(--sh-sm);}
.contiblk .songs{margin-top:8px;}
.rehsoon{padding:9px var(--card-gut) 2px; font-size:12px; font-weight:600; color:var(--faint);}
/* ══ 무대 배치 (70차) ══════════════════════════════════════════════════
   무대는 **아래쪽이 회중석**이다. 싱어가 앞(아래), 세션이 뒤(위)에 선다.
   ⚠ 무대 안에서는 페이지가 스크롤되면 안 된다 — 끌어 옮기는 자리라 `touch-action:none` 이 필수다. */
/* ⚠ `.stagebtn` 만 쓰면 **뒤에 오는 `.btn` 규칙에 진다**(둘 다 클래스 하나, 나중 것이 이긴다) —
   그래서 패딩이 안 먹어 이 단추만 9px 더 높았다(실측 40 vs 31). `.btn.stagebtn` 으로 무게를 올린다. */
.btn.stagebtn{margin:0; font-size:11px; padding:5px 10px; background:var(--card);
  border-color:var(--ink); color:var(--ink);}
.btn.stagebtn .ic{width:13px; height:13px;}
/* ⭐⭐ 카드 오른쪽 아래 모서리 (72차-c). 예전엔 **띄워서**(`.stagerow` absolute) 음향 줄 오른쪽 빈자리에 앉혔다.
   ⚠ 98차-b: 방송 | 음향이 한 줄 두 칸이 되면서 그 빈자리가 없어졌다 → 띄우기를 걷고 이름 아래 단추 줄 오른쪽에 뒀다(사용자가 물림).
   ⭐ 98차-c·d: **음향 줄 오른쪽**으로 돌아왔다(좁은 카드 = 음향 줄 오른쪽, 넉넉한 카드 = 두 칸 줄 오른쪽 끝). 띄우지 않고 격자 칸이라 겹칠 수 없다(규칙은 `.svline.crew` 블록의 `> .stagebtn`). */
.qcard, .spot{position:relative;}
/* 누를 것끼리 한 줄. ⚠ 정렬을 안 주면 링크(21px)와 단추(32px)의 **세로 중심이 어긋나** 삐딱해 보인다(실측) */
/* ⚠⚠ 예전엔 여기에 **폭이 없었다** — flex 자식이라 내용만큼만 서고, 넓은 화면에서는 양옆이 어두운
   띠로 남아 **태블릿에서 열어도 폰 화면처럼** 보였다(사용자 71차). 바깥은 화면을 꽉 채우고,
   폭은 안쪽 `.stagemid` 가 잡는다. */
.stagewrap{display:flex; justify-content:center; width:100%; height:100%; background:var(--paper);}
/* ⚠ 무대를 누운 직사각형으로 가둔 뒤로는 화면 아래가 많이 남는다 — 가운데 세운다.
   `justify-content:center` 가 아니라 **auto 여백**을 쓰는 이유: 내용이 화면보다 길어지면
   center 는 윗줄을 잘라 스크롤로도 못 보게 하지만, auto 여백은 그때 저절로 0 이 된다. */
.stagemid{display:flex; flex-direction:column; width:100%; min-width:0; max-width:940px; overflow-y:auto;}
.stagemid > .pvtop{margin-top:auto;}
.stagemid > .stagesave{margin-bottom:auto;}
/* ⚠ `.pvtop` 은 사진 뷰어용이라 **absolute + 어두운 그라데이션**이다. 무대는 밝은 종이 위 흐름 배치라
   그대로 두면 제목이 아래 줄과 **겹쳐 찍힌다**(실측). 여기서는 흐름 안에 세우고 잉크색으로 되돌린다. */
.stagewrap .pvtop{position:static; background:none; color:var(--ink);
  padding:calc(9px + var(--top-safe)) 12px 2px;}
/* ⚠ `.pvcount` 도 사진 뷰어용이다 — 어두운 알약에 흰 글씨, 제목과 날짜가 **한 줄에 겹쳐** 찍혔다(실측).
   가사책이 하는 것과 같은 방식으로 눕히고(flex), 밝은 바탕에 맞게 알약을 지운다. */
.stagewrap .pvcount{display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  background:none; color:var(--ink); padding:0; margin-right:auto; max-width:calc(100% - 70px);}
.stagewrap .pvcount .lbtitle{font-family:var(--f-disp); font-weight:900; font-size:17px; color:var(--ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.stagewrap .pvcount i{margin:0; vertical-align:0; font-size:12px; color:var(--ink2);}
.stagewrap .pvtop .iconbtn{margin-left:auto;}
/* ⭐ 상태 줄 — **누가 언제 맞췄나** (73차). 이게 없으면 기본 배치를 누가 맞춘 것으로 오해한다.
   초록 점 = 누군가 맞춘 것 · 모래 점 = 아직 아무도 안 맞춘 기본 배치. 색과 글이 같은 말을 한다. */
.stagestate{display:flex; align-items:center; gap:8px; margin:8px 14px 0; padding:7px 12px;
  border:1.5px solid var(--faint); border-radius:999px; background:var(--card);
  font-size:12px; font-weight:700; color:var(--ink2);}
.stagestate .stdot{flex:none; width:9px; height:9px; border-radius:999px; background:var(--faint);}
.stagestate.done{border-color:var(--sound); color:var(--sound);}
.stagestate.done .stdot{background:var(--sound-fill);}
.stagestate.draft{border-color:var(--sand); color:var(--sand);}
.stagestate.draft .stdot{background:var(--card); border:1.5px solid var(--sand);}
.stagestate b{font-weight:900;}
/* 잠긴 무대 — 끌 수 없다는 걸 커서로도 말한다. 잠금은 권한이 아니라 실수 방지다(수정하기로 언제든 연다). */
.stage.locked .stchip{cursor:default;}
.stagesave{flex-wrap:wrap;}
.stagesave + .formmsg{display:block; margin:0; padding:0 14px calc(env(safe-area-inset-bottom) + 10px);}
/* 클립보드가 막힌 기기용 — 그림을 그대로 띄운다 (길게 눌러 복사·저장) */
.shotbox{position:absolute; inset:0; z-index:20; display:flex; align-items:center; justify-content:center;
  padding:18px; background:rgba(7,31,54,.72);}
.shotin{width:100%; max-width:560px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-l); box-shadow:var(--sh); padding:14px; max-height:100%; overflow:auto;}
.shotin img{display:block; width:100%; border:1.5px solid var(--faint); border-radius:var(--r-s);}
.shotin p{margin:11px 2px 12px; font-size:12.5px; font-weight:600; color:var(--ink2);}
.shotfoot{display:flex; gap:10px; flex-wrap:wrap;}
.shotfoot .btn{margin:0;}
/* ⚠ **무대는 누운 직사각형이다** (70차, 사용자: "스테이지는 보통 누워있는 렉탱글이야").
   예전엔 `flex:1` 로 남은 높이를 다 먹어 세로로 길쭉했다 — 그건 무대가 아니라 복도다.
   ⚠ 71·72차에 세션을 빼면서 뒤쪽이 통째로 비었다 → 16:10 → 16:9 → **12:5** 로 눕혔다
     (사용자 72차: "싱어들만 선다면 좀 더 길다란 네모여야 해. 지금은 위아래로 공간이 너무 많아").
     싱어는 앞에서 한 줄(지그재그)로 서니 무대도 그 모양이어야 한다. */
.stage{position:relative; flex:none; aspect-ratio:12/5; max-height:40vh; margin:8px 14px 0;
  border:var(--bw) solid var(--ink);
  border-radius:var(--r-l); background:
    repeating-linear-gradient(90deg, transparent 0 39px, rgba(11,42,68,.05) 39px 40px), var(--card);
  box-shadow:var(--sh-sm); touch-action:none; overflow:hidden;}
.stage.dragging{cursor:grabbing;}
.stagefront{position:absolute; left:0; right:0; bottom:0; text-align:center; font-size:10.5px; font-weight:700;
  letter-spacing:.4px; color:var(--faint); padding:5px 0 6px; border-top:1.5px dashed var(--faint);
  background:linear-gradient(180deg, transparent, rgba(11,42,68,.05));}
/* 무대가 얕아졌으니(누운 직사각형) 이름표도 그만큼 작게 — 커야 잘 보이는 게 아니라 안 겹쳐야 잘 보인다 */
.stchip{position:absolute; transform:translate(-50%,-50%); display:inline-flex; align-items:center; gap:5px;
  padding:5px 11px; border:var(--bw) solid var(--ink); border-radius:999px; background:var(--card);
  font-size:12.5px; font-weight:800; color:var(--ink); white-space:nowrap; cursor:grab;
  box-shadow:var(--sh-sm); user-select:none; touch-action:none;}
.stchip i{font-style:normal; font-size:10px; font-weight:600; color:var(--ink2);}
.stchip.tier-lead{background:var(--accent);}
/* ⚠ `.stagetray`(무대 밖 대기 줄)는 75차에 없앴다 — 그 날 못 서는 사람은 **못 서는 날 알리기**가
   이미 받는다. 같은 사실을 두 곳에서 받으면 어느 쪽이 진짜인지 알 수 없다.
   ⚠⚠ 그때 배운 것은 남긴다: **display 를 준 요소는 `[hidden]` 이 안 먹는다**(이 저장소 네 번째 —
   52차 `.pvstage iframe` · 62차 `.lbtabs` · `.syncbar` · 73차 `.stagetray`). 짝 규칙을 반드시 같이 둘 것. */
.stagehint{margin:8px 14px 0 !important; font-size:11.5px;}
.stagesave{display:flex; align-items:center; gap:10px; padding:10px 14px calc(env(safe-area-inset-bottom) + 12px);}
.stagesave .formmsg{margin:0;}
/* ⭐ 태블릿·데스크톱 — 화면이 크면 무대도 커야 한다. 폰 치수를 그대로 늘려 놓으면
   "폰 화면을 태블릿에 띄운 것"으로 읽힌다(사용자 71차). 무대·이름표·제목을 같이 키운다. */
@media (min-width:760px){
  .stage{max-height:58vh; margin:14px 22px 0; border-radius:var(--r-xl);}
  .stchip{font-size:15px; padding:7px 16px; gap:6px;}
  .stagefront{font-size:12px; padding:7px 0 8px;}
  .stagewrap .pvtop{padding:calc(16px + var(--top-safe)) 22px 4px;}
  .stagewrap .pvcount .lbtitle{font-size:21px;}
  .stagewrap .pvcount i{font-size:13.5px;}
  .stagehint{margin:11px 22px 0 !important; font-size:12.5px;}
  .stagesave{padding:14px 22px calc(env(safe-area-inset-bottom) + 16px);}
}
/* 리허설 규칙은 새로 온 사람이 모른다. 홈 카드에서 한 번만 말해 준다 */
.hcal .caloff{display:flex; align-items:center; gap:5px; font-size:11px; font-weight:700;
  color:var(--sand); margin:-2px 0 8px;}
/* 폰 달력 요약 — 넓은 화면에서는 상세가 다 보이니 안 그린다 */
.calmini{display:none; flex-direction:column; align-items:flex-start; gap:2px; margin-top:3px;}
/* 메인·보조는 한 줄에 나란히(왼쪽이 메인). 폭이 모자라면 알아서 접힌다 */
.calmini .mline{display:flex; align-items:baseline; gap:3px; flex-wrap:wrap; max-width:100%;}
.calmini .teamchip{width:14px; height:14px; font-size:8.5px; border-width:1.5px;}
/* 그 날 서는 사람. 옛 휴대용 게임기 UI 처럼 **패딩을 버리고 글자를 촘촘히** 채운다
   (사용자: 작은 화면 공간 활용). 알약 패딩은 한 개당 가로 10px 를 먹어서
   두 이름을 한 줄에 못 놓게 만드는 주범이었다.
   메인·보조 구별은 자리(왼쪽이 메인) + **밑줄**로 한다 — 밑줄은 가로를 0px 먹는다. */
.mnm{display:inline-block; font-size:9.5px; font-weight:800; line-height:1.15; letter-spacing:-.4px;
  white-space:nowrap;}
/* ⚠ flex 기본값(shrink:1)이 이름을 찌그러뜨려 "운학"이 "운"으로 잘렸다(실측).
   이름은 안 줄인다 — 자리가 모자라면 줄바꿈으로 넘긴다. */
.calmini .mline .mnm{flex:none;}
/* 메인 = 색 + 밑줄(가로 0px), 보조 = 흐리게. 자리(왼쪽이 메인)까지 셋이 같이 말한다 */
.mnm.b{color:var(--bcast); padding-bottom:2px; box-shadow:inset 0 -3px 0 var(--bcast);}
.mnm.s{color:var(--sound); padding-bottom:2px; box-shadow:inset 0 -3px 0 var(--sound);}
/* ⚠ 보조를 opacity 로 흐리게 하면 **내 이름 칠까지 같이 흐려진다**(실측: 9/4 운학 보조에서 표시가 죽었다).
   투명도 대신 **연한 색을 직접** 준다. */
.mnm.b.sub{box-shadow:none; padding-bottom:2px; font-weight:700; color:var(--dk-skytx, #3F79A6);}
.mnm.s.sub{box-shadow:none; padding-bottom:2px; font-weight:700; color:var(--dk-leaftx, #2F8A57);}
.mnm.p{color:var(--praise); font-size:10px;}
/* 내 이름 — 코랄 칠. 밑줄 문법은 안 건드린다 */
.mnm.me{background:var(--praise-soft); border-radius:3px; padding-left:2px; padding-right:2px;
  margin:0 -2px;}
.mnm.p.me{background:var(--praise-fill); color:#fff;}   /* 인도자는 글자도 코랄이라 칠만 하면 안 보인다 */
.teamchip.me{outline:2px solid var(--accent); outline-offset:1.5px;}
/* 내가 서는 날. 늘 켜지는 표시가 아니라 **나에게만** 켜지는 표시라 자리값을 한다 */
.mine{width:8px; height:8px; border-radius:999px; display:inline-block; flex:none;
  background:var(--praise-fill); border:1.5px solid var(--ink);}
.calhint .mine{vertical-align:-1px;}
.linkbtn{border:0; background:none; padding:0; margin-left:4px; cursor:pointer;
  font-family:var(--f-body); font-size:11.5px; font-weight:800; color:var(--bcast);
  text-decoration:underline; text-underline-offset:2px;}
.hcal .caloff .teamchip{width:20px; height:20px; font-size:10px;}
.svline.crew .qnm{font-weight:800;}   /* 98차-b: 목록 600 · 홈 800 으로 갈려 있던 걸 홈 쪽으로 하나로 */
.svline.crew .sub{color:var(--ink2); font-size:12.5px; font-weight:500;}
.crow .none,.none{color:var(--faint); font-weight:500;}

/* ── 공지 ────────────────────────────────── */
.nlist{display:flex; flex-direction:column; gap:11px;}
/* ⚠ 여백은 **공지·모임 카드만** 조였다 (109차-d). 홈 첫 화면을 공지가 다 먹지 않게 하려는 것이라
   다른 카드에는 손대지 않는다. */
.notice{display:flex; gap:10px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-m); padding:10px 13px; box-shadow:var(--sh-sm); align-items:flex-start;}
.notice{transition:transform .16s ease, box-shadow .16s ease;}
.notice.pin{background:var(--accent-soft);}
.notice .ic{width:17px; height:17px; margin-top:2.5px; color:var(--ink);}
.notice .nb{flex:1; min-width:0; font-size:13.5px; font-weight:500; line-height:1.6; overflow-wrap:break-word;}
/* ⚠⚠ 줄바꿈을 살리는 건 **공지 본문 글자 한 곳**뿐이다(`.nbody`).
   처음엔 `.notice .nb` 에 `pre-line` 을 걸었는데, **모임 카드가 같은 `.nb` 를 쓴다** —
   그 카드는 조각(제목·날짜·배지·안내)을 여러 줄로 짠 마크업이라 소스의 들여쓰기와 줄바꿈이
   그대로 화면에 나와서 카드가 부풀고 아이콘과 줄이 어긋났다
   (사용자 2026-09-19: *"풍선에 바람 넣은 것마냥 부풀어 올랐잖아"*). 글자를 담는 자리에만 건다. */
.notice .nbody{white-space:pre-line;}
.notice .nmeta{font-size:11px; font-weight:600; color:var(--faint); margin-top:4px; display:flex; gap:7px; align-items:center;}
.tbadge{font-size:10px; font-weight:800; border-radius:999px; padding:1.5px 8px;
  background:var(--sand-soft); color:var(--sand); border:1.5px solid var(--sand);}
.tbadge.praise{background:var(--praise-soft); color:var(--praise); border-color:var(--praise);}
.tbadge.av{background:var(--bcast-soft); color:var(--bcast); border-color:var(--bcast);}

/* ── 모임 카드 (86차) ─────────────────────
   공지와 **같은 부품**(.notice)에 색과 한 줄만 더했다. 새 모양을 만들면 홈이 또 하나의 언어를 배운다.
   구별은 주최 팀 색의 굵은 왼쪽 띠 하나로 낸다 — 배지 색과 띠 색이 같아서 "누가 여는 자리인가"가
   글자를 읽기 전에 먼저 들어온다. */
.notice.meet{position:relative; overflow:hidden; padding-left:20px;}
.notice.meet::before{content:''; position:absolute; left:0; top:0; bottom:0; width:7px;
  background:var(--mc); border-right:var(--bw) solid var(--ink);}
.notice.meet > .ic{color:var(--mc);}
.mtop{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.mtop b{font-family:var(--f-disp); font-weight:900; font-size:15px; line-height:1.35;}
.dchip{font-size:10.5px; font-weight:800; padding:1px 7px; border-radius:999px;
  background:var(--card); color:var(--ink2); border:1.5px solid var(--ink); white-space:nowrap;}
.dchip.now{background:var(--mc); color:#fff;}
.mwho{display:flex; align-items:center; gap:7px; margin-top:6px;
  font-size:11.5px; font-weight:700; color:var(--ink2);}
.mnote{margin-top:6px; font-size:12.5px; font-weight:500; color:var(--ink2); line-height:1.55;}
.evopts{display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:6px;}

/* ── 리퀘스트 CTA (홈) ───────────────────── */

/* 그림 아이콘(2026-09-16). 예전 잉크·강조색 네모 타일. 그림에 남색 테두리가 있어 타일·그림자를 안 두른다 */




   /* 꺾쇠 하나. 위 타일 규칙에 먹히지 않게 자식 선택자로 갈랐다 */


/* ── 섬김표 (월 뷰) ──────────────────────── */
.monthbar{display:flex; align-items:center; justify-content:center; gap:12px; margin:8px 0 20px;}
.monthbar .mlabel{font-family:var(--f-disp); font-weight:900; font-size:22px; letter-spacing:-.4px; color:var(--ink);
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh); padding:8px 20px; transform:rotate(-1.2deg); min-width:154px; text-align:center;}
.mbtn{width:42px; height:42px; border-radius:13px; border:var(--bw) solid var(--ink); background:var(--card);
  box-shadow:var(--sh-sm); display:flex; align-items:center; justify-content:center; cursor:pointer;}
.mbtn:active{transform:translateY(2px); box-shadow:none;}
.mbtn .ic{width:17px; height:17px; color:var(--ink);}
.wklabel{font-family:var(--f-mono); font-weight:600; font-size:10px; letter-spacing:.16em;
  color:var(--ink2); margin:22px 2px 10px; display:flex; align-items:center; gap:8px;}
.wklabel::after{content:''; flex:1; border-top:2.5px dashed var(--faint);}
.svlist{display:flex; flex-direction:column; gap:12px;}
/* ⭐ 섬김표 목록은 **넓은 화면에서 한 줄로 늘이지 않는다** (96차-f).
   사용자: *"섬김표 목록 뷰로 보면 너무 길쭉하지 않아? 너무 옆으로 늘려 놓은 것 같아. 알아서 크기 조절되게."*
   한 줄이 1160px 까지 늘어나 머리 커버도 본문 이름 칩도 왼쪽에 몰리고 오른쪽이 텅 비었다.
   → 카드 폭을 340px 이상으로 두고 **들어가는 만큼 칸을 편다**(auto-fill). 1440 = 한 주 세 장 나란히(금·토·일), 900 언저리 = 두 장, 폰 = 한 장.
   ⚠ 폭을 760px 로 자르는 안(96차-e 시안 D)은 전폭인 알림 띠·주 구분선과 어긋났다. 이건 전폭을 그대로 쓰면서 카드를 나눈다.
   ⚠ `align-items:start` — 늘려 맞추면 사람이 적은 날(리허설) 카드 아래가 빈다(홈 `.rail` 과 같은 이유).
   ⚠ 달력 날짜 시트(#layer)의 목록은 `[data-view]` 밖이라 안 걸린다. */
[data-view="plan"] .svlist{display:grid; grid-template-columns:repeat(auto-fill,minmax(340px,1fr)); align-items:start;}
/* 목록 줄 = 홈 큐카드를 가로로 편 것. 머리(요일 색) + 본문(흰 바탕) 두 층.
   ⚠ 왼쪽 세로 띠(inset box-shadow)가 **달력의 요일 컬럼**과 같은 역할을 한다 —
      훑을 때 색만 보고 무슨 예배인지 가려낼 수 있어야 한다. */
.svrow{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh-sm); overflow:hidden;}
.svrow.sun{box-shadow:var(--sh-sm), inset 6px 0 0 var(--praise);}
.svrow.fri{box-shadow:var(--sh-sm), inset 6px 0 0 var(--bcast);}
.svrow.sat{box-shadow:var(--sh-sm), inset 6px 0 0 var(--sat);}
.svrow.ev {box-shadow:var(--sh-sm), inset 6px 0 0 var(--accent);}
.svrow .qhead{border-radius:0; padding:11px 15px 12px 19px;}
.svrow.today{border-width:3px; transform:rotate(-.3deg);}
.svrow.today .qhead{box-shadow:inset 0 -2px 0 var(--ink);}
.svbody{display:flex; flex-direction:column; gap:9px; padding:12px 15px 13px 19px;}
.svline{display:flex; align-items:center; gap:10px; flex-wrap:wrap; min-width:0;}
.svcchip{font-weight:800; font-size:10.5px; color:#fff; border-radius:999px; padding:3px 10px; border:1.5px solid var(--ink);}
.svcchip.fri{background:var(--bcast-fill);}
.svcchip.sun{background:var(--praise-fill);}
.svcchip.sat{background:var(--sat-fill);}
.svcchip.ev{background:var(--accent); color:var(--ink);}



/* ⭐⭐ 방송·음향 줄 = 섬김표 목록 줄(날짜 시트 포함) · 다가오는 예배 · 다음 섬김이 **같은 격자 하나**(`avCrewHTML`, 98차-e).
   흐름(전부 2026-09-13~14 한 세션, 상세 `docs/HISTORY.md` 98차):
   98차 목록을 두 칸으로(녹화가 방송 앞에 붙어 음향이 카드마다 다른 자리였다, 390 실측 92 · 155 · 171px) →
   98차-b 홈도 두 칸(*"디자인은 일관성이 있어야 돼"*) → 98차-c 무대 배치를 음향 줄 오른쪽으로 → 폰에서 보조가 접힘 →
   98차-d *"보조 이름도 한 줄로"* → 물어서 **«좁은 카드는 방송 줄 / 음향 줄, 넉넉한 카드만 두 칸»** (홈) →
   98차-e 사용자: *"목록 카드도 방송 줄 음향 줄로 맞춰줘."* → 목록도 같은 격자·같은 규칙. 목록만 쓰던 «두 칸 + 아래 녹화 줄»(`.crewbtns`)은 없앴다.
   다음 섬김만 이름이 19px(`.big` + `.spotname`). 칸·간격·단추 자리는 셋이 같다.
   ⚠ 이름은 안 자른다. 좁은 카드에서는 이름 칸 최소가 `max-content` 라 보조가 접히지 않는다. */
.svline.crew{display:grid; grid-template-columns:minmax(max-content,1fr) minmax(0,auto); gap:6px; align-items:start;
  font-size:13px; font-weight:600;}
/* ⚠ 가운데 맞춤이 아니라 **첫 줄 맞춤**이다. 보조가 접힌 칸만 딱지가 두 줄 가운데로 내려가 옆 칸 이름보다 낮게 섰다(360 다음 섬김 실측).
   값은 한 줄일 때 예전 가운데 맞춤과 같은 자리(딱지 25.3px · 13px 이름 줄 20.2px · 19px 이름 줄 29.5px)다 */
.svline.crew .pair{display:flex; align-items:flex-start; gap:6px; min-width:0;}
.svline.crew .pnm{margin-top:2.5px;}
.svline.crew.big .pnm{margin-top:0;}
.svline.crew.big .rlab{margin-top:2px;}
/* 보조 앞 «·» 는 글자가 아니라 여기서 그린다(98차-b). 보조가 좁아서 아래 줄로 접히면 점이 줄 **맨 앞**에 남았다.
   점을 `.sub` 왼쪽 틈(10px)에 띄워 두고 `.pnm` 이 넘친 걸 자르면, 줄 맨 앞으로 간 보조의 점만 잘려 나간다(한 줄일 땐 틈 안이라 보인다). */
/* ⚠ `nowrap` 을 두지 않는다(98차-c). 보조는 flex 줄바꿈으로 **통째로** 아래 줄에 가고, 그 한 줄에도 안 들어갈 만큼 좁을 때만 낱말에서 끊긴다.
   `nowrap` 이면 그때 `overflow:hidden` 에 글자가 잘렸다(344px 폰 계산). */
.svline.crew .pnm{display:flex; flex-wrap:wrap; align-items:baseline; column-gap:10px; min-width:0; overflow:hidden;}
.svline.crew .sub{position:relative;}
.svline.crew .sub::before{content:'·'; position:absolute; right:100%; margin-right:3px;}
/* ⭐⭐ 모양은 **카드 안쪽 폭**으로 갈린다(컨테이너 쿼리 `avcrew`, 화면 폭이 아니다). 컨테이너 = 세 곳의 방송·음향 덩어리.
   1440 데스크톱에서도 목록 줄(329px)·다가오는 예배(327px)는 안쪽이 폰과 같아서 두 줄이다.
   ⚠ 컨테이너 쿼리를 모르는 옛 브라우저(iOS 15 등)는 기본값 = 두 줄 모양을 본다. 폰 모양이 기본이어야 안전하다. 기본값을 두 칸으로 뒤집지 말 것.
   딱지 가운데(12.7 · big 14.7)에 단추 가운데(27.6px 의 13.8)를 맞춘 게 -1 · +1px 이다.
   ⚠ 무대 배치 칸에 `.stage` 라는 클래스를 붙이면 **무대 배치 캔버스**(`.stage`, 12:5 판)의 테두리·높이를 통째로 받는다(98차-c 첫 판에 밟았다).
   ⚠ 단추에 `nowrap` 이 없으면 `auto` 칸이 가장 긴 낱말 폭까지 줄어 «무/대/배/치» 로 세로로 접혔다. */
.qcard .qsec.crew,.svrow .svgrp.av {container:avcrew / inline-size;}
/* 좁은 카드(기본) = 방송 줄(오른쪽 녹화) / 음향 줄(오른쪽 무대 배치, 홈 카드만. 목록의 무대 배치는 찬양 줄에 있다).
   녹화 둘(리허설 녹화 + 녹화)이 안 들어가면 그 칸 안에서 둘이 위아래로 선다(오른쪽 정렬). */
.svline.crew > .crb{grid-area:1 / 1;}
.svline.crew > .crs{grid-area:2 / 1;}
.svline.crew > .recpair{grid-area:1 / 2; justify-self:end; display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; margin-top:-1px;}
/* 이 격자의 단추는 한 치수 조인다(좌우 여백 10 → 8, 아이콘 틈 7 → 5, 칸·단추 사이 8 → 6). 녹화·무대 배치가 같이 조여서 «같은 몸»은 그대로다(81차).
   이유: 주일 당일 390 폰의 오늘 섬김(안쪽 320px, 이름 19px 146px)에 «리허설 녹화 + 녹화»(171px)가 3px 모자라 둘이 위아래로 쌓였다 → 이제 158px.
   ⚠ 375·360 폰의 주일 카드(목록의 지난 주일 줄 포함)는 그래도 모자라서 녹화 둘이 위아래로 선다. 이름은 한 줄 그대로다. */
.svline.crew > .recpair .btn, .svline.crew > .stagebtn{padding-left:8px; padding-right:8px; gap:5px;}
.svline.crew > .stagebtn{grid-area:2 / 2; justify-self:end; margin-top:-1px; white-space:nowrap;}
.svline.crew.big > .recpair, .svline.crew.big > .stagebtn{margin-top:1px;}
/* 팀이 하나뿐이거나 배정 전 = 한 줄(이름 · 녹화 · 무대 배치). 두 줄로 두면 단추 혼자 한 줄이 된다 */
.svline.crew.solo{grid-template-columns:minmax(max-content,1fr) minmax(0,auto) auto;}
.svline.crew.solo > .pair{grid-area:1 / 1;}
.svline.crew.solo > .stagebtn{grid-area:1 / 3;}
/* 넉넉한 카드(안쪽 420px 이상: 태블릿·데스크톱 다음 섬김, 820 다가오는 예배, 한 줄로 펴진 넓은 목록 등) = 두 칸 한 줄 + 무대 배치 오른쪽 끝, 녹화는 아래 줄.
   420 = 다음 섬김 두 칸(146+146) + 무대 배치 83 + 간격 12 = 387 에 여유를 둔 값. ⚠ 칸은 160px 에서 멈춘다(1fr 이면 음향이 카드 가운데로 멀어진다) */
@container avcrew (min-width:420px){
  .svline.crew, .svline.crew.solo{grid-template-columns:repeat(2,minmax(0,160px)) minmax(auto,1fr);}
  .svline.crew > .crb{grid-area:1 / 1;}
  .svline.crew > .crs, .svline.crew.solo > .crs{grid-area:1 / 2;}   /* 음향만 있는 날도 음향 칸 자리 */
  .svline.crew > .stagebtn, .svline.crew.solo > .stagebtn{grid-area:1 / 3;}
  .svline.crew > .recpair, .svline.crew.big > .recpair{grid-area:2 / 1 / 3 / -1; justify-self:start; justify-content:flex-start; margin-top:0;}
}

/* 찬양 / 방송음향 = **두 덩어리**. 예전엔 한 흰 상자 안에 다 섞여 있어서
   "우리 팀이 어디까지인지"가 안 보였다(사용자: "방음팀이랑 찬양팀 좀 더 확실하게 구별되게").
   왼쪽 색 기둥이 그 덩어리가 누구 것인지 말한다 — 찬양 붉은꽃 / 방송음향 바다. */
.svgrp{position:relative; padding:10px 0 10px 13px; border-left:3px solid var(--gc,var(--faint));}
.svgrp.praise{--gc:var(--praise);}
.svgrp.av{--gc:var(--bcast);}
.svgrp + .svgrp{border-top:2px dashed rgba(11,42,68,.14); margin-top:2px;}

/* 파트 줄 — 리더 / 싱어 / 세션. 라벨은 왼쪽에 고정폭으로 세워 눈이 훑을 기준을 만든다 */
.ptiers{display:flex; flex-direction:column; gap:7px; margin-top:9px;}
.ptrow{display:flex; align-items:flex-start; gap:9px;}
.ptk{flex:none; width:32px; padding-top:3px; font-size:10.5px; font-weight:800; color:var(--ink2);
  letter-spacing:.02em;}
.ptags{display:flex; flex-wrap:wrap; gap:5px; min-width:0;}

/* ⭐ 내 이름은 어디서든 튀어야 한다. 목록에서 자기를 못 찾겠다는 게 이번 요청의 핵심이었다 */
.ptag.me{box-shadow:0 3px 0 var(--ink); outline:2.5px solid var(--praise); outline-offset:2px;}
.ptag.me::after{content:'나'; font-family:var(--f-disp); font-weight:900; font-size:9px; color:#fff;
  background:var(--praise-fill); border-radius:999px; padding:1px 5px 2px; margin-left:1px;}
.svrow .contilink{font-size:11.5px; font-weight:800; color:var(--praise); text-decoration:none; align-self:center;}

/* ── 홈 스포트라이트 = "오늘 누가 섬기지?" ──── */
/* ⚠ 홈에서 제일 중요한 카드인데 **등장이 아예 없었다** — 다른 것들이 다 튀어 들어오는 동안
   혼자 그냥 거기 있었다. 작은 줄들보다 한 박자 크고 느리게 내려앉는다(모션에도 위계가 있다). */
.spot{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-l);
  box-shadow:var(--sh); overflow:hidden;
  animation:riseBig .72s var(--e-glide) .04s backwards;}
@keyframes riseBig{
  from{opacity:0; transform:translateY(24px);}
  to{opacity:1; transform:none;}
}
.spot.istoday{border-width:3px; box-shadow:0 5px 0 var(--ink);}
.spot.istoday .spotdate{font-size:24px;}
/* ⚠⚠ 시그니처 ②(카드 머리의 계절 그림 74px)를 **뺐다** (2026-09-01, 35차).
   사용자: "위에 배경하고 아래 브뚜·9/4 이게 왜 분리돼야 될 이유가 있어? 너무 비효율적인 것 같은데."
   맞는 지적이었다. 원래 그림과 글자를 가른 건 **진짜 이유**가 있었지만(겨울 눈밭·봄 밝은 하늘에서
   흰 글자가 묻힌다, 16차) 그 해법의 대가가 컸다:
     · 카드의 **첫 74px 이 아무 정보도 없다**. "오늘 누가 서나"를 3초에 답하는 게 이 카드의 일인데,
       그 답이 한 화면 아래로 밀렸다.
     · 그림과 머리 사이 잉크 괘선이 **한 카드를 두 덩어리로** 보이게 했다.
     · 무엇보다 **같은 계절 그림이 한 화면에 이미 세 번** 나온다 — 상단바 하늘 · 화면 바닥 물가(24차) ·
       그리고 여기. 세 번째 사본이 제일 비싼 자리를 쓰고 있었다.
   19차에 정한 규칙을 그대로 적용한 것이다: **늘 같은 표시는 장식이지 신호가 아니다.**
   계절은 상단바와 배경이 이미 충분히 말한다. 카드는 이제 답부터 시작한다.
   → **36차에 사용자가 A안을 골랐다**: 그림은 두되 머리와 **한 덩어리로**. 아래 `.spothead` 참조.
      이 74px 짜리 별도 띠(`.spotart`)는 그대로 폐기다 — 되살릴 것은 없다. */
/* ⭐ 시그니처 ② 부활, 이번엔 **한 덩어리로** (36차. 사용자가 A안을 골랐다).
   35차엔 그림을 통째로 뺐는데, 사용자 판단은 "그림은 두되 머리와 합쳐라" 였다.
   16차가 그림 위에 글자를 못 얹었던 진짜 이유는 **스크림이 없었기 때문**이다 —
   상단바는 같은 그림 위에 흰 글자를 이미 잘 얹고 있었다(그때 하늘 띠의 덮개 층이 위쪽을 눌러 줬다. 2026-09-16 엽서 카드로 바뀌었다).
   여기도 같은 수를 쓴다: 그림을 머리 배경으로 깔고 위아래를 눌러 흰 글자를 세운다.
   ⚠ **예배 의미색은 글자에서 뺀다.** 붉은꽃·바다·풀색은 어두운 스크림 위에서 대비가 안 난다.
      대신 `--sc` 를 ①머리 위 4px 띠 ②`3일 뒤` 칩 두 군데로 옮겼다 — 색 코딩은 그대로 살아 있다. */
.spot.sun{--sc:var(--praise);} .spot.fri{--sc:var(--bcast);}
.spot.sat{--sc:var(--sat);}    .spot.ev {--sc:var(--accent);}
.spothead{position:relative; display:flex; align-items:flex-end; justify-content:space-between;
  gap:12px; padding:46px 16px 12px; min-height:112px;
  background:var(--sky2) var(--hero) right bottom/cover no-repeat;
  border-bottom:var(--bw) solid var(--ink);}
/* ⚠ 처음엔 위아래를 같이 눌렀더니 **그림이 죽고 파란 덩어리**가 됐다(실측 4계절).
   글자는 전부 아래에 모여 있으니 어둡게 할 곳도 아래뿐이다 —
   위는 거의 그대로 두고 아래로 갈수록 눌러서, 위쪽 절반은 그림이 그대로 보이게 한다. */
/* ⚠ 이 카드 머리의 그림도 **계절 그림이라 늘 한낮**이다. 저녁·밤에 여기만 파랗게 남으면
   화면에서 이 카드만 다른 시간에 있는 것처럼 뜬다 → 상단바와 같은 시각의 빛(--veil)을 한 겹 더 덮는다.
   ⚠ `filter` 는 못 쓴다(흰 글자까지 물든다). 그래서 스크림과 같은 자리에 배경 층으로 얹는다. */
.spothead::after{content:''; position:absolute; inset:0; pointer-events:none;
  background:var(--veil,none),
             linear-gradient(180deg, rgba(2,22,58,.08) 0, rgba(2,22,58,.03) 30%,
             rgba(2,22,58,.30) 58%, rgba(2,22,58,.76) 100%);}
/* ⚠ 그림의 물체는 전부 **오른쪽 아래**에 있고(그리게 할 때 그렇게 시켰다, 16차) 날짜도 오른쪽이다.
   그래서 오른쪽 아래만 한 겹 더 눌러 준다. 나무 우듬지는 위쪽이라 그대로 보인다. */
.spothead .qhr{position:relative;}
/* ⚠ 이 스크림은 **아래쪽(78% 90%)만** 눌렀다. 그래서 시각은 잘 읽혔는데 그 위에 있는 날짜가
   가을 그림의 **밝은 노란 나무**에 그대로 얹혔다 — 흰 글자가 잎에 먹혔다(실측, 사용자 지적 항목).
   가운데를 날짜 쪽으로 올리고 한 단 더 눌러 **날짜와 시각을 한 판으로** 받쳐 준다.
   ⚠ 이 스크림은 오른쪽 칸에만 걸린다. 머리 전체를 누르면 예전처럼 그림이 죽는다. */
/* ⚠ 진하게 키웠더니 이번엔 **네모난 경계선**이 그림 위에 보였다. 상자로 가리는 건 여기까지가 한계다
   (상자 안에서 투명해지는 그라디언트는 가장자리에 반드시 알파가 남는다).
   그래서 상자는 원래 세기로 돌려놓고, **읽히게 하는 일은 글자가 직접** 맡는다(아래 .spotdate 빛무리). */
.spothead .qhr::before{content:''; position:absolute; inset:-7px -9px -6px -14px; z-index:-1;
  border-radius:12px;
  background:radial-gradient(126% 146% at 76% 66%, rgba(2,22,58,.46) 0, rgba(2,22,58,0) 74%);}
/* 예배 색 띠는 스크림 **위에** 온다. inset box-shadow 로 두면 스크림이 덮어 색이 죽는다 */
.spothead::before{content:''; position:absolute; left:0; right:0; top:0; height:4px; z-index:2;
  background:var(--sc,var(--accent));}
.spothead>*{position:relative; z-index:1;}
/* `3일 뒤` = 예배 의미색을 든다(글자에서 뺀 색이 여기로 왔다). 잉크 테두리로 그림에서 떼어 놓는다 */
.spotwhen{font-family:var(--f-disp); font-weight:900; font-size:16.5px;
  background:var(--sc,var(--ink)); color:#fff; border:2px solid var(--ink);
  border-radius:10px; padding:2px 11px 3px;}
.spot.ev .spotwhen{color:var(--ink);}
/* 그림 위 흰 글자. 그림자는 **블러 0 하드 오프셋** — 이 스킨의 그림자 규칙 그대로 */
/* ⚠ 날짜가 가을 그림의 **밝은 노란 나무** 위에 그대로 얹혀 흰 글자가 잎에 먹혔다(사용자 지적 항목).
   하드 오프셋은 **아래쪽만** 받쳐 준다 — 글자 옆·위가 밝으면 소용이 없다.
   그래서 잉크 단(스킨 규칙)은 그대로 두고, 안 보이는 **빛무리 한 겹**을 더 깐다.
   모양이 없는 그림자라 네모난 경계가 안 생기고, 어떤 그림 위에서도 글자가 뜬다. */
.spotdate{font-family:var(--f-disp); font-weight:900; font-size:22px; letter-spacing:-.5px; color:#fff;
  display:flex; align-items:baseline; gap:4px;
  text-shadow:0 2px 0 rgba(3,20,48,.55), 0 0 9px rgba(2,16,42,.85), 0 0 3px rgba(2,16,42,.7);}
.spothead .qsvc{color:#fff !important;
  text-shadow:0 2px 0 rgba(3,20,48,.55), 0 0 9px rgba(2,16,42,.7);}
.spothead .qdow{color:rgba(255,255,255,.88);}
.spottime{font-family:var(--f-latin); font-weight:500; font-size:11.5px;
  letter-spacing:.08em; color:rgba(255,255,255,.92); font-variant-numeric:tabular-nums; line-height:1.45;
  text-shadow:0 1px 0 rgba(3,20,48,.5), 0 0 7px rgba(2,16,42,.8);}
/* 스포트라이트도 큐카드와 같은 두 칸 문법. 왼쪽 `언제쯤 · 무슨 예배`, 오른쪽 `날짜 · 시각·장소`.
   ⚠ 시각을 왼쪽에 두면 오른쪽 칸이 날짜 한 줄뿐이라 그 아래가 통째로 비었다.
      양쪽 다 두 줄로 맞춰야 머리가 꽉 찬다. */
.spothead .qhl{gap:7px; justify-content:space-between; flex:1 1 auto; min-width:0;}
.spothead .qhr{flex-direction:column; align-items:flex-end; gap:5px;}
.spothead .qsvc{font-size:34px;}
/* 리허설은 시각이 둘(찬양 9:00 · 방음 9:30)이라 길다. 한 줄로 고집하면 왼쪽 제목을 파고든다 → 오른쪽 칸 안에서 접는다 */
.spothead .spottime{text-align:right; white-space:normal; max-width:min(58vw, 240px);}

/* ══ 예배 커버 (96차, 2026-09-12) ══════════════════════════════════════════
   사용자: *"임시로 만들어 놓은 나가이 배경이 너무 안 들어오고 안 어울린다. 새로 만든 주일·브뚜·리허설 썸네일
   느낌으로, 누가 봐도 아 이거 주일 예배구나, 리허설이구나, 브뚜구나. 예쁘고 세련되고 깔끔하게."*
   → 카드 머리가 **유튜브 썸네일과 같은 얼굴**을 한다. 새로 지어낸 게 아니라 확정본에서 뽑았다
     (`tools/gen_svc_covers.py`, 원본 `교회/유튜브썸네일/2026-09-12/final`).
     · 주일   = 썸네일에 깐 그 하늘 사진 + SAEHAN XAPIS + 청년부 주일예배
     · 브뚜   = 검정 #0C0E11 + 흰 테두리 한 줄 + BREAK / †HROUGH + 8 3 0
     · 리허설 = 딥 에버그린 #14382C + 같은 테두리 + REHEARSAL + 9 0 0
   ⚠⚠ **세 장이 같은 문법이다: 큰 잠금장치(.svlock) + 그 밑 작은 줄(.svcap).** 다가오는 예배 카드도 같은 부품(96차-c). 96차 첫 판은 주일만
     한글 «주일예배» 글자로 뒀다가 사용자가 짚었다(*"왜 주일예배만 그냥 주일예배라고만 한 거야? 일관성 지켜줘"*).
     내가 «한글이 더 빨리 읽힌다»고 판단해 한 장만 예외로 둔 것이다. 한 벌 중 하나만 다르면 그게 먼저 보인다.
   ⚠⚠ **머리 높이도 세 장이 같다**(96차-b, 폰 116px). 왼쪽 = 무엇(잠금장치), 오른쪽 = 언제(칩·날짜 / 시각).
     첫 판은 칩이 잠금장치 위 왼쪽에 있어서 머리 키가 그 칸을 따라갔고(브뚜 144 · 주일 127 · 리허설 127),
     사용자가 *"주일만 위에 배너가 너무 크잖아"* 라고 했다. 칩을 날짜 옆으로 올리니 두 줄 BREAKTHROUGH 가
     칩 줄 옆까지 올라설 수 있어 셋이 같아졌다. 그리드: 잠금장치는 두 줄에 걸치고, 칩·날짜 줄은 두 칸에 걸친다.
   ⚠⚠ **브뚜와 리허설은 바탕색으로 갈린다** (2026-09-20). 첫 판은 둘 다 검정(#0C0E11 · #12100D)이고 글자 모양
     (두 줄에 십자가 / 긴 한 줄)만으로 갈리게 두었다. 사용자: *"리허설이랑 브뚜랑 겹치잖아? 이게 헷갈린데."*
     나란히 서면 사람은 색부터 본다. 글자를 읽어야 갈리는 건 안 갈리는 것이다.
     → 리허설만 **딥 에버그린**(#14382C). 테두리·활자·조판은 그대로 두고 **바탕색 한 값만** 바꾼다
       (세트 안의 예외를 만드는 게 아니라 같은 문법의 다른 값이다). 8안을 150px 로 찍어 사용자가 고른 값이다.
     ⚠ 달력 칸 바탕의 토요일 풀색 `--sat`(#3A7D22, 노란기)과는 **다른 초록**이다. 그쪽에서 뽑은 값이 아니니 같이 움직이지 않는다.
     ⚠ 썸네일(`교회/유튜브썸네일/2026-09-12/build_final.py` SAT_BG)과 **같은 값이어야 한다**. 한쪽만 고치면 둘이 갈라진다.
   ⚠ 그림자·빛무리를 전부 뺀다. 썸네일 때 사용자가 «마스카라»라고 물린 그것이다.
     바탕이 단순해서 그림자가 필요 없다. 그게 이 커버의 요점이다.
   ⚠ 4px 예배색 띠, `3일 뒤` 칩의 예배색, 날짜 뒤 스크림도 뺀다. 커버가 이미 무슨 예배인지 말한다.
     칩은 셋 다 **흰 알약** 하나(글자는 그 커버의 바탕색).
   ⚠ 하늘 위 작은 글자(시각·장소)만 잉크다. 흰 11px 는 옅은 하늘에서 1.8:1 이라 밖에서 안 읽힌다(시안 실측).
     잠금장치(SAEHAN XAPIS · 청년부 주일예배)와 날짜는 흰색 그대로, 썸네일과 같다.
   ⚠ 시각의 빛(--veil)을 안 덮는다. 썸네일은 밤에도 같은 얼굴이다. 본문 바닥도 밤에 밝게 두는 앱이라 튀지 않는다.
   ⚠ 특별예배(ev)는 썸네일이 없어서 `.svcover` 가 안 붙고 위의 계절 그림 머리를 그대로 쓴다.
   ⚠ 어두운 머리는 never 규칙의 «히어로 같은 크롬» 자리다. 카드 본문은 그대로 흰색이다. */
/* ⚠ 하늘 사진 위 잉크는 시각을 안 탄다(--cvink, 133차-h 아홉째 판). 커버는 밤에도 낮 얼굴인데 --ink 는 밤에 밝아진다.
   그래서 밤에 주일 커버의 «내일» 칩이 흰 알약에 흰 글자, 시각 줄이 하늘에 흰 글자가 됐다(JH 10-03 «내일이 너무 안 보여»).
   커버 안 글자는 --ink 말고 이걸 쓴다. 검사는 nightskin.mjs 가 커버 글자 대비까지 잰다 */
.svcover{--cvink:#0B2A44;}
.svcover.fri{--cvbg:#0C0E11;}
.svcover.sat{--cvbg:#14382C;}
.svcover.sun{--cvbg:var(--cvink);}
/* 어두운 두 장(검정 브뚜 · 풀색 리허설)의 테두리는 썸네일의 흰 선 그대로(1080 에 3px = 카드에서 한 줄) */
.spot.svcover.fri .spothead, .spot.svcover.sat .spothead,
.qcard.svcover.fri .qhead,   .qcard.svcover.sat .qhead,
.svrow.svcover.fri .qhead,   .svrow.svcover.sat .qhead{background:var(--cvbg);}
.spot.svcover.sun .spothead,
.qcard.svcover.sun .qhead,
.svrow.svcover.sun .qhead{background:#86CDFE url("/svc/sky.webp") center top/cover no-repeat;}
/* 잠금장치 = 폰트 윤곽 SVG. 밑줄은 썸네일처럼 글자 가운데 아래. 숫자는 흰색 190/255, 주일 부제는 흰색 그대로.
   ⚠ 아주 좁은 폰에서 칸이 모자라면 비율을 지킨 채 줄어든다(max-width + contain). 390px 에선 안 줄어든다. */
.svcover .qsvc{display:flex; flex-direction:column; align-items:center; line-height:1; text-shadow:none;}
.svlock,.svcap{display:block; width:auto; max-width:100%; object-fit:contain;}
.svcap{opacity:.745;}
.svcover.sun .svcap{opacity:1;}
/* 시각은 한 줄에 하나 (`timeLinesHTML`). 앞의 «연습·예배·찬양·방음»은 한 단 흐리게 */
.svln b{font-family:var(--f-body); font-weight:700; font-size:10.5px; letter-spacing:0; margin-right:5px; opacity:.72;}
.svcover.sun .svln b{opacity:.8;}

/* ── 다음 섬김 카드 머리 ──
   ⚠ 높이는 예전 머리와 같은 112px(폰)에 멈춘다. 첫 판 116~144px 은 줄 높이(날짜 29px · 시각 1.35)와 위아래 여백이 쌓인 것이라
   날짜 줄을 글자 키로(line-height 1), 시각 줄을 1.28 로 줄였다.
   ⭐ **위아래 가운데** (96차-c). 사용자: *"위아래 alignment 맞춰줘. 지금 보면 브뚜 빼고 다 아래로 쏠려 있잖아."*
     96차-b 는 잠금장치를 칸 바닥에 붙였다(align-self:end). 두 줄 BREAKTHROUGH 만 칸을 꽉 채워 가운데처럼 보였고
     한 줄짜리 둘(SAEHAN XAPIS · REHEARSAL)은 바닥에 앉아 위가 텅 비었다.
     → 잠금장치는 머리 한가운데(align-self:center), 줄 묶음도 가운데(align-content:center, 넓은 화면에서 남는 높이를 위아래로 나눈다),
       여백은 위아래 17 로 같게. 그러면 내용의 한가운데가 테두리 안쪽의 한가운데와 같은 자리다. */
.spot.svcover .spothead{display:grid; grid-template-columns:minmax(0,1fr) auto; grid-template-rows:auto auto;
  align-content:center; column-gap:12px; row-gap:4px; padding:17px 22px;}
.spot.svcover .spothead .qhl{grid-column:1; grid-row:1 / 3; align-self:center;}
.spotwhenrow{grid-column:1 / -1; grid-row:1; justify-self:end; align-self:start;
  display:flex; align-items:center; gap:8px;}
.spotwhenrow .spotdate{line-height:1;}
.spot.svcover .spothead .qhr{grid-column:2; grid-row:2; align-self:end;}
.spot.svcover .spothead::before,
.spot.svcover .spothead .qhr::before,
.spot.svcover.sun .spothead::after{display:none;}
.spot.svcover .spotdate,
.spot.svcover .spottime{text-shadow:none;}
.spot.svcover .spotwhen{background:#fff; border:0; color:var(--cvbg); font-size:13px; line-height:1.25;
  padding:3px 10px 4px; border-radius:999px;}
.spot.svcover.fri .spothead::after,
.spot.svcover.sat .spothead::after{inset:8px; background:none; border:1px solid rgba(255,255,255,.92);}
.spot .svlock{height:54px;}
.spot.sat .svlock{height:20px;}
.spot.sun .svlock{height:16px;}
.spot .svcap{height:9px; margin-top:7px;}
/* 주일 부제는 썸네일 비례(영문 키의 0.48)면 7.7px 이라 폰에서 안 읽힌다. 다른 두 장의 숫자(9px)와 같은 급으로 올린다 */
.spot.sun .svcap{height:10px; margin-top:6px;}
.spot.svcover .spothead .spottime{display:flex; flex-direction:column; align-items:flex-end; gap:0;
  max-width:none; line-height:1.28;}
.spot.svcover.sun .spottime{color:var(--cvink);}

/* ── 다가오는 예배 카드 · 섬김표 목록 줄 머리 (96차-c · e) ──
   사용자: *"다가오는 예배 카드도 같은 느낌으로 맞춰줘."* → *"전체 섬김표 목록도 같은 커버로 맞춰줘."*
   다음 섬김 카드와 **같은 문법, 한 치수 작게**. 두 곳이 같은 머리 부품(`qheadHTML`)이라 규칙도 같이 건다.
   다음 섬김이 먼저 읽혀야 해서 크기만 낮춘다(잠금장치 약 80%, 날짜 20px). 줄 배치·가운데 맞춤·색은 같다.
   ⚠ 이 머리엔 `3일 뒤` 칩이 없어서 날짜 줄이 오른쪽 칸 하나로 충분하다(다음 섬김처럼 두 칸에 걸칠 필요가 없다).
   ⚠ 섬김표 달력(table.hcal)은 그대로 요일 색이다. 목록 줄과 달력 날짜 시트만 커버다(둘이 `svRowHTML` 을 같이 쓴다). */
/* ⚠ 높이 93px 에 멈춘다(예전 이 머리는 77~81px, 다음 섬김은 112px). 시각 줄 간격 1.2 · 위아래 여백 14. 테두리 선에서 6px 안쪽 */
.qcard.svcover .qhead, .svrow.svcover .qhead{position:relative; display:grid; grid-template-columns:minmax(0,1fr) auto; grid-template-rows:auto auto;
  align-content:center; column-gap:12px; row-gap:3px; padding:14px 20px;}
.svcover .qhead .qhl{grid-column:1; grid-row:1 / 3; align-self:center; gap:0;}
.svcover .qhead .qhr{grid-column:2; grid-row:1; justify-self:end; align-self:start; padding-top:0;}
.svcover .qhead .qmeta{grid-column:2; grid-row:2; align-self:end; display:flex; flex-direction:column; align-items:flex-end;
  font-family:var(--f-latin); font-weight:500; font-size:11px; letter-spacing:.08em; line-height:1.2;
  color:rgba(255,255,255,.92);}
.svcover.sun .qhead .qmeta{color:var(--cvink);}
.svcover .qhead .qdate{font-size:20px; line-height:1; color:#fff;}
/* ⚠ 요일의 margin-left:-3px 는 25px 날짜에 맞춘 값이라 20px 에선 «4금»처럼 숫자에 붙었다(확대 실측) → 커버 머리에선 띄운다 */
.svcover .qhead .qdow{color:rgba(255,255,255,.88); margin-left:1px;}
.qcard.svcover.fri .qhead::after, .qcard.svcover.sat .qhead::after,
.svrow.svcover.fri .qhead::after, .svrow.svcover.sat .qhead::after{content:''; position:absolute; inset:7px; border:1px solid rgba(255,255,255,.92); pointer-events:none;}
/* 목록 줄: 커버가 무슨 예배인지 말하니 **왼쪽 예배색 띠(6px)를 뺀다**(다음 섬김의 4px 띠, 다가오는 예배의 색 테이프와 같은 이유).
   띠를 비켜 두려고 19px 이던 왼쪽 여백도 오른쪽과 같게 돌린다. 찬양·방송음향 덩어리의 왼쪽 선(.svgrp)은 역할 색이라 그대로다. */
.svrow.svcover{box-shadow:var(--sh-sm);}
.svrow.svcover .svbody{padding-left:15px;}
.svrow .svlock{height:44px;}
.svrow.sat .svlock{height:16px;}
.svrow.sun .svlock{height:13px;}
.svrow .svcap{height:8px; margin-top:6px;}
.svrow.sun .svcap{height:9px; margin-top:5px;}
/* ⚠ 테두리 때문에 머리가 position:relative 가 되면서 **워시테이프가 머리 뒤로 들어갔다**(위 반쪽만 보였다).
   위치가 있는 요소는 문서 순서대로 칠해지고 테이프(::before)가 먼저라서다 → 테이프를 한 층 올린다.
   ⭐ 테이프 색은 예배색(붉은꽃·바다·풀)을 버리고 **모래 한 가지**. 커버가 이미 무슨 예배인지 말하고,
     검정·하늘 위의 예배색 테이프는 시안에서 딱지를 붙인 것처럼 시끄러웠다(나란히 찍어 비교). 다음 섬김의 4px 띠를 뺀 것과 같은 이유. */
.qcard.svcover::before{z-index:2; background:var(--sand-soft);}
.qcard .svlock{height:44px;}
.qcard.sat .svlock{height:16px;}
.qcard.sun .svlock{height:13px;}
.qcard .svcap{height:8px; margin-top:6px;}
.qcard.sun .svcap{height:9px; margin-top:5px;}

.spotbody{display:flex; flex-direction:column; gap:0;}

/* 방송 | 음향 줄은 이름 격자 + 녹화 줄을 **위아래로** 쌓는다(98차-b, `avCrewHTML`). flex 로 두면 둘이 옆으로 붙는다 */

.rlab.p{color:#fff; background:var(--praise-fill);}
.spotname{font-family:var(--f-disp); font-weight:900; font-size:19px; letter-spacing:-.3px;}
/* «인도 강산» 의 «인도» (2026-09-16). 이름보다 작고 옅게, 다른 카드의 «인도» 와 같은 말 */

/* 콘티 링크·가사·전체 재생은 이제 이 줄이 아니라 아래 `.contiblk` 안에 있다 (2026-09-10, 93차) —
   «콘티 N곡 →» 알약 하나만 걸어 두던 자리라, 곡 목록을 펴면서 통째로 그 뭉치로 옮겼다.
   같은 말을 두 곳에서 하지 않는다: 뭉치 머리의 알약이 곧 그 링크다. */

/* ══ 녹화 링크 (78차) ══════════════════════════════════════════════════════
   ⭐ **자리를 만들지 말고 남는 자리를 쓴다**(71·72차에 네 번 고쳐 얻은 규칙) —
   `방송` 줄은 오른쪽이 늘 비어 있다. 흐름 안(`margin-left:auto`)이라 겹칠 수 없고 카드도 안 길어진다.
   ⚠ 칩은 줄 글자보다 작게(22px) — 크면 그 줄이 늘어나 카드 높이가 바뀐다. */
/* ⭐⭐ **같은 카드 안의 단추는 같은 몸을 쓴다** (81차, 사용자: *"리허설 녹화 버튼이 아래 무대 배치보다
   훨씬 납작해 보이거든. UI 는 일관성 있게"*). 처음엔 줄이 늘어날까 봐 작은 칩으로 만들었는데,
   3px 아끼려고 두 단추가 서로 다른 물건처럼 보이게 둔 셈이었다 — 값을 잘못 치른 것이다.
   이제 `.btn.stagebtn` 과 **같은 글자 크기·같은 잉크 2px·같은 그림자**를 쓰고 색만 다르다. */
.btn.recbtn{margin:0 0 0 auto; flex:none; font-size:11px; padding:5px 10px;
  background:var(--accent-soft); border-color:var(--accent); color:var(--accent-ink);}   /* 녹화가 «있다» = 상태색 하나 */
.btn.recbtn .ic{width:13px; height:13px;}
.btn.recbtn.has .ic{fill:currentColor; stroke:none;}
/* 점선 = "아직 없지만 넣을 수 있다" (52차 악보 올리기와 같은 문법). 조용해야 한다 — 매주 보는 줄이다. */
.btn.recbtn.none{background:var(--card); color:var(--faint); border-style:dashed; border-color:var(--faint);}
/* 전날 리허설 녹화 — 그 예배 것이 아니라 **어제 것**이라 색을 달리한다(모래). 둘이 나란히 서도 안 헷갈린다. */
.btn.recbtn.reh{background:var(--card); border-color:var(--ink); color:var(--ink);}   /* 어제 것은 채우지 않는다. 글자가 이미 «리허설 녹화» 다 */
.btn.recbtn.reh + .btn.recbtn{margin-left:7px;}
/* 방송·음향 격자(`.svline.crew`, 98차-e) 안의 녹화 둘은 칸의 틈(gap 6px)으로 띄운다 → 위 `.reh + .recbtn` 의 7px 을 여기서 지운다.
   ⚠ 두 규칙이 같은 무게(클래스 5개)라 **이 줄이 뒤에 있어야** 이긴다. 격자 규칙 옆으로 옮기면 둘 사이가 13px 이 된다. 자리 규칙은 `.svline.crew` 블록. */
.svline.crew > .recpair .btn.recbtn{margin:0;}
.recview{margin:12px 0 4px;}
.recframe{position:relative; width:100%; aspect-ratio:16/9; border:var(--bw) solid var(--ink);
  border-radius:var(--r-m); overflow:hidden; background:#000; box-shadow:var(--sh-sm);}
.recframe iframe{position:absolute; inset:0; width:100%; height:100%; border:0; display:block;}
.shsub{font-style:normal; font-family:var(--f-body); font-weight:700; font-size:12.5px;
  color:var(--ink2); margin-left:9px;}
#recBody .stagestate{margin:0 0 4px;}

/* ══ 피드백 (74차) ═════════════════════════════════════════════════════════
   ⭐ **새 부품을 만들지 않는다** — 진입점은 신청 CTA(`.reqcta`)를 그대로 쓰고 색만 라일락으로,
   목록은 공지 카드와 같은 잉크 2px + 하드 섀도다. 기존 UI 를 망가뜨리지 말라는 요청(74차)의 실행. */
/* ⚠ 신청을 빨강으로 두지 않는다(사용자 77차: *"빨간색은 딱 봐도 리포트하는 창 같은 느낌이잖아. 신청은 전혀 그런 게 아닌데"*).
   (2026-09-16) 두 카드의 색 타일은 걷었다. 이제 그림(말풍선 · 종이비행기)이 자리의 성격을 말한다. 둘 다 빨강이 없다. */

.fbform .formlab{margin-top:14px;}
.fbform .formlab:first-child{margin-top:0;}
.fbform .field{margin-bottom:0;}
.formfoot{display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:14px;}
.formfoot .btn{margin:0; flex:none;}
.formfoot .formmsg{margin:0;}
.fbcount{margin-left:auto; font-size:11.5px; font-weight:800; color:#fff; background:var(--praise-fill);
  border:var(--bw) solid var(--ink); border-radius:999px; padding:2px 10px;}
.fblist{display:flex; flex-direction:column; gap:11px;}
.fbrow{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh-sm); padding:12px 13px;}
.fbtop{display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:7px;}
.fbtop .linkbtn{margin-left:auto;}
/* 받는 곳 = 도메인 색 그대로(찬양 코랄 · 방송 바다 · 음향 잔디 · 이 앱 라일락). 색이 곧 어디 이야기인지다 */
.fbto{font-size:10.5px; font-weight:800; border-radius:999px; padding:2px 9px;
  border:1.5px solid currentColor;}
.fbto.app{color:var(--lilac); background:var(--lilac-soft);}
.fbto.praise{color:var(--praise); background:var(--praise-soft);}
.fbto.bcast{color:var(--bcast); background:var(--bcast-soft);}
.fbto.sound{color:var(--sound); background:var(--sound-soft);}
.fbto.all{color:var(--ink2); background:var(--paper);}
.fbstate{font-size:10.5px; font-weight:800; border-radius:999px; padding:2px 9px; color:#fff;}
.fbstate.new{background:var(--praise-fill);}
.fbstate.doing{background:var(--sand-fill);}
.fbstate.done{background:var(--sound-fill);}
.fbstate.hold{background:var(--faint);}
.fbbody{margin:0; font-size:14px; font-weight:500; line-height:1.65; color:var(--ink); white-space:pre-wrap;}
.fbbody.quote{margin:0 0 14px; padding-left:11px; border-left:3px solid var(--faint); color:var(--ink2);}
.fbmeta{display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:8px;
  font-size:11.5px; font-weight:700; color:var(--faint);}
.fbmeta span{font-variant-numeric:tabular-nums;}
/* ⭐ 리더가 남긴 한 줄. 상태만 있으면 "반영했어요"가 무엇을 했다는 건지 모른다 */
.fbnote{display:flex; gap:7px; align-items:flex-start; margin-top:9px; padding-top:9px;
  border-top:1.5px dashed var(--faint); font-size:12.5px; font-weight:600; color:var(--sound);}
.fbnote .ic{width:14px; height:14px; flex:none; margin-top:1px;}
/* 새로 온 것은 왼쪽에 코랄 띠 — 목록을 훑을 때 먼저 걸린다 */
.fbrow.new{box-shadow:inset 4px 0 0 var(--praise), var(--sh-sm);}

/* 무대 배치 상태 줄의 정확한 시각 · 그 아래 권유 한 줄 (74차) */
.stagestate i{font-style:normal; margin-left:7px; font-size:11px; font-weight:600; color:var(--faint);
  font-variant-numeric:tabular-nums;}



/* ── 공식 채널 (유튜브) ────────────────────── */



/* 그림 아이콘(2026-09-16). 예전 빨강·파랑 네모 타일. 두 채널 다 유튜브라 같은 재생 그림이고, 이름이 둘을 가른다 */









/* ── 섬김표: 달력/목록 토글 ────────────────── */
.monthbar{flex-wrap:wrap;}
.pvtoggle{display:flex; gap:4px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:999px; padding:3px; box-shadow:var(--sh-sm);}
.pvtoggle button{display:inline-flex; align-items:center; gap:5px; border:0; background:transparent;
  border-radius:999px; padding:6px 13px; font-size:12.5px; font-weight:700; color:var(--ink2); cursor:pointer;}
.pvtoggle button .ic{width:15px; height:15px;}
.pvtoggle button.on{background:var(--bcast-fill); color:#fff; font-weight:800;}

/* ── 섬김표: 달력 뷰 (스케줄러 문법 이식) ───── */
.calscroll{overflow-x:auto; -webkit-overflow-scrolling:touch; padding:3px 3px 8px; margin:0 -3px;}
table.hcal{border-collapse:separate; border-spacing:7px; width:100%; min-width:940px; table-layout:fixed;}
table.hcal th{border:var(--bw) solid var(--ink); border-radius:12px; font-family:var(--f-disp); font-weight:900;
  font-size:14px; padding:7px 6px; background:var(--card); color:var(--ink2); box-shadow:var(--sh-sm);}
table.hcal th.col-sun{background:var(--praise-soft); color:var(--praise);}
table.hcal th.col-fri{background:var(--bcast-soft); color:var(--bcast);}
table.hcal th.col-sat{background:var(--sat-soft); color:var(--sat);}
table.hcal td{border:var(--bw) solid var(--ink); border-radius:14px; vertical-align:top; padding:9px 9px 11px;
  width:14.28%; background:var(--card); box-shadow:var(--sh-sm); word-break:keep-all; overflow-wrap:break-word;}
table.hcal td.col-sun{background:var(--praise-soft);}
table.hcal td.col-fri{background:var(--bcast-soft);}
table.hcal td.col-sat{background:var(--sat-soft);}
table.hcal td.out{background:transparent; border-style:dashed; border-color:var(--faint); box-shadow:none; opacity:.5;}
/* 오늘 — 테두리만 굵게 하면 아무도 못 알아본다(사용자 지적).
   날짜 숫자를 잉크로 채운 동그라미에 넣고, 칸 전체에 잉크 링과 한 단 깊은 그림자를 준다. */
table.hcal td.today{border-width:3px; box-shadow:0 5px 0 var(--ink); position:relative;}
table.hcal td.today .dt{background:var(--ink); color:var(--on-ink); border-radius:999px;
  display:inline-flex; align-items:center; justify-content:center;
  width:28px; height:28px; font-size:15px; line-height:1;}
table.hcal td.today.wd .dt{color:var(--on-ink);}   /* 평일 오늘. 밤엔 잉크 동그라미가 밝아지니 글자는 바탕색(#fff 였을 때 대비 1.1, 10-07 nightskin) */
.hcal .todaytag{font-family:var(--f-body); font-size:9.5px; font-weight:800; color:#fff;
  background:var(--praise-fill); border-radius:999px; padding:2px 7px; line-height:1;}
table.hcal td .dt{font-family:var(--f-disp); font-weight:900; font-size:19px; line-height:1;}
table.hcal td.out .dt,table.hcal td.wd .dt{color:var(--faint); font-size:16px;}
.hcal .daytag{display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; margin-bottom:7px;
  padding-bottom:6px; border-bottom:1.5px dashed var(--ink);}
.hcal .daytag .svc{font-family:var(--f-disp); font-weight:900; font-size:12.5px;}
.hcal td.col-sun .svc{color:var(--praise);} .hcal td.col-fri .svc{color:var(--bcast);} .hcal td.col-sat .svc{color:var(--sat);}
.hcal .calltime{font-size:10.5px; font-weight:600; color:var(--ink2); margin:-3px 0 7px; font-variant-numeric:tabular-nums;}
.hcal .calstage{display:flex; align-items:center; gap:5px; font-size:12.5px; margin-bottom:8px;
  padding-bottom:7px; border-bottom:1.5px dashed var(--faint);}
.hcal .calstage .ic{width:13px; height:13px; color:var(--praise); flex:none;}
.hcal .calstage b, .hcal .calstage .calead{font-weight:800;}
.hcal .teams{display:grid; grid-template-columns:1fr 1fr; gap:8px;}
.hcal .teamcol{display:flex; flex-direction:column; gap:5px; min-width:0;}
.hcal .teamhd{font-family:var(--f-disp); font-weight:900; font-size:13px; text-align:center; padding-bottom:3px;
  border-bottom:1.5px dashed var(--faint);}
.hcal .teamhd.b{color:var(--bcast);} .hcal .teamhd.s{color:var(--sound);}
.hcal .slot{display:flex; flex-direction:column; gap:2px; min-width:0;}
.hcal .slot .role{font-size:9.5px; font-weight:800; color:var(--ink2); text-align:center; letter-spacing:.02em;}
.hcal .slotname{display:block; text-align:center; font-weight:800; font-size:13.5px;
  background:var(--card); color:var(--ink); border:1.5px solid var(--ink); border-radius:9px; padding:4px 2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.hcal .slot.main .slotname{color:#fff;}
.hcal td.col-sun .slot.main .slotname{background:var(--praise-fill);}
.hcal td.col-fri .slot.main .slotname{background:var(--bcast-fill);}
.hcal td.col-sat .slot.main .slotname{background:var(--sat-fill);}
.hcal .slotname.none{color:var(--faint); border-style:dashed; border-color:var(--faint); background:transparent;}
.hcal .calconti{display:inline-block; margin-top:8px; font-size:10.5px; font-weight:800; color:var(--praise);
  text-decoration:none; border:1.5px solid var(--praise); background:var(--card); border-radius:999px; padding:2px 9px;}
.hcal .multisvc{margin-top:8px; padding-top:7px; border-top:1.5px dashed var(--ink);}
.hcal .multisvc .svc{font-family:var(--f-disp); font-weight:900; font-size:12px; display:block; margin-bottom:5px;}
.calhint{font-size:11.5px; font-weight:600; color:var(--ink2); margin:4px 2px 0;}
/* 폰 달력엔 이름이 없다(칸이 44px). 그래서 안내 문구도 화면 폭에 따라 갈린다 */
.calhint.narrow{display:none;}

/* ══ 달력 칸 커버 (96차-f) ══════════════════════════════════════════════════
   사용자: *"달력 칸도 같은 커버로 맞춰줘."* 주일·브뚜·리허설 칸만(특별예배 칸은 그대로).
   넓은 화면: 칸 머리(.daytag)가 **커버 띠**다. 칸 테두리 안쪽에 꽉 차게(음수 여백) 깔고, 왼쪽 날짜 · 오른쪽 잠금장치.
     예배 이름 글자와 A·B 칩은 띠에서 뺀다(잠금장치가 이름이고, 칩은 바로 아래 인도자 줄에 이미 있다).
     밑줄(830 · 900 · 청년부 주일예배)은 칸이 158px 라 읽히지 않아 셋 다 뺀다. 셋이 같이 빼니 문법은 같다.
   칸 몸통은 흰색. 요일 색 바탕을 걷는다(다른 커버 카드에서 예배색 띠·테이프를 뺀 것과 같은 이유). */
/* ⚠ 달력 칸의 예배 클래스는 `fri` 가 아니라 `col-fri` 다(열 머리와 같은 이름). `.svcover.fri` 규칙이 안 걸려서 첫 판이 통째로 흰 칸이었다 */
table.hcal td.svcover.col-fri{--cvbg:#0C0E11;}
table.hcal td.svcover.col-sat{--cvbg:#14382C;}
table.hcal td.svcover.col-sun{--cvbg:var(--cvink);}
table.hcal td.svcover{background:var(--card);}
.hcal td.svcover .daytag{position:relative; flex-wrap:nowrap; align-items:center; gap:6px;
  margin:-9px -9px 9px; padding:9px 14px 9px 12px; min-height:56px; border-bottom:var(--bw) solid var(--ink);
  border-radius:12px 12px 0 0;}
.hcal td.svcover.col-fri .daytag, .hcal td.svcover.col-sat .daytag{background:var(--cvbg);}
.hcal td.svcover.col-sun .daytag{background:#86CDFE url("/svc/sky.webp") center top/cover no-repeat;}
.hcal td.svcover.col-fri .daytag::after, .hcal td.svcover.col-sat .daytag::after{content:''; position:absolute; inset:5px;
  border:1px solid rgba(255,255,255,.92); border-radius:7px 7px 0 0; pointer-events:none;}
.hcal td.svcover .daytag .svc, .hcal td.svcover .daytag .teamchip, .hcal td.svcover .todaytag{display:none;}
.hcal td.svcover .daytag .dt{position:relative; z-index:1; color:#fff;}
/* 오늘 = 날짜 동그라미. 잉크 동그라미는 검정 띠에서 안 보이니 흰 동그라미에 커버 바탕색 숫자 */
table.hcal td.svcover.today .dt{background:#fff; color:var(--cvbg);}
.calcov{position:relative; z-index:1; margin-left:auto; display:flex; flex-direction:column; align-items:flex-end; min-width:0;}
.calcov .svcap{display:none;}
/* ⭐ 요일 머리(일·금·토)의 예배색과 메인 이름 칸의 예배색 채움도 커버 색으로 (시안 비교: 붉은꽃·바다·풀 채움이 검정·하늘 띠 아래서 따로 놀았다).
   요일 머리는 무채, 메인 이름 칸 = 브뚜·리허설 검정 / 주일 잉크. 메인은 채움 · 보조는 테두리라는 규칙(안내 문구)은 그대로다.
   방송·음향 머리 글자색은 역할 색이라 그대로 둔다. */
table.hcal th.col-sun, table.hcal th.col-fri, table.hcal th.col-sat{background:var(--card); color:var(--ink2);}
.hcal td.svcover .slot.main .slotname{background:var(--cvbg);}
/* 칸 158px 에 날짜와 나란히 들어가는 크기. 첫 판(30 · 12 · 9px)은 BREAKTHROUGH·REHEARSAL 끝이 흰 선에 닿았다(확대 실측) */
.hcal td.svcover .svlock{height:27px;}
.hcal td.svcover.col-sat .svlock{height:11px;}
.hcal td.svcover.col-sun .svlock{height:9px;}


/* ── 인앱 문서 뷰어 ────────────────────────── */
[data-view="doc"]{padding:0 !important; max-width:none !important;}
.docbar{position:sticky; top:0; z-index:5; display:flex; align-items:center; gap:10px;
  padding:9px 14px; background:var(--card); border-bottom:var(--bw) solid var(--ink);}
.docbar .backlink{margin:0; white-space:nowrap;}
.doctitle{flex:1; min-width:0; font-family:var(--f-disp); font-weight:900; font-size:15.5px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:center;}
.docstage{height:calc(100vh - var(--tabbar-h) - 108px); height:calc(100dvh - var(--tabbar-h) - 108px); min-height:420px; background:var(--paper);}
.docframe{width:100%; height:100%; border:0; display:block; background:var(--paper);}
/* 넓게 보기 — 상단바·탭바를 접고 문서에 화면을 전부 준다 */
body.docfull{padding-bottom:0;}
body.docfull .topbar,body.docfull .tabbar{display:none;}
body.docfull .docstage{height:calc(100vh - 47px); height:calc(100dvh - 47px);}
.docbar .iconbtn.on{background:var(--accent);}
/* 믹서 연습실 = 앱. 화면을 통째로 준다 (높이는 vLab 이 숫자로 박는다) */
body.labfull{padding-bottom:0;}
body.labfull .tabbar{display:none;}
body.labfull .syncbar{display:none;}     /* 51px 짜리 상태 줄이 화면 밑에 남아 페이지가 스크롤됐다 */
body.labfull::after{display:none;}
.labstage{background:var(--paper); overflow:hidden;}
.labstage iframe{width:100%; height:100%; border:0; display:block; background:var(--paper);}
/* 연습실 쪽 "데스크" 계층(1100 이상)에서만 이 앱의 상단바를 남긴다. 태블릿 가로(1024)는 67px 이 아깝다 */
@media (max-width:1099px){ body.labfull .topbar{display:none;} }

/* ── PDF: 한 쪽씩, 화면 폭에 맞춰서 ──────────────
   기본 뷰어는 폰에서 가로·세로로 다 밀어야 읽힌다. 여기서는 **세로로만** 움직이면 된다.
   쪽 넘김 줄은 문서 바로 위에 붙박아 둔다. 읽다가 손을 옮기지 않아도 되게. */
.pdfbar{position:sticky; top:47px; z-index:4; display:flex; align-items:center; gap:8px;
  padding:8px 12px; background:var(--card); border-bottom:2px dashed var(--faint);}
.pdfbtn{flex:none; width:46px; height:38px; display:grid; place-items:center; cursor:pointer;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:999px;
  box-shadow:var(--sh-sm); color:var(--ink);}
.pdfbtn:active{transform:translateY(2px); box-shadow:0 0 0 var(--ink);}
.pdfbtn .ic{width:20px; height:20px;}
.pdfpg{display:inline-flex; align-items:center; gap:6px; font-family:var(--f-mono); font-size:13px;
  font-weight:600; color:var(--ink2);}
.pdfpg input{width:44px; text-align:center; font-family:var(--f-mono); font-size:14px; font-weight:700;
  color:var(--ink); background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-s);
  padding:4px 2px;}
.pdfpg input:focus{outline:0; box-shadow:0 0 0 3px var(--accent);}
.pdfpg i{font-style:normal; opacity:.5;}
.pdfpg b{font-weight:800; color:var(--ink);}
.pdfzoom{margin-left:auto; display:inline-flex; align-items:center; gap:5px; cursor:pointer;
  font-family:var(--f-body); font-size:12px; font-weight:800; color:var(--ink); padding:7px 12px;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:999px; box-shadow:var(--sh-sm);}
.pdfzoom.on{background:var(--accent);}
.pdfzoom:active{transform:translateY(2px); box-shadow:0 0 0 var(--ink);}
.pdfzoom .ic{width:15px; height:15px;}
.pdfstage{overflow:auto; overscroll-behavior:contain; display:flex; justify-content:center;
  align-items:flex-start; padding:10px 4px 20px; touch-action:pan-y;
  height:calc(100vh - var(--tabbar-h) - 163px); height:calc(100dvh - var(--tabbar-h) - 163px);}
.pdfstage.zoomed{touch-action:pan-x pan-y; justify-content:flex-start;}
.pdfpage{display:block; border:2px solid var(--ink); border-radius:var(--r-s); box-shadow:var(--sh);
  background:#fff; max-width:none;}
body.docfull .pdfstage{height:calc(100vh - 102px); height:calc(100dvh - 102px);}

/* ── 유튜브 인앱 플레이어 ──────────────────── */
.ytbtn{display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:24px; height:24px; padding:0; border-radius:8px; cursor:pointer;
  background:var(--praise-fill); color:#fff; border:1.5px solid var(--ink); box-shadow:0 2px 0 var(--ink);}
.ytbtn .ic{width:12px; height:12px; fill:currentColor; stroke:none;}
.ytbtn:active{transform:translateY(2px); box-shadow:none;}
.songs .ytbtn{margin-left:2px;}
.req .ytbtn{margin-top:1px;}
/* 세로로 쌓되 화면을 넘지 않는다. 넘칠 것 같으면 영상 높이를 먼저 줄인다(가로 화면 대비) */
.ytbox{width:min(100%,720px); max-height:100%; display:flex; flex-direction:column;
  background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-l); box-shadow:0 5px 0 rgba(7,31,54,.4); overflow:hidden;}
.ytbox > *{flex:none;}
.ythead{display:flex; align-items:center; gap:10px; padding:10px 12px 10px 15px;
  border-bottom:var(--bw) solid var(--ink); background:var(--praise-soft);}
.ytt{flex:1; min-width:0; font-family:var(--f-disp); font-weight:900; font-size:15px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap;}
.ytframe{position:relative; aspect-ratio:16/9; max-height:46vh; max-height:46dvh; background:#000;}
.ytframe iframe{width:100%; height:100%; border:0; display:block;}
/* ── 유튜브 멈춤 덮개 (133차-h 아홉째 판, app.js ytCover) ──
   멈추거나 끝나면 유튜브가 영상 위에 띄우는 같은 채널의 다른 영상을 그 영상 썸네일로 덮는다.
   가운데 88px 칸은 구멍이다(누르면 밑의 유튜브 재생 단추가 받는다). 나머지 여덟 칸(.ytcb)은 눌림을 막는다.
   ⚠ `.ytframe > div` 규칙(display:block)보다 세게 건다 */
.ytframe > .ytcover, .recframe > .ytcover{position:absolute; inset:0; z-index:2; display:grid;
  grid-template-columns:1fr 88px 1fr; grid-template-rows:1fr 88px 1fr;
  width:auto; height:auto; pointer-events:none; color:#fff; background:#0B1220 center/cover no-repeat;}
.ytframe > .ytcover[hidden], .recframe > .ytcover[hidden]{display:none;}
.ytcover::before{content:''; position:absolute; inset:0; background:rgba(6,12,22,.5); pointer-events:none;}
.ytcover > *{position:relative;}
.ytcover .ytcb{pointer-events:auto; cursor:pointer;}
.ytcover .ytchole{display:grid; place-items:center; pointer-events:none;}
.ytcover .ytcplay{width:60px; height:60px; border-radius:50%; display:grid; place-items:center;
  background:rgba(255,255,255,.94); color:#0B2A44; box-shadow:0 3px 0 rgba(0,0,0,.35);}
.ytcover .ytcplay .ic{width:26px; height:26px;}
.ytcover .ytctime{position:absolute; left:50%; bottom:12px; transform:translateX(-50%); pointer-events:none; white-space:nowrap;
  padding:3px 10px; border-radius:999px; background:rgba(6,12,22,.6);
  font-family:var(--f-latin); font-size:12px; font-weight:700; letter-spacing:.04em;}
.ytcover .ytctime:empty{display:none;}
.ytout{display:flex; align-items:center; justify-content:center; gap:6px; padding:10px;
  font-size:12.5px; font-weight:800; color:var(--ink); text-decoration:none; background:var(--card);}
.ytout .ic{width:14px; height:14px;}

/* ── 찬양 탭 ─────────────────────────────── */
.subtabs{display:flex; gap:5px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:999px; padding:4px; margin-bottom:18px; box-shadow:var(--sh-sm);}
.subtabs button{flex:1; min-width:0; white-space:nowrap; border:0; background:transparent; border-radius:999px;
  padding:8px 4px; font-size:13px; font-weight:700; color:var(--ink2); cursor:pointer;}
.subtabs button.on{background:var(--praise-fill); color:#fff; font-weight:800;}
.searchbar{display:flex; align-items:center; gap:9px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-m); padding:10px 14px; box-shadow:var(--sh-sm); margin-bottom:14px;}
.searchbar .ic{width:17px; height:17px; color:var(--ink);}
.searchbar input{flex:1; border:0; outline:0; background:transparent; color:var(--ink);
  font-family:var(--f-body); font-size:16px; min-width:0;}
.searchbar input::placeholder{color:var(--faint);}
/* 검색어 지우개 (103차). **글자가 있을 때만** 보인다 — 빈 칸에 X 가 서 있으면 «뭘 지우라는 거지»가 된다 */
.searchbar .sclr{flex:none; display:none; width:34px; height:34px; margin:-6px -6px -6px 0; padding:0;
  align-items:center; justify-content:center; border:0; background:transparent; color:var(--faint);
  border-radius:999px; cursor:pointer;}
.searchbar.has .sclr{display:flex;}
.searchbar .sclr:hover{color:var(--ink); background:var(--gridline);}
.searchbar .sclr .ic{width:18px; height:18px; stroke-width:2.6;}
.setcard{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  padding:14px 16px; box-shadow:var(--sh-sm); margin-bottom:14px;}
.setcard.hl{border-width:3px; box-shadow:0 4px 0 var(--praise);}
.setcard .shead{display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-bottom:9px;
  padding-bottom:9px; border-bottom:2.5px dashed var(--faint);}
.setcard .sdate{font-family:var(--f-disp); font-weight:900; font-size:18px;}
/* 지난 해 콘티에는 연도를 앞에 붙인다. 날짜보다 작게 — 먼저 읽을 것은 여전히 월/일이다 */
.syr{font-family:var(--f-mono); font-weight:600; font-size:.62em; color:var(--ink2); margin-right:4px;}
.setcard .slead{margin-left:auto; display:flex; align-items:center; gap:6px; font-size:13px; font-weight:500;}
.soon{font-size:12.5px; font-weight:600; color:var(--faint); padding:4px 2px 2px;}
/* 인도자만 정해진 주 = 한 줄 카드. 큰 카드와 같은 재료(날짜·예배 칩·인도)를 한 줄에 눕힌 것뿐이라 다른 물건으로 안 읽힌다 */
.setcard.slim{display:flex; align-items:center; gap:9px; flex-wrap:wrap; padding:10px 14px; margin-bottom:10px;
  box-shadow:0 2px 0 var(--faint);}
.setcard.slim .sdate{font-size:16px;}
.setcard.slim .slead{margin-left:0;}
.setcard.slim .slead .none{color:var(--faint);}
.setcard.slim .soonchip{margin-left:auto; font-size:11px; font-weight:700; color:var(--faint);
  border:1.5px dashed var(--faint); border-radius:999px; padding:2px 9px; white-space:nowrap;}
.setcard.slim .resp{margin:0; padding:5px 10px; font-size:11.5px;}
.filterchips{display:flex; gap:7px; flex-wrap:wrap; margin-bottom:12px;}
.fchip{border:var(--bw) solid var(--ink); background:var(--card); border-radius:999px; padding:6px 14px;
  font-size:12.5px; font-weight:700; color:var(--ink); cursor:pointer; box-shadow:var(--sh-sm);}
.fchip:active{transform:translateY(2px); box-shadow:none;}
.fchip.on{background:var(--praise-fill); color:#fff; font-weight:800; transform:rotate(-1.5deg);}
/* 콘티 = 월별 보기 + 전체 기간 검색 */
.mlabel .mcount{font-family:var(--f-mono); font-weight:600; font-size:11px; color:var(--ink2);
  background:var(--paper); border:1.5px solid var(--ink); border-radius:999px; padding:1px 7px; margin-left:8px;
  vertical-align:middle; white-space:nowrap;}
/* 숫자만 있으면 무슨 수인지 모른다(2026-09-16) → «콘티 8개». 숫자는 모노, 이름표는 본문 글꼴(팀 카드 «11명» 과 같은 문법) */
.mlabel .mcount .ko{font-family:var(--f-body); font-weight:800; font-size:10.5px;}
.mlabel .mcount .ko:first-child{margin-right:3px;}
.mbtn[disabled]{opacity:.3; box-shadow:none; cursor:default;}
.yrsel{font-family:var(--f-body); font-size:12.5px; font-weight:700; color:var(--ink); cursor:pointer;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:999px; padding:6px 10px;
  box-shadow:var(--sh-sm);}
.qnote{display:flex; flex-wrap:wrap; align-items:center; gap:9px; margin:2px 0 16px;
  font-size:12.5px; font-weight:600; color:var(--ink2);}
.qnote b{color:var(--praise); font-weight:800;}
.fchip.sm{padding:5px 11px; font-size:11.5px; display:inline-flex; align-items:center; gap:5px;}
.fchip.sm .ic{width:12px; height:12px;}
.qsum{display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 14px; padding:10px 14px;
  background:var(--praise-soft); border:var(--bw) solid var(--praise); border-radius:var(--r-m);
  font-size:13px; font-weight:700; color:var(--ink); box-shadow:0 3px 0 var(--praise);}
.qsum b{font-size:16px; font-family:var(--f-disp); font-weight:900; color:var(--praise);}
.qsum .ic{width:15px; height:15px; color:var(--praise);}
.qsum .d{font-size:11.5px; font-weight:600; color:var(--ink2); margin-left:auto;}
.songtable{display:flex; flex-direction:column; padding:6px 16px;}
.songtable .srow{display:flex; align-items:baseline; gap:9px; padding:9px 2px; font-size:13.5px; font-weight:500;
  border-bottom:1.5px dashed var(--faint);}
.songtable .srow:last-child{border-bottom:0;}
.songtable .tempo{font-size:10px; font-weight:700; color:var(--faint); flex:none;}
/* 결단찬양 줄: 템포 자리에 칩이 서고, 키가 없으면 빈 칸이 오른쪽 정렬만 지킨다 */
.songtable .srow .rchip{align-self:center; margin-top:0; flex:none;}
.key.blank{border-color:transparent; background:none; padding:0;}
/* ⚠ 키 칩은 기본이 `margin-left:auto`(콘티 줄에서 오른쪽으로 미는 용도)다. 곡 찾기 줄에선 템포도 auto 라서
   **둘이 남는 자리를 반씩 나눠 가져 템포가 줄 한가운데에 떴다.** 제목 길이마다 위치가 달라 세로로 안 맞았다(96차-i 넓은 화면 실측).
   → 곡 찾기 줄의 키는 템포 바로 뒤에 붙인다. 템포·키·담기·상세가 오른쪽에 한 덩어리로 선다. */
.songtable .srow .key{margin-left:0;}

/* ══ 찬양 탭 넓은 화면 (96차-i) ═════════════════════════════════════════════
   사용자: *"찬양 탭도 넓은 화면에서 확인해줘."* + 같은 말에서 원칙: **쓸데없이 큰 자리만 차지하는 디자인은 피한다.
   옆에 똑같은 블록이 있어서 선을 맞춰야 할 때만 늘인다.**
   넓은 화면에서 본 것 넷: ① 위 탭 알약 하나가 300px(글자는 두세 자) ② 콘티 카드 920px, 곡 이름과 단추 사이가 텅 빔
   ③ 곡 찾기 줄 920px + 템포가 가운데에 떠서 줄마다 위치가 다름(위 키 칩 규칙) ④ 신청 폼·목록이 920px 로 늘어남.
   → ① 탭은 글자만큼, 왼쪽(아래 칩·단추 줄과 선이 맞는다. 가운데로도 찍어 봤는데 혼자 떴다)
     ② 콘티 카드 = 들어가는 만큼 칸(섬김표 목록과 같은 340px 규칙). 높이는 곡 수만큼(`start`).
        억지로 맞추면 곡 네 곡짜리 카드 안에 200px 빈칸이 생겼다(시안 비교). 섬김표 목록과 같은 결정이다.
     ③ 곡 찾기 = 800px 부터 두 칸. 744·768(아이패드 미니·9세대 세로)은 칸이 330px 라 돋보기가 혼자 아랫줄로 떨어져서 한 줄 목록.
     ④ 신청 = 쓰는 칸 | 온 신청 두 기둥. 쓰는 칸은 따라 내려온다(sticky).
   ⚠ 폰(700 미만)은 한 줄도 안 바뀐다. 검색창은 그대로 전폭이다(아래 카드 격자의 양 끝과 선이 맞는다). */
@media (min-width:700px){
  .subtabs{width:fit-content;}
  .subtabs button{flex:none; padding:8px 24px;}
  #contiList{display:grid; grid-template-columns:repeat(auto-fill,minmax(340px,1fr)); gap:14px; align-items:start;}
  #contiList > .setcard{margin-bottom:0;}
  #contiList > :not(.setcard){grid-column:1 / -1;}   /* 검색 요약·더 보기·빈 안내는 한 줄을 다 쓴다 */
  .reqsplit{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:20px; align-items:start;}
  .reqsplit > .reqcompose{position:sticky; top:84px; margin-bottom:0;}   /* ⚠ 폰 규칙(`.reqcompose` 14px)이 파일 뒤쪽에 있어서 한 단 세게 건다 */
  .reqcompose #reqSend{margin-left:auto;}   /* 좁아서 아랫줄로 내려가면 오른쪽 끝에 선다 */
}
@media (min-width:800px){
  .songtable{display:grid; grid-template-columns:1fr 1fr; column-gap:28px;}
  /* 두 칸이라 줄 사이 점선은 **위쪽**에 긋는다(아래쪽이면 마지막 줄 한 칸에만 선이 남는다). 첫 줄 두 칸은 안 긋는다 */
  .songtable .srow{border-bottom:0; border-top:1.5px dashed var(--faint);}
  .songtable .srow:nth-child(-n+2){border-top:0;}
  .songtable .srow.srmore{grid-column:1 / -1;}   /* «...외 N곡」 줄. ⚠ `.more` 는 섹션 머리 링크 이름이라 안 쓴다 */
}
@media (min-width:800px) and (max-width:899px){
  /* 칸이 350px 안팎이라 간격만 줄인다. ⚠ «가사» 글자는 접지 않는다(2026-09-16 화면 점검: 아이콘만 남기면 «찾기» 로 읽혔다) */
  .songtable{column-gap:20px;}
  .songtable .srow{gap:7px;}
  .songtable .srow .infobtn.wide{padding:0 9px;}
}

/* ── 리퀘스트 보드 ────────────────────────── */
.reqcompose{margin-bottom:14px;}   /* 폰 = 쓰는 칸 아래로 목록이 이어진다. 넓은 화면은 위 96차-i 절에서 두 기둥 */
.reqlist{display:flex; flex-direction:column; gap:11px;}
.req{display:flex; gap:10px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-m); padding:12px 14px; box-shadow:var(--sh-sm); align-items:flex-start;}
.req.done{opacity:.45;}
.req .kbadge{flex:none; font-size:10px; font-weight:800; border-radius:8px; padding:3.5px 9px; margin-top:1px; border:1.5px solid;}
.req .kbadge.song{color:var(--praise); background:var(--praise-soft); border-color:var(--praise);}
.req .kbadge.etc{color:var(--bcast); background:var(--bcast-soft); border-color:var(--bcast);}
.req .kbadge.bgm{color:var(--sound); background:var(--sound-soft); border-color:var(--sound);}
/* 이름 공개 / 익명 + 보내기 한 줄 */
.whorow{display:flex; flex-wrap:wrap; gap:9px; align-items:center;}
.whorow .field{margin:0;}
.filterchips.sm{margin:0; gap:6px;}
.filterchips.sm .fchip{display:inline-flex; align-items:center; font-size:11.5px; padding:6px 11px; gap:5px;}
.filterchips.sm .fchip .ic{width:12px; height:12px;}
.req .rb{flex:1; min-width:0; font-size:13.5px; font-weight:500; line-height:1.55; overflow-wrap:break-word;}
.req .rmeta{font-size:11px; font-weight:600; color:var(--faint); margin-top:2px;}
.req .donechip{flex:none; font-size:10px; font-weight:800; color:#fff; background:var(--sound-fill);
  border:1.5px solid var(--ink); border-radius:999px; padding:2.5px 9px; margin-top:2px;}

/* ⭐⭐ 신청곱 = 곱 한 줄씩 (113차)
   홈 카드와 신청 화면이 **같은 줄 부품**(`rsRowHTML`)을 쓴다 — 같은 것이 두 모양이면 한쪽이 늘는다.
   ⚠ 예배 딱지는 섬김표가 쓰는 `.svcchip` 그대로다. 여기서 새 색을 만들지 않는다(색 규율: 의미색은 딱지에서만). */
.svcchip.any{background:var(--card); color:var(--ink2); border-color:var(--ink2);}
.rsgrp + .rsgrp{margin-top:15px;}
.rsghd{display:flex; align-items:baseline; gap:7px; font-family:var(--f-disp); font-weight:900;
  font-size:15px; color:var(--ink); margin:0 0 8px 2px;}
/* «전체 재생» 은 구역 머리의 **빈 오른쪽**을 쓴다. 줄을 새로 만들지 않는다(109차-d 와 같은 생각) */
.rsghd .rsall{margin-left:auto; align-self:center;}
/* 보내는 칸의 «어느 예배» 이름표. `.field label` 과 같은 치수다(한 벌은 한 문법) */
.rsnewlab{display:block; font-size:11.5px; font-weight:800; color:var(--ink2); margin:0 0 6px 2px;}
#rsFull{margin-bottom:6px;}
#rsFull .pastbar{margin-top:12px;}
.rsghd b{font-family:var(--f-body); font-size:11px; font-weight:800; color:var(--ink2);}
.rslist{display:flex; flex-direction:column; gap:7px; margin-top:9px;}
/* ⚠ 넓은 화면에서 한 줄짜리를 전폭으로 늘이지 않는다 — 같은 모양끼리 **칸**으로 놓는다
   (96차-f 섬김표 목록과 같은 규율. 1440 홈 왼 기둥 748px 에 두 칸 들어간다). 신청 카드 안의 줄은 이미 좁아서 그대로 둔다. */
@media (min-width:700px){
  .rsgrp .rslist{display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr));}
}
.rsloose{margin-bottom:13px;}
.rsong{display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-width:0;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-s);
  padding:8px 10px; box-shadow:var(--sh-sm);}
.rsong.done{opacity:.6;}
.rsong.done .rst{text-decoration:line-through; text-decoration-thickness:1.5px;}
/* 제목 줄 통째가 ▶ 단추다 — 폰에서 작은 아이콘을 조준하게 하지 않는다 */
.rsgo{flex:1 1 120px; min-width:0; display:flex; align-items:center; gap:8px; text-align:left;
  background:none; border:0; padding:0; margin:0; font:inherit; color:var(--ink); cursor:pointer;}
.rsgo .ic{flex:none; width:18px; height:18px; color:var(--praise);}
.rsgo:active{transform:translateY(1px);}
.rst{min-width:0; font-size:13.5px; font-weight:800; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.rst i{font-style:normal; font-weight:600; font-size:11.5px; color:var(--ink2); margin-left:6px;}
.rsmore{display:inline-block; margin:8px 0 0 2px; font-size:12px; font-weight:800; color:var(--ink2); text-decoration:none;}
.rsnone{margin:9px 0 0; font-size:12px; font-weight:600; color:var(--ink2);
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.req .rsadd{margin-top:9px;}
.rsedit{width:32px; height:32px; flex:none;}
/* 새 곡(133차-h 아홉째 판): 제목 밑에 튼 횟수 · 다음 콘티 한 줄. 정보라 글자만(단추 모양 없음) */
.rstw{display:flex; flex-direction:column; min-width:0; gap:1px;}
.rsrep{font-size:11px; font-weight:800; color:var(--praise); line-height:1.3; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.rsong.done .rsrep{color:var(--ink2);}
.rsacts .rsmark.on{background:var(--sp-leaf-100, #DDF1E1); color:var(--sp-leaf-700, #1D722E);}
.rsplays{margin:6px 0 0;}
/* 체크 · 연필 = 한 봉지(133차-h 아홉째 판). 자리가 있으면 한 줄, 없으면 둘이 같이 내려가 오른쪽 끝(예배 딱지 밑)에 선다 */
.rsacts{display:flex; align-items:center; gap:8px; flex:none; margin-left:auto;}
/* 보내는 칸의 곱 한 줄. ⚠ `.field` 밖이라 칸 스타일을 여기서 직접 준다(`.field input` 규칙은 그 안에서만 먹는다) */
.rsnew{position:relative; border:1.5px dashed var(--ink2); border-radius:var(--r-s);
  padding:9px 10px; margin-bottom:9px;}
.rsnew .rssvc{margin-bottom:8px;}
.rsnewin{display:flex; flex-direction:column; gap:7px;}
.rsnewin input{font-family:var(--f-body); font-size:16px; color:var(--ink); background:var(--card);
  border:var(--bw) solid var(--ink); border-radius:12px; padding:9px 12px; width:100%; min-width:0;}
.rsnewin input::placeholder{color:var(--faint); text-overflow:ellipsis;}
.rsnewin input:focus{outline:0; box-shadow:0 0 0 3px var(--accent);}
.rsx{position:absolute; top:5px; right:5px; width:30px; height:30px;}
#reqAdd{margin-bottom:12px;}
#reqRows[hidden],#reqAdd[hidden]{display:none;}

/* ── 자료실 ──────────────────────────────── */
.reslist{display:flex; flex-direction:column; gap:11px;}
/* 넓은 화면에선 한 줄에 여럿 (97차-b). 한 줄씩 쌓으면 1440 에서 줄 하나가 920px 인데 안에 든 건 아이콘과 제목뿐이라
   오른쪽 800px 가 빈 채로 늘어났다. 늘린 한 줄보다 같은 크기 타일 여러 장이 낫다. 팀 탭의 «같이 해 보고 싶으면» 자료도 같은 목록이다. */
@media (min-width:700px){
  .reslist{display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr));}
}
.res{display:flex; align-items:center; gap:12px; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-m); padding:12px 14px; box-shadow:var(--sh-sm); text-decoration:none;}
.res:active{transform:translateY(2px); box-shadow:none;}
.res > .hic{width:34px; height:34px; flex:none; transform:rotate(-3deg);}   /* 그림 아이콘(2026-09-16). 예전 초록 네모 타일 */
.res .rt{flex:1; min-width:0;}
.res .rt .n{display:block; font-weight:800; font-size:14px;}
.res .rt .d{display:block; font-size:11.5px; font-weight:500; color:var(--ink2); margin-top:1px;
  text-wrap:pretty;}   /* 타일이 좁아지면 «음향 / 기초» 처럼 낱말 하나가 끝줄에 혼자 남았다 */
.badge{flex:none; font-size:10px; font-weight:800; border-radius:999px; padding:3.5px 10px; white-space:nowrap; border:1.5px solid;}
.badge.doc{background:var(--sound-soft); color:var(--sound); border-color:var(--sound);}
.badge.ext{background:var(--bcast-soft); color:var(--bcast); border-color:var(--bcast);}
.badge.adm{background:var(--lilac-soft); color:var(--lilac); border-color:var(--lilac);}
.grptitle{font-family:var(--f-disp); font-weight:900; font-size:17px; margin:24px 2px 11px; display:flex; align-items:center; gap:9px;}
.grptitle::after{content:''; flex:1; border-top:2.5px dashed var(--faint);}
.grptitle.bcast{color:var(--bcast);} .grptitle.sound{color:var(--sound);} .grptitle.praise{color:var(--praise);}

/* ── 팀 (명단 = 락커룸 명찰 벽) ─────────────── */
.teamgrid{display:flex; flex-direction:column; gap:20px;}
.teamcard{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-l);
  box-shadow:var(--sh); overflow:visible; position:relative;
  animation:rise .64s var(--e-glide) backwards; animation-delay:calc(min(var(--i,0), 9) * 60ms);}
.teamcard::before{content:''; position:absolute; top:-11px; left:26px; width:84px; height:20px;
  transform:rotate(-4deg); border-radius:3px; opacity:.85; background:var(--deck);
  -webkit-mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);
  mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);}
.teamcard.bcast::before{background:var(--bcast-fill);}
.teamcard.sound::before{background:var(--sound-fill);}
.teamcard.praise::before{background:var(--praise-fill);}
/* 방송음향팀 = 한 장 안에 두 갈래 (67차). 머리 띠는 두 색을 그대로 이어 붙여 "둘이 한 팀"을 색으로도 말한다 */
.teamcard.av::before{background:linear-gradient(180deg,var(--bcast) 0 50%,var(--sound) 50% 100%);}
.teamcard .thead{display:flex; align-items:center; gap:9px; padding:13px 16px 11px;
  border-bottom:var(--bw) solid var(--ink);
  border-radius:calc(var(--r-l) - 3px) calc(var(--r-l) - 3px) 0 0;}
.teamcard.bcast .thead{background:var(--bcast-soft);}
.teamcard.sound .thead{background:var(--sound-soft);}
.teamcard.praise .thead{background:var(--praise-soft);}
.teamcard.av .thead{background:linear-gradient(100deg,var(--bcast-soft),var(--sound-soft));}
.teamcard.av .tname{color:var(--bcast);}
.thpair{display:inline-flex; align-items:center; gap:2px; flex:none;}
.thpair .thi:last-child{margin-left:-7px;}   /* 두 아이콘을 살짝 겹쳐 한 덩어리로 읽히게 */
/* '팀장' 단 이름표는 찬양팀 리더용 코랄을 물려받는다 — 파랑·초록 카드 안에서 혼자 붉으면 남의 색이다 */

.teamcard .tname{font-family:var(--f-disp); font-weight:900; font-size:19px; letter-spacing:-.3px;}
.teamcard.bcast .tname{color:var(--bcast);} .teamcard.sound .tname{color:var(--sound);} .teamcard.praise .tname{color:var(--praise);}
.teamcard .tcount{margin-left:auto; font-family:var(--f-mono); font-weight:600; font-size:13px;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:999px; padding:2.5px 11px;
  transform:rotate(2.5deg); box-shadow:var(--sh-sm);}
.teamcard .tcount .ko{font-family:var(--f-body); font-weight:800; font-size:11px; margin-left:1px;}
.teamcard .tdesc{padding:11px 16px 0; font-size:12px; font-weight:600; color:var(--ink2);}

/* ── 색 = 역할 ────────────────────────────────
   .rl-* 하나만 붙이면 이름(.ptag)이 같은 색 규칙을 따른다(팀 탭 명찰은 2026-09-27 UX 130 에서 이름 글자로 바뀌었다).
   --rc = 진한 색(점·글자), --rcs = 옅은 색(바탕). */
.rl-lead   {--rc:var(--rl-lead);    --rcs:var(--rl-lead-soft);}
.rl-vocal  {--rc:var(--rl-vocal);   --rcs:var(--rl-vocal-soft);}
.rl-session{--rc:var(--rl-session); --rcs:var(--rl-session-soft);}
.rl-bcast  {--rc:var(--rl-bcast);   --rcs:var(--rl-bcast-soft);}
.rl-sound  {--rc:var(--rl-sound);   --rcs:var(--rl-sound-soft);}


/* 명찰 구멍이 곧 역할 점이다. 옅은 바탕만으로는 작은 칩에서 구별이 안 된다 */

   /* 리더·팀장은 한 단 더 두껍게 */
/* 이 폰의 주인. 명단에서 자기 이름을 한 번 누르면 붙는다 */




/* 이름을 왜 눌러야 하는지 한 줄로. 안 정했으면 권하고, 정했으면 누구로 돼 있는지 밝힌다 */
.mecue{display:flex; align-items:flex-start; gap:9px; margin:0 0 15px; padding:10px 13px;
  border:var(--bw) dashed var(--ink); border-radius:var(--r-m); background:var(--card);
  font-size:12px; font-weight:600; color:var(--ink2); line-height:1.6;}
.mecue .ic{width:18px; height:18px; flex:none; margin-top:1px; color:var(--praise);}
.mecue b{color:var(--ink);}
/* 찬양팀 크루 칩. 지금은 `crewTiersHTML`(리더·싱어·세션 3단)만 이걸 쓴다 —
   한 줄로 눈히던 `.pcrew`/`praiseCrewHTML` 은 93차-d 에 지웠다(부르는 곳이 없었다). */
.ptag{display:inline-flex; align-items:center; gap:5px; padding:3px 9px 3px 7px; border-radius:999px;
  border:1.5px solid var(--ink); background:var(--rcs,var(--card)); color:var(--ink);
  font-size:12px; font-weight:800; box-shadow:0 2px 0 var(--ink);}
.ptag::before{content:''; width:7px; height:7px; border-radius:999px; flex:none;
  background:var(--rc,var(--faint));}
.ptag i{font-style:normal; font-size:9.5px; font-weight:700; opacity:.62;}
.ptag.head{box-shadow:0 3px 0 var(--ink);}
.spot .ptiers{margin:0; padding:11px var(--card-gut) 12px;}
/* 118: 경계선은 다음 구역의 위쪽 하나가 맡는다.
   명단 아래 + 콘티 위가 맞닿으면 두 줄이 되고, 콘티 아래 + 방송 위에는 선이 없었다.
   리허설 설명은 바로 위 콘티에 딸린 글이므로 별도 구분선을 만들지 않는다. */
.spotbody > :not(:first-child){border-top:1.5px dashed var(--faint);}

/* 못 서는 날 알리기 — 맨 아래 있으면 아무도 못 찾고 결국 팀장에게 카톡한다(사용자 지적).
   그래서 섬김표 **맨 위**에 접힌 채로 둔다: 자리는 눈에 띄고, 펴기 전엔 한 줄이라 표를 안 가린다. */
.bkbar{display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
  padding:11px 13px; margin-bottom:14px; border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  background:var(--bcast-soft); box-shadow:var(--sh-sm); font-family:var(--f-body); color:var(--ink);}
.bkbar .hic{width:32px; height:32px; flex:none; transform:rotate(-4deg); margin:-3px 0;}   /* 그림 아이콘(2026-09-16). 예전 흰 네모 타일 */
.bkbar .bt{font-family:var(--f-disp); font-weight:900; font-size:14.5px;}
.bkbar .bd{display:block; font-size:11.5px; font-weight:600; color:var(--ink2); margin-top:2px;}
.bkbar .bg{margin-left:auto; flex:none; font-size:11.5px; font-weight:800; color:var(--bcast);
  border:1.5px solid var(--bcast); border-radius:999px; padding:3px 10px; background:var(--card);}
.bkbar[aria-expanded="true"]{margin-bottom:0; border-bottom-left-radius:0; border-bottom-right-radius:0;}
.bkwrap{margin-bottom:14px;}
.bkwrap .card{border-top-left-radius:0; border-top-right-radius:0; border-top:0;}

/* 「지난 것」 접기 — **섬김표 목록과 찬양 콘티가 같은 부품**이다 (111차-b, 피드백 14번).
   ⚠ 앞으로 올 것과 섞이면 안 되니 위에 넉넉히 띄운다. 눌러야 펴지는 줄이라 가운데에 세운다. */
.pastbar{display:flex; align-items:center; justify-content:center; gap:7px; width:100%; cursor:pointer;
  margin:26px 0 0; padding:11px 14px; border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  background:var(--card); box-shadow:var(--sh-sm);
  font-family:var(--f-disp); font-weight:800; font-size:13.5px; color:var(--ink2);}
.pastbar .ic{width:15px; height:15px; flex:none; transition:transform .2s var(--e-snap);}
.pastbar.on{color:var(--ink);}
.pastbar.on .ic{transform:rotate(180deg);}
.pastwrap .wklabel:first-child{margin-top:16px;}
/* ⚠ 넓은 화면에서는 **글자만큼**이다 (96차-i 원칙 — 옆에 맞출 짝이 없는 요소는 늘이지 않는다).
   폰은 카드가 전폭이라 단추도 전폭이 맞지만, 여기서는 카드가 340px 칸으로 갈려서 1160px 짜리 단추 하나가 늘어져 보인다. */
@media (min-width:700px){ .pastbar{width:auto; margin-left:auto; margin-right:auto; padding-left:24px; padding-right:24px;} }


/* 생일 — 맨 앞에서 한 번 축하하고 지나간다. 아무도 없으면 아예 안 그린다.
   ⚠ 처음엔 노란 카드 하나였다가("생일 같지 않다"), 다음엔 이름 해시 파스텔을 썼다.
   그것도 여섯 색을 돌려 쓰는 거라 두 사람이 같은 색으로 겹쳤다(사용자: "그냥 같은 색을 반복해서 쓰는데").
   지금은 촛불이다: 카드에 뜬 사람 수만큼 --cd1..6 을 순서대로 집어서 한 카드 안에서는 절대 안 겹친다.
   색은 촛불 심지(점)와 이름표 바닥 띠에서만 낸다. 카드를 통째로 칠하면 요란해진다. */
/* ⚠ 바탕이 버터였는데 **바로 아래 공지 섹션 아이콘도 버터**(--accent)라 둘이 겹쳐 보였다
   (사용자: "생일 박스 색깔이 노랑인데 바로 아래 공지랑 겹치는 것 같다").
   섹션 아이콘 색은 홈 전체가 쓰는 규칙이라 못 건드린다 → **생일 카드를 라일락으로 옮겼다.**
   홈에서 라일락을 쓰는 자리가 여기뿐이라 아무것과도 안 겹치고, 축하 자리에 어울린다. */
/* 테이프는 카드와 **다른 색**이어야 테이프로 읽힌다. 라일락 카드 위에는 붉은꽃 한 조각 */
.bdcard{--tape:var(--praise); position:relative; display:flex; gap:12px; align-items:center; padding:14px 15px;
  border:var(--bw) solid var(--ink); border-radius:var(--r-l);
  background:var(--lilac-soft); box-shadow:var(--sh); margin-top:10px;
  animation:rise .62s var(--e-glide) backwards;}
.bdcard.on{background:var(--dk-lilwell, #DDCFF8);}
/* 워시테이프 — **한 조각, 가운데**. 예전엔 두 조각을 오른쪽에 어긋나게 붙였는데
   폰에서는 카드가 좁아 둘이 오른쪽 끝에 몰려 붙은 것처럼 보였다
   (사용자: "위에 파랑 빨강 테이프 오른쪽에 붙어있는 게 이상한 것 같아").
   큐카드·팀카드가 이미 쓰는 문법(가운데 한 조각)으로 맞춘다. */
.bdcard::before{content:''; position:absolute; pointer-events:none;
  top:-11px; left:50%; width:86px; height:20px; transform:translateX(-50%) rotate(-2.5deg);
  border-radius:3px; opacity:.9; background:var(--tape);
  -webkit-mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);
  mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);}
/* ⚠ z-index 만 얹고 position 은 각자 것을 지킨다
   (한 줄로 묶어 position:relative 를 씌웠다가 폭죽통이 카드 한가운데로 튀어나왔다) */
/* ⚠ party.png 은 주둥이가 **오른쪽 위**를 본다. 카드 오른쪽 끝에 있으니 그대로 두면 밖으로 쏜다.
   좌우를 뒤집어 카드 안쪽(왼쪽 위)을 겨누게 한다. 색종이도 그 방향으로 날아간다. */
.bdparty{position:absolute; z-index:1; right:11px; bottom:9px; width:30px; height:30px;
  transform:rotate(7deg) scale(-1,1); opacity:.9;}
.bdi{position:relative; z-index:1; flex:none; width:46px; height:46px; object-fit:contain;
  transform:rotate(-4deg);}
.bdb{position:relative; z-index:1; min-width:0;}
.bdt{font-family:var(--f-hand); font-size:25px; font-weight:400; line-height:1.25; letter-spacing:.01em;}
.bdt b{background:var(--card); border:1.5px solid var(--ink); border-radius:9px;
  padding:1px 9px 3px; display:inline-block; transform:rotate(-1.2deg);
  box-shadow:0 2px 0 var(--ink), inset 0 -4px 0 var(--cds,var(--butter-soft));}
.bdt b::before{content:''; display:inline-block; width:7px; height:7px; border-radius:999px;
  background:var(--cdc,var(--butter)); margin-right:6px; vertical-align:2px;}
.bds{font-size:12px; font-weight:600; color:var(--ink2); margin-top:7px; line-height:1.6;}

/* 오늘 생일과 "곧 온다"를 **확실히 갈라 놓는다.**
   ⚠ 예전엔 오늘 축하 문구 바로 밑에 다가올 사람 이름표가 라벨 없이 붙어 있었다
     (사용자: "이 사람들도 생일인 줄 알고 헷갈릴 것 같아"). 실제로 구분할 근거가 하나도 없었다.
     절취선(종이 문법) + 라벨 + 아직 불 안 켜진 초, 셋으로 나눈다. */
.bdsoon{margin-top:9px;}
.bdsoon.tear{margin-top:11px; padding-top:10px; border-top:1.5px dashed rgba(11,42,68,.3);}
.bdlab{font-family:var(--f-disp); font-weight:900; font-size:10.5px; letter-spacing:.02em;
  color:var(--ink2); opacity:.8; margin-bottom:7px;}
.bdnext{display:flex; flex-wrap:wrap; gap:6px;}
/* 오늘 = 불 켜진 초(●) + 단단한 이름표 / 곧 = 안 켜진 초(○) + 점선 이름표.
   그림자를 빼야 "아직 아니다"로 읽힌다. 이 화면에서 하드 그림자는 '지금 살아 있음'의 표시다. */
.bdn{display:inline-flex; align-items:center; gap:6px; padding:3px 10px 3px 8px; border-radius:999px;
  border:1.5px dashed rgba(11,42,68,.42); background:rgba(255,255,255,.5);
  font-size:11.5px; font-weight:800; color:var(--ink2);}
.bdn::before{content:''; width:8px; height:8px; border-radius:999px; flex:none;
  background:transparent; border:2px solid var(--cdc,var(--faint));}
.bdn i{font-style:normal; font-family:var(--f-body); font-weight:700; font-size:10.5px; opacity:.75;
  font-variant-numeric:tabular-nums;}
/* 생일 이름도 프로필로 간다 (명단에 있는 사람만) */
.bdn[data-who], .bdt b[data-who]{cursor:pointer;}
.bdn[data-who]:active, .bdt b[data-who]:active{transform:translateY(1px);}

/* ── 종이 폭죽 ────────────────────────────
   화면 전체에 쏟아지는 색종이. 그리는 건 전부 app.js 의 캔버스가 한다(여긴 자리만 잡아 준다).
   ⚠ 상단바·탭바(40)보다는 위, 시트(80)·토스트(99)보다는 아래. 축하가 조작을 가리면 안 된다.
   ⚠ 손가락은 통과시킨다. 색종이 때문에 버튼이 안 눌리면 그건 그냥 고장이다. */
.bdrain{position:fixed; inset:0; z-index:60; pointer-events:none;}
/* 폭죽통은 반동으로 젖혀지고, 케이크는 흔들리고, 이름표는 튀어 오른다. 한 번에 같이 */
.bdcard.popped .bdparty{animation:bdkick .66s cubic-bezier(.2,.85,.3,1) both;}
/* 뒤집힌 아이콘이라 모든 키프레임이 scale(-1,1) 을 달고 있어야 한다(빠지면 그 순간 다시 뒤집힌다) */
@keyframes bdkick{
  0%{transform:translate3d(0,0,0) rotate(7deg) scale(-1,1);}
  10%{transform:translate3d(7px,5px,0) rotate(-18deg) scale(-1.16,1.16);}
  38%{transform:translate3d(-2px,-2px,0) rotate(13deg) scale(-1,1);}
  100%{transform:translate3d(0,0,0) rotate(7deg) scale(-1,1);}
}
.bdcard.popped .bdi{animation:bdwob .8s cubic-bezier(.3,.9,.3,1) both;}
@keyframes bdwob{
  0%{transform:rotate(-4deg) scale(1);}
  18%{transform:rotate(-12deg) scale(1.08);}
  46%{transform:rotate(1deg) scale(1);}
  72%{transform:rotate(-6deg) scale(1);}
  100%{transform:rotate(-4deg) scale(1);}
}
.bdcard.popped .bdt b{animation:bdpop .7s cubic-bezier(.2,.9,.25,1) both;
  animation-delay:calc(var(--bi,0) * .09s);}
@keyframes bdpop{
  0%{opacity:0; transform:rotate(-1.2deg) scale(.8);}
  55%{opacity:1; transform:rotate(-3.4deg) scale(1.08);}
  100%{opacity:1; transform:rotate(-1.2deg) scale(1);}
}
[data-bdpop]{cursor:pointer;}
/* 움직임을 줄여 달라고 한 사람에겐 카드만 조용히 보여 준다 */
@media (prefers-reduced-motion:reduce){
  .bdrain{display:none;}
  .bdcard.popped .bdparty,.bdcard.popped .bdi,.bdcard.popped .bdt b{animation:none;}
}
/* 촛불 여섯 자루. 카드에 뜬 순서대로 하나씩 집어 쓴다 */
.cd1{--cdc:var(--cd1); --cds:var(--cd1s);}
.cd2{--cdc:var(--cd2); --cds:var(--cd2s);}
.cd3{--cdc:var(--cd3); --cds:var(--cd3s);}
.cd4{--cdc:var(--cd4); --cds:var(--cd4s);}
.cd5{--cdc:var(--cd5); --cds:var(--cd5s);}
.cd6{--cdc:var(--cd6); --cds:var(--cd6s);}







/* (2026-09-16) 팀 카드 끝의 «새 멤버 환영» 점선 명찰(`.ntag.ghost`)과 트레이닝 카드 규칙은 그 화면과 함께 지웠다 */

/* ── 앨범 ────────────────────────────────── */
.albumgrid{display:grid; grid-template-columns:repeat(2,1fr); gap:16px; padding-top:6px;}
.albumcard{position:relative; display:block; border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  overflow:visible; background:var(--card); box-shadow:var(--sh); text-decoration:none; padding:7px 7px 0;}
/* 기울기를 변수로 둔다 — 등장 애니메이션(riseTilt)과 눌림이 이 각도를 지켜야 한다 */
.albumcard:nth-child(even){--tilt:.7deg;}
.albumcard:nth-child(odd){--tilt:-.6deg;}
.albumcard{transform:rotate(var(--tilt,0deg));}
.albumcard:active{transform:rotate(var(--tilt,0deg)) translateY(3px); box-shadow:0 1px 0 var(--ink);}
.albumcard::before{content:''; position:absolute; top:-10px; left:50%; width:74px; height:18px;
  transform:translateX(-50%) rotate(-3deg); border-radius:3px; opacity:.85; background:var(--lilac-fill);
  -webkit-mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);
  mask:repeating-linear-gradient(90deg,#000 0 6px,rgba(0,0,0,.85) 6px 12px);}
.albumcard .cov{aspect-ratio:4/3; background:var(--lilac-soft); display:flex; align-items:center; justify-content:center;
  color:var(--lilac); border:1.5px solid var(--ink); border-radius:9px; overflow:hidden;}
.albumcard .cov img{width:100%; height:100%; object-fit:cover; display:block;}
.albumcard .cov .ic{width:30px; height:30px;}
.albumcard .ab{padding:9px 7px 11px; display:block;}
.albumcard .at{font-family:var(--f-disp); font-weight:900; font-size:15px; line-height:1.3; color:var(--ink); display:block;}
.albumcard .ad{font-size:11px; font-weight:600; color:var(--faint); margin-top:2px; display:block;}
.photogrid{display:grid; grid-template-columns:repeat(3,1fr); gap:8px;}
.photogrid button{border:var(--bw) solid var(--ink); border-radius:var(--r-s); overflow:hidden; padding:0;
  background:var(--lilac-soft); cursor:pointer; aspect-ratio:1; position:relative;}
.photogrid img{width:100%; height:100%; object-fit:cover; display:block;}
/* ── 영상 칸 = 필름 한 컷 ──────────────────────
   드라이브가 영상의 첫 장면을 그림으로 주기 때문에, 격자에서는 사진과 **완전히 똑같이** 생긴다.
   ⚠ 흰 동그라미 하나만 얹어 봤더니(50차) 밝은 사진 위에서 그대로 묻혔다
     (사용자: "딱히 구별이 안 되어 있어").
   그래서 색이나 뱃지가 아니라 **모양을 바꾼다** — 위아래를 잉크로 잘라 천공을 뚫은 필름 컷.
   축소돼도, 사진이 무슨 색이든, 옆 칸과 다른 물건으로 읽힌다. */
.photogrid .isvid{background:var(--ink); padding:9px 0;}
/* ⚠ 천공을 칸 끝까지 깔면 둥근 모서리에 걸려 반쯤 잘린 구멍이 생긴다 → 좌우 4px 들여놓는다 */
.photogrid .isvid::before, .photogrid .isvid::after{content:''; position:absolute;
  left:4px; right:4px; height:9px; pointer-events:none;
  background:var(--film) repeat-x center / 13px 9px;}
.photogrid .isvid::before{top:0;}
.photogrid .isvid::after{bottom:0;}
/* 재생 단추는 **계절을 타지 않는다** — 색이 곧 "이건 영상"이라는 뜻이라 흔들리면 안 된다.
   그래서 --accent(계절색)가 아니라 버터색 고정. 사진 위에서도 잉크 필름 위에서도 뜬다. */
.vbadge{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:37px; height:37px; display:grid; place-items:center; pointer-events:none;
  background:var(--accent); border:var(--bw) solid var(--ink); border-radius:999px;
  box-shadow:0 2px 0 var(--ink);}
.vbadge .ic{width:16px; height:16px; color:var(--ink); margin-left:2px;}
/* 영상 구간 제목 앞의 재생 조각 — 목록 제목과 같은 말투(잉크 테두리 + 2px 단) */
.grptitle .vgi{flex:none; display:grid; place-items:center; width:25px; height:25px;
  background:var(--accent); border:var(--bw) solid var(--ink); border-radius:8px;
  box-shadow:0 2px 0 var(--ink);}
.grptitle .vgi .ic{width:12px; height:12px; color:var(--ink); margin-left:1px;}
.backlink{display:inline-flex; align-items:center; gap:5px; font-size:12.5px; font-weight:700;
  color:var(--ink2); text-decoration:none; margin-bottom:12px;}
.backlink .ic{width:15px; height:15px;}
/* 돌아가기가 `<button>` 일 때도 링크처럼 보이게 (탭 아닌 화면들 — 진짜 히스토리로 돌아간다, 95차).
   ⚠ 손가락 자리는 링크보다 넉넉히. 12.5px 글씨 한 줄은 폰에서 너무 얇다 */
button.backlink{font-family:inherit; background:none; border:0; padding:6px 8px 6px 0; cursor:pointer;}
button.backlink:active{transform:translateX(-2px);}

/* ── 버튼/폼 공통 ─────────────────────────── */
/* ⚠ `line-height:normal` 을 박는 까닭 (108차-c): `<button>` 은 브라우저 기본 글꼴 지정(`font` 단축)이 줄높이를 normal 로
   되돌리는데 `<a class="btn">` 은 본문 줄높이를 그대로 물려받는다 → **같은 단추인데 링크만 6px 더 높았다**
   (콘티 카드의 «가사 슬라이드» 가 그랬다. 실측 37 vs 31). 단추에는 아무 변화가 없고 링크만 단추 높이에 맞는다. */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:7px; line-height:normal;
  font-family:var(--f-body); font-weight:800; font-size:14px;
  background:var(--card); color:var(--ink); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  padding:10px 17px; box-shadow:var(--sh-sm); cursor:pointer; text-decoration:none;
  transition:transform .08s ease, box-shadow .08s ease;}
.btn:active{transform:translateY(2px); box-shadow:none;}
.btn .ic{width:16px; height:16px;}
.btn.primary{background:var(--accent); color:var(--ink); box-shadow:0 3px 0 var(--ink);}
.btn.ghost{font-weight:700; font-size:13px;}
.btn.danger{color:#fff; background:var(--praise-fill);}
.btn.sm{padding:7px 13px; font-size:13px; border-radius:var(--r-s);}
.btn[disabled]{opacity:.5; pointer-events:none;}
.iconbtn{width:34px; height:34px; border-radius:11px; border:var(--bw) solid var(--ink); background:var(--card);
  display:inline-flex; align-items:center; justify-content:center; cursor:pointer; box-shadow:var(--sh-sm); flex:none;}
.iconbtn .ic{width:15px; height:15px; color:var(--ink);}
.iconbtn:active{transform:translateY(2px); box-shadow:none;}
/* 글자 붙은 연장 단추 (2026-09-16 화면 점검, 사용자 확인). 리더만 보는 완료·삭제·앨범 삭제가 아이콘뿐이라
   폰에서는 설명(title)이 안 떠서 무엇을 하는지 몰랐다. 모양은 아이콘 단추 그대로, 옆에 한 낱말 */
.iconbtn.txt{width:auto; padding:0 11px; gap:5px; font-family:var(--f-body); font-size:12px; font-weight:800;
  color:var(--ink); white-space:nowrap;}
.iconbtn.txt .ic{width:14px; height:14px;}

.field{display:flex; flex-direction:column; gap:5px; margin-bottom:12px;}
.field label{font-size:11.5px; font-weight:800; color:var(--ink2);}
.field input,.field textarea,.field select{font-family:var(--f-body); font-size:16px; color:var(--ink);
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:12px; padding:10px 13px; width:100%;}
/* ⚠ iOS 사파리는 input[type=date] 에 고유 폭이 있어서 width:100% 를 무시하고 칸을 밀어낸다.
   appearance 를 끄고 min-width 를 풀어 줘야 상자 안에 들어온다(데스크톱에선 재현 안 됨). */
input[type=date],input[type=url],input[type=text],input[type=password],input[type=search],select,textarea{
  max-width:100%; min-width:0;}
input[type=date]{-webkit-appearance:none; appearance:none;}
.field,.fieldrow .field{min-width:0;}
.field input::placeholder,.field textarea::placeholder{color:var(--faint); text-overflow:ellipsis;}
.field input:focus,.field textarea:focus,.field select:focus{outline:0; box-shadow:0 0 0 3px var(--accent);}
.field textarea{resize:vertical; min-height:78px;}
.fieldrow{display:flex; gap:10px;}
.fieldrow .field{flex:1;}
.formmsg{font-size:12.5px; font-weight:700; margin-top:6px; min-height:18px;}
.formmsg.err{color:var(--praise);} .formmsg.ok{color:var(--sound);}

/* ── 동기화 표시 (하단, 평소엔 거의 안 보이게) ── */
.syncbar{max-width:960px; margin:0 auto; padding:0 16px 26px; text-align:center;}
.syncbar[hidden]{display:none;}
.syncsum{border:0; cursor:pointer; padding:6px 11px; border-radius:999px;
  font-family:var(--f-body); font-size:11px; font-weight:600; color:var(--ink2);
  /* 페이지 맨 아래 = 배경 물가 그림 자리다. 바탕 없이 두면 나무 위에서 안 읽힌다 */
  background:rgba(255,255,255,.72);}
.syncsum:hover{color:var(--ink); background:#fff;}
/* ⚠ 글씨는 한 단 더 짙은 빨강이다. `--praise` 를 그대로 쓰면 `--praise-soft` 위에서 3.5:1 이라 11px 로는 안 읽힌다
   (2026-09-18, 103차-b 에 `tools/qa/skycontrast.mjs` 가 잡았다. 하늘과 무관한 예전부터의 것 — **동기화가 멈췄다는 말은 읽혀야 한다**). */
.syncbar.warn .syncsum{color:var(--dk-coratx, #A8331F); font-weight:800;
  background:var(--praise-soft); border:1.5px solid var(--praise);}
.synclist{display:flex; flex-direction:column; gap:9px;}
.syncrow{display:flex; align-items:center; gap:9px; flex-wrap:wrap; padding:11px 13px;
  border:var(--bw) solid var(--ink); border-radius:var(--r-m); background:var(--card); box-shadow:var(--sh-sm);}
.syncrow.bad{background:var(--praise-soft);}
.sysrc{font-family:var(--f-disp); font-weight:900; font-size:15px;}
.systat{font-size:10.5px; font-weight:800; border-radius:999px; padding:2px 9px; border:1.5px solid;
  background:var(--sound-soft); color:var(--sound); border-color:var(--sound);}
.syncrow.bad .systat{background:var(--praise-fill); color:#fff; border-color:var(--ink);}
.syago{margin-left:auto; font-size:11.5px; font-weight:700; color:var(--ink2);}
.sysum{flex:1 0 100%; font-family:var(--f-body); font-weight:600; font-size:11px; color:var(--faint);}
.symsg{flex:1 0 100%; font-size:12px; font-weight:600; color:var(--praise); line-height:1.5;}

/* ── 토스트 ──────────────────────────────── */
#toast{position:fixed; left:50%; bottom:calc(var(--tabbar-h) + 20px); transform:translateX(-50%);
  z-index:99; font-family:var(--f-body); font-size:13.5px; font-weight:800; padding:10px 19px;
  border-radius:999px; background:var(--ink); color:var(--butter); border:2px solid var(--card);
  box-shadow:0 4px 0 rgba(42,33,24,.3);
  opacity:0; transition:opacity .2s; max-width:86vw; text-align:center; pointer-events:none;}
#toast.err{background:var(--praise-fill); color:#fff;}

/* ── 시트/모달 ────────────────────────────── */
#layer{position:fixed; inset:0; z-index:80; background:rgba(7,31,54,.5);
  display:flex; align-items:flex-end; justify-content:center; overscroll-behavior:contain;}
/* ⚠ 여기는 아이디 선택자라 아래 .lightbox 클래스보다 세다. 그래서 폰에서 유튜브 창이
   화면 맨 아래에 붙어 마지막 줄이 브라우저 하단 바에 잘렸다(사용자 지적).
   라이트박스는 아이디 선택자로 다시 잡아 가운데 세우고, 위아래 여백은 노치·홈바까지 계산해 준다. */
#layer.lightbox{align-items:center;
  padding:calc(14px + var(--top-safe)) 10px calc(14px + env(safe-area-inset-bottom));}
#layer[hidden]{display:none;}
/* ⭐⭐ 창 한 겹 = 칸 하나 (2026-09-16). 칸은 `#layer` 를 꽉 채우고 정렬·여백을 그대로 물려받아서, 칸 안의 시트·뷰어는
   예전에 `#layer` 바로 밑에 있을 때와 같은 자리에 선다. 밑 칸은 **안 보이게만** 한다(display:none 이면 스크롤과
   판 크기가 사라져서 드러날 때 맨 위로 튀고 꾸미기 판이 0px 로 잰다). */
#layer > .lvl{position:absolute; inset:0; display:flex; align-items:inherit; justify-content:inherit; padding:inherit;
  box-sizing:border-box; overscroll-behavior:contain;}
#layer > .lvl.under{visibility:hidden; pointer-events:none;}
.sheet{width:100%; max-width:520px; overscroll-behavior:contain; background:var(--card); border:var(--bw) solid var(--ink);
  border-radius:var(--r-xl) var(--r-xl) 0 0; box-shadow:0 -5px 0 rgba(42,33,24,.25);
  padding:18px 18px calc(20px + env(safe-area-inset-bottom)); max-height:88vh; overflow:auto;
  animation:sheetup .3s var(--e-glide);}
@keyframes sheetup{from{transform:translateY(46px); opacity:0;} to{transform:none; opacity:1;}}
.sheet .shhead{display:flex; align-items:center; gap:10px; margin-bottom:14px;}
.sheet .shhead h3{font-family:var(--f-disp); font-weight:900; font-size:18px; margin:0;}
/* ⭐ 머리 아이콘은 **글자 가운데**에 선다 (108차-b, 사용자: *"달력 아이콘이랑 타이틀이랑 줄이 안 맞아"*).
   까닭: 인라인 svg 는 글자 밑줄(baseline)에 앉는다 → 22px 아이콘이 18px 글자보다 한참 밑으로 처지고 붙어 있다.
   ⚠ h3 를 flex 로 바꾸지 말 것 — 곡 정보 머리의 영어 이름(`.ensub`)이 제목과 같이 접히는 것을 잃는다.
   쓰는 곳 셋: 콘티 · 꾸미기 · 할 일. */
.sheet .shhead h3 > .ic{width:20px; height:20px; vertical-align:-5px; margin-right:7px;}
.sheet .shhead .iconbtn, .sheet .shhead .shacts{margin-left:auto;}
/* 머리 오른쪽 단추 묶음(돌아가기 · 닫기). 자리가 모자라면 같이 움직인다 */
.sheet .shhead .shacts{display:flex; align-items:center; gap:8px;}
.sheet .shhead .shacts .iconbtn{margin-left:0;}
.lightbox img{max-width:100%; max-height:100%; border-radius:var(--r-m); border:3px solid #fff;
  display:block; object-fit:contain;}

/* ── 사진 크게 보기 ────────────────────────────
   앨범 사진은 500장이 넘는다. 한 장 띄우고 닫는 게 아니라 **여기서 끝까지 넘겨 보는** 자리다.
   ⚠ 처음엔 사진을 여백 안에 얌전히 앉혀 뒀다(사용자: "뭔가 프리뷰 느낌이야").
      사진첩은 화면을 다 쓴다 → **사진이 끝에서 끝까지 차고, 버튼은 그 위에 뜬다.**
      한 번 톡 치면 버튼도 사라져서 사진만 남는다(.bare).
   ⚠ 흰 테두리를 안 두른다. 넘길 때마다 테두리가 크기를 바꾸며 덜컹거린다. */
#layer.photo{background:#050f1c; padding:0; align-items:stretch;}
/* ⚠⚠ **확대는 창 전체에서 막는다.** `touch-action:none` 을 아래 .pvstage 에만 걸어 뒀더니,
   그 위에 덮인 버튼 줄(.pvtop/.pvnav)은 `auto` 라 **거기서 시작한 두 손가락 확대를 브라우저가 가져갔다.**
   그러면 우리 그림이 아니라 **페이지 전체가 확대되고**, position:fixed 인 이 창이 화면 밖으로 밀려
   위쪽 절반만 남는다(사용자 2026-09-04: "악보 로드해보면 잘려서 나와, 위에 50%정도만" — 실측 재현).
   악보는 글씨가 작아 열자마자 확대하는 자리라 여기서만 유독 자주 걸렸다.
   ⚠ touch-action 은 상속되지 않는다 — **창 전체에 다시 걸어야** 버튼 줄까지 덮인다.
     탭·클릭은 touch-action 과 무관하므로 버튼은 그대로 눌린다. */
.pv{position:relative; width:100%; height:100%; overflow:hidden;}
/* ⚠⚠ **영상일 때는 풀어 준다.** touch-action 은 프레임 경계를 넘어 **안쪽까지** 묶는다 —
   `.pv` 에 none 을 걸었더니 드라이브 플레이어의 재생·구간 이동이 폰에서 통째로 안 먹었다
   (사용자 2026-09-04: "앨범에 동영상 플레이어 고장나있어", 실측 pv=none 확인).
   영상에서는 우리 확대·이동을 어차피 안 쓰니 막을 것도 없다. 사진·악보에서만 잠근다. */
.pv:not(.playing){touch-action:none;}
.pv:fullscreen{background:#050f1c;}
/* 버튼 줄은 사진 위에 뜬다. 밝은 사진에서도 읽히게 옅은 그늘을 깐다 */
.pvtop,.pvnav{position:absolute; left:0; right:0; z-index:2; display:flex; align-items:center; gap:8px;
  padding:10px 12px; transition:opacity .22s ease, transform .22s ease;
  /* 버튼 줄에서는 **영상일 때도** 잠근다 — 여기서 손가락을 벌릴 일은 없고, 확대가 새던 자리가 여기다 */
  touch-action:none;}
.pvtop{top:0; padding-top:calc(10px + var(--top-safe));
  background:linear-gradient(180deg,rgba(5,15,28,.72),rgba(5,15,28,0));}
.pvnav{bottom:0; padding-bottom:calc(10px + env(safe-area-inset-bottom));
  background:linear-gradient(0deg,rgba(5,15,28,.72),rgba(5,15,28,0));}
.pv.bare .pvtop{opacity:0; pointer-events:none; transform:translateY(-8px);}
.pv.bare .pvnav{opacity:0; pointer-events:none; transform:translateY(8px);}
.pvcount{font-family:var(--f-mono); font-size:12.5px; font-weight:600; color:#fff;
  background:rgba(7,31,54,.55); border-radius:999px; padding:5px 13px; margin-right:auto;
  font-variant-numeric:tabular-nums;}
.pvcount b{font-weight:800; font-size:14px;}
/* 악보를 한 권으로 볼 때 머리에 붙는 콘티 이름 (사진에는 안 붙는다) */
.pvcount i{display:inline-block; max-width:38vw; margin-right:8px; vertical-align:-1px;
  font-family:var(--f-body); font-style:normal; font-weight:800; font-size:11.5px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
/* 악보에서는 **지금 무슨 곡의 몇 쪽인가**가 제일 중요한 글자다. 사진 파일명과 같은 크기로 두지 않는다. */
.pv.paper .pvname{font-family:var(--f-disp); font-weight:900; font-size:13.5px; opacity:1;}
.pv .iconbtn{background:var(--card);}
/* 손가락 동작은 전부 우리가 받는다(touch-action:none) — 브라우저 기본 확대와 겹치면 둘 다 어긋난다 */
.pvstage{position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  overflow:hidden; cursor:zoom-in;}
/* ⭐⭐ 인스타그램식 넘기기 (76차) — 옆 사진을 화면 밖에 세워 두고 **트랙을 손가락만큼 옮긴다**.
   칸 하나가 화면 폭 그대로라 `±100%` 가 정확히 한 장이다(사진마다 폭이 달라도 어긋나지 않는다). */
.pvtrack{position:absolute; inset:0; will-change:transform;}
.pvtrack[hidden]{display:none;}
.pvslide{position:absolute; inset:0; display:flex; align-items:center; justify-content:center;}
.pvslide.l{transform:translateX(calc(-100% - 14px));}
.pvslide.r{transform:translateX(calc(100% + 14px));}
/* 프레임(영상)이 이 안에 들어 있다 → 잠글 땐 **조상 전부**를 풀어야 플레이어가 손가락을 받는다 */
.pv:not(.playing) .pvstage{touch-action:none;}
.pv.zoomed .pvstage{cursor:grab;}
.lightbox .pvstage img{border:0; border-radius:0; max-width:100%; max-height:100%; width:auto; height:auto;
  display:block; will-change:transform;}
/* 드라이브 플레이어. 16:9 로 자리를 잡되 화면을 넘지 않게 묶는다.
   ⚠ 프레임이 손가락을 먹으니 좌우로 밀어 넘기는 건 안 된다 → 아래 화살표 버튼으로 넘긴다.
      그래서 영상일 땐 버튼 줄을 감추지 않는다(.playing). */
/* ⚠⚠ **프레임을 16:9 로 못 박지 않는다.**
   그렇게 뒀더니 폰(375px)에서 높이가 **211px** 밖에 안 됐고, 드라이브 플레이어는 그 안에
   영상 + 타임라인 + 배속 메뉴를 전부 넣으려다 **UI 가 잘리고, 타임라인이 위로 올라가고,
   영상이 잘못 줌된 것처럼** 보였다(사용자 2026-09-04, 실측 375x211).
   플레이어는 **자기 상자 안에서 스스로 레터박스**를 잡는다 — 그러니 넓게 주고 맡기면 된다.
   우리 버튼 줄 사이를 통째로 내준다: 위아래가 겹치지 않고, 메뉴를 펼칠 높이도 생긴다. */
/* 프레임 크기는 **JS 가 정한다**(`fitFrame`) — 영상마다 비율이 다르기 때문이다. 여기서는 모양만 잡는다.
   ⚠⚠ 드라이브 플레이어는 자기 상자를 **꽉 채우며 잘라낸다**(레터박스가 아니다, 실측).
     그래서 상자 비율이 영상 비율과 다르면 **"잘못 줌된 것처럼" 잘려 보인다**
     (사용자 2026-09-04). 16:9 로 못 박아 두면 세로 영상이 잘리고, 세로로 늘리면 가로 영상이 잘린다.
     → 썸네일의 실제 크기에서 비율을 읽어 그 모양대로 준다.
   ⚠ 프레임은 대체 요소라 left/right 를 잡아 줘도 안 늘어난다(`width:auto` 가 고유 300x150 으로 굳는다).
     폭·높이를 직접 넣어야 한다. */
.pvstage iframe{border:0; border-radius:var(--r-s); background:#000; display:block; max-width:100%;}
/* ⚠⚠ `hidden` 은 **작성자 규칙에 진다.** 바로 위에서 프레임에 display:block 을 줬기 때문에
   숨긴 프레임이 스테이지(flex) 안에서 자리를 그대로 차지했고, 옆에 선 사진이 화면 밖으로 밀렸다
   (실측: 375px 화면에서 사진이 x=-187.5, 딱 절반이 잘렸다). 50차에 프레임을 넣은 뒤로 그랬다.
   숨김을 `hidden` 으로 하는 요소에 display 를 주면 **그 짝이 되는 [hidden] 규칙도 같이** 둘 것. */
.pvstage iframe[hidden]{display:none;}
.pv.playing .pvnav, .pv.playing .pvtop{opacity:1 !important; pointer-events:auto !important; transform:none !important;}
/* 넘어갈 때 살짝 밀려 들어온다. 큰 그림이 도착하기 전 빈 칸이 덜 허전하다.
   ⚠ 확대·이동은 인라인 transform 이 맡는다 → 등장 애니메이션은 **opacity 만** 건드린다.
      여기서 transform 을 쓰면 확대한 배율이 매번 초기화된다. */
.pvstage img.in{animation:pvin .24s ease;}
/* ⚠ 아래 `blank`(받는 중 감추기)는 **가운데 사진에만** 걸어야 한다 — 옆 사진까지 숨기면
   손가락을 따라 들어오는 그 장이 빈 화면으로 보인다. */
/* 받는 동안 = 반쯤 칠해진 그림을 숨긴다. 느릴 때만(.waiting) 글자를 띄운다. */
.pv.blank .pvstage img:not(.pvside){visibility:hidden;}
.pvwait, .pvfail{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  color:#fff; font-size:12.5px; font-weight:700; letter-spacing:-.2px; opacity:.85;
  padding:8px 14px; border-radius:999px; background:rgba(7,31,54,.55); white-space:nowrap; display:none;}
.pv.waiting .pvwait{display:block;}
.pv.failed .pvfail{display:block;}
.pv.failed .pvwait{display:none;}
@keyframes pvin{from{opacity:0;} to{opacity:1;}}
.pvbtn{flex:none; width:52px; height:44px; display:grid; place-items:center; cursor:pointer;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:999px; box-shadow:var(--sh-sm);
  color:var(--ink);}
.pvbtn:active{transform:translateY(2px); box-shadow:0 0 0 var(--ink);}
.pvbtn .ic{width:22px; height:22px;}
.pvname{flex:1; min-width:0; text-align:center; color:#fff; font-size:11px; font-weight:600;
  opacity:.8; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
/* 사진을 더 불러오는 자리 표시 */
.dvmore{text-align:center; color:var(--faint); font-size:12px; font-weight:600; padding:18px 0 4px;}

/* ── 관리자 ──────────────────────────────── */
.mgcard{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-l);
  padding:16px 18px; box-shadow:var(--sh-sm); margin-bottom:16px;}
.mgcard>h3{font-family:var(--f-disp); font-weight:900; font-size:17px; margin:0 0 4px;
  display:flex; align-items:center; gap:9px;}
.mgcard>h3 .hic{width:34px; height:34px; flex:none; transform:rotate(-4deg);}   /* 그림 아이콘(2026-09-16). 예전 라일락 네모 타일 */
.mgcard>.hint{font-size:12px; font-weight:500; color:var(--ink2); margin:2px 0 12px; line-height:1.6;}
.adminhero{display:flex; align-items:center; gap:11px; background:var(--lilac-soft);
  border:var(--bw) solid var(--ink); border-radius:var(--r-l); padding:13px 16px; margin-bottom:16px; box-shadow:var(--sh-sm);}
.adminhero .ic{color:var(--lilac);}
.adminhero b{color:var(--lilac);}
.adminhero .btn{margin-left:auto;}
/* 팀 명단 편집기 — 팀 하나가 한 덩어리로 읽혀야 어느 칸이 어느 팀 것인지 헷갈리지 않는다 (65차) */
.rteam{border:1.5px solid var(--line); border-radius:var(--r-m); padding:12px 13px 4px; margin-bottom:10px;
  background:var(--paper);}
.rteam .fieldrow{align-items:flex-end;}
.rteam .fieldrow>.iconbtn{margin-bottom:12px; flex:none;}
.rteam .rtname{font-weight:800;}
/* 공지 고치기 시트의 '상단 고정' 체크 — 라벨과 네모가 한 줄에 붙어 있어야 누르기 쉽다 */
.nechk{display:flex; align-items:center; gap:7px; font-size:13px; font-weight:600;
  white-space:nowrap; margin-bottom:12px;}
.songedit{display:flex; flex-direction:column; gap:7px; margin-bottom:10px;}
.wsitem{display:flex; flex-direction:column; gap:4px;}
.wsnote{font-size:11.5px; font-weight:700; line-height:1.45; padding-left:3px; min-height:0;}
.wsnote.hit{color:var(--ink2);}
.wsnote.miss{color:var(--praise);}
.songedit input.t.miss{border-color:var(--praise);}
.songedit .row{display:flex; gap:7px; align-items:center; flex-wrap:wrap;}
/* 제목 칸이 주인공이다. 유튜브 링크는 제 줄로 내린다 —
   한 줄에 넷을 욱여넣으면 폰에서 제목 칸이 40px 로 찌그러져 뭘 쳤는지 안 보였다. */
.songedit input.t{flex:1 1 150px; width:auto; min-width:150px;}
.songedit input.y{flex:1 1 100%; width:auto; min-width:0;}
.songedit input.k{width:76px; font-family:var(--f-mono); text-align:center;}
.songedit input{font-size:16px; border:var(--bw) solid var(--ink); border-radius:11px; padding:8px 11px;
  background:var(--card); color:var(--ink); font-family:var(--f-body);}
.songedit input:focus{outline:0; box-shadow:0 0 0 3px var(--accent);}
/* 계절 고르기 = 색칩이 아니라 **그 계절 그림**. 네 장을 나란히 보고 고른다
   (색칩 네 개로는 "여름이랑 뭐가 다른데"를 답할 수가 없었다). */
.themepick{display:flex; gap:10px; flex-wrap:wrap;}
.themepick button{width:96px; height:64px; border-radius:14px; border:var(--bw) solid var(--ink);
  cursor:pointer; box-shadow:var(--sh-sm); position:relative; overflow:hidden; padding:0;
  background:var(--paper) center/cover no-repeat;
  display:flex; align-items:flex-end; justify-content:center;}
.themepick button span{width:100%; padding:3px 0 4px; font-size:10.5px; font-weight:800;
  color:var(--ink); background:rgba(255,255,255,.86);}
.themepick button.on{box-shadow:0 3px 0 var(--ink); border-width:3px;}
.themepick button.on span{background:var(--ink); color:var(--on-ink);}

/* ── 로드 모션 (transform/opacity만) ─────────
   ⚠ 카드가 **딱 멈추면** 기계 같다. 끝에서 3px 지나쳤다가 제자리로 오면 종이가 툭 놓이는 느낌이 난다
     (사용자: "좀 더 귀엽고 발랄하고 청량한 느낌"). 튐은 이 한 번뿐이다. 계속 흔들면 그건 장난감이다.
   ⚠ 기울어 붙인 카드(앨범·오늘 큐카드)는 **제 각도를 지키면서** 올라와야 한다.
     `transform:none` 으로 끝내면 마지막 프레임에 각도가 툭 돌아온다 → --tilt 를 키프레임 안에 넣는다. */
/* 등장 = **미끄러져 들어오기**. 조금 아래·조금 작게 시작해 제자리로 미끄러져 멎는다. 튀지 않는다.
   ⚠ 기울여 붙인 카드는 각도를 **모든 키프레임에서** 지켜야 한다(riseTilt).
     `transform:none` 으로 끝내면 마지막 프레임에 각도가 툭 돌아온다. */
.svrow,.setcard,.notice,.req,.res{animation:rise .62s var(--e-glide) backwards;}
.qcard,.albumcard{animation:riseTilt .64s var(--e-glide) backwards;}
/* ⚠ 차례로 오는 간격을 **아홉 번째에서 끊는다**. 자료실처럼 열네 줄이면 마지막 줄이 1.5초 뒤에나 온다. */
.qcard,.albumcard{animation-delay:calc(min(var(--i,0), 9) * 60ms);}
.svrow,.notice,.req,.res{animation-delay:calc(min(var(--i,0), 9) * 52ms);}
/* 살짝 아래에서 떠오르며 밝아진다. 크기는 안 건드린다 — scale 이 조금만 들어가도 "튀어나온다"로 읽힌다 */
@keyframes rise{
  from{opacity:0; transform:translateY(18px);}
  to{opacity:1; transform:none;}
}
@keyframes riseTilt{
  from{opacity:0; transform:translateY(18px) rotate(var(--tilt,0deg));}
  to{opacity:1; transform:rotate(var(--tilt,0deg));}
}
/* 탭 전환.
   ⚠ 예전엔 화면 전체가 통째로 **위로** 떠올랐다. 어느 탭으로 가든 같은 방향이라
      "갈아 끼웠다"로만 읽히고 앞뒤 관계가 안 보였다(사용자: "페이지 넘길 때 좀 딱딱해").
   지금은 **탭바 순서대로** 온다. 오른쪽 탭으로 가면 오른쪽에서 밀려 들어오고, 왼쪽이면 왼쪽에서.
   탭이 아닌 이동(상세·문서)은 예전처럼 위에서 내려온다.
   ⚠ transform·opacity 만 쓴다. 높이·여백을 애니메이션하면 매 프레임 레이아웃을 다시 잰다.
   ⚠ 옆으로 미는 동안 가로 스크롤이 생기면 안 된다 → 본문을 감싸 잘라 둔다(overflow-x:clip).
      clip 은 스크롤 컨테이너를 안 만들어서 상단바의 sticky 가 그대로 산다(hidden 이면 깨진다). */
body{overflow-x:clip;}
.view.vin{animation:viewin .5s var(--e-glide) backwards;}
.view.vin[data-dir="r"]{animation-name:viewslideR;}
.view.vin[data-dir="l"]{animation-name:viewslideL;}
.fadein{animation:viewin .44s var(--e-glide) backwards;}
@keyframes viewin{from{transform:translateY(18px); opacity:0;} to{transform:none; opacity:1;}}
@keyframes viewslideR{from{transform:translateX(40px); opacity:0;} to{transform:none; opacity:1;}}
@keyframes viewslideL{from{transform:translateX(-40px); opacity:0;} to{transform:none; opacity:1;}}
/* 제목 밑 물결이 왼쪽에서 그어진다. 화면마다 한 번, 짧게. 이 앱에서 "청량"은 여기서 난다 */
.view.vin .sec>h2::after, .view.vin .secrow h2::after{
  animation:squig .66s var(--e-glide) .08s backwards;}
@keyframes squig{from{transform:scaleX(0);} to{transform:scaleX(1);}}
/* 누르면 잉크 단 위로 내려앉는다. **찌그러뜨리지 않는다** — 스쿼시는 42차에 뺐다(사용자 요청).
   떼는 순간만 짧게 되돌려 딱딱하지 않게 한다. */
.btn,.fchip,.iconbtn,.res,.secrow .more,.pvbtn,.pdfbtn,.pdfzoom,.mbtn,.chan,.sdh,.adminBtn,.ytbtn,
.plnav,.albumcard,.tabbar a{transition:transform .16s var(--e-snap), box-shadow .14s ease;}

@media (prefers-reduced-motion:reduce){
  *{animation:none !important; transition:none !important;}
}

/* ── 데스크톱 ────────────────────────────── */

/* ── 찬양팀 A·B ─────────────────────────────
   같은 코랄 가족(찬양 = 코랄이라는 IA 유지)에, 글자 배지로 갈라 본다.
   A = 채운 배지 / B = 테두리 배지 — 섬김표의 "메인=채움, 보조=테두리"와 같은 문법. */
.teamcard.praise-a::before{background:var(--praise-fill);}
.teamcard.praise-b::before{background:var(--praise2-fill);}
.teamcard.praise-a .thead{background:var(--praise-soft);}
.teamcard.praise-b .thead{background:var(--praise2-soft);}
.teamcard.praise-a .tname{color:var(--praise);}
.teamcard.praise-b .tname{color:var(--praise2);}

.tletter{flex:none; width:30px; height:30px; display:inline-flex; align-items:center; justify-content:center;
  font-family:var(--f-mono); font-weight:600; font-size:16px; line-height:1; border-radius:10px;
  border:var(--bw) solid var(--ink); box-shadow:var(--sh-sm); transform:rotate(-3deg);}
.teamcard.praise-a .tletter{background:var(--praise-fill); color:#fff;}
.teamcard.praise-b .tletter{background:var(--praise2-fill); color:#fff;}
.tnext{font-size:10.5px; font-weight:800; color:var(--ink); background:var(--card);
  border:1.5px solid var(--ink); border-radius:999px; padding:3.5px 9px; transform:rotate(1.4deg); white-space:nowrap;}
/* 알약 안 이름표(«다음 섬김»). 값보다 옅게, 그래도 읽히게 */
.tnext i{font-style:normal; font-weight:700; color:var(--ink2); margin-right:4px;}
/* 좁은 폰(360)에서는 한 줄에 안 들어간다 → 알약만 아랫줄로 내린다(인원 수 «11명» 이 쪼개지지 않게) */
@media (max-width:379px){
  .teamcard .thead:has(.tnext){flex-wrap:wrap; row-gap:6px;}
  .teamcard .thead:has(.tnext)::after{content:''; order:3; flex-basis:100%; height:0;}
  .teamcard .thead .tname, .teamcard .thead .tcount{white-space:nowrap;}
  .teamcard .thead .tcount{order:2;}
  .teamcard .thead .tnext{order:4;}
}

/* 3단 = 리더 → 싱어 → 세션. 찬양팀의 실제 구조를 그대로 보이게 한다.
   파트 아이콘은 직접 그린 잉크 라인아트(public/icons/*.png, gen_role_icons.py). */











.rolei{width:22px; height:22px; flex:none; display:block; object-fit:contain;}
.rolei.thi{width:24px; height:24px; transform:rotate(-4deg);}

/* ── 프로필 카드 (이름을 누르면) ─────────────
   옛 팀 탭 명찰을 그대로 키운 모양이다(같은 구멍 · 같은 잉크 2px · 같은 기울임). 명찰은 UX 130 에서 걷었고 이 카드만 남았다.
   새 모양을 하나 더 만들면 "어디서 온 창인지"를 다시 배워야 한다. */
/* ⚠⚠ 명찰 **몸통(바탕·테두리·그림자·기울임)은 `::before` 에** 그린다 (2026-09-16).
   예전엔 `.whocard` 자체를 기울였다. `transform` 은 그 요소를 **쌓임 맥락**으로 만들어서, 안쪽 글자와 바탕이
   한 덩어리가 된다 → 판 전체에 걸친 낙서를 «바탕 위·글자 아래» 에 끼워 넣을 수가 없었다.
   몸통을 `::before` 로 빼면 바탕(0) · 낙서(1) · 글자(2) 가 **판 하나의 맥락**에서 나란히 쌓인다.
   글자는 각자 같은 각도로 기울여서 예전 모양 그대로다(0.8도라 회전 중심 차이는 1px 도 안 된다). */
/* 안쪽 여백은 예전 값 + 테두리 두께. 테두리가 몸통(::before) 안쪽에 그려지니 그만큼 더해야 글자 자리가 그대로다 */
.whocard{position:relative; display:flex; align-items:center; gap:12px;
  padding:calc(14px + var(--bw)) calc(16px + var(--bw)) calc(14px + var(--bw)) 26px; margin:2px 2px 18px;}
.whocard::before{content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:var(--rcs,var(--card)); border:var(--bw) solid var(--ink); border-left:6px solid var(--rc,var(--ink));
  border-radius:var(--r-m); box-shadow:0 4px 0 var(--ink); transform:rotate(-.8deg);}
.whocard .hole{position:absolute; left:9px; top:50%; width:10px; height:10px; margin-top:-5px; z-index:1;
  border-radius:999px; background:var(--rc,var(--paper)); border:var(--bw) solid var(--ink);}
.whoi{width:46px; height:46px; flex:none; display:block; object-fit:contain; transform:rotate(2deg);}
.whot{min-width:0; transform:rotate(-.8deg);}
.whot b{display:block; font-family:var(--f-disp); font-weight:900; font-size:26px; letter-spacing:-.4px;
  line-height:1.15; color:var(--ink);}
.whot .whos{display:block; margin-top:3px; font-size:12.5px; font-weight:700; color:var(--ink2);}
.whot .whos i{font-style:normal; margin:0 6px; color:var(--rc,var(--faint));}
/* «나» 딱지는 흐름에서 뺀다(2026-09-16). 본인에게만 붙는 딱지가 자리를 차지하면 긴 이름이 본인 화면에서만
   두 줄로 접혀 명찰 높이가 사람마다 달라진다 → 붙인 스티커가 사람마다 다른 자리에 선다. */
.whome{position:absolute; top:10px; right:12px; transform:rotate(-.8deg);
  font-family:var(--f-disp); font-weight:900; font-size:12px; color:#fff;
  background:var(--praise-fill); border:var(--bw) solid var(--ink); border-radius:999px; padding:2px 10px 3px;}

/* 카드 뒷면 = 사실 목록. 줄 사이는 팀 탭 단 나누기와 같은 잉크 점선 */
.whorows{display:flex; flex-direction:column;}
.wrow{display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:12px 2px;
  border-top:2px dashed rgba(11,42,68,.18);}
.wrow:first-child{border-top:0;}
.wri{width:26px; height:26px; flex:none; display:block; object-fit:contain;}
/* 붙여 둔 한마디. 그림 아이콘이 없는 줄은 잉크 선으로 그린다 */
svg.wrp{fill:none; stroke:var(--ink2); stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  padding:2px; transform:rotate(-8deg);}
.wrk{font-size:11.5px; font-weight:800; color:var(--ink2); letter-spacing:.02em; min-width:30px;}
.wrv{font-size:15px; font-weight:800; color:var(--ink);}
.wrv.none{font-size:13px; font-weight:600; color:var(--faint);}
/* 프로필 사진 (68차). 아이콘 자리를 그대로 쓴다 — 카드 모양이 사진 유무로 달라지지 않게 */
.whofoot .linkbtn.del{color:var(--praise);}
.whofoot .linkbtn.off{color:var(--faint); text-decoration:none; cursor:default;}
.wrn{font-size:11px; font-weight:800; color:var(--praise); background:var(--praise-soft);
  border:1.5px solid var(--praise); border-radius:999px; padding:2px 9px;}
/* 소개는 한 줄이 넘어갈 수 있으니 줄을 통째로 쓴다 */
.wrow.bio{align-items:flex-start;}
.wrow.bio .wri, .wrow.bio .wrk{margin-top:2px;}
/* ⚠ 소개는 명조(--f-serif)였다 — 본인이 쓴 한 줄인데 **너무 진지하게** 읽혔다
   (사용자 70차: "자기소개 폰트 왜 이렇게 진지해. 다른 폰트들처럼 둥굴둥굴하게").
   가사책이 쓰는 둥근 글꼴로 바꾼다 — 이 앱에서 '사람 목소리'를 내는 자리는 다 이 글꼴이다. */
.wrb{margin:8px 0 0; font-family:var(--f-lyric); font-size:15.5px; font-weight:400;
  line-height:1.7; color:var(--ink);}

/* ⭐⭐ 소개 + 사진 = 미니홈피 배치 (71차, 사용자: "옛날 미니홈 같은 데 가면 왼쪽에 글, 오른쪽에 사진").
   사진을 `float:right` 로 띄우면 소개 글이 그 옆을 타고 흐르다 밑으로 이어진다 —
   상자 둘을 나란히 놓는 것과 다르다(한 줄짜리 소개가 사진 옆에서 혼자 붕 뜨지 않는다). */
.biobox{flex:1 1 100%; min-width:0;}
.biobox::after{content:''; display:block; clear:both;}
.biobox .wrb{margin-top:2px;}
.wpic{float:right; margin:2px 0 6px 13px; padding:0; cursor:pointer; position:relative;
  width:108px; height:108px; border:var(--bw) solid var(--ink); border-radius:14px;
  background:var(--paper); box-shadow:3px 3px 0 var(--ink); transform:rotate(1.2deg);
  overflow:hidden; display:block;}
.wpic img{display:block; width:100%; height:100%; object-fit:cover;}
.wpic:active{transform:rotate(1.2deg) translateY(2px); box-shadow:1px 1px 0 var(--ink);}
/* 여러 장이면 몇 장인지 알려 준다 — 안 알려 주면 아무도 눌러 보지 않는다 */
.wpicn{position:absolute; right:5px; bottom:5px; font-family:var(--f-disp); font-weight:900;
  font-size:11px; color:#fff; background:rgba(12,28,48,.72); border-radius:999px; padding:1px 8px;}

/* 사진 고르기 줄. 대표 한 장만 채운 테두리 — 섬김표의 "메인은 채움" 문법과 같다. */
.picstrip{display:flex; gap:14px; flex-wrap:wrap; margin-top:13px;}
.pth{position:relative; display:block; line-height:0;}
.pthb{padding:0; border:var(--bw) solid var(--faint); border-radius:11px; overflow:hidden;
  background:var(--paper); cursor:pointer; display:block;}
.pthb img{display:block; width:54px; height:54px; object-fit:cover; opacity:.72;}
.pth.on .pthb{border-color:var(--ink); box-shadow:2px 2px 0 var(--ink);}
.pth.on .pthb img{opacity:1;}
.pthx{position:absolute; right:-6px; top:-6px; width:22px; height:22px; padding:0; cursor:pointer;
  border:var(--bw) solid var(--ink); border-radius:999px; background:var(--paper); color:var(--praise);
  display:flex; align-items:center; justify-content:center;}
.pthx .ic{width:12px; height:12px; stroke-width:3;}
.picnote{margin:9px 0 0; font-size:11.5px; color:var(--ink2);}

/* ⚠ 밑줄 단추가 넘치면 글자 단위로 쪼개졌다(`overflow-wrap:anywhere` 전역 규칙) —
   `소개 / 고치기` 처럼 읽힌다. 줄바꿈은 허용하되 **단추 안에서는 안 쪼개다**. */
/* ⭐⭐ 카드 밑 단추 = **층 셋** (2026-09-12 다시 짬).
   사용자: "꾸미기랑 소개 고치기·사진 더 넣기 버튼이 왜 다른 건지 모르겠거든. 꾸미기가 더 특별하진 않잖아.
   사진 지우기는 아래로 밀리면서 왼쪽 끝으로 벌어져서 보기가 그렇고. 딱 봤을 때 밸런스 있게 놓여진 것 같아?"
   ⭐ 큰 단추 + 중간 단추 + 밑줄 글씨 넷이 한 줄에 섞여 있었다. **무게가 셋이면 «아무렇게나 놓였다»로 읽힌다.**
   ① (133-b 에 뺐다) 이게 나예요 단추
   ② 꾸미기·소개·사진 = 고치는 것 셋 (같은 크기 타일, 3열 격자)
   ③ 지우는 것 = 드물고 되돌릴 수 없다 (맨 아래 작은 글씨, 오른쪽에 모음)
   ⚠ 층 안에서는 **전부 같은 모양**이다. 한 층에 무게를 섞지 않는다. */
.whofoot{display:flex; flex-direction:column; gap:10px; margin-top:16px;}
/* 96차-i 원칙(옆에 맞출 짝이 없는 단추는 늘이지 않는다)은 «이게 나예요» 단추에서 나왔다. 그 단추는 133-b 에 뺐다.
   ⚠ 타일 셋(꾸미기·소개·사진)은 **같은 모양끼리 나란히**라 칸을 나눠 갖는 게 맞다. */
/* 같은 규칙, 관리자 «콘티 임시 수정」의 «곡 추가」. 세로로 쌓는 칸(.field) 안이라 폭을 통째로 먹었다(넓은 화면 880px, 96차-i 훑기) */
#wsAddSong{align-self:flex-start;}
/* 고치는 것 셋. 타일이 둘일 때도(리더가 남의 카드를 볼 때) 격자가 알아서 나눠 가진다 */
.wfacts{display:grid; grid-template-columns:repeat(auto-fit,minmax(0,1fr)); gap:8px;}
.wfact{display:flex; align-items:center; justify-content:center; gap:6px; cursor:pointer;
  font-family:var(--f-body); font-weight:800; font-size:12.5px; letter-spacing:-.2px; color:var(--ink);
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh-sm); padding:10px 8px; min-height:42px; text-align:center;
  transition:transform .08s ease, box-shadow .08s ease;}
.wfact .ic{width:15px; height:15px; flex:none;}
.wfact span{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.wfact:active{transform:translateY(2px); box-shadow:none;}
.wfact:hover{background:var(--accent-soft);}
/* 못 하는 것은 **단추처럼 안 보이게** 한다 — 눌리는 척하면 그게 고장으로 읽힌다(57차) */
.wfact.off{color:var(--faint); border-style:dashed; border-color:var(--faint);
  box-shadow:none; cursor:default; background:transparent;}
.wfact.off:hover{background:transparent;}
.wfdel{display:flex; justify-content:flex-end; gap:14px; flex-wrap:wrap;}
.whofoot .linkbtn{white-space:nowrap;}
.whohint{margin:11px 0 2px; font-size:11.5px; color:var(--ink2);}

/* 이제 이름은 어디서든 눌러서 프로필을 연다 — 찬양 크루 칩 · 방송·음향 배정 · 인도자 전부.
   ⚠ 밑줄·상자를 더하지 않는다. 이 화면에서 이름의 색·굵기·밑줄은 **이미 뜻이 있다**
      (색=역할 · 밑줄=메인 · 흐림=보조). 누를 수 있다는 티를 그 위에 덧그리면 그 뜻을 덮는다. */
.ptag[data-who], .nml{cursor:pointer;}
.ptag[data-who]:active, .nml:active{transform:translateY(1px);}

/* 팀 명단 시트 머리 — A·B 동그라미 · 인원 · 다음 섬김 */
.tsmeta{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0 0 14px;}
.tscount{font-family:var(--f-mono); font-weight:700; font-size:14px; color:var(--ink);}
.tscount .ko{font-family:var(--f-body); font-weight:800; font-size:11px; margin-left:1px;}
.tsnext{margin-left:auto; font-size:11.5px; font-weight:700; color:var(--ink2);
  background:var(--accent-soft); border:1.5px solid var(--accent); border-radius:999px; padding:3px 11px;}
.tsnext.none{background:none; border-color:var(--faint); color:var(--faint); font-weight:600;}
/* 누를 수 있는 A·B 동그라미 */
.teamchip.tap{cursor:pointer;}
.teamchip.tap:active{transform:translateY(1px);}

/* ── 가사 ────────────────────────────────── */
.lyrbox{margin-top:16px;}
.lyrload{font-size:12.5px; font-weight:600; color:var(--faint); padding:6px 0;}
.lyrhead{display:flex; align-items:center; gap:8px; margin-bottom:9px;}
.lyrhead .ic{width:17px; height:17px; color:var(--praise);}
.lyrhead b{font-family:var(--f-disp); font-weight:900; font-size:15px;}
.lyrhead .lyrdl{margin-left:auto;}   /* «다운로드»(2026-09-16, 예전 «ProPresenter용») */
/* 언어 탭 — **기본은 늘 `전체`**다. 한글/English 는 걸러 보는 것이지 다른 판본이 아니다. */
.lyrtabs{display:flex; gap:0; margin:0 0 9px; border:var(--bw) solid var(--ink);
  border-radius:999px; overflow:hidden; width:fit-content; box-shadow:var(--sh-sm);}
.lyrtabs button{border:0; background:var(--card); cursor:pointer; padding:6px 15px;
  font-family:var(--f-body); font-size:11.5px; font-weight:800; color:var(--ink2);}
.lyrtabs button + button{border-left:var(--bw) solid var(--ink);}
.lyrtabs button.on{background:var(--praise-fill); color:#fff;}
/* 곡이 무슨 언어인지 — 곡 줄과 가사 머리에 붙는 작은 칩 */
.lchip{flex:none; align-self:center; font-family:var(--f-body); font-size:9px; font-weight:800;
  letter-spacing:-.2px; padding:2px 6px; border-radius:999px; border:1.5px solid currentColor;
  white-space:nowrap;}
.lchip.ko{color:var(--bcast); background:var(--bcast-soft);}
.lchip.en{color:var(--sand); background:var(--sand-soft);}
.lchip.mix{color:var(--lilac); background:var(--lilac-soft);}
/* 콘티 줄에서는 딱지 줄(`.stags`) 안에 들어가니 자기 여백을 갖지 않는다 (72차) */
.songrow .lchip{margin:0;}
.songtable .srow .lchip{margin-left:7px;}
/* ⭐ «부른 적 없음» (102차-e). 시트 곡 목록에만 있고 2018년 콘티부터 한 번도 없는 곡. 예외 딱지라 색을 새로 안 쓴다:
   «없음» 은 점선 · 흐린 글자(`.sdchip.none` «라이브러리에 없는 곡» 과 같은 말). 한영 딱지(`.lchip`)와 같은 크기 */
.nschip{flex:none; align-self:center; font-family:var(--f-body); font-size:9px; font-weight:800; letter-spacing:-.2px;
  padding:2px 6px; border-radius:999px; border:1.5px dashed var(--faint); color:var(--ink2); background:transparent; white-space:nowrap;}
.songtable .srow .nschip{margin-left:7px;}
/* ⭐ 이름 옆 다른 언어 이름 «위대한 구원의 날 (Happy Day)» (102차-g). 곡 이름이지 딱지가 아니라 테두리 없이 흐린 글씨로 잇는다 */
.ensub{margin-left:5px; font-size:.86em; font-weight:600; color:var(--ink2); white-space:nowrap;}
.shhead h3 .ensub{font-size:.7em; font-weight:700;}
.hint .nschip{display:inline-block; vertical-align:1px; margin-right:1px;}
.sdhnote{margin:0 0 7px; font-size:12px; font-weight:600; color:var(--ink2);}
.lyrhead .lyrdl .ic{width:14px; height:14px; color:currentColor;}
/* 가사는 **줄바꿈이 곧 뜻**이라 pre 로 둔다. 다만 폭이 모자라면 어절 단위로 접는다.
   폰트는 나눔스퀘어라운드 — 획 끝이 둥글어 한 줄씩 훑어 내려갈 때 눈이 덜 걸린다.
   ⚠ 예전엔 나눔명조였다. 예뻤지만 **성경 본문처럼** 읽혀서 부르는 글로 안 보였다.
   글자를 키우고(14.5→15.5) 줄 사이도 벌렸다(1.85→1.95) — 한 손으로 들고 따라 부르는 거리다. */
.lyrbody{margin:0; padding:15px 16px; white-space:pre-wrap; word-break:keep-all;
  font-family:var(--f-lyric); font-size:15.5px; font-weight:400; line-height:1.95;
  letter-spacing:-.1px; color:var(--ink);
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh-sm); max-height:46vh; overflow:auto; overscroll-behavior:contain;}
/* ⭐ «크게 보기» 는 가사 상자 **안 오른쪽 아래**에 떠 있다 (2026-09-16, 사용자: *"누르기 쉽게 가사창 오른쪽 아래에 놔 줘. 상자 안에다"*).
   상자(`pre`)는 스크롤되고 단추는 그 밖 형제라 제자리에 있다. 마지막 줄이 단추에 안 가리게 상자 아래 안쪽을 띄운다.
   손가락으로 누르기 쉽게 44px 높이(`.btn` 기본 몸). */
.lyrwrap{position:relative;}
.lyrwrap .lyrbody{padding-bottom:66px;}
.lyrwrap .lyrbig{position:absolute; right:12px; bottom:12px; min-height:44px; z-index:1;}
/* 가사를 누가 고쳤나 (107차-b). «크게 보기» 가 쓰는 그 줄의 **빈 왼쪽**에 앉는다 — 새 줄을 만들지 않는다.
   ⚠ 손가락이 닿는 것이라 44px 을 지킨다. 「크게 보기」와 부딪히지 않게 오른쪽 끝을 그 단추 앞에서 멈춘다. */
.lyrwrap .lyrwho{position:absolute; left:12px; bottom:12px; z-index:1; max-width:calc(100% - 150px);
  min-height:44px; display:flex; align-items:center; text-align:left; font-size:12px; color:var(--ink2);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
@media (max-width:399px){ .lyrwrap .lyrwho{font-size:11px; max-width:calc(100% - 132px);} }
/* 기록 창 */
.lglist{display:flex; flex-direction:column; gap:10px;}
.lglog{padding:10px 12px; background:var(--paper); border:1.5px solid var(--faint); border-radius:var(--r-s);}
.lglog .lgl{font-size:14px;}
.lglog .lgh{color:var(--ink2);}
.lglog .lgt{font-size:12px; color:var(--ink2); margin-top:2px;}
.lglog .btn{margin-top:8px;}
/* ⚠⚠ **글자가 16px 보다 작으면 iOS 사파리가 칸을 누를 때 화면을 확대한다.** 그리고 빠져나와도
   저절로 줄어들지 않아서 사용자가 손으로 축소해야 한다(70차 실측: 소개 쓰기에서 그랬다).
   입력칸 글자는 **어디서든 16px 아래로 내리지 말 것.** 좁아 보인다고 줄이면 그 대가가 이거다. */
.sheet textarea{width:100%; min-width:0; font-family:var(--f-body); font-size:16px; line-height:1.7;
  padding:11px 13px; border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  background:var(--card); color:var(--ink); resize:vertical;}
.hint code{font-family:var(--f-mono); font-size:11.5px; background:var(--accent-soft);
  border:1.5px solid var(--accent); border-radius:6px; padding:1px 6px;}

/* ── 곡 찾기 한 줄 — 제목=재생, 상세=정보 ───── */
.songtable .srow{align-items:center; flex-wrap:wrap; row-gap:8px; justify-content:flex-start;}
/* ⚠ (2026-09-16) 예전엔 `justify-content:flex-end` 로 아랫줄에 내려간 것들을 오른쪽에 모았다. 이제 오른쪽 넷이 한 봉지(`.srside`)이고
   봉지의 `margin-left:auto` 가 어느 줄에서든 오른쪽으로 민다. flex-end 를 남기면 봉지가 내려간 줄에서 **제목이 오른쪽으로 밀린다**(실측). */
/* ⭐⭐ 제목은 **필요한 만큼만 가져가고, 대신 안 줄어든다** (79차, `flex:1 0 auto`).
   · 예전(`min-width:0`)엔 제목이 먼저 찌그러져 `이 날은 주가 지으신 / 날` 로 접혔다 —
     오른쪽은 비어 있는데 제목만 좁은 칸에서 접히는 꼴이었다.
   · `min-width` 를 크게 박아 봤더니 이번엔 **짧은 제목 줄에서도 돋보기가 혼자 아랫줄로** 내려갔다(실측).
   지금은 짧은 제목이면 예전처럼 한 줄, 긴 제목이면 제목이 한 줄을 다 쓰고 나머지가 아래로 간다.
   ⚠ 아랫줄로 내려간 것들은 오른쪽에 모은다. 왼쪽에 흩어지면 새 목록처럼 읽힌다.
     (2026-09-16 부터는 `justify-content` 가 아니라 한 봉지 `.srside` 의 `margin-left:auto` 가 민다. 바로 위 주석) */
.songtable .srow .stitle{flex:0 0 auto; max-width:100%; font-size:13.5px;
  /* 121: 위아래 기존 줄 여백을 눌리는 영역으로 사용한다. 오른쪽 정보·담기는 따로 남긴다. */
  min-height:44px; margin-block:-6px;}
/* ⚠ 제목이 `flex-grow` 를 가지면 남는 자리를 **전부** 먹어 나머지가 늘 아랫줄로 간다(실측 200/201).
   제목은 제 폭만 쓰게 두고, 오른쪽 것들은 `margin-left:auto` 로 민다. */
.songtable .srow .tempo, .songtable .srow .rchip{margin-left:auto;}
/* ⭐ 제목이 두 줄로 접히던 진짜 이유는 **오른쪽 단추들이 자리를 먹어서**였다(실측 201줄 중 80줄).
   예전엔 좁은 화면에서 `상세` 글자를 접었는데, 아이콘만 남으니 돋보기가 «찾기» 로 읽혔다(2026-09-16 화면 점검).
   → 글자(«가사»)는 남기고 안쪽 여백만 줄인다. 넘치면 오른쪽 봉지(`.srside`)가 통째로 아랫줄로 간다. */
@media (max-width:460px){
  .songtable .srow{gap:7px;}
  /* 아이콘은 접고 글자(«가사»)만 남긴다. 390 폰 200줄 중 아랫줄로 내려가는 줄: 아이콘+글자 48 · 글자만 34 · 옛 아이콘만 24 (실측) */
  .songtable .srow .infobtn.wide{padding:0 9px; gap:3px;}
  .songtable .srow .infobtn.wide .ic{display:none;}
  .songtable .tempo{font-size:9.5px;}
}
.songtable .srow .tempo, .songtable .srow .key{flex:none;}
/* ⭐ 오른쪽 넷(템포·키·담기·상세)은 **한 봉지**다 (2026-09-16 화면 점검). 줄이 넘치면 넷이 같이 아랫줄 오른쪽으로 간다.
   예전엔 넷이 하나씩 줄을 넘어서 맨 끝 돋보기만 혼자 떨어졌다(390 폰 200줄 중 24줄 · 360 폰 59줄). 그 돋보기는 아래 곡의 단추처럼 읽혔다.
   간격은 줄과 같게(`gap:inherit`), 미는 힘(`margin-left:auto`)은 봉지가 갖는다. 템포·결단 칩의 auto 는 봉지 밖(«...외 N곡» 줄)에만 남는다. */
.songtable .srow .srside{display:flex; align-items:center; gap:inherit; margin-left:auto; flex:none;}
.songtable .srow .srside .tempo, .songtable .srow .srside .rchip{margin-left:0;}
.infobtn.wide{width:auto; height:32px; padding:0 12px; gap:4px; border-radius:999px;
  font-family:var(--f-body); font-size:10.5px; font-weight:800; letter-spacing:-.2px;}
.infobtn.wide .ic{width:12px; height:12px;}
/* 콘티 곡 줄의 «악보»·«가사» 도 폰에서는 글자만(곡 찾기 줄과 같은 문법). 자리를 덜 먹어 제목이 덜 접힌다 */
@media (max-width:460px){
  .songrow .infobtn.wide{padding:0 9px; gap:3px;}
  .songrow .infobtn.wide .ic{display:none;}
}

/* ── 유튜브 박스 ────────────────────────────── */
.ytfoot{display:flex; border-top:var(--bw) solid var(--ink);}
.ytfoot .ytout{flex:1;}
.ytfoot .ytout + .ytout{border-left:var(--bw) solid var(--ink);}
.ytout.alt{color:var(--ink2);}
.ytwait{width:100%; height:100%; display:flex; align-items:center; justify-content:center; gap:9px;
  color:#fff; font-size:13px; font-weight:700; text-align:center; padding:0 18px;}
.ytwait.col{flex-direction:column; gap:7px;}
.ytwait .sub{font-size:11px; font-weight:600; opacity:.72;}
.ytwait .ic{width:16px; height:16px;}
.ytfoot button.ytout{border:0; cursor:pointer; font-family:var(--f-body);}
/* 임베드는 화면이 꺼지면 멈춘다(프리미엄이라도). 그 사실을 숨기지 말고 나갈 길과 같이 둔다. */
.ythint{margin:0; padding:9px 13px 11px; background:var(--card); border-top:var(--bw) solid var(--ink);
  font-size:11px; font-weight:600; line-height:1.55; color:var(--ink2);}
.ythint b{color:var(--ink);}
.ytframe > div{width:100%; height:100%; border:0; display:block;}

/* 재생목록 = 앱 안에서 끝까지 듣기. 영상 아래에 순서가 보이고, 눌러서 건너뛴다. */
.ytbox.pl .pllist{flex:1 1 auto;}
.plcount{font-family:var(--f-mono); font-weight:600; font-size:11px; flex:none;
  background:var(--card); border:1.5px solid var(--ink); border-radius:999px; padding:2px 9px;}
/* ⭐ 섞기·반복 (108차-d). 창 머리의 작은 두 단추 — 켜지면 잉크로 채운다(«지금 켜져 있다»가 한눈에).
   ⚠ 닫기(`.iconbtn` 34px)보다 한 치수 작게 둔다. 이건 듣는 방식이고 닫기는 창을 끄는 것이라 무게가 다르다. */
.plmode{width:30px; height:30px; flex:none; border-radius:10px; cursor:pointer;
  background:var(--card); border:var(--bw) solid var(--ink); box-shadow:var(--sh-sm);
  display:inline-flex; align-items:center; justify-content:center; color:var(--ink);}
.plmode .ic{width:15px; height:15px;}
.plmode:active{transform:translateY(2px); box-shadow:none;}
.plmode.on{background:var(--ink); color:var(--on-ink);}
.plbar{display:flex; align-items:center; gap:9px; padding:9px 12px;
  border-top:var(--bw) solid var(--ink); background:var(--praise-soft);}
.plnav{width:30px; height:30px; flex:none; border-radius:9px; cursor:pointer;
  background:var(--card); border:var(--bw) solid var(--ink); box-shadow:var(--sh-sm);
  display:inline-flex; align-items:center; justify-content:center; color:var(--ink);}
.plnav .ic{width:14px; height:14px;}
.plnav:active{transform:translateY(2px); box-shadow:none;}
.plnow{flex:1; min-width:0; font-size:13px; font-weight:800; text-align:center;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.pllist{min-height:0; overflow:auto; overscroll-behavior:contain; margin:0; padding:6px 0; list-style:none;
  background:var(--card); border-top:var(--bw) solid var(--ink);}
.plrow{display:flex; align-items:center; gap:9px; padding:9px 14px; cursor:pointer;
  font-size:13px; font-weight:600; color:var(--ink2);}
.plrow .no{font-family:var(--f-mono); font-size:10px; color:var(--faint); width:14px; flex:none; text-align:right;}
.plrow .t{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.plrow .ic.tiny{width:11px; height:11px; fill:currentColor; stroke:none; flex:none;}
.plrow:hover{background:var(--praise-soft);}
.plrow.on{color:var(--praise); font-weight:800; background:var(--praise-soft);}
/* ⭐ 듣는 곡 가사 (2026-09-17). «가사» 단추는 영상 바로 아래 줄, 가사는 그 밑에 펼쳐진다(재생목록이면 목록 자리를 빌린다).
   한 곡일 때도 같은 줄을 둔다. 단추는 글자만큼(짝 없는 단추를 늘이지 않는다), 자리는 재생목록 때와 같은 오른쪽. */
.plbar.solo{justify-content:flex-end;}
/* ⭐ «목록 | 가사» = **한 알약 안의 두 쪽** (108차-c). 사용자: *"가사 버튼 옆에 리스트 버튼을 추가해서 쉽게 토글해서."*
   둘은 같은 자리를 나눠 쓰는 두 화면이니 붙여서 하나로 보이게 한다 — 가사 창의 언어 탭(`.lbtabs`)과 같은 문법이다.
   ⚠ 글자만 둔다(아이콘 없이). 390 폰에서 이 줄은 [◀][지금 곡][목록|가사][▶] 인데, 아이콘까지 넣으면 **곡 이름 자리를 50px 먹는다.**
      알약 모양 자체가 «둘 중 하나» 를 말하니 아이콘이 없어도 안 헷갈린다. */
.plsw{display:flex; flex:none; border:var(--bw) solid var(--ink); border-radius:999px;
  overflow:hidden; box-shadow:var(--sh-sm);}
.plswb{border:0; background:var(--card); cursor:pointer; padding:6px 13px; line-height:normal;
  font-family:var(--f-body); font-size:12px; font-weight:800; color:var(--ink2);}
.plswb + .plswb{border-left:var(--bw) solid var(--ink);}
.plswb.on{background:var(--ink); color:var(--on-ink);}
.plbar .pllyr{flex:none; padding:5px 11px; font-size:12px; gap:5px;}
.plbar .pllyr .ic{width:13px; height:13px;}
.plbar .pllyr.on{background:var(--ink); border-color:var(--ink); color:var(--on-ink);}
.ytbox > .pllyrics{flex:1 1 auto; min-height:140px; overflow:auto; overscroll-behavior:contain;
  background:var(--card); border-top:var(--bw) solid var(--ink); padding:12px 15px 18px;}
.ytbox.lyron > .pllist{display:none;}
.pllyrics .pllyrtabs{margin:0 0 10px;}
.pllyrtext{margin:0; white-space:pre-wrap; word-break:keep-all; font-family:var(--f-lyric); font-size:15.5px;
  font-weight:400; line-height:1.9; letter-spacing:-.1px; color:var(--ink);}
.pllyrtext .lbsec{display:inline-block; font-family:var(--f-mono); font-size:.6em; font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; color:var(--faint); margin-top:.4em; line-height:1;}
.pllyrnone{padding:22px 6px; text-align:center; font-size:13px; font-weight:700; color:var(--ink2);}

/* 전체 재생 버튼 · 내 목록 줄 */
.btn.playall{margin-top:11px; font-size:12px; padding:7px 13px; background:var(--ink);
  border-color:var(--ink); color:var(--on-ink);}   /* 카드의 주 동작 하나만 채운다 (색 규율) */
.btn.playall .ic{width:13px; height:13px; fill:currentColor; stroke:none;}
.qsec .btn.playall{margin:0 0 0 auto; padding:5px 10px; font-size:11px;}
/* ⭐⭐ 콘티 뭉치의 단추 줄 — 전체 재생·가사·악보·결단찬양이 **한 줄에 다 선다** (93차-c, 사용자:
   *"가사랑 결단찬양이 같은 줄에 있었으면. 지금 너무 줄이 많아. 폰으로 한 화면에 다 잡혀야 돼"*).
   홈 큐카드와 **같은 작은 몸**을 쓴다 — `.setfoot` 의 큰 몸(12px · 7/13 패딩)이면 셋도 한 줄에 못 선다.
   ⚠ **이 규칙은 반드시 `.btn.playall` 보다 뒤에 있어야 한다.** 무게가 같아서(둘 다 클래스 둘) 순서로 갈린다.
     위쪽(`.contihd` 정의부)에 뒀더니 `margin-top:11px` 가 살아남아 **전체 재생만 11px 내려앉고**
     그 바람에 줄 높이가 42px 이 돼서 다른 단추가 늘어났다(실측 t=361.6 vs 350.6). 70차와 같은 병이다. */
.contihd .btn{margin:0; min-height:28px; padding:5px 9px; font-size:11px;}
.contihd .btn .ic{width:12px; height:12px;}
/* ⭐ 홈 큐카드의 단추 봉지 — 전체 재생 · 가사 · 결단찬양이 **같이** 움직인다.
   `margin-left:auto` 를 단추가 아니라 **봉지**가 가진다. 단추마다 걸면 줄이 갈릴 때
   앞 단추만 남고 뒤 단추가 다음 줄 **왼쪽 끝**으로 떨어져 짝이 흩어진다(2026-09-10 실측 390px).
   봉지 안은 오른쪽 정렬 + 자체 wrap 이라, 셋이 다 있어도 오른쪽 아래로 가지런히 접힌다. */
.leadbtns{margin-left:auto; display:flex; flex-wrap:wrap; justify-content:flex-end;
  align-items:center; gap:8px; row-gap:8px; min-width:0;}
.leadbtns:empty{display:none;}
.leadbtns > *{margin-left:0;}          /* 봉지 안에서는 각자 밀지 않는다 — 미는 건 봉지 하나뿐 */
.qsec .leadbtns .btn{margin:0; padding:5px 10px; font-size:11px;}
/* 가사(라일락)는 재생(붉은꽃)과 **다른 사람이 누르는 단추**다 — 색으로 갈라 둔 것을 홈에서도 지킨다 */
.qsec .leadbtns .btn.lyrbookbtn .ic{width:12px; height:12px;}
.qbar{display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-bottom:11px;}
.qbar .btn .ic{width:13px; height:13px;}
.qadd{flex:none; width:32px; height:32px; padding:0; border-radius:999px; cursor:pointer;
  background:var(--card); border:1.5px solid var(--faint); color:var(--ink2);
  display:inline-flex; align-items:center; justify-content:center;}
.qadd .ic{width:14px; height:14px;}
.qadd:hover{border-color:var(--ink); color:var(--ink);}
.qadd.on{background:var(--praise-fill); border-color:var(--ink); color:#fff;}

/* ── 시그니처 ④ · 풀 데크 밴드 ────────────────
   나가이 그림에서 물과 잔디를 가르는 건 수영장 가장자리의 납작한 색 띠다.
   카드 바닥에 같은 띠를 둘러서 카드가 물 위에 뜬 게 아니라 놓인 것처럼 보이게 한다. */
.card,.spot,.teamcard,.qcard,.mgcard,.bdcard{border-bottom:5px solid var(--deck);}

@media (min-width:900px){
  body{padding-bottom:30px;}
  .spothead{min-height:146px; padding-top:70px;}
  /* ⭐ 예배 커버는 넓은 화면에서도 폰과 같은 112px (96차-d).
     위의 146px 은 계절 그림을 보여 주려던 높이다(그림이 머리 위쪽 70px 을 차지했다). 커버는 글자 머리라 그 높이가 빈 하늘로 남았다.
     사용자(데스크톱 웹): *"오늘 섬김 배너가 너무 크다. 공백이 너무 많아 보인다. 브뚜·리허설은 흰 상자가 있어서 괜찮은데
     주일은 공백이 많아 보인다. 배너 자체도 불필요하게 크다."* 가로 744px 짜리 하늘에 214px 글자가 떠 있었다.
     → 높이를 112 로 내리고 잠금장치는 머리 안에서 한 단 키운다. 세 장의 상대 크기는 썸네일 비례 그대로
       (썸네일 가로 폭 SAEHAN XAPIS 1555 : BREAKTHROUGH 1040 : REHEARSAL 1098 ≈ 1.5 : 1 : 1.06). */
  .spot.svcover .spothead{min-height:112px;}
  .spot .svlock{height:58px;}
  .spot.sat .svlock{height:22px;}
  .spot.sun .svlock{height:23px;}
  .spot .svcap{height:10px; margin-top:8px;}
  .spot.sun .svcap{height:13px; margin-top:7px;}
  /* (96차-e 에 여기서 목록 줄 잠금장치를 키웠다. 96차-f 에 목록이 칸으로 나뉘어 카드가 폰 폭이 되면서 뺐다) */
  .tabbar{display:none;}
  .topbar{padding:18px 16px 14px;}
  .topbar .in{padding:8px 16px;}
  .bartip{width:124px; height:84px; margin:-20px 16px -20px auto;}   /* 넓은 화면은 우표도 한 치수 크게 */
  .bartip b{top:4px; font-size:11px;}
  /* ⭐⭐ 2026-09-12: **상단바는 하늘에 구멍을 내지 않는다.**
     이 바의 규칙은 이미 위에 적혀 있었다 — 시계도 로고도 «상자를 없애고 하늘 위에 그냥 얹었다».
     그런데 **켜진 탭만 흰 알약**이라 그 규칙을 혼자 어기고 있었다. 한 바 안에서 두 언어가 섞이면
     사람은 이유를 못 짚고 «뭔가 어색하다»고만 느낀다(사용자: *"메뉴바가 디자인적으로 아쉽다, 쌈박하게"*).
     → 켜진 탭 = **흰 글자 + 데크색 밑줄 3px.** 평평하고, 하늘을 안 가리고, 바 아래 수평선과 같은 색이다.
     ⚠ 바탕을 깔지 않으니 «켜짐」은 굵기와 밑줄로만 말한다. 색으로 말하지 않는다(색 규율).
     ⚠ 가운데 정렬 — 넓은 화면에서 왼쪽에 다 몰리고 오른쪽이 통째로 비어 있었다. */
  .deskNav{display:flex; gap:2px; margin:0 auto;}
  .deskNav a{position:relative; display:flex; align-items:center; gap:6px; text-decoration:none; white-space:nowrap;
    color:var(--ink); font-size:13.5px; font-weight:700; letter-spacing:-.2px;
    border-radius:9px; padding:7px 13px 8px; opacity:.72;
    transition:opacity .14s ease, background-color .14s ease;}
  .deskNav a .ic{width:16px; height:16px;}
  .deskNav a:hover{opacity:1; background:var(--paper);}
  .deskNav a.on{opacity:1; font-weight:800;}
  /* 밑줄은 글자 아래 한 줄, 계절 강조색(우표 테이프와 같은 색). 흰 카드 위라 바탕을 깔지 않아도 읽힌다 */
  .deskNav a.on::after{content:''; position:absolute; left:12px; right:12px; bottom:0; height:3px;
    border-radius:2px; background:var(--accent);}
  /* ⚠ 켜진 탭의 아이콘에 도메인 색을 칠하던 다섯 줄은 지웠다 (2026-09-12).
     흰 알약 위에서는 읽혔지만 하늘 위에서는 남색 아이콘이 배경에 먹힌다.
     그리고 색 규율상 도메인 색은 그 탭 **안에서만** 쓴다 — 상단바는 그 안이 아니다. */
  .view{padding:28px 20px 60px;}
  .rail{display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); align-items:stretch; overflow:visible; margin:0; padding:16px 0 6px;}
  .qcard{width:auto;}
  .albumgrid{grid-template-columns:repeat(3,1fr);}
  .photogrid{grid-template-columns:repeat(5,1fr);}
  .sheet{border-radius:var(--r-xl); align-self:center;}
  #layer{align-items:center;}
  .svrow{grid-template-columns:58px 1fr;}
  /* 팀 격자는 아래 95차-b · 96차-g 절에서 정한다(세 장 한 줄) */
  .docstage{height:calc(100vh - 110px); height:calc(100dvh - 110px);}
  body.docfull .docstage{height:calc(100vh - 49px); height:calc(100dvh - 49px);}
  .docbar{padding:10px 20px;}
  /* 119: 넓은 카드도 명단·콘티·안내문이 같은 세로선에서 시작한다. */
  .spot{--card-gut:20px;}
  
  .spot .ptiers{padding:11px var(--card-gut) 14px;}
  /* 달력은 7열이라 본문 폭(960)보다 넓다 — 섬김표 화면만 넓혀서 토요일이 잘리지 않게 */
  [data-view="plan"]{max-width:1200px;}

}
/* 폰을 가로로 눕히면(또는 낮은 창) 유튜브 창에 자리가 없다.
   영상은 더 낮추고, 안내문은 접는다. 목록은 남긴다(곡을 못 넘기면 창이 반쪽이 된다). */
@media (max-height:520px){
  .ytframe{max-height:38vh; max-height:38dvh;}
  .ythint{display:none;}
  .ytbox.pl .pllist{min-height:56px;}
}
@media (max-width:899px){
  
  .ytbox.pl .pllist{max-height:34vh; max-height:34dvh;}
  .monthbar{gap:9px;}
  .monthbar .mlabel{font-size:19px; min-width:132px; padding:7px 14px;}
  .pvtoggle{order:3; flex:1 0 100%; justify-content:center;}
  .spothead{padding:12px 14px;}
  .spotdate{font-size:20px;}
  .spotwhen{font-size:15.5px;}
}
/* ── 달력 = 한 화면에 한 달 (폰 · 태블릿 세로 · 좁은 창, 1000 아래) ──────────────────
   ⚠ 133차-c(2026-10-01)에 이 규칙을 폭과 상관없이 쓰게 했다(넓은 화면 본문이 720 한 기둥이라 큰 달력의 금 · 토가 칸 밖에 있었다).
   133차-h 일곱째 판(2026-10-03)에 되돌렸다. JH: "그 달력 뷰가 테블릿이나 데스크톱으로 이전엔 큼지막하게 나왔는데 이젠 그냥 핸드폰뷰랑 다르지 않게 나와".
   1000 이상(아이패드 가로 · 컴퓨터)은 섬김표 본문이 넓어서 칸마다 방송 · 음향을 펼친 큰 달력(`min-width:940px`)이 다시 들어간다(맨 끝 «화면마다 제 폭» 절).
   900~999 창은 본문이 940 보다 좁아 큰 달력이 옆으로 밀리니 이 달력을 쓴다. */
/* ⭐ 폰 달력 = **한 화면에 한 달**. 예전엔 min-width:940px 라 가로로 밀어야 했고
   토요일이 늘 화면 밖에 있었다(사용자: "한눈에 보이게").
   칸이 46px 밖에 안 되니 이름·시간·콘티 줄(.calfull)은 접고, 칸 배경색(예배 종류) +
   찬양 팀 글자 + 방송·음향 점만 남긴다. 자세한 건 **날을 누르면 시트로** 편다. */
@media (max-width:999px){
.calscroll{overflow-x:visible; padding:0; margin:0 -10px;}
table.hcal{min-width:0; border-spacing:3px;}
table.hcal th{font-size:12px; padding:5px 2px; border-radius:9px;}
table.hcal td{padding:4px 3px 4px; border-radius:10px; cursor:pointer;}
table.hcal td[data-cd]:active{transform:translateY(1px);}
table.hcal td .dt{font-size:14.5px;}
table.hcal td.out .dt,table.hcal td.wd .dt{font-size:13px;}
.hcal .calfull{display:none;}
/* 날짜와 A·B 칩을 **한 줄 양끝**에. 날짜만 있는 줄의 오른쪽 공백이 이 칸 최대의 낭비였다 */
.hcal .daytag{display:flex; align-items:center; justify-content:space-between; gap:2px;}
.hcal .daytag .teamchip{width:15px; height:15px; font-size:9px; border-width:1.5px; flex:none;}
/* ⚠ 날짜는 **왼쪽 위**. 예전엔 .daytag 가 예배 있는 날에만 있어서 금·토·일만 가운데,
   나머지는 왼쪽이라 줄이 어긋나 보였다(사용자 지적). 이제 모든 칸이 같은 규칙을 쓴다. */
.hcal .daytag{margin:0; padding:0; border-bottom:0; text-align:left; line-height:1;}
.hcal .daytag .svc,.hcal .todaytag{display:none;}
table.hcal td.today .dt{width:22px; height:22px; font-size:13px;}
.hcal .calmini{display:flex;}
/* ⭐ 폰 달력 칸 커버 (96차-f). 칸이 51×42px 라 잠금장치·띠가 안 들어간다 → **칸 바탕이 곧 커버**다.
   주일 = 그 하늘 사진, 브뚜·리허설 = 검정 + 안쪽 흰 선. 넓은 화면의 띠 규칙(여백·높이·밑선)은 여기서 되돌린다.
   ⚠ 검정 칸 위 글자는 흰색으로 뒤집는다(역할 색 이름은 검정 위에서 안 읽힌다). 하늘 칸은 잉크 그대로. */
.hcal td.svcover .daytag{margin:0; padding:0; min-height:0; border-bottom:0; border-radius:0; background:none !important;}
.hcal td.svcover .daytag::after{display:none;}
.hcal td.svcover .daytag .teamchip{display:inline-flex;}
.hcal .calcov{display:none;}
table.hcal td.svcover{position:relative;}
table.hcal td.svcover.col-fri, table.hcal td.svcover.col-sat{background:var(--cvbg);}
table.hcal td.svcover.col-sun{background:#86CDFE url("/svc/sky.webp") center top/cover no-repeat;}
/* ⚠ 안쪽 흰 선은 폰 칸에선 뺀다. 칸 여백이 3~4px 라 선이 날짜·이름·A·B 칩을 그대로 긋고 지나갔다(확대 실측). 검정 바탕만으로 커버다. */
.hcal td.svcover.col-sun .daytag .dt{color:var(--cvink);}
table.hcal td.svcover.col-sun.today .dt{background:var(--cvink); color:#fff;}
/* 폰 달력의 주일 칸은 칸 전체가 하늘 사진이라 밤에도 낮 글자색이다(흰 이름 바탕 위 역할색 · A·B 칩). 133차-h 아홉째 판.
   ⚠ 토큰을 이 칸 안에서만 낮 값으로 되깐다. --bcast 처럼 var() 로 정의된 토큰은 위에서 이미 풀린 값이 내려오니 이름마다 직접 준다 */
table.hcal td.svcover.col-sun{--ink:var(--cvink); --ink2:#2E5878; --faint:#4F687A; --on-ink:#fff;
  --bcast:#2E588A; --sound:#1D722E; --praise:#A8393C; --praise-soft:#F6DCDC;
  --sp-leaf-100:#DDF1E1; --sp-leaf-700:#1D722E; --dk-skytx:initial; --dk-leaftx:initial;}
.hcal td.svcover.col-fri .mnm, .hcal td.svcover.col-sat .mnm{color:#fff; box-shadow:none;}
.hcal td.svcover.col-fri .mnm.b, .hcal td.svcover.col-fri .mnm.s,
.hcal td.svcover.col-sat .mnm.b, .hcal td.svcover.col-sat .mnm.s{box-shadow:inset 0 -2px 0 rgba(255,255,255,.85);}
.hcal td.svcover.col-fri .mnm.sub, .hcal td.svcover.col-sat .mnm.sub{color:rgba(255,255,255,.72); box-shadow:none;}
.hcal td.svcover.col-fri .mnm.me, .hcal td.svcover.col-sat .mnm.me{color:var(--ink);}   /* 내 이름 칠(연분홍) 위는 잉크 */
.hcal td.svcover.col-fri .teamchip, .hcal td.svcover.col-sat .teamchip{border-color:#fff;}   /* B 칩(잉크)이 검정에 묻힌다 */
.calhint.wide{display:none;} .calhint.narrow{display:block; margin:8px 2px 0;}
}
/* 폰은 칸이 좁아 양옆 10px 을 더 쓴다. 넓으면 칸 끝을 위 카드 선에 맞춘다(칸 사이 3px 만큼만 내민다) */
@media (min-width:600px) and (max-width:999px){ .calscroll{margin:0 -3px;} }


/* ══ 2026-09-12 · 홈 두 기둥 · 파노라마 바닥 · 노션 바로 알림 카드 · 발 ═══════════════
   사용자: "전체적인 디자인을 보면 뭔가 미완성된, 공사 하다 만 건물을 보는 느낌. 뭔가 비어 보여."
   무엇이 비어 보였나(실측 1440px): 본문 960px 기둥 하나가 옅은 파랑 위에 서 있고 양옆이 빈 바다였다.
   바닥의 물가 그림은 30% 투명이라 있는 줄도 몰랐다. 폰(390px)은 카드가 꽉 차 있어 그 자체로는 괜찮았다.
   그래서 ① **넓은 화면에서만** 두 기둥으로 갈라 폭을 쓴다(왼쪽 = 무대: 오늘 섬김·이어지는 예배·일정 / 오른쪽 = 게시판:
   공지·보내는 길·채널·교회) ② 바닥 그림을 21:9 파노라마(GPT Image 2.5, `tools/gen_season_art.py` 와 같은 나가이 문법,
   원본 `tools/_sky_src/*-pano-src.png`)로 바꾸고 더 진하게 ③ 페이지에 발(footer)을 달아 끝을 만든다.
   ⚠ 폰 순서는 한 칸도 안 움직였다(71차 "시키지 않은 재배치 금지"). 기둥은 폰에서 `display:contents` 로 사라지고
      `order` 가 원래 순서(공지 → 오늘 섬김 → …)를 지킨다.
   ⚠ 파노라마는 폰에 안 깐다 — 390px 에 cover 로 넣으면 한가운데 빈 바다만 잘려 나온다. 폰은 오른쪽에 나무가 선 `-shore` 그대로. */
[data-view="home"]{display:flex; flex-direction:column;}
[data-view="home"] .bdsec{order:-2;}
[data-view="home"] .sec.sec-notice{order:-1; margin-top:10px;}
[data-view="home"] .sec.sec-duty{margin-top:34px;}
@media (min-width:1100px){
  .topbar .in, .syncbar, .hubfoot{max-width:1180px;}
  [data-view="home"]{max-width:1180px; display:grid; grid-template-columns:minmax(0,1fr) 356px;
    column-gap:36px; align-items:start;}
  [data-view="home"] .bdsec{grid-column:1 / -1;}
  [data-view="home"] .sec.sec-notice, [data-view="home"] .sec.sec-duty{margin-top:10px;}
  [data-view="home"] .rail{grid-template-columns:1fr 1fr; align-items:start;}   /* 카드는 제 키만큼. 늘려 맞추면 콘티 없는 카드 가운데가 빈다 */

}
/* 바닥 그림 — 넓은 화면은 장면 폭 그대로(왼쪽 소나무 줄까지), 폰은 교회가 선 오른쪽 조각.
   넓은 화면엔 탭바가 없어 바닥에 붙인다. 높이는 화면 높이의 60% 에서 멈추고, 그때 그림이 화면보다 좁아지면
   오른쪽(교회)에 붙이고 왼쪽 끝은 그림 안에서 흐려 둔 것이 받는다(2026-09-16). */
@media (min-width:900px){
  body::after{bottom:0; height:min(calc(100vw * .396), 60vh); opacity:.62;
    background:var(--scene) right bottom/auto 100% no-repeat;}
  body.tabhide::after{transform:none;}   /* 넓은 화면엔 탭바가 없다. 스크롤 표시만 붙어도 그림은 안 움직인다 */
}
/* 발. 맨 아래가 `정보 동기화` 알약 하나로 끝나서 페이지가 잘린 것처럼 보였다 */
.hubfoot{max-width:960px; margin:0 auto; padding:2px 16px 30px; text-align:center; display:flex; flex-direction:column; gap:2px;}
/* 폰: 끝까지 내리면 발 글자가 바닥 교회의 정면(출입문·벽돌 박공) 위에 겹쳐 둘 다 안 읽혔다(2026-09-16 실측).
   발 아래를 바닥 그림 높이의 절반만큼 비운다 → 끝까지 내리면 글자는 첨탑 쪽 하늘에, 정면은 온전히 보인다.
   넓은 화면은 교회가 오른쪽이라 가운데 발 글자와 안 겹친다. */
@media (max-width:899px){ .hubfoot{padding-bottom:calc(min(66vw, 420px, 60vh) * .5);} }
.hubfoot .hf1{font-family:var(--f-disp); font-weight:900; font-size:13.5px; letter-spacing:-.2px; color:var(--ink);}
/* ⚠ 발 글씨는 **늘 하늘 위에 선다**(바닥 교회 그림 자리다). 흐린 잉크(ink2)는 어느 시각에도 3.2~4.3:1 이라 진한 잉크로 통일했다
   (2026-09-18, 103차-b 실측. 한때 밤만 흰 글씨로 뒤집었는데, 하늘색을 그림에서 뽑은 뒤로는 잉크가 더 잘 읽힌다). */
.hubfoot .hf2{font-family:var(--f-latin); font-weight:500; font-size:10.5px; letter-spacing:.1em; color:var(--ink); text-transform:uppercase;}
/* 노션 바로 알림(웹훅) 상태 상자 — 관리자 «구글 시트에서 가져오기» 카드 안 */
.hookbox{margin-top:12px; padding:11px 13px; border:2px dashed var(--faint); border-radius:var(--r-m);
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:12.5px; font-weight:600; color:var(--ink2);
  background:rgba(255,255,255,.6);}
.hookbox.on{border-style:solid; border-color:var(--accent); background:var(--accent-soft);}   /* «켜짐» 도 상태색 하나 (색 규율) */
.hooklab{font-family:var(--f-disp); font-weight:900; font-size:13px; color:var(--ink);}
.hookst{font-size:10.5px; font-weight:800; border-radius:999px; padding:2px 9px; border:1.5px solid var(--faint); color:var(--ink2);}
.hookst.on{display:inline-flex; align-items:center; gap:4px; background:var(--ink); color:var(--on-ink); border-color:var(--ink);}
.hookst.on .ic{width:12px; height:12px;}
.hookstep{flex:1 0 100%; line-height:1.5;}
.hookcode{font-family:var(--f-mono); font-size:11.5px; background:var(--card); border:1.5px solid var(--faint);
  border-radius:8px; padding:4px 8px; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.hookago{font-size:11.5px; color:var(--faint); margin-left:auto;}
.hookbox .linkbtn{margin-left:auto;}

/* 캐시로 먼저 그렸다가 새 응답으로 조용히 갈아 끼울 때 (app.js rerenderQuiet). 떠오르는 등장은 한 번이면 된다 */
#view.noanim, #view.noanim *{animation:none !important;}

/* ── 62차: 정보 원본 안내줄 · 접힌 관리자 카드 · 카카오 알림 ── */
.srcnote{text-align:center; color:var(--ink); font-size:12px; margin:14px 0 0; text-wrap:balance;}
/* 접어 둔 카드(콘티 임시 수정). 열기 전에는 제목 한 줄만 — 원본이 아닌 도구를 크게 두지 않는다 */
details.mgcard.adv>summary{list-style:none; cursor:pointer; font-family:var(--f-disp); font-weight:900; font-size:17px;
  display:flex; align-items:center; gap:9px; flex-wrap:wrap;}
details.mgcard.adv>summary::-webkit-details-marker{display:none;}
details.mgcard.adv>summary .hic{width:34px; height:34px; flex:none; transform:rotate(-4deg);}
details.mgcard.adv>summary .advnote{font-family:var(--f-body); font-weight:500; font-size:12px; color:var(--ink2); flex-basis:100%;}
details.mgcard.adv[open]>summary{margin-bottom:4px;}
.kklist{display:flex; flex-direction:column;}
.kkrow{display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:9px 0; border-top:1.5px dashed var(--faint); font-size:13px;}
.kkrow:first-child{border-top:0; padding-top:2px;}
.kkrow .kkwho{font-weight:600;}
.kkrow .kkwhen{color:var(--faint); font-size:12px; margin-left:auto;}
.kkrow .kkwhen .bad{font-style:normal; color:var(--praise);}
.kkrow.dead .kkwho{color:var(--faint);}
.kkrow .kkwhen a{color:var(--praise); font-weight:800; text-decoration:underline; margin-left:6px;}

/* 62차 화면 점검: 카드 바닥의 방송·음향 줄을 아래에 붙여 옆 카드와 바닥이 맞게 */
.qcard .qsec.crew{margin-top:auto;}
/* 오늘 이미 끝난 예배 한 줄 (스포트라이트는 다음 예배로 넘어간다) */
/* 끝난 예배 한 줄 — 여기에 녹화 단추가 산다(82차). 글과 단추가 한 줄에 서게 flex 로 눕힌다. */
.spotdone{display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  font-size:12.5px; font-weight:600; color:var(--ink2); margin:0 0 10px;}
.spotdone .btn.recbtn{margin-left:auto;}
.spotdone a{color:var(--praise); font-weight:800; text-decoration:none;}

/* ── 62차 화면 점검: 가사 한 권 머리·구간 표식 ── */
.lb .pvcount{display:flex; flex-wrap:wrap; align-items:baseline; gap:6px 8px; max-width:calc(100% - 150px);}
.lb .lbtitle{display:block; width:100%; font-family:var(--f-disp); font-weight:900; font-size:17px; color:#fff;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lb .pvcount i{margin-right:0; vertical-align:0; font-size:12px;}
.lb .pvcount .lbn{font-size:12.5px;}
.lbnone{color:rgba(255,255,255,.7); font-family:var(--f-body); font-size:15px; text-align:center; padding-top:20vh; white-space:normal;}
/* 넘기기 단추 = 화살표 + 그쪽 곡 제목(작게) (2026-09-16). 두 단추가 양 끝에 서고, 제목이 길면 말줄임.
   ⚠ `.pvbtn` 은 52px 네모 격자라 여기서 폭·배치를 풀어 준다. 곡이 없는 쪽은 JS 가 visibility 로 감춘다(자리는 남는다) */
.lb .lbnav{justify-content:space-between;}
.lb .lbstep{width:auto; min-width:52px; max-width:calc(50% - 6px); display:flex; align-items:center; gap:5px;
  padding:0 14px 0 8px;}
.lb .lbstep.next{margin-left:auto; padding:0 8px 0 14px;}
.lb .lbstep .ic{flex:none; width:20px; height:20px;}
.lb .lbstept{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-family:var(--f-body); font-size:12px; font-weight:800; letter-spacing:-.2px; color:var(--ink);}
.lbnone .linkbtn{color:#fff; margin-top:10px;}
.lbtext .lbsec{display:inline-block; font-family:var(--f-mono); font-size:.6em; font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; color:rgba(255,255,255,.55); margin-top:.4em; line-height:1;}
.lbstage{scrollbar-width:none;}
.lbstage::-webkit-scrollbar{display:none;}
/* ⭐ 큰 화면에서 가사가 **왼쪽에 다 쏠려** 보였다 (72차-b, 사용자: 태블릿에서 확인).
   `.lbstage` 가 화면 폭을 다 쓰다 보니 글줄이 왼쪽 끝에만 붙고 오른쪽이 통째로 비었다.
   ⚠ 글자 자체를 가운데 정렬하지는 않는다 — 가사는 한 줄씩 눈으로 훑어 내려가는 글이라
     줄 시작이 들쭉날쭉하면 오히려 놓친다. **덩어리를 가운데로** 옮기고 줄은 왼쪽에 맞춘 채 둔다. */
@media (min-width:760px){
  .lbstage{padding-left:26px; padding-right:26px;}
  .lbstage > *{max-width:680px; margin-left:auto; margin-right:auto;}
  .lbtabs{margin-bottom:18px;}
  /* ⚠ 덩어리를 가운데로 옮기는 것만으로는 모자란다 — 가사 줄은 짧아서
     680px 칸 안에서 **여전히 왼쪽에만 붙어 있었다**(실측). 큰 화면에서는 줄 자체를 가운데로 둔다
     — 가사는 원래 무대에 가운데 정렬로 띄우는 글이다(프로프레젠터도 그렇다).
     폰은 줄이 화면 폭을 거의 채워서 그대로 둔다(왼쪽 정렬). */
  .lbtext{text-align:center;}
}
.mehint{margin:0 0 12px; font-size:12.5px;}

/* ── 연락처 · 생년월일 (리더 전용, 84차) ───────────────
   ⚠ 이 화면은 **리더만** 본다. 그래서 "리더만" 표시를 두 곳에 남긴다 —
     들어오는 문(팀 탭)과 나가는 발(안내문). 보는 사람이 그걸 모르면 스샷을 찍어 카톡에 올린다.
   ⚠ 새 부품을 안 만든다: 검색은 `.searchbar`, 문은 `.mecue`, 칩은 `.cttel` 하나뿐이다. */

/* 로그인 전 — 못 여는 문을 정직하게 보여 준다(빈 화면보다 낫다) */
.ctlock{display:flex; flex-direction:column; align-items:center; gap:12px; text-align:center; padding:26px 18px;}
.ctlock .hic{width:52px; height:52px; transform:rotate(-4deg);}   /* 그림 아이콘(2026-09-16). 예전 모래색 네모 타일 */
.ctlock p{margin:0; font-size:13.5px; font-weight:600; color:var(--ink2); line-height:1.65;}

/* 팀별 묶음. 머리 왼쪽 색 기둥 = 섬김표 목록과 같은 문법(29차) */
.ctgrp{background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
  box-shadow:var(--sh-sm); margin-bottom:14px; overflow:hidden;}
.ctgh{display:flex; align-items:baseline; gap:9px; padding:9px 13px;
  background:var(--sand-soft); box-shadow:inset 4px 0 0 var(--sand);
  border-bottom:var(--bw) solid var(--ink);}
.ctgh b{font-family:var(--f-disp); font-weight:900; font-size:16px; color:var(--ink);}
.ctgh span{font-size:11px; font-weight:700; color:var(--ink2);}
.ctgrp.praise-a .ctgh{background:var(--praise-soft); box-shadow:inset 4px 0 0 var(--praise);}
.ctgrp.praise-b .ctgh{background:var(--praise2-soft); box-shadow:inset 4px 0 0 var(--praise2);}
.ctgrp.bcast   .ctgh{background:var(--bcast-soft); box-shadow:inset 4px 0 0 var(--bcast);}
.ctgrp.sound   .ctgh{background:var(--sound-soft); box-shadow:inset 4px 0 0 var(--sound);}

/* ⚠ 폰에서는 이름이 한 줄을 통째로 갖는다. 이름·생일·번호 셋을 390px 한 줄에 밀어 넣으면
   번호가 반드시 접혀서 어느 사람 것인지 흐려진다(78·79차 곡 제목에서 배운 것). */
.ctrow{display:flex; align-items:center; gap:7px 10px; flex-wrap:wrap; padding:11px 13px;
  border-top:2px dashed rgba(11,42,68,.16);}
.ctrow:first-of-type{border-top:0;}
.ctwho{flex:1 1 100%; display:flex; align-items:baseline; gap:7px; min-width:0;
  background:none; border:0; padding:0; cursor:pointer; text-align:left; color:var(--ink);}
.ctwho b{font-family:var(--f-disp); font-weight:900; font-size:16px;}
.cttag{font-size:11px; font-weight:700; color:var(--ink2);}
.ctbd{font-family:var(--f-mono); font-size:12.5px; font-weight:600; color:var(--ink2);
  display:inline-flex; align-items:center; gap:6px;}
.ctbd i{font-style:normal; font-family:var(--f-body); font-size:10.5px; font-weight:800;
  color:var(--sand); background:var(--sand-soft); border:1.5px solid var(--sand);
  border-radius:999px; padding:1px 7px;}
.ctbd .none, .cttel.none{font-family:var(--f-body); font-size:11.5px; font-weight:600; color:var(--faint);}
.ctacts{margin-left:auto; display:inline-flex; align-items:center; gap:6px;}
.cttel{display:inline-flex; align-items:center; gap:6px; text-decoration:none;
  font-family:var(--f-mono); font-size:12.5px; font-weight:700; color:var(--sound);
  background:var(--sound-soft); border:var(--bw) solid var(--sound); border-radius:999px;
  padding:4px 11px; box-shadow:var(--sh-sm);}
.cttel .ic{width:13px; height:13px;}
.cttel:active{transform:translateY(2px); box-shadow:none;}
.cttel.none{margin-left:auto; background:none; border:0; box-shadow:none; padding:0; color:var(--faint);}
.ctcopy{width:30px; height:30px;}
.ctcopy .ic{width:15px; height:15px;}
.ctnote{display:flex; align-items:flex-start; gap:9px; margin:16px 0 0; padding:11px 13px;
  border:var(--bw) dashed var(--ink); border-radius:var(--r-m); background:var(--card);
  font-size:11.5px; font-weight:600; color:var(--ink2); line-height:1.65;}
.ctnote .ic{width:16px; height:16px; flex:none; margin-top:2px; color:var(--sand);}

/* 팀 탭의 문 — `.mecue` 를 그대로 쓰고 색만 모래(팀 색) */
.mecue.lead{padding:0; border-style:solid;}
.mecue.lead .ic{color:var(--sand);}
.ctopen{display:flex; align-items:center; gap:9px; width:100%; padding:11px 13px;
  background:none; border:0; cursor:pointer; text-align:left;
  font-family:var(--f-body); font-size:12px; font-weight:600; color:var(--ink2); line-height:1.6;}
.ctopen b{color:var(--ink);}
.ctopen .go{width:15px; height:15px; margin-left:auto; flex:none; color:var(--faint);}
.ctopen:active{transform:translateY(1px);}

/* 프로필 카드 — 나이 칩과 "리더만" 표시 */
.wrage{font-size:11px; font-weight:800; color:var(--sand); background:var(--sand-soft);
  border:1.5px solid var(--sand); border-radius:999px; padding:2px 9px;}
.wrow.lead .cttel{margin:0;}




/* 넓은 화면에서는 한 줄에 다 선다. 폰에서만 이름이 줄을 통째로 갖는 것이지,
   960px 칸에서까지 이름 한 줄 · 나머지 한 줄로 두면 그게 23차에 지적받은 "칸 안의 공백"이다. */
@media (min-width:620px){
  .ctwho{flex:0 0 auto; min-width:150px;}
  .ctbd{margin-left:4px;}
}

/* ── 사용 기록 (리더 전용, 85차) ─────────────────────
   ⚠ 이 화면의 존재 이유는 "망해 가는 걸 일찍 아는 것"이다. 그래서 **숫자를 예쁘게 꾸미지 않는다** —
     막대는 잉크 한 색이고, 색이 갈리는 곳은 판정 줄 하나뿐이다. */

/* 판정 한 줄. 좋을 때만 초록이고, 조용하면 조용하다고 말한다 */
.stverdict{display:flex; flex-direction:column; gap:5px; padding:14px 16px; margin-bottom:14px;
  border:var(--bw) solid var(--ink); border-radius:var(--r-m); background:var(--card);
  box-shadow:var(--sh-sm);}
.stverdict b{font-family:var(--f-disp); font-weight:900; font-size:19px; color:var(--ink);}
.stverdict span{font-size:12.5px; font-weight:600; color:var(--ink2); line-height:1.65;}
.stverdict.good{background:var(--sound-soft); box-shadow:inset 5px 0 0 var(--sound), var(--sh-sm);}
.stverdict.ok  {background:var(--bcast-soft); box-shadow:inset 5px 0 0 var(--bcast), var(--sh-sm);}
.stverdict.warn{background:var(--praise-soft); box-shadow:inset 5px 0 0 var(--praise), var(--sh-sm);}
.stverdict.new {background:var(--sand-soft);  box-shadow:inset 5px 0 0 var(--sand),  var(--sh-sm);}

.stcards{display:grid; grid-template-columns:repeat(3,1fr); gap:9px; margin-bottom:14px;}
.stcard{display:flex; flex-direction:column; gap:2px; padding:11px 10px; text-align:center;
  border:var(--bw) solid var(--ink); border-radius:var(--r-m); background:var(--card); box-shadow:var(--sh-sm);}
.stcard .sthd{font-size:10.5px; font-weight:800; color:var(--ink2); line-height:1.3;}
.stcard b{font-family:var(--f-disp); font-weight:900; font-size:27px; color:var(--ink); line-height:1.15;}
.stcard b i{font-style:normal; font-family:var(--f-body); font-size:12px; font-weight:800; margin-left:2px;}
.stcard .stsub{font-size:10px; font-weight:600; color:var(--faint); line-height:1.35;}
/* ⭐ 가운데가 이 화면의 주인공이다 — 방문 수가 아니라 **다시 오는 사람** */
.stcard.hero{background:var(--lilac-soft); border-width:3px;}
.stcard.hero b{color:var(--lilac);}

.stbox{border:var(--bw) solid var(--ink); border-radius:var(--r-m); background:var(--card);
  box-shadow:var(--sh-sm); padding:13px 15px; margin-bottom:14px;}
.stbh{display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; margin-bottom:11px;}
.stbh b{font-family:var(--f-disp); font-weight:900; font-size:16px; color:var(--ink);}
.stbh span{font-size:11px; font-weight:700; color:var(--faint);}

/* 날짜 막대 — 빈 날도 자리를 지킨다(안 온 날이 보여야 한다) */
.stdays, .sthours{display:flex; align-items:flex-end; gap:2px; overflow-x:auto; padding-bottom:2px;}
.stday, .sthour{flex:1 1 0; min-width:7px; display:flex; flex-direction:column;
  align-items:center; justify-content:flex-end; gap:3px;}
.stday i, .sthour i{display:block; width:100%; max-width:16px; background:var(--ink);
  border-radius:3px 3px 0 0; min-height:4px;}
.stday em, .sthour em{font-style:normal; font-family:var(--f-mono); font-size:8.5px;
  font-weight:600; color:var(--faint); white-space:nowrap;}
.sthour i{background:var(--lilac-fill);}

.strows{display:flex; flex-direction:column;}
.strow{display:flex; align-items:center; gap:9px; padding:6px 0;
  border-top:2px dashed rgba(11,42,68,.14);}
.strow:first-child{border-top:0;}
.stk{flex:0 0 auto; min-width:74px; font-size:12.5px; font-weight:800; color:var(--ink);}
.stbarw{flex:1 1 auto; min-width:24px; height:11px; background:rgba(11,42,68,.08); border-radius:999px;}
.stbarw i{display:block; height:100%; background:var(--ink); border-radius:999px;}
.stn{flex:0 0 auto; font-family:var(--f-mono); font-size:12px; font-weight:700; color:var(--ink);
  text-align:right; min-width:56px;}
.stn em{font-style:normal; font-family:var(--f-body); font-size:10px; font-weight:700;
  color:var(--faint); margin-left:5px;}

.stents{display:flex; gap:9px; flex-wrap:wrap;}
.stent{flex:1 1 90px; display:flex; flex-direction:column; align-items:center; gap:1px;
  padding:9px 6px; border:1.5px solid var(--ink); border-radius:var(--r-s); background:var(--paper);
  font-size:10.5px; font-weight:700; color:var(--ink2); text-align:center;}
.stent b{font-family:var(--f-disp); font-weight:900; font-size:20px; color:var(--ink);}

@media (max-width:400px){
  .stcards{gap:6px;}
  .stcard{padding:10px 5px;}
  .stcard b{font-size:23px;}
  .stcard .sthd{font-size:9.5px;}
  .stk{min-width:62px; font-size:11.5px;}
}

/* 아무도 안 온 날 — 막대가 아니라 흐린 밑선. 0과 1이 비슷해 보이면 그 그래프는 거짓말을 한다 */
.stday i.zero{background:var(--faint); opacity:.5; min-height:2px; border-radius:2px;}

/* ── 본인이 적는 연락처 (86차) ────────────────────
   ⭐ 적으라고 하기 전에 안심시킨다. 이 줄이 입력칸보다 **먼저** 온다 —
     사람이 먼저 궁금한 건 뭘 적느냐가 아니라 그게 어디까지 보이느냐다. */
.telsafe{display:flex; align-items:flex-start; gap:7px; margin:0 0 2px; padding:8px 11px;
  border:1.5px dashed var(--sound); border-radius:var(--r-s); background:var(--sound-soft);
  font-size:11.5px; font-weight:700; color:var(--sound); line-height:1.6;}
.telsafe .ic{width:13px; height:13px; flex:none; margin-top:2px;}
.telsafe b{color:var(--sound);}
.telsafe.big{margin:0 0 16px; padding:11px 13px; font-size:12.5px;}
/* 연락처 목록에서 "본인이 직접 적었어요" 표시 — 리더가 출처를 구분할 수 있게 */
.ctself{font-style:normal; font-size:9.5px; font-weight:800; color:var(--sound);
  border:1.5px solid var(--sound); border-radius:999px; padding:1px 6px; flex:none;}


/* ── 교회 카드 (90차) ─────────────────────────
   ⭐ 공식 채널 카드(`.chan`)를 **그대로** 쓴다. 크기·여백·모션이 저절로 같아진다
     (사용자 90차: *"다른 유튭 링크들 카드랑 같은 크기로 맞춰줘, 일관성 있게"*).
     여기서 다른 건 **아이콘 자리 하나**뿐이다. 로고가 빨강·주황이고 하트가 뚫린 자리라 흰 바탕이어야 한다.
     (2026-09-16) 흰 네모 타일을 걷었다. 카드가 흰색이라 하트는 그대로 희다. 로고는 스티커가 아니라서 안 기울인다. */



/* ── 2026-09-12 fixes (frontend review) ── */
/* 밑줄 단추(`가사 고치기`·`소개 쓰기` 등)는 글자 높이 그대로라 손가락에 16px 밖에 안 된다.
   글자 크기는 그대로 두고 **눌리는 자리만** 넓힌다(그림에는 아무 변화가 없다).
   ⚠ `.iconbtn` 은 34px 인데, 이건 시트 머리·문서 줄에서 줄 높이를 정하는 값이라 손대지 않았다
      (93차-c 에 단추 크기를 덮어써서 한 줄이 두 줄로 갈린 적이 있다). */
.linkbtn{position:relative;}
.linkbtn::after{content:''; position:absolute; inset:-12px -8px;}

/* ══ 2026-09-12 · 95차 · 피드백이 먼저 보이게 ═══════════════════════════════
   사용자: "리더 리스트에서 피드백 받으면 바로 눈에 안 띄어서 보기가 힘든데 더 눈에 띄게,
   리더 로그인하면 바로 노티피케이션으로 볼 수 있게. 피드백은 핵심 기능중 하나라 놓치면 안 돼."
   색은 새로 안 만든다 — 이미 «새로 왔어요»가 쓰던 --praise 를 그대로 세 자리에 돌려 쓴다
   (색 규율: 의미색은 딱지와 머리띠에서만). 자물쇠 위 알약도 딱지고, 홈의 띠도 머리띠다. */
/* ⚠⚠ `display:flex` 는 `[hidden]` 을 이긴다. 이 한 줄이 없어서 **로그아웃 상태에서도 빨간 «0»** 이
   자물쇠에 붙어 있었다(2026-09-12 스크린샷에서 잡았다). 표시를 `hidden` 으로 끄는 요소에
   `display` 를 주면 반드시 이 짝을 같이 쓴다. */
.fbdot[hidden]{display:none;}
.fbdot{position:absolute; top:-8px; left:-8px; min-width:19px; height:19px; padding:0 5px;
  display:flex; align-items:center; justify-content:center;
  background:var(--praise-fill); color:#fff; font-family:var(--f-latin); font-weight:700;
  font-size:10.5px; line-height:1; font-variant-numeric:tabular-nums;
  border:2px solid var(--card); border-radius:999px;}

/* 홈 맨 위 띠(리더만) — **잉크 띠**(131차-c, 2026-09-29). 사용자: *"저 리더만 보는 노티스는 다르게 표현 못해? 눈에 좀 더 뛰게"*
   흰 카드 · 흰 찾기 칸 사이에서 같은 흰 띠라 묻혔다. 시안 셋(숫자 배지만 · 계절색 띠 · 잉크 띠)을 리더 화면에 끼워 보고 사용자가 잉크 띠를 골랐다.
   잉크 채움 = 이 앱에서 «주 동작» 단추의 옷(전체 재생과 같은 문법)이라 누르는 것임이 읽힌다. 계절을 안 탄다.
   빨강은 왼쪽 머리띠와 아이콘 위 숫자 배지(`.fbn`, 자물쇠 위 숫자 `.fbdot` 과 같은 부품)에서만(색 규율: 의미색은 딱지 · 머리띠). */
.fbalert{display:flex; align-items:center; gap:13px; width:100%; text-align:left; cursor:pointer;
  font-family:inherit; background:var(--ink); color:var(--on-ink);
  border:var(--bw) solid var(--ink); border-left-width:6px; border-left-color:var(--praise);
  border-radius:var(--r-m); box-shadow:0 4px 0 var(--ink); padding:13px 15px; margin:10px 0 0;}
.fbalert:active{transform:translateY(3px); box-shadow:0 1px 0 var(--ink);}
.fbalert .fbi{position:relative; flex:none; width:42px; height:42px; margin:-3px 0; display:flex; align-items:center; justify-content:center;
  transform:rotate(-5deg);}
.fbalert .fbi .hic{width:100%; height:100%;}   /* 그림 아이콘(2026-09-16). 예전 빨강 네모 타일. 빨강은 왼쪽 머리띠가 맡는다 */
/* 숫자 배지: 아이콘 오른쪽 위에 걸친다(폰 앱 배지). 아이콘이 -5도 기울어 있어서 배지는 +5도로 바로 세운다 */
.fbalert .fbn{position:absolute; top:-8px; right:-10px; box-sizing:border-box; min-width:23px; height:23px; padding:0 6px;
  display:flex; align-items:center; justify-content:center; background:var(--praise-fill); color:#fff;
  font-family:var(--f-latin); font-weight:700; font-size:12.5px; line-height:1; font-variant-numeric:tabular-nums;
  border:2px solid var(--ink); border-radius:999px; transform:rotate(5deg);}
.fbalert .fbt{display:flex; flex-direction:column; min-width:0;}
.fbalert .fbt b{font-family:var(--f-disp); font-weight:900; font-size:16px; color:#fff;}
.fbalert .fbt i{font-style:normal; font-size:12px; font-weight:600; color:rgba(255,255,255,.8); margin-top:1px;}
.fbalert .fbgo{margin-left:auto; color:#fff;}
.fbalert .fbgo .ic{width:18px; height:18px;}
[data-view="home"] .fbalert{order:-4;}          /* 공지보다도 위. 리더에게는 이게 첫 줄이다 */
@media (min-width:1100px){ [data-view="home"] .fbalert{grid-column:1 / -1;} }


/* 목록에서 «아직 안 본 것»이 한눈에 갈리게. 본 것과 같은 카드면 열어도 어디부터 볼지 모른다 */
.fbrow.new{border-left-width:6px; border-left-color:var(--praise);}

/* ── 2026-09-12 · 95차-b · 피드백 상태 다섯 · 할 일 알림 ────────────────────────
   상태 이름을 사람이 쓰는 말로 바꿨다(사용자: "'들어갔어요'가 무슨 말인지 모르겠어요").
   색은 늘리지 않는다 — «새 글」만 의미색(--praise)이고 나머지는 잉크 계열이다.
   무엇이 남았는지가 신호고, 처리된 것들끼리는 서로 구별될 이유가 없다(색 규율). */
.fbstate.pastor{background:var(--ink); color:var(--on-ink);}
.fbstate.done{background:var(--sound-fill);}
.fbstate.hold{background:var(--faint);}
.fbtop .iconbtn.sm{width:26px; height:26px; padding:5px; border-width:1.5px;}
.fbtop .iconbtn.sm .ic{width:14px; height:14px;}

/* 할 일 알림 — 한 줄이 곧 한 가지 일이고, 누르면 그 자리로 간다 */
.todolist{display:flex; flex-direction:column; gap:8px; margin-top:10px;}
.todorow{display:flex; align-items:center; gap:11px; width:100%; text-align:left; cursor:pointer;
  font-family:inherit; color:inherit; background:var(--card);
  border:var(--bw) solid var(--ink); border-radius:var(--r-m); box-shadow:var(--sh-sm); padding:11px 13px;}
.todorow:active{transform:translateY(2px); box-shadow:none;}
.todorow.bad{border-left-width:6px; border-left-color:var(--praise);}
.todorow .tdi{flex:none; width:34px; height:34px; display:flex; align-items:center; justify-content:center;}
.todorow .tdi .hic{width:100%; height:100%;}   /* 그림 아이콘(2026-09-16). 예전 노랑 네모 타일 */
.todorow .tdt{display:flex; flex-direction:column; min-width:0;}
.todorow .tdt b{font-family:var(--f-disp); font-weight:900; font-size:14.5px; color:var(--ink);}
.todorow .tdt i{font-style:normal; font-size:12px; font-weight:600; color:var(--ink2); margin-top:1px;}
.todorow .tdgo{margin-left:auto; color:var(--faint);}
.todorow .tdgo .ic{width:16px; height:16px;}

/* ── 2026-09-12 · 95차-b · 찬양팀 A·B 는 같은 줄에 ────────────────────────────
   사용자(아이패드 가로): "방송음향팀 있고 찬양팀 A 있고 그 아래 찬양팀 B 이렇게 돼 있는데,
   찬양팀 A 팀 B 이렇게 이어서 사이드로 보이게끔 해줘. 찬양팀은 같은 팀이니까 같은 라인에서 보이는 게 맞다."
   ⭐ 맞는 말이다. 세로로 쌓으면 **A 와 B 가 서로 다른 팀처럼** 읽힌다. 격자로 놓으면 «한 팀의 두 조」로 읽힌다.
   ⚠ (95차-b 엔 방송음향 한 장이 맨 위에서 두 칸을 통째로 썼다. 96차-g 에 바꿨다, 아래)
   ⭐⭐ 96차-g: **세 장이 한 줄, 같은 크기.** 사용자: *"방송·음향 팀 카드만 너무 양옆으로 늘어나 있어서 이상하다.
     크기는 다 일관성 있게. 찬양팀은 A·B 가 양쪽에 붙어 있기만 하면 돼."*
     → 방송음향 | 찬양 A | 찬양 B 세 칸(방송음향이 맨 앞 = «위로 올려줘» 지시 유지, A·B 는 붙어 있다).
     본문 폭(960)은 그대로 둔다. 1200 으로 넓혀 373px 카드로 찍어 봤더니 아래 트레이닝·자료 칸이 1160px 로 늘어졌다.
     높이도 맞춘다(stretch). 세 장이 한 줄이라 바닥 띠가 한 선에 서야 «같은 크기»로 읽힌다. 내용은 위에서 시작하니 남는 자리는 아래로 간다.
   ⭐ 96차-h: **태블릿 세로도 세 장 한 줄**(사용자: *"태블릿 세로도 세 장 한 줄로 맞춰줘"*). 900 에서 700 으로 내렸다.
     아이패드 세로(744 미니 · 768 · 820 · 834)가 전부 여기 든다. 폰(가장 넓은 것 430 안팎)은 안 걸린다.
     820 에서 한 장 약 250px. 그 폭에서 카드 머리가 넘치는지는 아래 규칙과 실측으로 막는다. */
@media (min-width:700px){
  .teamgrid{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); align-items:stretch;}
}
/* (2026-09-16) 팀 탭 맨 아래 자료 세 장과 그 칸 맞춤 규칙은 지웠다. 팀 탭엔 팀 정보만 둔다(`vTeamRender` 주석) */
/* ⚠ 좁은 세 칸(700~999px, 한 장 224~290px)에서는 카드 머리가 한 줄에 안 들어간다.
   820 실측: «찬양팀 / A», 알약 속 «오늘 / 주일», «11 / 명» 으로 글자가 쪼개졌다.
   → 머리를 **정해서 두 줄로** 나눈다: 윗줄 = 표식 · 팀 이름 · 인원 수, 아랫줄 = 다음 주일 알약. 알약 안 글자는 안 쪼갠다.
     줄 나눔은 높이 0 짜리 가로 꽉 찬 가상 요소(::after)가 만든다. 폭에 따라 한 줄이 됐다 두 줄이 됐다 하지 않게.
   세 장의 머리 높이는 같게(min-height) 둔다. 방송음향은 다음 주일 알약이 없어 한 줄이라 가운데에 선다. 본문은 같은 선에서 시작한다. */
/* ⚠ (2026-09-16) 알약에 «다음 섬김» 이름표가 붙으며 넓은 화면 세 칸(한 장 289px)에서도 한 줄에 안 들어갔다
   («11 / 명» 이 두 줄로 쪼개졌다, 실측) → 700 이상 전부 같은 두 줄 머리를 쓴다. */
@media (min-width:700px){
  .teamcard .thead{flex-wrap:wrap; align-content:center; gap:6px 7px; padding:10px 12px; min-height:90px;}   /* 두 줄 머리 실측 89px */
  .teamcard .thead::after{content:''; order:3; flex-basis:100%; height:0;}
  .teamcard .tname{font-size:16.5px; white-space:nowrap;}
  .teamcard .tcount{order:2; white-space:nowrap; font-size:12px; padding:2px 9px;}
  .teamcard .tnext{order:4; white-space:nowrap;}
  /* 744(아이패드 미니 세로)에서 방송 줄 설명 «송출 · 자막 · ProPresenter · 본당 조명»이 카드 밖으로 5px 나갔다(flex:none) → 여기선 접힌다 */
  
}

/* ══ 2026-09-12 · 95차-c · 꾸미기 ═══════════════════════════════════════════
   사용자: "찬양팀에 여자 애들이 꽤 있는데 꾸미는 거 좋아하잖아. 프로필 꾸미기 옵션도 넣을까.
   스티커도 붙이고. 너무 과하지 않게, 지금 디자인을 해치지 않는 선에서. 대신 어려우면 사람들이
   있는지도 모르고 묻히니까 누가 봐도 꾸미기 버튼인 걸 알게."
   ⭐ 붙는 자리는 **프로필 카드 한 장**뿐이다. 화면 아무 데나 붙게 하면 그날로 운영 화면이 망가진다.
   ⭐ 스티커 그림은 이 앱 언어로 직접 그렸다(tools/gen_stickers.py, 잉크 외곽선 + 납작한 색면). */

/* ⭐⭐ **역할 색은 꾸미기가 못 지운다** (2026-09-12). 사용자: "리더가 커스터마이징하면 다른 멤버랑
   구별이 안 된다는 얘기잖아." 맞는 말이다 — 바탕을 바꾸면 `--rcs` 가 덮여서 역할이 사라졌다.
   → 왼쪽 6px 띠는 **늘 그 사람의 역할 색**(`--rc`)이다. 꾸미는 건 «바탕」이고 역할은 «띠」다.
   층이 다르면 서로 안 잡아먹는다(피드백 목록의 왼쪽 띠와 같은 문법). */
/* (2026-09-16) 띠는 명찰 몸통과 함께 `.whocard::before` 로 옮겼다. 여기 두면 곧은 띠가 기운 몸통 옆에 하나 더 선다 */
/* 카드 색은 고른 값을 **눕혀서**(softHex) `--rcs` 에 인라인으로 꽂는다 — 목록을 CSS 에 두면
   색을 하나 늘릴 때마다 두 곳을 고쳐야 한다. 무엇을 골라도 옅어지니 잉크 글자가 늘 읽힌다. */

/* ══ 프로필 판 (2026-09-16) ══════════════════════════════════════════════════════════
   명찰 + 생일 + 소개·사진이 **한 장의 판**이고, 꾸미기(스티커·낙서·바탕 색)가 그 판 전체에 붙는다.
   ⚠ 판에는 테두리를 두지 않는다. 테두리가 있으면 `offset*`(판 안쪽 기준)과 화면 좌표가 그만큼 어긋난다.
   ⚠ `isolation:isolate` 로 판 하나를 쌓임 맥락으로 묶는다. 그 안에서 순서가:
     바탕 색 → 명찰 몸통(0)·사진 → 낙서(1) → 글자(2) → 스티커(3) */
.whoboard{position:relative; isolation:isolate; padding:6px 8px 2px; border-radius:20px;}
/* (2026-09-17) 판 속은 늘 한 폭(`BOARD_W`)으로 짜고 무대가 화면에 맞게 줄이거나 키운다. 폰에서 붙인 스티커가 태블릿에서 글자와 떨어지던 것.
   ⚠ 줄이는 건 transform 이다. 글자 줄바꿈은 판 속 폭으로 정해지고 배율은 그리기만 바꾼다. 무대 높이·배율·가운데는 JS(`fitBoard`)가 넣는다.
   ⚠ 판 바깥 여백(-8px 로 시트 끝까지 뻗기)은 무대가 갖는다. 판에 두면 배율에 같이 곱해진다. */
.whostage{position:relative; margin:0 -8px 10px;}
.whostage > .whoboard{width:var(--boardw); margin:0; transform-origin:0 0; transform:translateX(var(--bx,0px)) scale(var(--bk,1));}
.whoboard.tinted{background:var(--deco);}
.whoboard .whorows{position:relative;}
/* 글자는 낙서 위로. 명찰 안 글자와 판 안 사실 줄 글자 모두 */
.whocard .whoi, .whocard .whot, .whocard .whome{position:relative; z-index:2;}
.whocard .whome{position:absolute;}
.whoboard .wri, .whoboard .wrk, .whoboard .wrv, .whoboard .wrage, .whoboard .wrn, .whoboard .wrb{position:relative; z-index:2;}
/* ⚠⚠ 소개 문단은 **사진 옆을 흐르는 글**이라 문단 상자가 사진 밑까지 뻗는다. 낙서 위로 올리느라 z 를 주면
   그 상자가 사진을 덮어서 **사진을 눌러도 안 열린다**(실측: 사진 한가운데를 누르면 `p.wrb` 가 받았다).
   소개 글에는 누를 것이 없으니 손가락은 통과시킨다. */
.whoboard .wrb{pointer-events:none;}
/* 사진은 낙서 **아래**(사용자: "프로필 사진 위에도 낙서 가능하게"). 기울임이 있어 제 맥락을 만들지만 z 가 0 이다 */
.whoboard .wpic{z-index:0;}
.whoboard.deco-stage .wpic{cursor:inherit;}
/* ⭐⭐ **꾸밀 때 판은 얼어 있다** (108차). 사용자: *"펜으로 프로필 사진 위에 그리려니까 사진이 버튼처럼 눌려.
   반응은 안 하는데 눌릴 때 안으로 들어가잖아. 그리는 중엔 그러면 안 되지. 꾸미기 모드에 들어가면 프로필은 프리즈."*
   까닭: `.wpic:active` 는 **누른 요소면 다 걸린다** — 꾸밀 때는 사진이 `<span>` 이라 아무 일도 안 하는데도
   손가락 밑에서 2px 내려앉았다. 획을 긋는 내내 종이가 움직인 셈이다.
   ⚠⚠ 고침은 `:active` 하나를 막는 게 아니라 **구조**다. 판 안의 «보는 것»(명찰·생일·소개·사진)은 꾸밀 때
     이벤트를 아예 안 받는다 → 눌린 척도, 손가락 밑에서 자라는 효과도 생길 수 없다. 나중에 누가 판에
     새 단추를 달아도 여기서 같이 얼어붙는다. 움직임(전환·등장)도 함께 멈춘다.
   ⚠ 스티커·✕·손잡이는 `.decoover` 쪽이라 그대로 살아 있다(꾸미는 연장이다). 보는 프로필은 손도 안 댄다. */
.whoboard.deco-stage .whocard, .whoboard.deco-stage .whorows{pointer-events:none;}
.whoboard.deco-stage .whocard, .whoboard.deco-stage .whocard *,
.whoboard.deco-stage .whorows, .whoboard.deco-stage .whorows *{
  transition:none !important; animation:none !important;}

/* 얹는 층. `.decoover` 는 **z-index 를 주지 않는다** — 주면 그 안의 낙서와 스티커가 한 덩어리로 묶여
   글자 사이에 끼울 수가 없다. 자식 둘이 판의 맥락에 각자 선다. */
.decoover{position:absolute; inset:0; pointer-events:none;}
/* 스티커 층. 판 위에 떠 있되 **글자를 막지 않는다**(보기 모드에선 클릭도 통과시킨다) */
.decolayer{position:absolute; inset:0; pointer-events:none; overflow:visible; z-index:3;}
/* ⚠ 회전은 **그림에만** 준다. 스티커 상자를 돌리면 ✕ 와 손잡이까지 같이 돌아서 비뚤게 매달린다 */
.decolayer .dstk{position:absolute; width:28px; height:28px; margin:-14px 0 0 -14px;
  filter:drop-shadow(0 1.5px 0 rgba(11,42,68,.22));}
.decolayer .dstk img{width:100%; height:100%; display:block; transform:rotate(var(--r,0deg));
  -webkit-user-drag:none; user-select:none; -webkit-touch-callout:none;}
/* 고치는 동안만 손잡이가 산다 */
.decolayer.edit .dstk{pointer-events:auto; cursor:grab; touch-action:none;}
.decolayer.edit .dstk:active{cursor:grabbing;}
.stkx{position:absolute; top:-9px; right:-9px; width:19px; height:19px; padding:0;
  display:flex; align-items:center; justify-content:center; cursor:pointer; pointer-events:auto;
  background:var(--card); color:var(--ink); border:1.5px solid var(--ink); border-radius:999px;
  box-shadow:0 1px 0 var(--ink);}
.stkx .ic{width:11px; height:11px; stroke-width:3;}
/* 손가락으로 고른 스티커 — 둘레에 점선 고리. ✕ 는 손가락이 누를 수 있게 한 치수 크게 */
.decolayer.touch .dstk.sel::after{content:''; position:absolute; inset:-6px; border-radius:999px;
  border:2px dashed var(--ink); pointer-events:none;}
.decolayer.touch .stkx{top:-16px; right:-16px; width:26px; height:26px;}
.decolayer.touch .stkx .ic{width:13px; height:13px;}
/* ⭐⭐ 손잡이 (2026-09-16, 폰에서만). 사용자: *"손가락으로 가려져서 어디로 옮기는지를 모르겠어.
   이동시킬 땐 손잡이를 만들어 주든지."* 스티커 **아래로** 줄을 늘여 동그란 손잡이를 단다.
   손잡이를 끌면 스티커는 손가락 위에 떠서 따라온다. 판 아래 끝에 가까우면 위로 단다(`.up`). */
.stkgrip{position:absolute; left:50%; top:calc(100% + 14px); width:38px; height:38px; margin-left:-19px;
  display:flex; align-items:center; justify-content:center; pointer-events:auto; touch-action:none; cursor:grab;
  background:var(--accent); color:var(--ink); border:var(--bw) solid var(--ink); border-radius:999px;
  box-shadow:0 2px 0 var(--ink);}
.stkgrip .ic{width:20px; height:20px; stroke-width:2.4;}
.stkgrip::before{content:''; position:absolute; left:50%; bottom:100%; width:2px; height:16px;
  margin-left:-1px; background:var(--ink);}
.stkgrip.up{top:auto; bottom:calc(100% + 14px);}
.stkgrip.up::before{bottom:auto; top:100%;}

/* 꾸미기 안내 한 줄 — **판 밖**이다. 판 안에 넣으면 보기 화면과 판 모양이 달라진다 */
.dchint{margin:0 0 10px; font-size:12.5px; font-weight:700; color:var(--ink2);}

/* ⭐⭐ 손가락 돋보기 (2026-09-16 두 번째 판). 1판은 연필을 손가락 48px 위에 띄워 그 끝에서 그었는데 시작점을 조준할 수 없었다
   (사용자: *"시작점을 알 수가 없어서 그리면서 알아내야 해. 글쓰기도 힘들어"*). 이제 손가락 닿는 곳에 그리고, 가려진 그 자리를
   손가락 위 동그라미에 1.6배로 비춘다(`openDecoEdit` 의 lens 함수들). 가운데 = 그리는 점, 거기에 연필 끝(지우개면 지워지는 동그라미).
   ⚠ 원 밖을 자르는 건 안쪽 칸(`.dcloupeclip`)이 한다. 바깥 칸에서 자르면 하드 그림자까지 잘리고,
     iOS 는 border-radius + overflow 만으로는 변형된 자식을 못 자를 때가 있어 clip-path 를 같이 건다. */
.dcloupe{position:fixed; left:0; top:0; z-index:6; width:116px; height:116px; box-sizing:border-box; border-radius:50%;
  pointer-events:none; background:var(--card); border:3px solid var(--ink); box-shadow:0 4px 0 var(--ink);
  opacity:0; transition:opacity .18s ease;}
.dcloupe.on{opacity:1; transition:none;}
.dcloupeclip{position:absolute; inset:0; border-radius:50%; overflow:hidden; clip-path:circle(50% at 50% 50%);}
.dcloupein{position:absolute; left:50%; top:50%; width:0; height:0;}
.dcloupein > .whoboard{position:absolute; left:0; top:0; margin:0; transform-origin:0 0;}
/* 복제한 판은 등장 효과를 다시 틀지 않는다(돋보기를 열 때마다 명찰이 튀어 오르면 안 된다) */
.dcloupe *{animation:none !important; transition:none !important;}
.dcloupetip{position:absolute; left:50%; top:50%; width:0; height:0; z-index:2;}
.dcloupetip svg{position:absolute; left:-2.5px; top:-37.5px; width:40px; height:40px; filter:drop-shadow(0 2px 0 rgba(11,42,68,.22));}
/* 지우개 동그라미 = 지워지는 넓이(반지름 15px)의 1.6배. 그림 속 원 반지름이 32칸의 14.5 라 53px */
.dcloupe.era .dcloupetip svg{left:-26.5px; top:-26.5px; width:53px; height:53px; filter:none;}

/* 서랍 */
/* (옛 5x5 스티커 격자는 2026-09-12 에 가로 서랍으로 바뀌었다 — `.dcrow`) */
/* ⚠ `.btn.deco` 는 2026-09-12 에 지웠다 — 꾸미기만 «진짜 단추」였던 게 밸런스를 깼다.
   지금은 소개·사진과 **같은 타일**(`.wfact`)이다. 셋이 같은 모양이면 어차피 안 묻힌다. */

/* ── 2026-09-12 · 95차-d · 낙서 ──────────────────────────────────────────────
   사용자: "핸드폰으로 그냥 이렇게 하는 낙서 기능같이 아기자기하게 적당하게만 넣어줘.
   근데 프로필 안에서만 하고, 글 같은 거 가리거나 그런 거는 못 하게."
   ⭐⭐ **그래서 낙서는 글자 뒤에 그린다.** 무엇을 그리든 이름과 역할은 위에 남는다 —
      «가리지 못하게» 를 규칙으로 막는 게 아니라 **구조로** 막는 것이다(그래야 안 뚫린다).
   ⚠ 층 순서(2026-09-16 판으로 넓힘): 명찰 몸통·사진(0) → 낙서(1) → 글자(2) → 스티커(3). 스티커는 «붙이는 것»이라 위가 맞다. */
.decodraw{position:absolute; inset:0; width:100%; height:100%; z-index:1;
  pointer-events:none; overflow:visible;}
/* (2026-09-17) `non-scaling-stroke` 를 뺐다. 판이 한 폭이 되면서 그림판 1px = 판 속 1px 이라 필요가 없고,
   남겨 두면 무대가 판을 키워도 선만 안 굵어져서 기기마다 선이 가늘거나 굵어 보였다 */
.decodraw polyline{fill:none; stroke-linecap:round; stroke-linejoin:round;}
.decodraw .dl-ink{stroke:var(--ink);}      .decodraw .dl-coral{stroke:var(--praise);}
.decodraw .dl-sea{stroke:var(--bcast);}    .decodraw .dl-grass{stroke:var(--sound);}
.decodraw .dl-lilac{stroke:var(--lilac);}  .decodraw .dl-butter{stroke:#E0A81E;}

/* 펜·지우개를 켜면 카드가 «그릴 판」이 된다 — 손가락이 스크롤로 새지 않게 touch-action 을 끊는다 */
.deco-stage.penon{cursor:crosshair; touch-action:none;}
.deco-stage.eraseon{cursor:cell; touch-action:none;}
/* 그리는 동안엔 스티커 자체는 안 잡는다 (스티커 위로도 선이 그어져야 하니까) */
.deco-stage.penon .decolayer, .deco-stage.eraseon .decolayer{pointer-events:none;}
/* ⚠⚠ **단, ✕ 는 살려 둔다.** 펜을 켠 게 스티커를 못 떼는 이유가 될 수는 없다
   (2026-09-12 사용자: "그 상태에서 스티커를 닫으려고 ✕ 를 눌러도 반응이 없어").
   부모가 pointer-events:none 이어도 자식이 auto 면 자식은 받는다. */
.deco-stage.penon .stkx, .deco-stage.eraseon .stkx{pointer-events:auto; cursor:pointer;}
/* ⭐ 꾸미는 창 = 글자 선택 · 그림 끌기 · 길게 누르기 메뉴 없음 (2026-09-16. 사용자: *"꾸미기 모드에선 전부 락 못 걸어? 드래그나 선택 안 되게"*).
   낙서를 꾹 누른 채 끌면 폰이 글자를 고르거나 사진을 들어 올렸다. 까닭과 이벤트 쪽은 `openDecoEdit` «글자·그림이 안 잡힌다» 주석.
   ⚠ 창 칸(`.sheet.dcsheet`)에만 건다. 보는 프로필의 소개 글은 복사할 수 있어야 한다. */
.sheet.dcsheet, .sheet.dcsheet *{-webkit-user-select:none; user-select:none; -webkit-touch-callout:none; -webkit-user-drag:none;}

/* ⚠⚠ (2026-09-16 지움) `.whocard.hasdraw, .deco-stage{min-height:118px}` 가 스티커가 튀던 **원인**이었다.
   꾸미는 판은 늘 118px, 보는 카드는 낙서가 있을 때만 118px 이라 둘의 높이가 달랐다. 판 높이를 따로 주지 않는다. */

/* ══ 2026-09-12 · 95차-g · 꾸미기 = 연장 셋 + 서랍 하나 ════════════════════════════
   사용자: "인터페이스 줄이 너무 많아. 너무 복잡하고 지저분해. 다섯 살짜리도 그냥 와서 쓸 수 있게.
   한 화면에 다 나오게. 스티커도 네다섯 개씩 옆으로 넘기게. 닌텐도는 아기부터 노인까지 다 쉽게 쓰게
   만들어 놓은 애들이잖아."
   ⭐ 서랍을 한꺼번에 펼치지 않는다. 연장을 고르면 **그 서랍만** 열린다. 한 화면에 들어온다.
   ⭐ 서랍은 가로 한 줄이다. 세로로 쌓으면 화면을 먹고, 옆으로 넘기는 건 손가락이 이미 아는 몸짓이다. */
.dctabs{display:grid; grid-template-columns:repeat(3,1fr); gap:6px; margin-top:2px;}
.dctab{display:flex; align-items:center; justify-content:center; gap:6px; cursor:pointer;
  font-family:var(--f-body); font-weight:800; font-size:13px; color:var(--ink2);
  background:var(--paper); border:var(--bw) solid var(--faint); border-radius:var(--r-m);
  padding:9px 6px; min-height:42px;}
.dctab .ic{width:15px; height:15px;}
.dctab.on{color:var(--ink); background:var(--card); border-color:var(--ink); box-shadow:var(--sh-sm);}
.dctab:active{transform:translateY(2px);}

.dcdrawer{margin-top:8px;}
/* 가로 한 줄. 끝이 잘려 보여야 «더 있다」가 읽힌다(스크롤바는 숨긴다) */
.dcrow{display:flex; gap:7px; overflow-x:auto; overflow-y:hidden; padding:2px 2px 6px;
  scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch;}
.dcrow::-webkit-scrollbar{height:0;}
.dcpick{flex:0 0 auto; scroll-snap-align:start; cursor:pointer; display:flex;
  align-items:center; justify-content:center; background:var(--card);
  border:var(--bw) solid var(--ink); border-radius:14px; box-shadow:var(--sh-sm);
  width:60px; height:60px; padding:6px;}
.dcpick:active{transform:translateY(2px); box-shadow:none;}
.dcpick img{width:100%; height:100%; object-fit:contain; display:block;}
/* 색은 동그라미 하나면 된다 — 글자를 붙이면 줄이 길어지고 고를 게 많아 보인다 */
.dcpick.dot{position:relative; width:52px; height:52px; background:var(--dot,var(--card));}
/* 「바탕 없음」 = 판에 색을 안 칠한다. 빈 종이에 사선 하나 */
.dcpick.dot.base{background:linear-gradient(135deg, transparent 46%, var(--faint) 46%, var(--faint) 54%, transparent 54%), var(--card);}
.dcpick.dot.on, .dcpick.era.on{border-width:4px; box-shadow:0 0 0 3px var(--accent-soft), var(--sh-sm);}
.dcpick.dot .ic{width:20px; height:20px; color:var(--ink);}
.dcpick.dot.pick input[type="color"]{position:absolute; inset:0; opacity:0; width:100%; height:100%;
  border:0; padding:0; cursor:pointer;}
.dcpick.era{width:52px; height:52px; background:var(--paper);}
.dcpick.era .ic{width:22px; height:22px; color:var(--ink); stroke-width:2.6;}
/* 연필 굵기 단추. 선 셋이 곧 고를 수 있는 굵기이고 색이 든 선이 지금 굵기다. 누를 때마다 다음 굵기로 */
.dcpick.sz{flex-direction:column; gap:4px; padding:0 11px;}
.dcpick.sz i{display:block; align-self:stretch; height:var(--sz); border-radius:99px; background:var(--faint); opacity:.55;}
.dcpick.sz i.on{background:var(--col); opacity:1;}

/* ⚠⚠ **손이 꼭 닿아야 하는 연장은 스크롤 뒤에 두지 않는다** (2026-09-12).
   지우개가 여덟 번째 자리라 폰에서는 옆으로 밀어야 나왔다 — 지우개를 못 찾는 그림판은 그림판이 아니다.
   고르는 것(색·스티커)만 굴리고, 연장(지우개·되돌리기·직접 고르기)은 오른쪽에 못 박는다. */
.dcline{display:flex; gap:7px; align-items:flex-start;}
.dcline .dcrow{flex:1; min-width:0;}
.dcfix{flex:none; display:flex; gap:7px; padding:2px 0 6px;}
/* ⚠⚠ 색 줄은 **다 보이거나, 끝에 반 개가 걸려 보여야** «옆에 더 있다」가 읽힌다 (2026-09-16 굵기 단추가 붙으며 실측).
   390 폰에서 색 동그라미가 딱 세 개로 떨어져 네 번째가 통째로 숨었다 → 초록·보라·노랑이 없는 줄 안다.
   → 크기(`--dotsz`, 40~52px. ⚠ `--dot` 은 동그라미 색이라 이름이 겹치면 폭이 색이 된다)는 줄 폭을 재서 꾸미기 창이 정한다(`fitRow`). 좁은 폰에선 연장 단추도 46px 로. */
.dcline .dcrow .dcpick.dot{width:var(--dotsz, 52px); height:var(--dotsz, 52px);}
@media (max-width:400px){
  .dcfix .dcpick.era, .dcfix .dcpick.dot{width:46px; height:46px;}
}
/* ⚠⚠ 스티커 줄도 같다 (2026-09-16 화면 점검). 넓은 화면은 여섯 장이 서랍 끝에 딱 맞아 일곱 번째가 안 보였고
   390 폰은 여섯 번째가 5px 만 걸렸다 → 크기(`--stksz`, 54~72px)도 `fitRow` 가 정해서 끝에 반 장이 걸리게 한다.
   ⚠ `min-width:0` 은 빼지 말 것. 사용 기록 화면의 줄 이름 `.stk{min-width:74px}`(폰 62px) 가 이름이 같아 스티커 칸까지 늘리고 있었다. */
.dcrow .dcpick.stk{min-width:0; width:var(--stksz, 62px); height:var(--stksz, 62px);}
/* 스티커 서랍 두 줄(2026-10-01): 위 = 동물 친구 이모티콘, 아래 = 기본 스티커. 두 줄이 한 덩어리로 옆으로 넘어간다 */
.dcrow.two{display:grid; grid-auto-flow:column; grid-template-rows:var(--stksz, 62px) var(--stksz, 62px);
  grid-auto-columns:var(--stksz, 62px); gap:7px;}

/* 114: request playlists use real buttons; switching tabs only replaces the list. */
.reqplayer .plrow{padding:0;gap:0;}
.plreqgo{display:flex;align-items:center;gap:9px;width:100%;min-width:0;min-height:44px;
  padding:10px 14px;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;}
.plreqgo:focus-visible{outline:2px solid var(--ink);outline-offset:-3px;}
.plmiss{font-size:10px;flex:none;color:var(--ink2);}
.plreqsearch{font-size:11px;flex:none;padding:10px;color:var(--ink2);}
.reqplayer .plswb{min-height:36px;}
@media(max-width:600px){
  .reqplayer .plbar{display:grid;grid-template-columns:30px minmax(0,1fr) 30px;gap:8px 9px;}
  .reqplayer .plnow{grid-column:2;grid-row:1;}
  .reqplayer #plPrev{grid-column:1;grid-row:1;}
  .reqplayer #plNext{grid-column:3;grid-row:1;}
  .reqplayer .plreqsw{grid-column:1 / -1;grid-row:2;justify-self:center;}
}

[data-view="home"] .fbalert{order:-5;}
.rsbundle{padding:0;overflow:hidden;container:requestcard / inline-size;}
/* 118: .card가 이미 계절색 바닥을 갖는다. 별도 ::after를 더하면 띠가 두 번 그려진다. */
.rsbundlehead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-height:44px;padding:6px var(--card-gut);
  border-bottom:1.5px dashed var(--faint);}
.rsbundlehead h2{display:flex;align-items:center;gap:7px;margin:0;font-family:var(--f-disp);font-size:17px;font-weight:900;color:var(--ink);}
.rsbundlehead .hic{width:28px;height:28px;flex:none;transform:rotate(-4deg);}
.rsbundleacts{display:flex;align-items:center;gap:8px;margin-left:auto;}
.rsheadbtn{display:inline-flex;align-items:center;justify-content:center;gap:4px;min-height:28px;padding:3px 2px;
  border:0;background:none;color:var(--ink2);text-decoration:none;font-family:var(--f-body);font-size:11px;font-weight:800;cursor:pointer;white-space:nowrap;}
.rsheadbtn .ic{width:13px;height:13px;}
.rsheadbtn.btn{min-height:28px;padding:5px 8px;border:var(--bw) solid var(--ink);border-radius:var(--r-s);background:var(--card);color:var(--ink);box-shadow:var(--sh-sm);font-size:11px;}
.rsheadbtn.btn:active{box-shadow:none;}
.rsheadbtn:hover{text-decoration:underline;}
.rsbundlebody{padding:6px var(--card-gut);}
.rsbundle .rsgrp + .rsgrp{margin-top:6px;padding-top:6px;border-top:1.5px dashed var(--faint);}
.rsbundle .rsghd{margin:0 0 6px;font-size:12px;gap:6px 10px;text-shadow:none;align-items:center;flex-wrap:wrap;}
.rsbundle .rsghd b{font-size:10px;text-shadow:none;}
.rsbundle .rsall{min-height:28px;margin:0;padding:5px 8px;gap:4px;font-size:11px;font-weight:800;flex:none;white-space:nowrap;
  border:var(--bw) solid var(--ink);border-radius:var(--r-s);box-shadow:var(--sh-sm);}
.rsbundle .rsall .ic{width:12px;height:12px;margin:0;}
.rsbundle .rsall:active{box-shadow:none;}
.rsbundle .rslist,.rsarchive .rslist{display:flex;flex-direction:column;gap:0;margin:3px 0 0;}
.rsbundle .rsong,.rsarchive .rsong{border:0;border-radius:0;box-shadow:none;background:none;padding:7px 0;gap:8px;}
.rsbundle .rslist{margin:0;}
/* 곡 줄의 바깥 14px를 빼고, 제목 단추 안의 44px 누를 자리는 남긴다. */
.rsbundle .rsong{padding:0;flex-wrap:nowrap;}
.rsbundle .rsong + .rsong{border-top:1px dashed var(--faint);}
.rsbundle .rsgo,.rsarchive .rsgo{min-height:44px;flex-basis:110px;}
.rsbundle .rsgo{flex:1 1 0;padding:5px 0;}
.rsbundle .rsgo .ic{width:14px;height:14px;color:var(--ink);}
.rsbundle .rst,.rsarchive .rst{white-space:normal;overflow-wrap:anywhere;line-height:1.5;font-size:13px;}
.rsbundle .rst i,.rsarchive .rst i{display:block;margin:0;font-size:11px;line-height:1.4;}
.rsbundle .rsmark,.rsarchive .rsmark{box-shadow:none;}
.rsbundle .rsmark{height:auto;min-height:28px;padding:5px 7px;font-size:11px;gap:4px;}
.rsbundle .rsmark .ic{width:12px;height:12px;}
.rsbundle .svcchip{flex:none;white-space:nowrap;}
.rsbundle :is(.rsgo,.rsheadbtn,.rsall,.rsmark):focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
.rsbundle .rsmore{display:block;margin:0;text-shadow:none;min-height:28px;line-height:28px;}
@container requestcard (min-width:620px){
  /* 두 종류가 있을 때만 옆의 빈 공간을 쓴다. 한 종류는 그대로 한 목록이다. */
  .rsbundlebody:has(.rsgrp + .rsgrp){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:24px;}
  .rsbundle .rsgrp + .rsgrp{margin:0;padding:0;border:0;}
  .rsbundlebody > .rsgrp:only-child .rst i{display:inline;margin-left:7px;}
}
.rsempty{margin:4px 0 10px;font-size:12px;font-weight:600;line-height:1.7;color:var(--ink2);}
.rsempty a{color:var(--ink);}
.rsempty:empty{display:none;}
.rsarchive .shhead small{font-family:var(--f-latin);font-size:11px;font-weight:500;color:var(--ink2);}
.rsarchiveday{margin:18px 0 2px;padding-bottom:6px;border-bottom:var(--bw) solid var(--ink);font-size:12px;color:var(--ink);}
.rsarchiveentry + .rsarchiveentry{border-top:1px dashed var(--faint);}
.rsarchive .rsong.done{opacity:1;}
.rsarchive .rsong.done .rst{text-decoration:none;}
.rsarchivemeta{margin:0 0 8px 26px;font-size:10.5px;font-weight:600;color:var(--faint);}
#rsArchiveMore{margin-top:14px;}
@media(max-width:374px){
  .rsbundlehead{gap:6px;padding:6px 10px;}
  .rsbundlehead .hic{width:28px;height:28px;}
  .rsbundleacts{gap:6px;}
  .rsheadbtn{font-size:11px;}
}

/* 120: 전체 재생은 구역 제목 바로 옆. 오른쪽 곡별 완료 단추와 붙여 놓지 않는다. */
.rsloadmsg{grid-column:1 / -1;display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;
  padding:8px 0;font-size:12px;line-height:1.5;color:var(--ink2);}
.rsloadmsg > span{flex:1;min-width:140px;}
.rsloadmsg .btn{flex:none;}
#layer .lvl:focus{outline:none;}
.rsghdlabel{display:inline-flex;align-items:baseline;gap:6px;white-space:nowrap;}
/* 방송 배정 없는 리허설도 영상 링크가 필요하다. 빈 격자 줄 없이 기존 단추 줄을 쓴다. */
.svline.crew.nocrew{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;}
.svline.crew.nocrew > .recpair,.svline.crew.nocrew > .stagebtn{margin:0;}
.svline.crew.nocrew > .none{margin-right:auto;}
/* 한 팀만 있는 좁은 카드: 이름과 두 단추를 한 줄에 억지로 넣지 않는다. */
@container avcrew (max-width:419px){
  .svline.crew.solo:not(.nocrew):has(.recpair){grid-template-columns:minmax(max-content,1fr) minmax(0,auto);}
  .svline.crew.solo:not(.nocrew):has(.recpair) > .stagebtn{grid-area:2 / 2;}
}

/* ══ UX 130 시안 (2026-09-26) — «누르는 것만 볼록하게» ═══════════════════════════════
   사용자: *"이름도 버튼처럼 보이고, 아래 보면 전체 재생·가사·가사 슬라이드 이런 것들이 다 버튼인데,
   버튼이 일단 너무 많아. 그러면 머리가 아프거든."*
   실측(라이브 390 폰, 9/27 주일 카드 하나): 단추처럼 생긴 조각 34개 · 모양 12가지 · 그중 11개는 누를 일이 없는 딱지.
   ① 정보(이름 · 역할 · 키 · 한영 · 예배 딱지)는 테두리·그림자 없이 **글자**로
   ② 카드의 주 동작(전체 재생 · 가사)만 잉크 단추
   ③ 줄마다 붙는 동작(정보)은 테두리 없이 조용하게
   ④ 가끔 쓰는 도구(녹화 · 무대 배치 · 가사 슬라이드 · 유튜브 링크)는 카드 맨 아래 한 줄
   ⚠ 잉크 2px 선과 하드 그림자(스킨의 확신)는 **카드와 진짜 단추에만** 남는다. 선을 없애는 게 아니라 뜻을 준다.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ① 이름 = 글자. 역할 색은 줄 머리(싱어 · 세션 · 방송 · 음향)가 맡는다. 누르면 여전히 프로필이 뜬다 */
.ptag{border:0; box-shadow:none; background:none; padding:1px 0; border-radius:6px; font-size:14px; gap:4px; color:var(--ink);}
.ptag::before{display:none;}
.ptag i{font-size:10.5px; opacity:1; color:var(--faint); font-weight:700;}
.ptag.head{box-shadow:none;}
.ptag[data-who]:active{background:var(--paper); transform:none;}
.ptags{gap:4px 14px; align-items:baseline;}
.ptk{font-size:11.5px; font-weight:900; padding-top:1px; letter-spacing:0;}
.ptk.t-lead{color:var(--rl-lead);} .ptk.t-vocal{color:var(--rl-vocal);} .ptk.t-session{color:var(--rl-session);}
.ptk.t-b{color:var(--rl-bcast);} .ptk.t-s{color:var(--rl-sound);}
/* 내 이름 = 형광펜 한 줄 + «나». 테두리 대신 밑에 칠한다(«이게 나예요» 를 해 둔 사람만) */
.ptag.me{outline:0; box-shadow:none; padding:1px 3px; margin:0 -3px;
  background:linear-gradient(180deg, transparent 50%, var(--accent-soft) 50%, var(--accent-soft) 94%, transparent 94%);}
@supports (background:color-mix(in srgb, red 50%, transparent)){
  .ptag.me{background:linear-gradient(180deg, transparent 48%, color-mix(in srgb, var(--accent) 55%, transparent) 48%,
    color-mix(in srgb, var(--accent) 55%, transparent) 94%, transparent 94%);}
}
/* 역할 딱지(찬양 · 방송 · 음향 · 교제 · 빠짐) = 색 글자 */
.rlab{background:none !important; border:0; width:auto; min-width:30px; padding:0; text-align:left;
  font-size:11.5px; font-weight:900; border-radius:0;}
.rlab.p{color:var(--praise);} .rlab.b{color:var(--bcast);} .rlab.s{color:var(--sound);}
.rlab.o{color:var(--ink2);} .rlab.a{color:var(--praise);}
/* 키 · 한영 · 예배 딱지 · 결단찬양 딱지 · 콘티 아직 = 글자 */
.key{background:none; border:0; padding:0; border-radius:0; font-size:12px; color:var(--ink2);}
.lchip{background:none !important; border:0 !important; padding:0 !important; font-size:11px !important;
  font-weight:700 !important; color:var(--faint) !important; letter-spacing:0;}
.svcchip{background:none !important; border:0; padding:0; font-size:12px; font-weight:900;}
.svcchip.sun{color:var(--praise);} .svcchip.fri{color:var(--bcast);} .svcchip.sat{color:var(--sat);} .svcchip.ev{color:var(--accent-ink);}
.rchip{background:none !important; border:0 !important; padding:0 !important; box-shadow:none !important;
  color:var(--accent-ink) !important; font-size:11px !important;}
.soonchip{background:none !important; border:0 !important; box-shadow:none !important; padding:0 !important; color:var(--faint) !important;}

/* 곡 한 줄: 제목 아래 «한영 · 빠름» 한 줄로 (예전엔 딱지 줄과 템포 줄이 따로 서서 곡 하나가 세 줄이었다) */
.songrow .sbody{flex-direction:row; flex-wrap:wrap; align-items:baseline; column-gap:0;}
.songrow .stitle{flex-basis:100%;}
.songrow .stags:empty{display:none;}
.songrow .stags:not(:empty) + .smeta::before{content:'·'; margin:0 5px; color:var(--faint);}
.songrow .smeta{font-size:11px; font-weight:700;}

/* ③ 줄마다 붙는 «정보» = 테두리 없는 글자 단추(높이는 예전과 같은 32px. 늘리면 곡 찾기 200줄이 800px 길어진다) */
.infobtn.wide:not(.up){border:0; background:none; color:var(--ink2); height:32px; padding:0 2px 0 8px;
  font-size:12px; font-weight:800; gap:3px;}
.infobtn.wide:not(.up) .ic{display:inline-block !important; width:14px; height:14px;}
.infobtn.wide:not(.up):active{background:var(--paper);}

/* ── 다음 섬김 카드 (ux130) ─────────────────────────────────────────── */
/* «누가 서나» 한 덩어리 */
.spot.ux130 .uxpeople{display:flex; flex-direction:column; gap:10px; padding:14px var(--card-gut) 15px;}
.spot.ux130 .uxpeople .ptiers{padding:0; margin:0; gap:10px;}
.spot.ux130 .ptrow{gap:12px; align-items:baseline;}
.spot.ux130 .ptk{width:30px; flex:none;}
.spot.ux130 .ptag{font-size:15px;}
.spot.ux130 .uxasst{display:inline-flex; align-items:baseline; gap:5px;}
.spot.ux130 .uxasst > i{font-style:normal; font-size:11px; font-weight:700; color:var(--faint);}
.spot.ux130 .ptag.none{color:var(--faint); font-weight:700;}

/* «뭘 부르나» = 주 동작 둘(전체 재생 · 가사)만 단추, 그다음 곡 */
.spot.ux130 .contiblk{padding:12px var(--card-gut) 10px;}
.spot.ux130 .contihd{gap:8px;}
.spot.ux130 .contihd .btn{min-height:36px; padding:6px 15px; font-size:12.5px;}
.spot.ux130 .contihd .btn .ic{width:13px; height:13px;}
.spot.ux130 .songs{margin-top:8px;}
/* 결단찬양 = 곡 목록 맨 끝의 빈칸(점선 = «아직 없지만 넣을 수 있다», 52차 문법 그대로) */
.songrow.uxslot{align-items:center !important;}
.songrow.uxslot .no{margin-top:0 !important;}
.songrow.uxslot .no .ic.tiny{width:11px; height:11px; fill:none; stroke:var(--faint); stroke-width:2;}
.songrow.uxslot .btn.resp{flex:1; justify-content:flex-start; margin:0; min-height:34px; padding:5px 12px;
  background:none; border:1.5px dashed var(--faint); box-shadow:none; border-radius:10px;
  color:var(--ink2); font-size:12.5px; font-weight:800;}
.songrow.uxslot .btn.resp .ic{width:13px; height:13px;}
.songrow.uxslot .btn.resp.has{border-style:solid; border-color:var(--accent); background:var(--accent-soft); color:var(--accent-ink);}

/* ④ 도구 줄 = 카드 맨 아래 한 줄, 아이콘 위 · 글자 아래. 테두리 없이 조용하게 */
.spot.ux130 .uxtools{display:flex; justify-content:space-around; gap:2px; padding:6px 6px 8px;}
.spot.ux130 .uxtools .btn{flex:1 1 0; min-width:0; flex-direction:column; gap:4px; margin:0; padding:9px 2px 7px;
  background:none; border:0; box-shadow:none; border-radius:12px; color:var(--ink2);
  font-size:11px; font-weight:800; line-height:1.2; white-space:nowrap; text-align:center;}
.spot.ux130 .uxtools .btn .ic{width:20px; height:20px;}
.spot.ux130 .uxtools .btn:active{background:var(--paper); transform:none;}
.spot.ux130 .uxtools .btn.recbtn.none{color:var(--faint);}
.spot.ux130 .uxtools .btn.recbtn.has:not(.reh){color:var(--accent-ink);}

/* ── 섬김표 목록 줄(svRow)도 같은 문법 ────────────────────────────── */
.svrow.ux130 .svgrp.av{display:flex; flex-direction:column; gap:8px;}
.svrow.ux130 .ptrow{align-items:baseline;}
.ux130 .uxasst{display:inline-flex; align-items:baseline; gap:5px;}
.ux130 .uxasst > i{font-style:normal; font-size:10.5px; font-weight:700; color:var(--faint);}
.ux130 .ptag.none{color:var(--faint); font-weight:700;}
/* 도구 줄은 홈 카드와 섬김표 줄이 같은 몸 */
.ux130 .uxtools{display:flex; justify-content:space-around; gap:2px; padding:6px 6px 8px;}
.ux130 .uxtools .btn{flex:1 1 0; min-width:0; flex-direction:column; gap:4px; margin:0; padding:9px 2px 7px;
  background:none; border:0; box-shadow:none; border-radius:12px; color:var(--ink2);
  font-size:11px; font-weight:800; line-height:1.2; white-space:nowrap; text-align:center;}
.ux130 .uxtools .btn .ic{width:20px; height:20px;}
.ux130 .uxtools .btn:active{background:var(--paper); transform:none;}
.ux130 .uxtools .btn.recbtn.none{color:var(--faint);}
.ux130 .uxtools .btn.recbtn.has:not(.reh){color:var(--accent-ink);}
.svrow.ux130 .uxtools{margin:4px 0 -4px; border-top:1.5px dashed var(--faint); padding-top:6px;}

/* 팀 동그라미 «A» → 글자 «A팀» (카드 안에서만. 달력 칸은 그대로 동그라미) */
.setcard .teamchip {width:auto; height:auto; border:0; border-radius:0; padding:0;
  background:none !important; color:var(--ink2) !important; font-family:var(--f-body); font-size:12px; font-weight:900;}
.setcard .teamchip::after {content:'팀';}

/* 콘티 카드(찬양 탭) 발: 전체 재생 · 가사만 단추, 가사 슬라이드는 조용한 글자 */
.setfoot .btn.slidefile{border:0; box-shadow:none; background:none; color:var(--ink2); padding:7px 4px; margin-left:auto;}

/* 곡 찾기: 거르개 두 칸 (키 · 템포). 거르는 중이면 칸이 켜진다 */
.uxfilters{display:flex; gap:8px; flex-wrap:wrap; margin:12px 0 6px;}
.uxsel{position:relative; display:inline-flex; align-items:center; gap:7px; min-height:40px; padding:0 34px 0 14px;
  border:1.5px solid var(--faint); border-radius:999px; background:var(--card); cursor:pointer;
  font-family:var(--f-body); font-size:13px; font-weight:800; color:var(--ink);}
.uxsel > span{color:var(--faint); font-size:12px;}
.uxsel select{appearance:none; -webkit-appearance:none; border:0; background:none; font:inherit; color:inherit;
  padding:8px 0; margin:0; outline:none; cursor:pointer;}
.uxsel::after{content:''; position:absolute; right:15px; top:50%; width:7px; height:7px; pointer-events:none;
  border-right:2px solid var(--ink2); border-bottom:2px solid var(--ink2); transform:translateY(-70%) rotate(45deg);}
.uxsel.on{border-color:var(--ink); border-width:2px; background:var(--accent-soft);}
.uxsel:focus-within{outline:2px solid var(--ink); outline-offset:2px;}
/* 곡 줄의 ＋ = 테두리 없이. 담으면 채운 동그라미(상태는 보이게) */
.qadd:not(.on){border-color:transparent; background:none;}
/* 섬김표 줄의 찬양 덩어리 = 인도 · 싱어 · 세션 명단(홈 카드와 같은 간격) */
.svrow.ux130 .svgrp.praise{display:flex; flex-direction:column; gap:8px;}
.svrow.ux130 .svgrp .ptiers{margin:0; gap:8px;}
.svrow.ux130 .rehsoon{margin:0;}

/* 공지·모임의 팀 딱지와 «14일 뒤» = 글자. «오늘» 만 칠한 채로 둔다(지금 일어나는 일이라는 신호) */
.tbadge{background:none !important; border:0 !important; padding:0 !important; font-size:11px; font-weight:900;}
.dchip:not(.now){background:none; border:0; padding:0; color:var(--ink2);}
.dchip.now{border:0; padding:2px 8px;}

/* 홈 순서(사용자 09-26 확인): 찾기 → 소통 링크 → 다음 섬김 → 공지 → 신청곡 → 일정 → 채널.
   예전엔 공지가 먼저라 돌아온 사람 첫 화면이 공지 다섯 장으로 찼고 «이번 주 누가 서나» 가 안 보였다 */
[data-view="home"] .sec.sec-duty{order:-1; margin-top:10px;}
[data-view="home"] .sec.sec-notice{margin-top:34px;}
/* 카드 안 «콘티 아직» 은 상태 글이다(단추 모양을 벗긴다). 리허설의 «주일 콘티 N곡» 은 그대로 링크 */
.spot.ux130 .contilab{border:0; box-shadow:none; background:none; padding:0 2px; min-height:0;
  font-family:var(--f-body); font-size:12.5px; font-weight:800; color:var(--ink2);}
.spot.ux130 a.contilab::after{content:' →';}
/* «정보» 한 치수 가볍게 — 줄마다 서 있는 글자라 목록보다 튀면 안 된다 */
.infobtn.wide:not(.up){font-size:11.5px; font-weight:700;}
.infobtn.wide:not(.up) .ic{width:13px !important; height:13px !important;}
/* 넓은 카드(태블릿·데스크톱)에서는 도구를 칸 폭으로만 — 카드 끝까지 벌려 세우지 않는다(짝 없는 늘이기 금지) */
@media (min-width:700px){
  .ux130 .uxtools{justify-content:flex-start; gap:4px;}
  .ux130 .uxtools .btn{flex:0 0 104px;}
}

/* ── 시안 C: 찾기 창 ───────────────────────────────────────────
   예전엔 홈 맨 위 찾기 줄이 문이었다(133 에서 뺐다). 133 에선 상단바 돋보기(`data-find`)가 문이다(어느 화면에서나) */
.shhead h3 > .ic{width:20px; height:20px; vertical-align:-4px; margin-right:6px;}
.fdres{margin-top:12px; padding-bottom:8px;}
.fdgrp + .fdgrp{margin-top:14px;}
.fdhd{font-size:11.5px; font-weight:900; color:var(--ink2); margin:0 2px 4px; letter-spacing:.02em;}
.fdrow{display:flex; align-items:center; gap:12px; width:100%; min-height:54px; padding:8px 6px;
  border:0; border-bottom:1.5px dashed rgba(11,42,68,.16); background:none; border-radius:0; cursor:pointer;
  font-family:var(--f-body); color:var(--ink); text-align:left; text-decoration:none;}
.fdrow:last-child{border-bottom:0;}
.fdrow:active{background:var(--paper);}
.fdrow > .ic:first-child{width:20px; height:20px; flex:none; color:var(--ink2);}
.fdrow > .ic:last-child{width:14px; height:14px; flex:none; margin-left:auto; color:var(--faint);}
.fdt{display:flex; flex-direction:column; min-width:0;}
.fdt b{font-size:15px; font-weight:800; line-height:1.35; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.fdt small{font-size:11.5px; font-weight:600; color:var(--faint); line-height:1.4; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.fdnone{padding:28px 8px; text-align:center; font-size:13.5px; font-weight:700; color:var(--ink2);}
/* 찾기 창은 늘 키 큰 창이다. 결과가 한 줄이어도 창이 바닥에 낮게 앉으면 폰 자판에 가려진다 → 칸이 위, 결과가 그 아래로 */
.fdres{min-height:calc(88vh - 170px);}

/* ══ UX 130 2차 (2026-09-27) — 같은 규칙을 앱 전체에 ══════════════════════════════════
   사용자(09-26): *"이 느낌대로 전체적으로 UI UX 감사를 해 주고 업데이트를 진행해 줘."*
   단추의 층 넷: ① 주 동작(채움) ② 보조(잉크 테두리) ③ 조용한 동작(테두리 없는 글자·아이콘) ④ 정보(글자).
   고르는 칩은 안 고른 것이 가볍고 고른 것만 볼록하다.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* 고르는 칩: 안 고른 것 = 흐린 선 · 그림자 없음, 고른 것 = 채움 + 잉크 선 + 단. 한 줄에 칩이 일곱이어도 무엇을 골랐는지만 튄다 */
.fchip{border:1.5px solid var(--faint); box-shadow:none; color:var(--ink2);}
.fchip.on{border:var(--bw) solid var(--ink); box-shadow:var(--sh-sm); color:#fff;}
.fchip:not(.on):active{background:var(--paper);}

/* 달 이름 = 제목 글자(누르는 게 아니다). 앞뒤 화살표만 단추. «콘티 8개» 도 글자 */
.monthbar .mlabel{background:none; border:0; box-shadow:none; transform:none; padding:4px 4px; min-width:0;}
.mlabel .mcount{border:0; background:none; box-shadow:none; padding:0; margin-left:8px;}

/* 달력: 요일 머리는 글자, 예배 없는 날은 칸을 그리지 않는다(눌러도 열 것이 없다). 예배 있는 날만 카드로 선다 */
table.hcal th{border:0; box-shadow:none; background:none !important; padding:4px 2px 2px;}
table.hcal td.wd, table.hcal td.out{border-color:transparent; box-shadow:none; background:transparent; cursor:default;}
table.hcal td.wd.today{border-color:transparent; box-shadow:none;}
table.hcal td.out .dt{opacity:.55;}

/* 지난 예배 · 지난 콘티 펼치기 = 조용한 글자 단추(목록 끝이라 제자리에서 보인다) */
.pastbar{border:0; box-shadow:none; background:none; color:var(--ink2); margin-top:16px; min-height:44px;}
.pastbar:active{background:rgba(255,255,255,.55);}

/* 신청곡 카드: 주 동작 = 전체 재생(다음 섬김 카드와 같은 잉크 채움), «지난 곡» 은 조용한 글자 */
.rsheadbtn.btn{border:0; box-shadow:none; background:none; color:var(--ink2); padding:5px 4px;}
.rsbundle .btn.rsall{background:var(--ink); border:var(--bw) solid var(--ink); color:var(--on-ink); box-shadow:var(--sh-sm);}
.rsbundle .btn.rsall .ic{fill:currentColor; stroke:none;}

/* 온 신청: 종류 · 완료 딱지 = 색 글자, 곡 줄 = 신청곡 카드와 같은 목록 줄(칸마다 테두리 없음) */
.req .kbadge{border:0; background:none !important; padding:0; font-size:11px; font-weight:900; margin-top:2px;}
.req .donechip{border:0; background:none; color:var(--sound); padding:0; font-size:11px; font-weight:900;}
.req .rsong{border:0; box-shadow:none; background:none; border-radius:0; padding:8px 0;}
.req .rsong + .rsong{border-top:1px dashed var(--faint);}
.req .rslist{margin-top:6px;}

/* 팀 탭: 머리의 사람 수 · 다음 섬김 = 글자, 세션 악기 = 이름 옆 흐린 글자(명찰 안의 알약 한 겹을 걷는다) */
.teamcard .tcount{border:0; background:none; box-shadow:none; transform:none; padding:0;}
.tnext{border:0; background:none; box-shadow:none; transform:none; padding:0; font-size:11.5px;}
.tsnext{border:0 !important; background:none !important; box-shadow:none; padding:0 !important;}

/* 방음 A팀 · B팀 = 이름 글자 줄. 위 명찰과 같은 사람들이라 명찰을 두 번 세우지 않는다 */


/* 곡 듣기 창: «1 / 5» = 글자, 섞기 · 반복 = 테두리 없는 아이콘(켜지면 잉크로 채운다, 뮤직 앱과 같은 문법) */
.plcount{border:0; background:none; padding:0 4px;}
.plmode{border-color:transparent; box-shadow:none; background:none;}
.plmode.on{background:var(--ink); color:var(--on-ink);}

/* 곡 정보 창: 가수 · 키 · 템포 = 글자. 주 동작은 «들어보기» 하나, «크게 보기» 는 흰 단추, «다운로드» 는 조용한 글자 */
.sdchips{gap:4px 14px;}
.sdchip{border:0 !important; background:none !important; padding:0 !important; color:var(--ink2); font-size:12.5px;}
.sdchip.resp{color:var(--accent-ink);}
.sdchip.none{color:var(--faint);}
.lyrwrap .lyrbig{background:var(--card); color:var(--ink);}
.lyrhead .lyrdl{border:0; box-shadow:none; background:none; color:var(--ink2);}

/* 곡 찾기 «부른 적 없음» = 흐린 글자 */
.nschip{border:0 !important; background:none !important; padding:0 !important; color:var(--faint) !important;}

/* 자료실(폰): 팀마다 카드 한 장 안의 목록. 줄마다 카드였던 것을 한 장으로 묶는다(신청곡 카드와 같은 문법).
   넓은 화면은 그대로 타일(97차-b, 한 줄로 늘이면 오른쪽이 빈다) */
@media (max-width:699px){
  .reslist{gap:0; background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-m);
    box-shadow:var(--sh-sm); overflow:hidden;}
  .reslist .res{border:0; border-radius:0; box-shadow:none;}
  .reslist .res + .res{border-top:1.5px dashed rgba(11,42,68,.18);}
  .reslist .res:active{transform:none; background:var(--paper);}
}

/* 피드백 «내 팀» 고르기 칸: 폭은 글자만큼 */
.uxsel.fbteam{padding-left:14px; margin:0 0 4px;}

/* 섬김표 목록 칸이 340px 아래로 안 줄어서 344 폰에서 화면이 옆으로 13px 밀렸다(라이브에도 있던 것). 칸 최소를 화면 폭으로 묶는다 */
[data-view="plan"] .svlist{grid-template-columns:repeat(auto-fill,minmax(min(340px,100%),1fr));}

/* 인도 줄 끝의 «A팀» = 조용한 글자(누르면 그 팀 명단) */
.ux130 .uxteam{font-size:12px; font-weight:800; color:var(--ink2); cursor:pointer; margin-left:2px;}
.ux130 .uxteam:active{color:var(--ink);}

/* ══ UX 130 3차 (2026-09-27) — 팀 탭도 같은 문법 ══════════════════════════════════════
   사용자: *"디자인은 통일시켜 주고"*. 명찰 벽(잉크 테두리 이름표 + 역할 아이콘)을 걷고 다음 섬김 카드와 같은
   «이름표 | 이름 글자» 줄로. 이름을 누르면 그대로 프로필이 뜬다. 역할 색은 줄 머리 글자가 맡는다.
   ═════════════════════════════════════════════════════════════════════════════════════ */
.ptiers.teamtiers{display:flex; flex-direction:column; gap:11px; margin:0; padding:14px 16px 18px;}
.teamtiers .ptrow{gap:12px; align-items:baseline;}
.teamtiers .ptk{width:30px; flex:none;}
.teamtiers .ptag{font-size:15px;}
.teamtiers .avghd{margin:8px 0 0; padding-top:14px; border-top:2px solid var(--paper2);}
.teamtiers .avgwhen{font-size:11px; font-weight:700; color:var(--faint); align-self:center;}
.teamcard.av .avghd b{font-size:12.5px;}
/* 팀 명단 창(A팀 · B팀 누르면): 창 안쪽은 이미 여백이 있다 */
.sheet .ptiers.teamtiers{padding:4px 0 8px;}

/* ══ 131차 (2026-09-29) — 입장권 · New ════════════════════════════════════════════════
   ① 입장 화면 = 입장권 한 장. 상단바의 교회 우표(`.bartip`)와 큐카드의 절취선(`.cut`)을 그대로 빌린다. 새 모양·새 색은 없다.
   ② New = 처음 부르는 곡. 테두리 없는 글자(UX 130: 정보는 단추 모양을 안 입는다). 색은 제목 옆 ▶ 와 같은 찬양 색.
   never: 입장 화면에 설명 문단 · 두 번째 단추 · 블러 그림자. New 에 알약 · 테두리 · 배경 · 깜빡임.
   ═════════════════════════════════════════════════════════════════════════════════════ */
body.gated .topbar, body.gated .tabbar, body.gated .deskNav, body.gated .syncbar, body.gated .hubfoot{display:none !important;}
body.gated{padding-bottom:0;}
/* 카드는 위쪽 가운데. 폰 아래 절반은 바닥 교회 그림 자리라 그걸 덮지 않는다 */
.gatewrap{display:flex; align-items:center; justify-content:center; box-sizing:border-box;
  min-height:calc(100vh - 64px); min-height:calc(100dvh - 64px); padding:34px 0 22vh;}
.gatecard{position:relative; box-sizing:border-box; width:100%; max-width:360px; padding:30px 22px 20px; text-align:center;
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:var(--r-xl); box-shadow:0 5px 0 var(--ink);}
/* 우표: 상단바 우표를 조금 키워 카드 모서리에 붙인다(카드 위로 반쯤 나오게, 붙인 우표) */
.bartip.gatestamp{position:absolute; top:-30px; right:12px; width:96px; height:68px; margin:0; transform:rotate(6deg);}
.gatehead{display:flex; flex-direction:column; align-items:center; gap:9px; margin:0 0 18px;}
.gatelogo{width:52px; height:52px; display:block;}
.gatename{margin:0; font-family:var(--f-disp); font-weight:900; font-size:25px; letter-spacing:-.4px; line-height:1.15; color:var(--ink);}
/* 절취선 구멍이 카드 테두리 위에 오게 (카드 안 여백 22 + 테두리 반) */
.gatecard .cut{margin:0 0 18px;}
.gatecard .cut::before{left:-31px;} .gatecard .cut::after{right:-31px;}
.gateform{display:flex; flex-direction:column; gap:10px;}
.gatelab{font-size:12px; font-weight:800; color:var(--ink2);}
.gateform input{box-sizing:border-box; width:100%; padding:12px 14px; text-align:center;
  font-family:var(--f-body); font-size:18px; font-weight:800; letter-spacing:.04em; color:var(--ink);
  background:var(--card); border:var(--bw) solid var(--ink); border-radius:14px;}
.gateform input:focus{outline:0; box-shadow:0 0 0 3px var(--accent);}
.gatego{width:100%; min-height:48px; font-size:15.5px; border-radius:14px;}
.gateform .formmsg{margin:0; min-height:18px;}
.gatehint{margin:4px 0 0; font-size:12px; font-weight:600; color:var(--faint);}

/* New: 제목 아래 딱지 줄 맨 앞(«New 한영 · 빠름»). 옆 딱지들과 같은 크기의 글자, 색만 찬양 색으로 */
.songrow .stags > .newtag{font-family:var(--f-body); font-size:11px; font-weight:900; letter-spacing:.02em; color:var(--praise);}

/* 곡 찾기 «부른 횟수» 로 거를 때만 줄마다 붙는 «N번 부름» (131차-b). **제목 아래 한 줄**(줄의 맨 끝 순서 + 한 줄 다 쓰기).
   ⚠ 제목 바로 뒤에 두었더니 390 에서 101줄 중 64줄의 단추 묶음(템포 · 키 · ＋ · 정보)이 아랫줄로 떨어져 줄마다 모양이 들쭉날쭉했다(원래 21줄).
     아래로 내리니 단추는 제자리이고 숫자가 왼쪽에 세로로 줄을 맞춘다(많이 부른 순이라 훑어 내려가기 좋다) */
.songtable .srow .sncount{order:3; flex-basis:100%; margin:-5px 0 0; font-family:var(--f-body); font-size:11px; font-weight:800;
  color:var(--ink2); white-space:nowrap;}

/* ══════════════════════════════════════════════════════════════════════════════════════
   UX 133 «새싹» 스킨 (2026-09-30) · 정본 기록 `docs/UX-133.md`
   사용자: *"바로 틀면 필요한 정보들이 한눈에 다 들어오고, 기능이 너무 많아 복잡해 보이지 않고"* ·
   *"청년부랑 어울리는 푸릇푸릇한 느낌, 보기만 해도 기분이 좋은 편안한 경험"*
   ⚠ 이 블록이 **앞의 같은 선택자를 덮는다**(`html.sp` 를 앞에 붙여 한 단 무겁다). 옛 규칙을 고치기 전에 여기부터 볼 것.
      `<html class="sp">` 를 떼면 옛 «SEASIDE v5» 로 돌아간다(되돌리기 = index.html 한 글자).
   색 = 카리스 로고 클로버 네 잎에서만 뽑는다(`logo.svg`): 잎 #8FCB9B · 하늘 #6192CD · 코랄 #DC7273 · 해 #F2E06B.
        글자·단추용 진한 판은 같은 색상(H)에서 흰 바탕 대비 4.5:1 을 넘게 계산한 값이다(잎 #268238 4.85:1 · 하늘 #2E588A 7.3:1 ·
        코랄 #A8393C · 해 #776B22 5.4:1). 하늘 사진은 사용자가 고른 «청량» 그 사진(`/sky/sp-day.webp`).
   never (133):
   - **담는 상자에 잉크 테두리·단단한 그림자를 입히지 않는다.** 카드·구역·목록은 흰 면 하나. 그 옷은 «누르는 것» 과
     시그니처(내 섬김 티켓) 차지다. 130차 «누르는 것만 단추 모양» 을 상자에까지 넓힌 것이다.
   - 블러 그림자 금지(그대로). 단추 밑 단은 블러 0 · 낮은 투명도의 같은 색.
   - 바탕은 민트빛 흰색 하나(`--page`). 시각·계절은 **홈 하늘 머리 안에서만** 보인다. 화면 바닥 교회 그림·하늘 층은 끈다.
   - 탭 색 = 그 탭의 클로버 잎(홈 잎 · 섬김표 하늘 · 찬양 코랄 · 팀 해). 더보기는 무채색.
   - 저대비 베이지 헤어라인을 카드 테두리로 쓰지 않는다(v3 기각 지문). 카드 안 줄 나눔만 옅은 선 1px.
   ══════════════════════════════════════════════════════════════════════════════════════ */
html.sp{
  --page:#F3F8F4; --page2:#EBF3ED;
  --sp-leaf:#8FCB9B; --sp-leaf-50:#EEF8F0; --sp-leaf-100:#DDF1E1; --sp-leaf-600:#268238; --sp-leaf-700:#1D722E; --sp-leaf-800:#155323;
  --sp-sky:#6192CD;  --sp-sky-50:#EEF3FA;  --sp-sky-100:#DCE7F5;  --sp-sky-700:#2E588A;
  --sp-coral:#DC7273;--sp-coral-50:#FBEEEE;--sp-coral-100:#F6DCDC;--sp-coral-700:#A8393C;
  --sp-sun:#F2E06B;  --sp-sun-50:#FBF7E2;  --sp-sun-100:#F6EDB6;  --sp-sun-700:#776B22;
  --sp-line:#E3ECE6;  --sp-line2:#D3E0D7;
  --sp-ledge:var(--sp-line2);   /* 누르는 것 밑 단(옅은 단). 어두운 시각엔 어두운 그림자가 된다(133차-e) */
  --sp-sub:#5B7385;
  --sp-lift:0 3px 0 rgba(11,42,68,.13);
  --sp-r:22px;
  /* 진한 칠(배경) = 글자색 -700 과 같은 값. 어두운 시간대엔 글자색 토큰만 밝아지고 칠은 그대로 진하다(133차-e) */
  --sp-coral-fill:#A8393C; --sp-sky-fill:#2E588A; --sp-leaf-fill:#1D722E; --sp-sun-fill:#776B22;
  /* 옛 규칙이 쓰는 토큰을 새 값으로 — 고친 자리가 아니어도 같은 옷이 된다 */
  --card-gut:16px;
  --sh:none;
  --sh-sm:0 2px 0 rgba(11,42,68,.12);
  --deck:transparent;
  --accent:var(--sp-leaf-600); --accent-soft:var(--sp-leaf-100); --accent-ink:var(--sp-leaf-700); --accent-line:var(--sp-leaf-600);
  --muted:var(--sp-sub);
  background-color:var(--page); background-image:none;
}
html.sp body{background-color:var(--page); background-image:linear-gradient(180deg, var(--page) 0, var(--page2) 100%);}
html.sp body::after, html.sp .sky{display:none;}
/* 홈 화면 앱(iOS)은 애플이 상태바를 흰색으로 고정한다(107차). 133 에선 덮개(sbveil) 대신 **상단바 자체가 흰색에서 바탕색으로** 번진다 */
html.sp.iosapp, html.sp.iosapp body{background-image:linear-gradient(180deg, var(--page) 0, var(--page2) 100%);}

/* ── 상단바 ───────────────────────────────────────────
   홈 = 하늘 머리 위에 투명하게(제목은 하늘 머리가 한다). 다른 화면 = 바탕색 띠 + 화면 제목. 상자·테두리 없음 */
html.sp .topbar{position:sticky; top:0; z-index:40; padding:0 12px; background:var(--page);}
html.sp.iosapp .topbar{padding-top:0;}   /* 133차-f: 흰 번짐을 뺐다. 상태바가 theme-color(바탕색)로 칠해지니 상단바도 바탕색 그대로다 */
html.sp .topbar .in{display:flex !important; align-items:center; gap:6px; max-width:720px; height:56px; margin:0 auto; padding:0 2px;
  background:none; border:0; border-radius:0; box-shadow:none;}
html.sp .topbar .tile, html.sp .topbar .tile img{width:30px; height:30px;}
html.sp .logo{flex:none; align-self:center;}
html.sp .topbar .tile{align-self:center; margin-right:2px;}
html.sp .logo .nm{font-size:17px; letter-spacing:-.3px; color:var(--ink);}
html.sp .logo .nm small{display:none;}
html.sp .topbar .bartip, html.sp .nowplate{display:none !important;}
html.sp .sp-title{display:none; font-family:var(--f-disp); font-weight:900; font-size:20px; letter-spacing:-.4px; color:var(--ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0;}
html.sp:not([data-page="home"]) .logo .nm{display:none;}
html.sp .sp-title i{font-family:var(--f-latin); font-style:normal; font-weight:500; font-size:11.5px; letter-spacing:.06em; color:var(--sp-sub); margin-left:7px;}
html.sp:not([data-page="home"]) .sp-title{display:block;}
html.sp .sp-tbacts{margin-left:auto; display:flex; align-items:center; gap:6px; flex:none;}
html.sp .sp-find{width:40px; height:40px; border:0; border-radius:50%; background:transparent; color:var(--ink);
  display:inline-flex; align-items:center; justify-content:center; cursor:pointer;}
html.sp .sp-find .ic{width:22px; height:22px; stroke-width:2.3;}
html.sp .sp-find:active{background:rgba(11,42,68,.07);}
html.sp .sp-save{display:inline-flex; align-items:center; gap:5px; height:32px; padding:0 12px 0 10px; border:0; border-radius:999px;
  background:rgba(255,255,255,.86); color:var(--sp-leaf-700); font-family:var(--f-body); font-size:12.5px; font-weight:900; cursor:pointer;
  box-shadow:0 2px 0 rgba(11,42,68,.10);}
html.sp .sp-save .ic{width:15px; height:15px;}
html.sp .sp-save[hidden]{display:none;}
html.sp:not([data-page="home"]) .sp-save{display:none;}
/* 상단바 자물쇠(리더 로그인 · «팀장» 딱지)는 133 에서 뺐다. 사용자: *"오른쪽 위에 저 팀장 저것도 필요 없을 것 같아. 팀장은 나 포함해서 세 명인데
   이거 때문에 오른쪽 위를 차지하는 게 맞는지. 팀장 로그인할 수 있는 스위치를 크게 눈에 띄지 않는 곳에 넣는 거지."*
   → 리더 문 = 더보기 맨 아래 작은 «리더 로그인» 글자. 로그인한 리더는 더보기의 «관리자» 줄(할 일 숫자) · 더보기 탭 배지 · 홈 맨 위 할 일 띠로 들어간다.
   (3주 동안 팀원 기기 31대가 자물쇠를 눌러 봤다 = 리더가 아닌 사람에게 그 자리는 헷갈리는 단추였다) */
html.sp .adminBtn{display:none !important;}
/* 홈: 상단바가 하늘 위에 뜬다 */
html.sp[data-page="home"] .topbar{position:absolute; left:0; right:0; background:transparent;}
/* 홈 화면 앱의 홈 = 흰 상단바(상태바와 한 면) 밑에서 하늘이 시작한다. 하늘 위에 띄우면 흰 상태바와 밤하늘 사이에 선이 생긴다 */
/* 133차-f: 홈 화면 앱의 홈도 브라우저처럼 상단바가 하늘 위에 투명하게 뜬다(예전엔 흰 상태바에 맞춰 흰 상단바였다) */
html.sp[data-page="home"][data-tod="dawn"] .logo .nm, html.sp[data-page="home"][data-tod="evening"] .logo .nm,
html.sp[data-page="home"][data-tod="night"] .logo .nm{color:#fff;}
html.sp[data-page="home"][data-tod="dawn"] .sp-find, html.sp[data-page="home"][data-tod="evening"] .sp-find,
html.sp[data-page="home"][data-tod="night"] .sp-find{color:#fff;}

/* ── 아래 탭 다섯 ──────────────────────────────────── */
html.sp .tabbar{background:var(--card); border-top:1px solid var(--sp-line); box-shadow:none; gap:0;
  height:calc(64px + env(safe-area-inset-bottom)); padding:6px 4px calc(env(safe-area-inset-bottom) + 6px);}
html.sp .tabbar a{max-width:none; gap:3px; color:var(--dk-sub, #7C909D); font-size:11px; font-weight:700; letter-spacing:-.2px;
  border:0 !important; border-radius:0; background:none !important; box-shadow:none !important; transform:none;}
html.sp .tabbar a .ic{width:22px; height:22px; padding:4px 15px; box-sizing:content-box; border-radius:16px 6px 16px 6px;
  transition:background-color .18s ease, color .18s ease;}
html.sp .tabbar a.on{color:var(--ink); font-weight:900; transform:none; box-shadow:none;}
html.sp .tabbar a.on .ic{animation:none; stroke-width:2.4;}
html.sp .tabbar a[data-nav="#/home"].on .ic{background:var(--sp-leaf-100); color:var(--sp-leaf-700);}
html.sp .tabbar a[data-nav="#/plan"].on .ic{background:var(--sp-sky-100); color:var(--sp-sky-700);}
html.sp .tabbar a[data-nav="#/praise"].on .ic{background:var(--sp-coral-100); color:var(--sp-coral-700);}
html.sp .tabbar a[data-nav="#/team"].on .ic{background:var(--sp-sun-100); color:var(--sp-sun-700);}
html.sp .tabbar a[data-nav="#/more"].on .ic{background:var(--dk-track, #E8EDF0); color:var(--ink);}
html.sp .tabbar a:active .ic{transform:scale(.92);}
/* 더보기 배지 = 리더의 할 일(자물쇠 숫자와 같은 수) */
html.sp .tabbar a[data-nav="#/more"]{position:relative;}
html.sp .tabbar .sp-tabdot{position:absolute; top:3px; right:calc(50% - 30px); min-width:17px; height:17px; padding:0 5px; border-radius:999px;
  background:#E5484D; color:#fff; font-size:10px; font-weight:900; line-height:17px; text-align:center; box-sizing:border-box;}

/* ── 본문 ─────────────────────────────────────────── */
html.sp .view{max-width:720px; padding:8px 16px 40px;}
html.sp[data-page="home"] .view{padding-top:0;}
html.sp .hubfoot{display:none;}
html.sp .syncbar{background:none;}

/* ── 홈 하늘 머리 ─────────────────────────────────────
   그 시각의 하늘 + 그 계절·시각의 우리 교회(`--shore`, 100차 그림). 낮은 사용자가 고른 «청량» 하늘 사진, 새벽·저녁·밤은 그 시각 하늘색.
   교회는 오른쪽 아래에 작게 — 글자(인사)는 왼쪽 위라 안 겹친다. 바닥은 바탕색으로 물들어 아래 카드와 이어진다. */
.sp-hero{position:relative; margin:0 -16px; height:calc(232px + var(--top-safe)); overflow:hidden; isolation:isolate;
  color:var(--ink);}
.sp-sky{position:absolute; inset:0; z-index:-2;
  background:url("/sky/sp-day.webp") 30% 40%/cover no-repeat, linear-gradient(110deg,#C6E6DC 0,#9CC9EE 100%);}
html[data-tod="dawn"] .sp-sky{background:linear-gradient(180deg, var(--sky1) 0, var(--sky2) 52%, var(--sky3) 100%);}
html[data-tod="evening"] .sp-sky{background:linear-gradient(180deg, var(--sky1) 0, var(--sky2) 55%, var(--sky3) 100%);}
html[data-tod="night"] .sp-sky{background:linear-gradient(180deg, #0B1F4D 0, #153A73 60%, #2E5C96 100%);}
html[data-tod="afternoon"] .sp-sky{background:url("/sky/sp-day.webp") 30% 40%/cover no-repeat, linear-gradient(110deg,#C6E6DC,#9CC9EE);
  filter:saturate(1.05);}
/* 해 = 그 시각 자리(103차 `--sun` 을 그대로 빌린다). 낮엔 사진이 이미 밝아서 안 얹는다 */
.sp-sun, .sp-stars{position:absolute; inset:0; display:block; pointer-events:none;}
html[data-tod="dawn"] .sp-sun, html[data-tod="evening"] .sp-sun{background:var(--sun, none);}
.sp-stars{opacity:0; top:52px;}   /* 상단바 줄에는 별을 안 둔다(메뉴 사이 별이 구분점으로 읽혔다) */
html[data-tod="night"] .sp-stars, html[data-tod="evening"] .sp-stars{opacity:var(--starop, 0);
  background-image:
  radial-gradient(2.6px 2.6px at 8% 22%, #fff 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2px 2px at 20% 48%, rgba(255,255,255,.9) 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2.8px 2.8px at 33% 14%, #fff 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2px 2px at 46% 36%, rgba(255,255,255,.85) 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2.4px 2.4px at 58% 10%, #fff 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2px 2px at 71% 28%, rgba(255,255,255,.9) 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2.8px 2.8px at 86% 16%, #fff 0 34%, rgba(255,255,255,0) 72%),
  radial-gradient(2px 2px at 94% 40%, rgba(255,255,255,.8) 0 34%, rgba(255,255,255,0) 72%);
  background-repeat:no-repeat;}
.sp-art{position:absolute; right:-6px; bottom:22px; width:min(62%, 300px); height:168px; z-index:-1;
  background:var(--shore) right bottom/contain no-repeat;}
/* 아래 끝은 바탕색으로 물든다 — 하늘 사진이 칼로 자른 선으로 끝나지 않게 */
.sp-hero::after{content:''; position:absolute; left:0; right:0; bottom:0; height:46px; z-index:-1;
  background:linear-gradient(180deg, transparent 0, var(--page) 88%);}
.sp-herotx{position:absolute; left:16px; right:16px; top:calc(62px + var(--top-safe));}
.sp-date{margin:0; display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-family:var(--f-body); font-size:13.5px; font-weight:800; letter-spacing:-.2px; color:var(--ink2);}
.sp-wx{display:inline-flex; align-items:center; gap:4px; padding:3px 9px 3px 6px; border-radius:999px;
  background:rgba(255,255,255,.62); color:var(--ink);}
.sp-wx:empty{display:none;}
.sp-wx .wxi{width:16px; height:16px;}
.sp-wx b{font-weight:900;}
.sp-wxko{font-weight:700; color:var(--ink2);}
.sp-hello{margin:6px 0 0; max-width:62%; font-family:var(--f-disp); font-weight:900; font-size:25px; line-height:1.25; letter-spacing:-.6px;
  color:var(--ink); word-break:keep-all;}
html[data-tod="dawn"] .sp-hero, html[data-tod="evening"] .sp-hero, html[data-tod="night"] .sp-hero{color:#fff;}
html[data-tod="dawn"] .sp-date, html[data-tod="evening"] .sp-date, html[data-tod="night"] .sp-date{color:rgba(255,255,255,.88);}
html[data-tod="dawn"] .sp-hello, html[data-tod="evening"] .sp-hello, html[data-tod="night"] .sp-hello{color:#fff;}
html[data-tod="dawn"] .sp-wx, html[data-tod="evening"] .sp-wx, html[data-tod="night"] .sp-wx{background:rgba(255,255,255,.16); color:#fff;}
html[data-tod="dawn"] .sp-wxko, html[data-tod="evening"] .sp-wxko, html[data-tod="night"] .sp-wxko{color:rgba(255,255,255,.82);}

/* ── 홈 본문 ─────────────────────────────────────── */
.sp-home{position:relative; z-index:1; display:flex; flex-direction:column; margin-top:-34px;}
.sp-home > * + *{margin-top:22px;}
/* 접힌 신청곡 줄(.sp-ask)은 뒤쪽 .sp-ask{margin:0} 이 무게가 같아 위 간격을 지웠다. 그래서 «다음 예배» 카드에 딱 붙었다(10-05 JH «딱 붙어있는데 의도한거야?»).
   무게를 한 단 올려 되살린다. 아래 .fbalert + * 규칙이 더 뒤라 알림 띠 바로 밑이면 그 12px 이 그대로 이긴다 */
.sp-home > * + .sp-ask{margin-top:22px;}
/* 133-b: 맨 앞이 티켓 · 할 일 띠 · 생일 카드(하늘 끝에 겹쳐 앉는 흰 면)가 아니라 바로 «다음 예배» 제목이면(교회 컴퓨터, 이름을 안 고른 폰) 하늘 그림 위에 제목이 얹히지 않게 내린다 */
.sp-home > .sp-sec:first-child{padding-top:30px;}
.sp-home > .fbalert + *{margin-top:12px;}
.sp-sec{margin-left:0; margin-right:0;}
.sp-sechd{display:flex; align-items:flex-end; gap:10px; margin:0 2px 10px;}
.sp-sechd h2{margin:0; display:flex; align-items:baseline; gap:7px; font-family:var(--f-disp); font-weight:900; font-size:19px; letter-spacing:-.4px; color:var(--ink);}
.sp-sechd h2 i{font-family:var(--f-latin); font-style:normal; font-weight:500; font-size:11.5px; letter-spacing:.06em; color:var(--sp-sub);}
.sp-more{margin-left:auto; display:inline-flex; align-items:center; gap:2px; padding:4px 2px; text-decoration:none;
  font-size:13px; font-weight:800; color:var(--sp-leaf-700); white-space:nowrap;}
.sp-more::after{content:''; width:7px; height:7px; margin-left:3px; border-right:2px solid currentColor; border-top:2px solid currentColor; transform:rotate(45deg);}
.sp-empty{padding:22px 16px; border-radius:var(--sp-r); background:var(--card); text-align:center; font-size:14px; font-weight:700; color:var(--sp-sub);}

/* ⭐ 시그니처 = 내 섬김 티켓. 이 앱에서 잉크 테두리 + 단단한 그림자를 입는 큰 카드는 이것 하나(누르면 그 예배가 열린다).
   절취선과 양쪽 반달 홈은 입장권(131차 `.cut`)과 같은 문법. 오른쪽 칸 = 며칠 남았나 */
.sp-ticket{--tk:var(--sp-leaf-100); --tki:var(--sp-leaf-700);
  position:relative; display:flex; align-items:stretch; width:100%; padding:0; margin:0; text-align:left; cursor:pointer;
  font-family:var(--f-body); color:var(--ink); background:var(--card);
  border:2.5px solid var(--ink); border-radius:26px; box-shadow:0 5px 0 var(--ink); overflow:visible;
  transition:transform .08s ease, box-shadow .08s ease;}
.sp-ticket:active{transform:translateY(4px); box-shadow:0 1px 0 var(--ink);}
.sp-ticket.t-lead{--tk:var(--sp-sun-100); --tki:var(--sp-sun-700);}
.sp-ticket.t-vocal{--tk:var(--sp-coral-100); --tki:var(--sp-coral-700);}
.sp-ticket.t-bcast{--tk:var(--sp-sky-100); --tki:var(--sp-sky-700);}
.sp-ticket.t-sound{--tk:var(--sp-leaf-100); --tki:var(--sp-leaf-700);}
.sp-ticket.t-session{--tk:#E9E1FA; --tki:#5A3FA8;}
.tk-main{flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; padding:13px 14px 14px 16px;}
.tk-lab{font-size:12px; font-weight:900; letter-spacing:-.1px; color:var(--sp-sub);}
.tk-date{font-family:var(--f-disp); font-weight:900; font-size:34px; line-height:1.05; letter-spacing:-1px; margin-top:2px; white-space:nowrap;}
.tk-date small{font-family:var(--f-body); font-size:15px; font-weight:900; letter-spacing:0; margin-left:5px; color:var(--ink2);}
/* 133차-h 여덟째 판: 말랑 탑승권. 예배 이름 옆 장소 · 탑승권 칸(작은 이름표 위, 값 아래) · 동그란 구멍 절취선 · 바코드 · 반짝 두 줄 · 친구 스티커 */
.tk-svc{display:flex; align-items:baseline; gap:7px; flex-wrap:wrap; margin-top:3px; font-size:15.5px; font-weight:900;}
.tk-svc em{font-style:normal; font-size:12.5px; font-weight:800; color:var(--sp-sub);}
.tk-grid{display:grid; grid-auto-flow:column; grid-auto-columns:max-content; justify-content:start; margin-top:10px; padding-top:9px;
  border-top:1.5px dashed var(--sp-line2);}
.tk-cell{display:flex; flex-direction:column; gap:2px; min-width:0; padding:0 12px;}
.tk-cell:first-child{padding-left:0;}
.tk-cell + .tk-cell{border-left:1.5px solid var(--sp-line);}
.tk-cell i{font-style:normal; font-size:11px; font-weight:800; color:var(--sp-sub);}
.tk-cell b{font-size:14px; font-weight:900; white-space:nowrap; letter-spacing:-.2px;}
.tk-cell.seat b{color:var(--tki);}
@media (max-width:375px){ .tk-cell{padding:0 9px;} .tk-cell b{font-size:13px;} }
@media (max-width:350px){ .tk-cell{padding:0 7px;} .tk-cell b{font-size:12.5px; letter-spacing:-.4px;} }
/* 절취선 점은 위아래 반달 홈 사이에만 고르게(space, 안쪽 여백 13px 안). 예전엔 칸 끝까지 이어져 맨 위 점이 테두리에 잘리고 아래 홈 위에 점이 얹혔다(JH 10-03) */
.tk-stub{position:relative; flex:none; width:88px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px;
  padding:13px 0; border-radius:0 23px 23px 0;
  background:radial-gradient(circle, var(--ink) 2.3px, transparent 2.8px) 0 0 / 7px 11px no-repeat space content-box, var(--tk);}
.tk-stub b{font-family:var(--f-disp); font-weight:900; font-size:25px; letter-spacing:-.6px; color:var(--tki);}
.tk-stub small{font-size:11px; font-weight:800; color:var(--tki); opacity:.85;}
/* 바코드는 진짜 Code 128(app.js tkBarcode, 예배 날짜 MMDD). 한 칸 1px, 57칸이라 57px. 막대는 잉크색, 모서리 없음(JH "너무 둥글둥글해서 바코드같이 안 보이는데") */
.tk-bar{display:block; width:57px; height:20px; margin-top:9px; fill:var(--ink); shape-rendering:crispEdges;}
/* 그루터기 글 · 바코드는 절취선 점 줄(왼쪽 7px)을 뺀 칸의 가운데에(JH "바코드 왼쪽에 있는 경계선 절단선이 너무 걸쳐 있는 것 같지 않아?").
   점 줄은 바탕 무늬(content-box)라 그루터기 안쪽 여백은 못 건드린다. 그래서 글마다 왼쪽에 7px 를 둔다(가운데 맞춤이 그만큼 오른쪽으로 3.5px) */
.tk-stub > *{margin-left:7px;}
/* 그루터기 오른쪽 위에 있던 흰 반짝 두 줄은 걷었다(JH "오른쪽 위에 랜덤하게 너겟 두개 있는데 이건 뭐야?", 뜻 없는 장식은 추측하게 만든다) */
/* 친구 스티커: 날짜 오른쪽 흰 자리에 살짝 기울여 붙인다. 흰 칼선과 그림자는 그림에 구워 있다(기울인 그림에 filter 금지, 95차-b).
   열 때마다 바뀌면 한 번 «착» 붙는다(.pop). 움직임 줄이기면 그냥 놓인다.
   ⭐ 자리 = 머리 글(내 다음 섬김 · 날짜 · 예배) 오른쪽 끝에서 **36px**, 머리 글의 위아래 가운데. 기울기는 그대로(133차-h 아홉째 판 뒤).
   JH: "웹에서 보니까 또 너무 스티커만 중간에 떡하니 떨어져 있어 보이네 ... 비율로 고정보단 그냥 왼쪽 텍스트에서 거리를 고정하는게".
   황금비로 빈칸을 나누면 폰(393 에서 32px · 430 에서 55px)은 괜찮은데 넓은 화면(720 칸)은 234px 떨어져 혼자 떴다.
   36 은 그 무렵 폰(393 · 402)의 황금비 자리다. 좁은 폰은 빈칸이 모자라 틈이 먼저 줄고 오른쪽은 8px 를 남긴다.
   ⚠ 격자(minmax(0, 36px))로 짜면 빈칸이 모자랄 때 격자가 틈과 글 칸에 남는 폭을 똑같이 나눠 줘서 글 칸이 먼저 줄었다
     (320 에서 날짜 103px 가 92px 칸에 끼어 틈으로 넘쳤다, 실측). 그래서 flex 로 짠다: 틈(::before)은 줄어드는 힘이 1000배라
     먼저 0 까지 줄고, 그다음에야 글이 준다. 오른쪽 빈칸(::after)은 늘기만 하고 8px 밑으로는 안 준다.
   지나온 판: 절취선에서 8px 띄우기(절취선에 붙음) → 위 · 오른쪽 모서리 맞추기(넓은 폰에서 왼쪽 빈칸이 큼) → 빈칸 가운데(티켓 가운데가 떠 보임)
   → 빈칸 황금비(넓은 화면에서 혼자 뜸) → 글에서 고정 거리
   10-07: 320, 360, 375 폭에서 요일 "일" 이 날짜 밑 줄로 혼자 떨어졌다. 틈은 아직 5px 넘게 남아 있었다.
     줄어드는 힘이 1000배여도 글 칸이 받는 몫은 0 이 되지 않아서 글 칸이 0.1px 쯤 같이 줄었고(320 에서 0.11, 375 에서 0.03),
     날짜 줄이 글 칸과 같은 폭이라 그만큼만 줄어도 요일이 다음 줄로 갔다. 숫자와 한글 사이는 keep-all 이어도 끊길 수 있는 자리다.
     그래서 날짜 줄은 끊지 않고(.tk-date 의 nowrap), 글 칸은 날짜 폭보다 좁아지지 않는다(min-width:min-content). 모자란 폭은 틈이 다 받는다.
     가장 넓은 날짜(10/30 금, 125px)도 320 에서 틈 3px 를 남기고 들어간다. 390 이상은 줄어들 일이 없어서 그대로다 */
.tk-head{display:flex; align-items:center;}
.tk-headtx{order:1; flex:0 1 auto; display:flex; flex-direction:column; gap:1px; min-width:min-content;}
.tk-head::before{content:''; order:2; flex:0 1000 36px; min-width:0;}
.tk-sticker{order:3; flex:none; width:64px; height:64px; transform:rotate(9deg); pointer-events:none;}
.tk-head::after{content:''; order:4; flex:1 0 8px;}
/* 로고 워터마크(JH "진짜 티켓처럼 너무 bother 안 되고 깔끔하게 새한 카리스 주일로고 워터마크"). 티켓 몸통 맨 아래 띠에 잉크색 9% 로 찍는다.
   종이 티켓 아래 인쇄된 상호처럼. 모양(mask)이라 밤엔 밝은 잉크로 같이 바뀐다.
   ⭐ 예배마다 그 예배 커버의 로고다(133차-h 아홉째 판, JH: "주일 예배면 새한 사피스 주일 예배 로고랑, 부트면 브레이크스루 로고랑, 리허설이면 리허설 로고로").
     주일 = SAEHAN XAPIS + 청년부 주일예배, 브뚜 = BREAK †HROUGH + 830, 리허설 = REHEARSAL + 900, 특별예배 = SAEHAN XAPIS.
     커버 잠금장치와 같은 문법(위 로고 · 그 밑 가운데 작은 글)이고 비례도 커버 그대로다(aspect-ratio = 로고 폭 : 로고 + 틈 + 밑 글 키).
     여덟째 판은 «브뚜 로고는 두 줄이라 띠에선 너무 작다» 고 한 장으로 묶었는데, 띠를 14px 높여 두 줄 로고가 들어가게 했다(아래 44px).
   ⚠ 글 뒤에 깔지 않는다: 가운데 · 비스듬히 · 아래 칸 · 크게 걸치기를 찍어 보니 로고가 티켓 글자와 겹쳐 어디서나 지저분했다(_proposals/ticket-133h8/shots/wm-*.png).
   ⚠ 로고 SVG 를 바꾸면 aspect-ratio 와 밑 글 폭(%)을 다시 셈한다(tools/gen_svc_covers.py 가 만든 크기) */
.tk-main{position:relative; padding-bottom:44px;}
.tk-main.k-ev{padding-bottom:30px;}
.tk-wm{position:absolute; left:16px; bottom:10px; pointer-events:none; background:var(--ink); opacity:.09;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;}
.tk-wm.wm-ev{width:52%; aspect-ratio:3110 / 276;
  -webkit-mask-image:url(/svc/xapis.svg); mask-image:url(/svc/xapis.svg);
  -webkit-mask-position:left center; mask-position:left center; -webkit-mask-size:contain; mask-size:contain;}
.tk-wm.wm-sun{width:146px; aspect-ratio:180.3 / 32;
  -webkit-mask-image:url(/svc/xapis.svg), url(/svc/sun-sub.svg); mask-image:url(/svc/xapis.svg), url(/svc/sun-sub.svg);
  -webkit-mask-position:center top, center bottom; mask-position:center top, center bottom;
  -webkit-mask-size:100% auto, 44.1% auto; mask-size:100% auto, 44.1% auto;}
.tk-wm.wm-fri{height:30px; aspect-ratio:149.3 / 70;
  -webkit-mask-image:url(/svc/bt.svg), url(/svc/830.svg); mask-image:url(/svc/bt.svg), url(/svc/830.svg);
  -webkit-mask-position:center top, center bottom; mask-position:center top, center bottom;
  -webkit-mask-size:100% auto, 23% auto; mask-size:100% auto, 23% auto;}
.tk-wm.wm-sat{width:132px; aspect-ratio:168.8 / 36;
  -webkit-mask-image:url(/svc/reh.svg), url(/svc/900.svg); mask-image:url(/svc/reh.svg), url(/svc/900.svg);
  -webkit-mask-position:center top, center bottom; mask-position:center top, center bottom;
  -webkit-mask-size:100% auto, 21.8% auto; mask-size:100% auto, 21.8% auto;}
.tk-sticker.pop{animation:tkstick .34s cubic-bezier(.2,.9,.3,1.25) both;}
@keyframes tkstick{from{transform:rotate(-6deg) scale(1.28); opacity:0;} to{transform:rotate(9deg) scale(1); opacity:1;}}
@media (prefers-reduced-motion:reduce){ .tk-sticker.pop{animation:none;} }
@media (max-width:359px){ .tk-sticker{width:54px; height:54px;} }
/* 340 밑 폰(아이폰 SE 1세대 · 작은 안드로이드): 연습 · 예배 · 자리 세 칸이 오른쪽 칸 밑으로 들어갔다(320 에서 15px, 실측).
   오른쪽 칸을 76 으로 좁히고 칸 여백을 줄인다. 스티커는 좁힌 만큼 오른쪽으로 따라간다 */
@media (max-width:339px){
  .tk-main{padding-right:10px;}
  .tk-cell{padding:0 5px;}
  .tk-stub{width:76px;}
  .tk-stub b{font-size:23px;}
  .tk-sticker{width:46px; height:46px;}
}
/* 반달 홈: 절취선 위아래에 바탕색 동그라미를 반쯤 걸친다. 가운데를 점 줄 가운데(칸 왼쪽에서 3.5px)에 맞춘다.
   ⚠ 동그라미는 테두리까지 22px 다(가상 요소는 content-box). 그래서 left = 3.5 - 11 = -7.5. 예전 -11 은 가운데가 칸 경계라 점 줄과 3.5px 어긋났다(JH 10-03) */
.tk-stub::before, .tk-stub::after{content:''; position:absolute; left:-7.5px; width:18px; height:18px; border-radius:50%;
  background:var(--page); border:2px solid var(--ink);}
.tk-stub::before{top:-11px; clip-path:inset(50% 0 0 0);}
.tk-stub::after{bottom:-11px; clip-path:inset(0 0 50% 0);}

/* 이름을 안 고른 폰 · 3주 안에 서는 날이 없는 폰 = 티켓 자리에 한 줄 */
.sp-ask{display:flex; align-items:center; gap:12px; width:100%; min-height:72px; padding:12px 14px; margin:0; text-align:left; cursor:pointer;
  font-family:var(--f-body); color:var(--ink); text-decoration:none;
  background:var(--card); border:2px solid var(--ink); border-radius:20px; box-shadow:0 4px 0 var(--ink);}
.sp-ask:active{transform:translateY(3px); box-shadow:0 1px 0 var(--ink);}
.sp-ask.quiet{border:0; box-shadow:none; min-height:60px;}
.sp-ask.quiet:active{transform:none; background:var(--sp-leaf-50);}
.sp-askic{flex:none; width:44px; height:44px; border-radius:14px 6px 14px 6px; background:var(--sp-leaf-100);
  display:inline-flex; align-items:center; justify-content:center;}
.sp-askic .hic{width:32px; height:32px; transform:none;}
.sp-askt{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px;}
.sp-askt b{font-size:16px; font-weight:900; letter-spacing:-.3px;}
.sp-askt small{font-size:12.5px; font-weight:700; color:var(--sp-sub);}
.sp-ask > .ic{flex:none; width:18px; height:18px; color:var(--sp-sub);}

/* ── 다음 예배 카드 (spotlightHTML 그대로, 옷만) ────────── */
html.sp .spot{border:0; border-radius:var(--sp-r); box-shadow:none; overflow:hidden; background:var(--card);}
html.sp .spot::before, html.sp .spot::after{display:none;}
html.sp .spotbody > :not(:first-child){border-top:1px solid var(--sp-line);}
html.sp .spot.ux130 .uxtools{background:var(--dk-well, #FAFCFB);}
html.sp .spot.ux130 .uxtools .btn{color:var(--ink2);}
html.sp .spot.ux130 .uxtools .btn:active{background:var(--sp-leaf-50);}
html.sp .spotdone{margin:0 2px 10px; font-size:13px; font-weight:700; color:var(--sp-sub);}
html.sp .spotdone a{color:var(--sp-leaf-700); font-weight:900;}

/* ── 공지 · 모임 ─────────────────────────────────── */
html.sp .sp-nlist{gap:10px;}
html.sp .notice{border:0 !important; border-radius:18px; box-shadow:none !important; background:var(--card); transform:none !important;}
html.sp .notice.pinned, html.sp .notice.pin{background:var(--sp-sun-50);}
html.sp .notice .nmeta{color:var(--sp-sub);}

/* ── 단추 (앱 전체) ─────────────────────────────────
   기본 = 흰 면 + 옅은 초록 회색 테두리와 밑 단 / 주 동작 = 잎 초록 채움 + 진한 잎 밑 단(흰 글자 4.85:1) */
html.sp .btn{border:1.5px solid var(--sp-line2); background:var(--card); color:var(--ink); border-radius:14px; box-shadow:0 2px 0 var(--sp-ledge);}
html.sp .btn:active{transform:translateY(2px); box-shadow:none;}
html.sp .btn.primary, html.sp .btn.playall, html.sp .sp-btn.primary{background:var(--sp-leaf-600); color:#fff; border-color:var(--sp-leaf-600);
  box-shadow:0 3px 0 var(--sp-leaf-800);}
html.sp .btn.primary .ic, html.sp .btn.playall .ic{color:#fff;}
html.sp .btn.danger{background:var(--sp-coral-fill); border-color:var(--sp-coral-700); color:#fff; box-shadow:0 3px 0 #7E2A2C;}
html.sp .iconbtn{border:1.5px solid var(--sp-line2); border-radius:12px; box-shadow:0 2px 0 var(--sp-ledge); background:var(--card);}
html.sp .iconbtn:active{transform:translateY(2px); box-shadow:none;}
.sp-btn{display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:50px; padding:0 20px; border-radius:16px;
  font-family:var(--f-body); font-size:16px; font-weight:900; letter-spacing:-.2px; text-decoration:none; cursor:pointer;
  border:1.5px solid var(--sp-line2); background:var(--card); color:var(--ink); box-shadow:0 3px 0 var(--sp-ledge);}
.sp-btn:active{transform:translateY(3px); box-shadow:none;}
.sp-btn.wide{display:flex; width:100%;}
.sp-btn .ic{width:19px; height:19px;}

/* ── 창(시트) ──────────────────────────────────── */
html.sp #layer{background:rgba(11,42,68,.42);}
/* ⚠ 사진 · 악보 보기는 짙은 바탕 그대로(사진에 집중하는 자리). 위 한 줄이 아이디 + 클래스 + 요소라 `#layer.photo` 보다 세서
   133 첫 판에 사진 뒤로 앨범 · 탭바가 비쳐 보였다(133-c 에 잡았다) */
html.sp #layer.photo{background:#050f1c;}
html.sp .sheet{border:0; border-radius:26px 26px 0 0; box-shadow:none; padding-top:22px; position:relative;}
html.sp .sheet::before{content:''; position:absolute; top:8px; left:50%; width:38px; height:5px; margin-left:-19px; border-radius:3px; background:var(--dk-skywell, #D5DFE5);}
html.sp .sheet .shhead h3{font-size:19px; letter-spacing:-.4px;}

/* ── 앱으로 저장하기 창 ───────────────────────────── */
.sp-install{display:flex; flex-direction:column; gap:14px;}
.sp-insthead{display:flex; align-items:center; gap:12px; padding:12px 14px; border-radius:18px; background:var(--sp-leaf-50);}
.sp-insthead img{width:52px; height:52px; border-radius:12px; box-shadow:0 0 0 1px rgba(11,42,68,.08);}
.sp-insthead span{display:flex; flex-direction:column; gap:2px;}
.sp-insthead b{font-size:17px; font-weight:900;}
.sp-insthead small{font-size:13px; font-weight:700; color:var(--sp-sub);}
.sp-sheetlead{margin:0; font-size:14.5px; font-weight:700; line-height:1.55; color:var(--ink2);}
.sp-steps{margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:10px;}
.sp-step{display:flex; align-items:center; gap:12px; font-size:15px; font-weight:700; line-height:1.5;}
.sp-stepn{flex:none; width:28px; height:28px; border-radius:50%; background:var(--sp-leaf-600); color:#fff;
  display:inline-flex; align-items:center; justify-content:center; font-size:14px; font-weight:900;}
.sp-stept{flex:1; min-width:0;}
.sp-stept b{font-weight:900;}
.sp-key{display:inline-flex; align-items:center; gap:5px; vertical-align:middle; height:30px; padding:0 9px; margin:0 2px; border-radius:9px;
  background:var(--dk-well, #EEF1F3); color:var(--dk-skytx, #1E66D0); font-size:13.5px; font-weight:800; white-space:nowrap;}
.sp-key .ic{width:17px; height:17px; stroke-width:2.1;}
.sp-key span{color:var(--ink);}
.sp-note{margin:0; font-size:13px; font-weight:700; color:var(--sp-sub); line-height:1.6;}
.sp-note.soft{padding:10px 12px; border-radius:14px; background:var(--sp-sun-50); color:var(--sp-sun-700);}
/* 사파리 아래 주소창 모양 — «⋯» 자리를 손가락으로 짚어 준다 */
.sp-mock{display:flex; align-items:center; gap:8px; padding:10px 12px; border-radius:20px; background:#F4F6F8;}
.sp-mockback, .sp-mockdots{flex:none; width:40px; height:40px; border-radius:50%; background:var(--card); display:inline-flex; align-items:center; justify-content:center;
  box-shadow:0 1px 3px rgba(11,42,68,.10); color:#1E66D0; position:relative;}
.sp-mockback .ic, .sp-mockdots .ic{width:20px; height:20px;}
.sp-mockurl{flex:1; min-width:0; height:40px; border-radius:20px; background:var(--card); box-shadow:0 1px 3px rgba(11,42,68,.10);
  display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:700; color:var(--ink2); overflow:hidden; white-space:nowrap; text-overflow:ellipsis; padding:0 10px;}
.sp-tapdot{position:absolute; inset:-6px; border-radius:50%; border:3px solid var(--sp-leaf-600); animation:sptap 1.6s ease-out infinite;}
@keyframes sptap{0%{transform:scale(.7); opacity:0;} 25%{opacity:1;} 100%{transform:scale(1.25); opacity:0;}}
@media (prefers-reduced-motion:reduce){ .sp-tapdot{animation:none; opacity:1;} }

/* ── 내 이름 고르기 ──────────────────────────────── */
.sp-picker{display:flex; flex-direction:column; gap:16px; margin-top:14px;}
.sp-pickhd{margin:0 0 8px 2px; font-size:13px; font-weight:900; color:var(--sp-sub);}
.sp-pickhd.praise-a, .sp-pickhd.praise-b, .sp-pickhd.praise{color:var(--sp-coral-700);}
.sp-pickhd.bcast{color:var(--sp-sky-700);}
.sp-pickhd.sound{color:var(--sp-leaf-700);}
.sp-pickrow{display:flex; flex-wrap:wrap; gap:8px;}
.sp-pick{min-width:64px; min-height:46px; padding:0 14px; border-radius:14px; border:1.5px solid var(--sp-line2); background:var(--card);
  font-family:var(--f-body); font-size:16px; font-weight:800; color:var(--ink); cursor:pointer; box-shadow:0 2px 0 var(--sp-ledge);}
.sp-pick:active{transform:translateY(2px); box-shadow:none;}
.sp-pick.on{background:var(--sp-leaf-100); border-color:var(--sp-leaf-600); color:var(--sp-leaf-700); box-shadow:0 2px 0 var(--sp-leaf-600);}
.sp-sheetfoot{display:flex; justify-content:center; margin-top:18px;}
.sp-sheetfoot .linkbtn{font-size:14px;}

/* ── 안녕, 나는 ___ (처음 한 번) ─────────────────────
   화면을 통째로 덮는 한 장. 가운데 = 이름표 스티커(위 띠 «안녕 · 나는», 아래 흰 칸에 펜 글씨 이름). 잉크 테두리 + 단단한 그림자는
   내 섬김 티켓 · 입장권과 같은 «표» 식구다. 띠 색은 고른 사람의 팀 색(방송 하늘 · 음향 초록 · 찬양 빨강), 고르기 전엔 이름표 빨강.
   위아래는 고정, 이름 목록만 스크롤된다(카톡 안 창 664px 에서도 단추가 보이게). */
html.hellomode, html.hellomode body{overflow:hidden;}
.hello{--ht:#D8463E; --htd:#A8322B;
  position:fixed; inset:0; z-index:95; display:flex; justify-content:center;
  background:radial-gradient(120% 60% at 50% 0, var(--dk-skywell, #DDF0F7) 0, rgba(221,240,247,0) 70%), linear-gradient(180deg, var(--page) 0, var(--page2) 100%);
  opacity:0; transition:opacity .24s ease;}
.hello[data-cls="bcast"]{--ht:var(--sp-sky-700); --htd:#1F3F66;}
.hello[data-cls="sound"]{--ht:var(--sp-leaf-600); --htd:var(--sp-leaf-800);}
.hello.hello-on{opacity:1;}
.hello.hello-off{opacity:0; transition-duration:.3s;}
.hello-in{width:100%; max-width:460px; height:100%; display:flex; flex-direction:column; align-items:stretch;
  padding:calc(var(--top-safe) + 26px) 16px calc(env(safe-area-inset-bottom) + 12px); box-sizing:border-box;}
/* 이름표 */
.hello-tag{flex:none; align-self:center; width:min(300px, 82%); background:#fff; color:var(--ink);
  border:2.5px solid var(--ink); border-radius:22px; box-shadow:0 6px 0 var(--ink); overflow:hidden;
  transform:rotate(-2.5deg) translateY(-14px); transition:transform .5s cubic-bezier(.25,.46,.45,.94);}
.hello.hello-on .hello-tag{transform:rotate(-2.5deg);}
.ht-band{display:flex; flex-direction:column; align-items:center; gap:0; padding:13px 16px 11px; background:var(--ht); color:#fff;
  transition:background-color .3s ease;}
.ht-band b{font-family:var(--f-disp); font-weight:900; font-size:40px; line-height:1; letter-spacing:-1.5px;}
.ht-band span{margin-top:4px; font-size:15px; font-weight:800; letter-spacing:.08em; opacity:.95;}
.ht-body{height:96px; display:flex; align-items:center; justify-content:center; padding:0 18px; border-top:2.5px solid var(--ink);}
.ht-name{position:relative; display:inline-block; min-width:4px; font-family:'Nanum Pen Script', var(--f-disp); font-size:56px; line-height:1;
  color:var(--dk-ink, #0E2234); transform:rotate(-1.5deg); white-space:nowrap;}
/* 비어 있으면 = 펜으로 쓸 자리(점선) + 깜빡이는 자리 표시. 다 쳐지면 표시가 꺼진다 */
.ht-name.ht-blank{width:62%; min-width:150px; height:46px; border-bottom:2.5px dashed #B9C9D3; transform:none;}
.ht-name::after{content:''; position:absolute; right:-7px; top:10%; width:3px; height:80%; border-radius:2px; background:var(--ht);
  animation:htcaret 1.05s steps(1) infinite;}
.ht-name.ht-blank::after{left:50%; right:auto;}
.ht-name.ht-typed::after{display:none;}
@keyframes htcaret{50%{opacity:0;}}
.hello-hint{flex:none; margin:20px 0 10px; text-align:center; font-size:14.5px; font-weight:800; color:var(--sp-sub);}
.hello-hint b{display:block; font-weight:900; color:var(--ink2);}
.hello-hint small{display:block; margin-top:3px; font-size:12.5px; font-weight:700; line-height:1.45; color:var(--dk-sub, #7C909D); word-break:keep-all; text-wrap:balance;}
/* 이름 목록 (팀마다) */
/* 옆 여백 6px · 바깥으로 -4px(이름 칸 폭은 그대로): 처음 고른 이름(컴퓨터는 첫 이름에 초점)의 테 3px + 띄움 2px 가 목록 칸 왼쪽에서 잘렸다
   (스크롤 칸은 옆으로 넘친 것을 자른다. JH 10-03 "선택됐다고 표시되는 그 창의 왼쪽이 약간 잘려서 나갔거든") */
.hello-list{flex:1; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain; scrollbar-width:thin;
  padding:6px 6px 18px; margin:0 -4px; display:flex; flex-direction:column; gap:16px;
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 22px), transparent 100%);
  mask-image:linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 22px), transparent 100%);}
.hello-grphd{display:flex; align-items:center; gap:7px; margin:0 0 8px 2px; font-size:13px; font-weight:900; color:var(--sp-sub);}
.hello-grphd::before{content:''; width:9px; height:9px; border-radius:50%; background:#D8463E;}
.hello-grphd.bcast::before{background:var(--sp-sky-fill);}
.hello-grphd.sound::before{background:var(--sp-leaf-600);}
.hello-names{display:grid; grid-template-columns:repeat(auto-fill, minmax(62px, 1fr)); gap:8px;}
.hello-nm{min-height:46px; padding:0 6px; border-radius:14px; border:1.5px solid var(--sp-line2); background:var(--card); box-shadow:0 2px 0 var(--sp-ledge);
  font-family:var(--f-body); font-size:16px; font-weight:800; color:var(--ink); cursor:pointer; white-space:nowrap;
  transition:background-color .15s ease, color .15s ease, border-color .15s ease;}
.hello-nm:active{transform:translateY(2px); box-shadow:none;}
.hello-nm.picked{background:var(--ht); border-color:var(--ht); color:#fff; box-shadow:0 2px 0 var(--htd);}
.hello-nm:focus-visible, .hello-go:focus-visible, .hello-skip:focus-visible{outline:3px solid var(--sp-sky); outline-offset:2px;}
/* 아래 = 시작하기 */
.hello-foot{flex:none; display:flex; flex-direction:column; align-items:center; gap:2px; padding-top:10px;}
.hello-go{width:100%; min-height:52px; font-size:16.5px;}
html.sp .sp-btn.hello-go:disabled{background:var(--dk-track, #DCE5E0); border-color:var(--dk-line, #DCE5E0); color:var(--dk-sub, #8A9BA6); box-shadow:0 3px 0 var(--dk-ledge, #C6D2CB); cursor:default;}
.hello-skip{margin-top:6px; padding:8px 12px; font-size:14px; font-weight:800; color:var(--sp-sub);}
.hello-note{margin:0; font-size:12px; font-weight:700; color:var(--dk-sub, #8A9BA6);}
@media (prefers-reduced-motion:reduce){ .hello, .hello-tag{transition:none;} .ht-name::after{animation:none;} }
@media (min-width:700px){ .hello-in{padding-top:calc(var(--top-safe) + 48px);} }

/* ── 더보기 ─────────────────────────────────────── */
.sp-h{margin:0 4px 8px; display:flex; align-items:baseline; gap:7px; font-family:var(--f-body); font-size:13px; font-weight:900; color:var(--sp-sub);}
.sp-h i{font-family:var(--f-latin); font-style:normal; font-weight:500; font-size:11px; letter-spacing:.06em; opacity:.85;}
[data-view="more"] .sp-sec + .sp-sec{margin-top:22px;}
.sp-list{background:var(--card); border-radius:var(--sp-r); overflow:hidden;}
.sp-row{display:flex; align-items:center; gap:13px; width:100%; min-height:64px; padding:10px 14px; margin:0; text-align:left;
  background:none; border:0; text-decoration:none; color:var(--ink); font-family:var(--f-body); cursor:pointer;}
.sp-row + .sp-row{border-top:1px solid var(--sp-line);}
.sp-row:active{background:var(--sp-leaf-50);}
.sp-ri{flex:none; width:38px; height:38px; display:inline-flex; align-items:center; justify-content:center;}
.sp-ri .hic{width:36px; height:36px; transform:none; margin:0;}
.sp-ri img:not(.hic){width:30px; height:auto;}
.sp-rt{flex:1; min-width:0; display:flex; flex-direction:column; gap:1px;}
.sp-rt b{font-size:15.5px; font-weight:900; letter-spacing:-.3px;}
.sp-rt small{font-size:12.5px; font-weight:700; color:var(--sp-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.sp-row > .ic, .sp-mecard > .ic{flex:none; width:18px; height:18px; color:var(--dk-sub, #9AAAB5);}
.sp-badge{flex:none; min-width:22px; height:22px; padding:0 7px; border-radius:999px; background:#E5484D; color:#fff;
  font-size:12px; font-weight:900; line-height:22px; text-align:center;}
.sp-mecard{display:flex; align-items:center; gap:14px; width:100%; min-height:78px; padding:14px 16px; margin:0; text-align:left; cursor:pointer;
  background:var(--card); border:0; border-radius:var(--sp-r); font-family:var(--f-body); color:var(--ink);}
.sp-mecard:active{background:var(--sp-leaf-50);}
.sp-av{flex:none; width:50px; height:50px; border-radius:18px 7px 18px 7px; background:var(--sp-leaf-100); color:var(--sp-leaf-700);
  display:inline-flex; align-items:center; justify-content:center; font-family:var(--f-disp); font-size:17px; font-weight:900;}
.sp-av .ic{width:24px; height:24px;}
.sp-mecard .sp-rt b{font-size:18px;}
.sp-colophon{margin:26px 0 0; text-align:center; font-size:12px; font-weight:700; line-height:1.6; color:var(--sp-sub);}
/* 리더 문 = 맨 아래 작은 글자 하나(133). 단추 옷을 안 입힌다. 누르는 자리만 손가락 크기로 */
.sp-leadin{margin:6px 0 0; text-align:center;}
.sp-leadin a{display:inline-flex; align-items:center; min-height:40px; padding:0 12px; font-size:12.5px; font-weight:800;
  color:var(--dk-sub, #7C909D); text-decoration:underline; text-underline-offset:3px; text-decoration-color:#C3CFD6;}

/* ── 넓은 화면 ─────────────────────────────────────
   본문은 한 기둥(720). 94차의 두 기둥 격자(`[data-view="home"]{display:grid}`, 1100 이상)는 133 홈에선 끈다.
   안 끄면 하늘 머리가 왼쪽 296px 칸에 갇히고 티켓이 상단바 밑으로 올라간다(1440 실측).
   하늘 머리는 창 폭 그대로 깔고, 인사·교회·상단바는 본문 칸 선(카드 왼쪽 끝 = 칸 가운데 - 344px)에 맞춘다. */
html.sp [data-view="home"]{display:block;}
@media (min-width:900px){
  html.sp .topbar .in{max-width:692px;}
  html.sp .deskNav{display:flex; gap:2px; margin:0 auto;}
  html.sp .deskNav a{color:var(--ink); opacity:.7;}
  html.sp .deskNav a.on{opacity:1;}
  html.sp .deskNav a.on::after{background:var(--sp-leaf-600);}
  html.sp[data-page="home"] .deskNav a{color:var(--ink);}
  html.sp[data-page="home"][data-tod="dawn"] .deskNav a, html.sp[data-page="home"][data-tod="evening"] .deskNav a,
  html.sp[data-page="home"][data-tod="night"] .deskNav a{color:#fff;}
  html.sp[data-page="home"][data-tod="dawn"] .deskNav a.on::after, html.sp[data-page="home"][data-tod="evening"] .deskNav a.on::after,
  html.sp[data-page="home"][data-tod="night"] .deskNav a.on::after{background:var(--card);}
  html.sp .view{max-width:720px;}
  /* 100vw 는 세로 스크롤바 폭까지 넣는다 → 오른쪽으로 8px 넘쳤다(1440 실측). 스크롤바 폭(`--sbw`, app.js 가 잰다)을 빼서 창 안쪽 폭만큼만 */
  .sp-hero{width:calc(100vw - var(--sbw, 0px)); margin:0 0 0 calc(50% - 50vw + var(--sbw, 0px) / 2); border-radius:0; height:284px;}
  .sp-herotx{left:calc(50% - 344px); right:auto; width:430px; top:96px;}
  .sp-hello{font-size:30px; max-width:none;}
  .sp-art{right:calc(50% - 350px); width:340px; height:206px;
    /* 폰은 그림 오른쪽 끝이 화면 끝에 숨지만, 넓은 화면은 하늘 한가운데서 나무가 칼로 잘린 선이 보인다 → 오른쪽을 풀어 준다 */
    -webkit-mask-image:linear-gradient(90deg,#000 0 82%,transparent 100%); mask-image:linear-gradient(90deg,#000 0 82%,transparent 100%);}
}

/* ── UX 133 · 화면별 옷 ─────────────────────────────────────────────
   담는 상자는 흰 면 하나, 누르는 것은 옅은 테두리 + 밑 단, 고른 것은 잎 초록.
   ⚠ 프로필 카드 판(`.whocard` · `.wpic` · 꾸미기 층)은 **안 건드린다.** 꾸미기 좌표가 그 판의 크기·여백에 붙어 있다(100차·101차-b).
   ⚠ 입장권(`.gatecard` · `.cut` · `.bartip`)은 잉크 옷 그대로 — 내 섬김 티켓과 같은 «표» 식구다. */
html.sp .topbar .bartip{display:none !important;}
html.sp .gatecard .bartip{display:block;}

/* 제목 */
html.sp .sec{margin-top:26px;}
html.sp .sec:first-child{margin-top:4px;}
html.sp .sec>h2, html.sp .secrow h2{font-size:20px; padding-bottom:0; margin:0 0 6px; text-shadow:none; letter-spacing:-.4px;}
html.sp .sec>h2::after, html.sp .secrow h2::after{display:none;}
html.sp .sec>h2 .hic, html.sp .secrow h2 .hic{width:30px; height:30px; transform:none; margin-right:0;}
html.sp .sec>h2 i, html.sp .secrow h2 i{font-weight:500; font-size:11.5px; color:var(--sp-sub); text-shadow:none; margin:0 0 3px -2px;}
html.sp .sec>.hint, html.sp .srcnote, html.sp .grptitle, html.sp .rsghd, html.sp .rsghd b, html.sp .rsmore{text-shadow:none;}
html.sp .sec>.hint{color:var(--sp-sub); margin:4px 2px 14px;}
html.sp .secrow .more{background:none; border:0; box-shadow:none; padding:4px 2px; color:var(--sp-leaf-700);}
html.sp .secrow .more.acts{color:var(--ink);}
/* 상단바가 화면 이름을 말하는 화면은 본문 첫 제목을 접는다(같은 말이 위아래 두 번) */
html.sp [data-view="team"] > .sec:first-child > .secrow:first-child,
html.sp [data-view="docs"] > .sec:first-child > .secrow:first-child,
html.sp [data-view="album"] > .sec:first-child > .secrow:first-child,
html.sp [data-view="feedback"] > .sec:first-child > .secrow,
html.sp [data-view="stats"] > .sec:first-child > .secrow:first-of-type,
html.sp [data-view="contacts"] > .sec:first-child > .secrow:first-of-type{display:none;}
html.sp .grptitle{font-size:15px; margin:22px 4px 8px; color:var(--sp-sub);}
html.sp .grptitle::after{display:none;}
html.sp .wklabel{font-family:var(--f-body); font-size:12px; font-weight:900; letter-spacing:0; color:var(--sp-sub); margin:18px 4px 8px;}
html.sp .wklabel::after{display:none;}
html.sp .backlink{color:var(--sp-sub); font-weight:800; padding:6px 2px;}

/* 담는 상자 = 흰 면 */
html.sp .card, html.sp .qcard, html.sp .svrow, html.sp .setcard, html.sp .req, html.sp .res, html.sp .teamcard, html.sp .bdcard,
html.sp .albumcard, html.sp .mgcard, html.sp .stcard, html.sp .ytbox, html.sp .rsbundle,
html.sp .fbrow, html.sp .todorow, html.sp .ctgrp, html.sp .adminhero, html.sp .rsitem, html.sp .rsong, html.sp .bkbar{
  border:0 !important; box-shadow:none !important; border-radius:20px; background:var(--card); transform:none;}
html.sp .card::before, html.sp .qcard::before, html.sp .teamcard::before, html.sp .albumcard::before, html.sp .setcard::before{display:none !important;}
html.sp .setcard.hl{box-shadow:inset 0 0 0 2px var(--sp-coral) !important;}
html.sp .svrow.today{box-shadow:inset 0 0 0 2px var(--sp-leaf-600) !important;}
html.sp .svrow.today .qhead{border:0;}
html.sp .empty{border:0; background:var(--card); border-radius:20px; color:var(--sp-sub);}
/* 찬양 / 방송음향 두 덩어리의 왼쪽 띠는 남긴다(사용자 130차: «방음팀이랑 찬양팀 좀 더 확실하게 구별되게»). 색만 클로버로 */
html.sp .svrow .svgrp.praise{--gc:var(--sp-coral);}
html.sp .svrow .svgrp.av{--gc:var(--sp-sky);}
html.sp .svgrp + .svgrp{border-top:1px solid var(--sp-line);}
html.sp .ptag.me::after{background:var(--sp-leaf-600);}
html.sp .setcard .shead, html.sp .setcard .songs{border-color:var(--sp-line) !important;}
html.sp .svrow.ux130 .uxtools{border-top:1px solid var(--sp-line);}
html.sp .contiblk{border-top-color:var(--sp-line) !important;}
html.sp .spot .contiblk, html.sp .spot .ptiers{border-color:var(--sp-line) !important;}

/* 고르기 (세그먼트) — 회녹색 홈 안에 흰 알약 하나 */
html.sp .subtabs, html.sp .pvtoggle, html.sp .lbtabs, html.sp .lyrtabs, html.sp .plsw, html.sp .wd-tabs{
  border:0 !important; box-shadow:none !important; background:var(--dk-track, #E4ECE7); border-radius:14px; padding:4px; gap:4px;}
html.sp .subtabs button, html.sp .pvtoggle button, html.sp .lbtabs button, html.sp .lyrtabs button, html.sp .plsw button, html.sp .wd-tabs button{
  border:0 !important; border-radius:10px; color:var(--sp-sub); font-weight:800; transform:none; box-shadow:none;}
html.sp .lbtabs button + button, html.sp .lyrtabs button + button, html.sp .plswb + .plswb{border-left:0 !important;}
html.sp .subtabs button.on, html.sp .pvtoggle button.on, html.sp .lbtabs button.on, html.sp .lyrtabs button.on, html.sp .plsw button.on, html.sp .wd-tabs button.on,
html.sp .lbtabs button[aria-selected="true"], html.sp .lyrtabs button[aria-selected="true"]{
  background:var(--card) !important; color:var(--ink) !important; box-shadow:0 2px 0 rgba(11,42,68,.08) !important;}
html.sp [data-view="praise"] .subtabs button.on{color:var(--sp-coral-700) !important;}
html.sp .subtabs{margin-bottom:14px;}

/* 찾는 칸 · 입력 칸 */
html.sp .searchbar{border:1.5px solid var(--sp-line2) !important; box-shadow:none !important; border-radius:14px; background:var(--card); min-height:48px;}
html.sp .searchbar:focus-within{border-color:var(--sp-leaf-600) !important;}
html.sp .searchbar .ic{color:var(--sp-sub);}
html.sp .field input, html.sp .field textarea, html.sp .field select, html.sp .sheet textarea, html.sp .songedit input, html.sp .rsnewin input, html.sp .gateform input{
  border:1.5px solid var(--sp-line2) !important; box-shadow:none !important; border-radius:14px; background:var(--card);}
html.sp .gateform input{border:2px solid var(--ink) !important;}
html.sp .field input:focus, html.sp .field textarea:focus, html.sp .field select:focus, html.sp .sheet textarea:focus{border-color:var(--sp-leaf-600) !important;
  box-shadow:0 0 0 3px var(--sp-leaf-100) !important;}
html.sp .yrsel{border:1.5px solid var(--sp-line2) !important; box-shadow:none !important; border-radius:999px; background:var(--card);}

/* 칩: 안 고른 것 = 흰 외곽선, 고른 것 = 잎 채움 */
html.sp .fchip, html.sp .uxsel{border:1.5px solid var(--sp-line2) !important; box-shadow:none !important; background:var(--card); transform:none !important; color:var(--ink);}
html.sp .fchip.on{background:var(--sp-leaf-600) !important; border-color:var(--sp-leaf-600) !important; color:#fff !important;}
html.sp .uxsel.on{border-color:var(--sp-leaf-600) !important; background:var(--sp-leaf-50) !important;}
html.sp .themepick button{box-shadow:none;}

/* 달 넘기기 */
html.sp .monthbar .mlabel{border:0 !important; box-shadow:none !important; background:none !important; padding:0 4px;}
html.sp .mbtn{border:1.5px solid var(--sp-line2) !important; box-shadow:0 2px 0 var(--sp-ledge) !important; border-radius:50%; background:var(--card);}
html.sp .mbtn:active{box-shadow:none !important;}
html.sp .mlabel .mcount{border:0 !important; background:none !important; box-shadow:none !important; color:var(--sp-sub);}

/* 섬김표 */
html.sp .bkbar{padding:12px 14px; min-height:64px;}
html.sp .bkbar .hic{transform:none;}
html.sp .bkbar .btn{box-shadow:none;}
html.sp .pastbar{border:0 !important; box-shadow:none !important; background:none; color:var(--sp-leaf-700); font-weight:900;}
html.sp table.hcal th{border:0 !important; box-shadow:none !important; background:none !important; color:var(--sp-sub);}
html.sp table.hcal td{border:0 !important; box-shadow:none !important; border-radius:12px; background:var(--card);}
html.sp table.hcal td.today{box-shadow:inset 0 0 0 2px var(--sp-leaf-600) !important;}
html.sp .hcal .daytag{border:0 !important; box-shadow:none !important;}
html.sp .teamchip{box-shadow:none !important;}

/* 팀 */
html.sp .teamcard{overflow:hidden;}
html.sp .teamcard .thead{border:0 !important; box-shadow:none !important;}
html.sp .teamcard .tcount{border:0 !important; box-shadow:none !important; background:none !important; color:var(--sp-sub);}
html.sp .mecue{border:0 !important; box-shadow:none !important; background:var(--sp-leaf-50); border-radius:16px;}
html.sp .mecue .ic{color:var(--sp-leaf-700);}
/* 133-b: 프로필 카드 밑 고치는 타일(꾸미기 · 소개 · 사진)도 다른 누르는 것과 같은 옷. 잉크 테두리 + 단단한 그림자는 옛 판이었다.
   ⚠ 카드 판(.whocard · 꾸미기 층)은 그대로다(꾸미기 좌표) */
html.sp .wfact{border:1.5px solid var(--sp-line2); border-radius:14px; background:var(--card); box-shadow:0 2px 0 var(--sp-ledge); color:var(--ink);}
html.sp .wfact:hover{background:var(--sp-leaf-50);}
html.sp .wfact.off{border:1.5px dashed var(--sp-line2); box-shadow:none; background:transparent; color:var(--dk-sub, #8A9BA6);}
html.sp .telsafe{border:0; border-radius:12px; background:var(--sp-leaf-50); color:var(--sp-leaf-700);}
html.sp .telsafe b{color:var(--sp-leaf-700);}

/* 자료실 · 앨범 */
html.sp .reslist{border:0 !important; box-shadow:none !important; background:var(--card); border-radius:20px; overflow:hidden; gap:0;}
html.sp .reslist .res{border-radius:0;}
html.sp .reslist .res + .res{border-top:1px solid var(--sp-line) !important;}
html.sp .albumcard{padding:8px; transform:none !important;}
html.sp .albumcard .cov{border:0 !important; box-shadow:none !important; border-radius:14px;}
html.sp .photogrid button{border:0 !important; box-shadow:none !important; border-radius:10px;}
html.sp .vbadge{border:0 !important; box-shadow:none !important;}

/* 신청 · 신청곡 */
html.sp .rsbundle .btn.rsall, html.sp .rsbundle .rsall{background:var(--sp-leaf-600) !important; color:#fff !important; border-color:var(--sp-leaf-600) !important;
  box-shadow:0 2px 0 var(--sp-leaf-800) !important;}
html.sp .rsbundle .rsgrp, html.sp .rsbundle .rslist > *{border-color:var(--sp-line) !important;}
html.sp .rsheadbtn.btn{box-shadow:none !important;}
html.sp .req .donechip{box-shadow:none !important;}

/* 곡 듣기 창 */
html.sp .ytbox{border-radius:22px; overflow:hidden;}
html.sp .ythead, html.sp .ytfoot, html.sp .plbar, html.sp .plnav, html.sp .pllist, html.sp .plcount, html.sp .plmode, html.sp .ythint{border-color:var(--sp-line) !important; box-shadow:none !important;}
html.sp .ytbtn, html.sp .pvbtn, html.sp .pdfbtn, html.sp .pdfzoom{box-shadow:none !important; border:1.5px solid var(--sp-line2) !important;}
html.sp .docbar{border:0 !important; box-shadow:none !important; background:var(--page);}

/* 아래 «업데이트 N분 전» = 조용한 한 줄. 멈췄을 때만 코랄 */
html.sp .syncbar{padding-bottom:22px;}
html.sp .syncbar .syncsum{background:none; border:0; box-shadow:none; color:var(--sp-sub); font-weight:700;}
html.sp .syncbar.warn .syncsum{background:var(--sp-coral-50); color:var(--sp-coral-700); border-radius:999px; padding:6px 14px;}

/* 관리자 */
html.sp .mgcard{padding:16px;}
html.sp .mgcard > h3 .hic, html.sp .mgcard summary .hic{transform:none;}
html.sp .syncrow, html.sp .jrow{border-color:var(--sp-line) !important; box-shadow:none !important;}

/* 이름 «나» 형광펜 = 잎 */
html.sp .ptag.me{background:linear-gradient(180deg, transparent 58%, var(--sp-leaf-100) 58%);}
/* 창이 떠 있으면 알림 한 줄은 위로 — 창 글자를 덮지 않게(133, 이름 고른 뒤 바로 앱 저장 창이 뜰 때 겹쳤다) */
html.sp body:has(#layer:not([hidden])) #toast{bottom:auto; top:calc(var(--top-safe) + 14px);}
/* 좁은 폰(400 아래)은 이름 글자만 한 치수 줄인다. «앱 저장» 글자는 접지 않는다(아래 화살표 하나만으로는 무슨 단추인지 추측하게 된다) */
@media (max-width:399px){
  html.sp .logo .nm{font-size:16px;}
}
@media (max-width:339px){ html.sp .logo .nm{font-size:15px; letter-spacing:-.5px;} html.sp .topbar .tile, html.sp .topbar .tile img{width:26px; height:26px;} }


/* ══ UX 133-c · 남은 옛 옷 정리 (2026-10-01) ══════════════════════════════════════════════
   사용자: *"왜 다른 데는 UI가 다 바뀐 것 같은데 프로필 페이지만 이전하고 똑같아? 뭔가 업데이트가 되다가 만 것 같아.
   할 거면은 일관성 있게 다 뜯어 고쳐야 된다고. 내가 딱 지적한 부분만 고치지 말고."*
   → 눈으로 찾지 않고 `tools/qa/oldskin.mjs` 로 **전 화면 · 전 창**에서 옛 옷(잉크 굵은 테두리 · 잉크 단단한 그림자 · 기울임 ·
     잉크 2px 점선 · 짙은 색 테두리 + 같은 색 단단한 그림자)을 셌다. 첫 판 181개 · 35종. 여기서 종류마다 한 번에 갈아입힌다.
   ⚠ 시그니처(내 섬김 티켓 · 입장권 · «안녕, 나는» 이름표 · 우표)와 사용자가 고른 리더 알림 띠(잉크 띠, 131차-c)는 그대로.
   ⚠ 사람이 붙인 꾸미기(스티커 · 낙서)는 그 사람 것이다. 판의 몸만 바꾸고 꾸미기 좌표가 기대는 상자 셋(명찰 · 사진 · 판)은 크기를 거의 그대로 둔다. */

/* ── 0. 옛 색 토큰을 클로버 색으로 ─────────────────────────────
   옛 규칙들이 `--praise` · `--bcast` · `--sound` · `--sand` · `--rl-*` 같은 이름으로 v4 색(벽돌 빨강 · 진파랑 · 진녹 · 모래)을 쓴다.
   이름은 그대로 두고 값만 바꾸면 고치지 않은 옛 부품도 같은 색 언어를 쓴다(찬양 = 산호, 방송 = 하늘, 음향 = 잎, 팀 = 해). */
html.sp{
  --praise:var(--sp-coral-700); --praise-soft:var(--sp-coral-100);
  --praise2:#9B3D6B; --praise2-soft:#F6E1EC;
  --bcast:var(--sp-sky-700);    --bcast-soft:var(--sp-sky-100);
  --sound:var(--sp-leaf-700);   --sound-soft:var(--sp-leaf-100);
  --sand:var(--sp-sun-700);     --sand-soft:var(--sp-sun-100);
  --sat:var(--sp-leaf-700);     --sat-soft:var(--sp-leaf-100);
  --lilac:#5A3FA8;              --lilac-soft:#ECE4FB;
  --butter:#E9CC3F;             --butter-soft:var(--sp-sun-100); --butter-ink:var(--sp-sun-700);
  --sea:var(--sp-sky-700);
  --rl-lead:var(--sp-sun-700);     --rl-lead-soft:var(--sp-sun-100);
  --rl-vocal:var(--sp-coral-700);  --rl-vocal-soft:var(--sp-coral-100);
  --rl-session:#5A3FA8;            --rl-session-soft:#ECE4FB;
  --rl-bcast:var(--sp-sky-700);    --rl-bcast-soft:var(--sp-sky-100);
  --rl-sound:var(--sp-leaf-700);   --rl-sound-soft:var(--sp-leaf-100);
  /* 칠(배경)용. 글자용 토큰과 갈라 둔다 — 어두운 시간대엔 글자용만 밝아진다(133차-e) */
  --praise-fill:var(--sp-coral-fill); --praise2-fill:#9B3D6B; --bcast-fill:var(--sp-sky-fill); --sound-fill:var(--sp-leaf-fill);
  --sand-fill:var(--sp-sun-fill); --sat-fill:var(--sp-leaf-fill); --lilac-fill:#5A3FA8;
}

/* ── 1. 손그림 아이콘은 곧게 ─────────────────────────────
   v4 는 스티커처럼 -3~-8도 기울였다. 133 은 흰 면 위에 곧게 선다 */
html.sp .hic, html.sp .rolei, html.sp .rolei.thi, html.sp svg.wrp, html.sp .wri, html.sp .whoi{transform:none;}

/* ── 2. 프로필 판 ───────────────────────────────────────
   명찰 = 그 사람 역할 색의 옅은 면(팀 탭 팀 카드 머리와 같은 문법). 구멍 · 잉크 테두리 · 단단한 그림자 · 기울임을 걷었다.
   ⚠ 상자 크기는 거의 그대로다(안쪽 여백은 옛 값 + 테두리 두께를 그대로 지킨다). 꾸미기가 명찰 · 사진 상자의 비율로 붙어 있다. */
html.sp .whocard::before{background:var(--rcs, var(--sp-leaf-100)); border:0; border-radius:20px; box-shadow:none; transform:none;}
html.sp .whocard .hole{display:none;}
html.sp .whoi{background:var(--card); border-radius:16px; box-shadow:0 2px 0 rgba(11,42,68,.08);}
html.sp .whot{transform:none;}
html.sp .whot b{letter-spacing:-.6px;}
html.sp .whot .whos{color:var(--rc, var(--sp-sub)); font-weight:800;}
html.sp .whot .whos i{color:inherit; opacity:.45;}
html.sp .whome{transform:none; border:0; background:var(--sp-leaf-600); color:#fff; font-size:12px; padding:3px 11px 4px;}
/* 사실 줄 나눔 = 옅은 실선 한 줄(옛 2px 잉크 점선) */
html.sp .wrow{border-top:1px solid var(--sp-line);}
html.sp .wrow:first-child{border-top:0;}
html.sp .wrk{color:var(--sp-sub);}
html.sp svg.wrp{stroke:var(--sp-sub);}
/* 사진 = 둥근 모서리 한 장. 잉크 테두리 · 그림자 · 기울임 없이(테두리 두께만큼 상자가 같은 크기로 남게 안쪽 선으로 그린다) */
html.sp .wpic{border:0; border-radius:18px; background:var(--sp-leaf-50); transform:none; box-shadow:inset 0 0 0 1px rgba(11,42,68,.06);}
html.sp .wpic img{border-radius:18px;}
html.sp .wpic:active{transform:scale(.98); box-shadow:inset 0 0 0 1px rgba(11,42,68,.06);}
html.sp .wpicn{background:rgba(11,42,68,.66);}
html.sp .whoboard.deco-stage .wpic:active{transform:none;}
/* 생일 옆 나이 · «N일 뒤» · 연락처 번호 = 옅은 칩(옛 = 굵은 테두리 + 단단한 그림자 알약) */
html.sp .wrage, html.sp .ctbd i{border:0; background:var(--sp-sun-100); color:var(--sp-sun-700); padding:2px 9px;}
html.sp .wrn{border:0; background:var(--sp-coral-100); color:var(--sp-coral-700);}
html.sp .cttel{border:1.5px solid var(--dk-line, #CBE7D2); background:var(--sp-leaf-50); color:var(--sp-leaf-700); box-shadow:0 2px 0 var(--dk-ledge, #CBE7D2);}
html.sp .cttel:active{transform:translateY(2px); box-shadow:none;}
html.sp .cttel.none{border:0; background:none; box-shadow:none;}

/* 사진 고르기 줄 */
html.sp .pth{border-radius:14px;}
html.sp .pthb{border:1.5px solid var(--sp-line2) !important; box-shadow:none !important; border-radius:14px; transform:none !important;}
html.sp .pth.on .pthb{border-color:var(--sp-leaf-600) !important; box-shadow:0 0 0 2px var(--sp-leaf-100) !important;}
html.sp .pthx{border:0 !important; box-shadow:0 1px 0 rgba(11,42,68,.15) !important;}

/* ── 3. 꾸미기 창 ─────────────────────────────────────── */
html.sp .dctab{background:var(--card); border:1.5px solid var(--sp-line2); border-radius:14px; box-shadow:0 2px 0 var(--sp-ledge); color:var(--sp-sub);}
html.sp .dctab.on{background:var(--sp-leaf-50); border-color:var(--sp-leaf-600); color:var(--sp-leaf-700); box-shadow:0 2px 0 var(--sp-leaf-600);}
html.sp .dcpick{border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); border-radius:16px;}
html.sp .dcpick:active{box-shadow:none;}
html.sp .dcpick.dot.on, html.sp .dcpick.era.on{border:3px solid var(--sp-leaf-600); box-shadow:0 0 0 3px var(--sp-leaf-100);}
html.sp .dcpick.era{background:var(--card);}

/* ── 4. 관리자 «허브 점검» 줄 ─────────────────────────────
   옛 = 잉크(또는 빨강 · 노랑) 굵은 테두리 + 단단한 그림자. 133 = 옅은 면 + 왼쪽 색 띠 하나(등급은 색으로만) */
html.sp .chkrow{background:var(--dk-well, #F6F9F7); border:0; border-radius:14px; box-shadow:inset 4px 0 0 var(--sp-line2);}
html.sp .chkrow.bad{background:var(--sp-coral-50); box-shadow:inset 4px 0 0 var(--sp-coral-700);}
html.sp .chkrow.warn{background:var(--sp-sun-50); box-shadow:inset 4px 0 0 #D9B92E;}
html.sp .chkrow.info{box-shadow:inset 4px 0 0 #B8C7CF;}
html.sp .chkdot{border:0;}
html.sp .chkrow.bad .chkdot{background:var(--sp-coral-fill);}
html.sp .chkrow.warn .chkdot{background:#D9B92E;}
html.sp .chkrow:not(.bad):not(.warn):not(.info) .chkdot{background:var(--sp-leaf-600);}
html.sp .chkrow.bad .chkdetail{color:var(--sp-coral-700);}
html.sp a.chkrow:active{filter:brightness(.97);}
/* 계절 미리보기 · 자동 같은 고르기 단추 */
html.sp .themepick button{border:1.5px solid var(--sp-line2); box-shadow:none; border-radius:14px;}
html.sp .themepick button.on{border:3px solid var(--sp-leaf-600); box-shadow:0 0 0 3px var(--sp-leaf-100);}
html.sp .themepick button.on span{background:var(--sp-leaf-600);}

/* ── 5. 사용 기록 ───────────────────────────────────── */
html.sp .stbox{border:0; box-shadow:none; border-radius:20px; background:var(--card);}
html.sp .strow{border-top:1px solid var(--sp-line);}
html.sp .strow:first-child{border-top:0;}
html.sp .stverdict{border:0; border-radius:20px; background:var(--card); box-shadow:inset 5px 0 0 var(--sp-line2);}
html.sp .stverdict.good{background:var(--sp-leaf-50);  box-shadow:inset 5px 0 0 var(--sp-leaf-600);}
html.sp .stverdict.ok  {background:var(--sp-sky-50);   box-shadow:inset 5px 0 0 var(--sp-sky-700);}
html.sp .stverdict.warn{background:var(--sp-coral-50); box-shadow:inset 5px 0 0 var(--sp-coral-700);}
html.sp .stverdict.new {background:var(--sp-sun-50);   box-shadow:inset 5px 0 0 #D9B92E;}
html.sp .stcard.hero{background:var(--dk-lilwell, #F1ECFB);}
html.sp .stday i{background:var(--sp-sky-fill);}
html.sp .stbarw i{background:var(--sp-sky-fill);}
html.sp .ctnote{border:0; border-radius:16px; background:var(--dk-well, #F6F9F7); color:var(--sp-sub);}
html.sp .ctnote .ic{color:var(--sp-sub);}

/* ── 6. 연락처 ─────────────────────────────────────── */
html.sp .ctgh{border-bottom:0; border-radius:0;}
html.sp .ctgrp .ctgh{background:var(--dk-well, #F6F9F7); box-shadow:inset 4px 0 0 var(--sp-line2);}
html.sp .ctgrp.praise-a .ctgh{background:var(--sp-coral-50); box-shadow:inset 4px 0 0 var(--sp-coral-700);}
html.sp .ctgrp.praise-b .ctgh{background:var(--dk-well, #FBF0F5); box-shadow:inset 4px 0 0 #9B3D6B;}
html.sp .ctgrp.bcast .ctgh{background:var(--sp-sky-50); box-shadow:inset 4px 0 0 var(--sp-sky-700);}
html.sp .ctgrp.sound .ctgh{background:var(--sp-leaf-50); box-shadow:inset 4px 0 0 var(--sp-leaf-600);}
html.sp .ctrow{border-top:1px solid var(--sp-line);}
html.sp .ctrow:first-of-type{border-top:0;}

/* ── 7. 팀 탭: A · B 글자 딱지 ───────────────────────────── */
html.sp .tletter{border:0; box-shadow:none; transform:none; border-radius:10px; font-family:var(--f-disp); font-weight:900;}
html.sp .teamcard.praise-a .tletter{background:var(--sp-coral-fill);}
html.sp .teamcard.praise-b .tletter{background:#9B3D6B;}

/* ── 8. 홈 · 창 여기저기 남은 잉크 선 ─────────────────────────
   ⚠ 예배 커버 머리(그림 · 검정 · 하늘)는 본문 흰 면과 저절로 갈린다. 그 밑의 잉크 2px 줄은 v4 카드 테두리의 일부였다 */
html.sp .spothead, html.sp .qhead{border-bottom:0;}
html.sp .notice.meet::before{border-right:0; width:5px;}
html.sp .dchip{border:0; background:var(--dk-well, #EEF3F0); color:var(--sp-sub);}
html.sp .ytfoot .ytout + .ytout{border-left:1px solid var(--sp-line);}
html.sp .rsarchiveday{border-bottom:1px solid var(--sp-line); color:var(--sp-sub);}
html.sp .fbcount{border:0; background:var(--sp-coral-fill);}
html.sp .btn.ghost.xs{border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card); color:var(--sp-leaf-700);}
/* A · B 팀 동그라미(달력 · 예배 창) = 팀 탭 글자 딱지와 같은 색(A 산호 · B 자두). 잉크 테두리는 걷는다.
   검정 · 풀색 커버 칸 위에서는 흰 테두리 한 줄로 떠 보이게(예전 규칙의 흰 테두리 자리) */
html.sp .teamchip{border:0; font-family:var(--f-disp); font-weight:900;}
html.sp .teamchip.A{background:var(--sp-coral-fill); color:#fff;}
html.sp .teamchip.B{background:#9B3D6B; color:#fff;}
html.sp .teamchip.me{outline-color:var(--sp-leaf-600);}
html.sp .hcal td.svcover.col-fri .teamchip, html.sp .hcal td.svcover.col-sat .teamchip{box-shadow:0 0 0 1.5px #fff;}
/* 줄 나눔 = 옅은 1px 실선(옛 = 점선). 점선은 133 에서 «더하기 자리» 단추(네 변 점선)에만 남는다. 변마다 따로 적는다(모든 변을 실선으로 바꾸면 기본 3px 테두리가 살아난다) */
html.sp .srow{border-bottom:1px solid var(--sp-line);}
html.sp .songtable .srow{border-bottom:0; border-top:1px solid var(--sp-line);}
html.sp .fdrow{border-bottom:1px solid var(--sp-line);}
html.sp .rsarchiveentry + .rsarchiveentry{border-top:1px solid var(--sp-line);}
html.sp .rsbundlehead{border-bottom:1px solid var(--sp-line);}
html.sp .rsbundle .rsgrp + .rsgrp{border-top:1px solid var(--sp-line);}
html.sp .rsbundle .rsong + .rsong{border-top:1px solid var(--sp-line);}
html.sp .setcard .shead{border-bottom:1px solid var(--sp-line) !important;}
html.sp .fbnote{border-top:1px solid var(--sp-line);}

/* ── UX 133-c 둘째 판 · 평소엔 안 뜨는 화면 (2026-10-01) ──────────────────────────────
   첫 판은 «그 날 데이터로 그려지는 화면»만 쟀다. 생일 · 무대 배치 · 플레이어 가사 · PDF · 곡 정보의 부른 기록 ·
   신청 곡 줄처럼 그 날 없거나 눌러야 열리는 부품은 옛 옷 그대로였다(CSS 를 훑으니 덮이지 않은 옛 규칙이 61종).
   `tools/qa/oldskin.mjs` 의 «숨은 상태» 판이 이제 가짜 값으로 그려서 잰다.
   그리고 133 의 넓은 덮개(`html.sp .card, … {background:var(--card); border:0 !important; box-shadow:none !important}`)가
   **구분 표시까지 같이 지웠다**: 오늘 생일 카드 색 · 새 피드백 줄 · 할 일의 빨간 줄. 그 셋을 133 말로 되살린다. */

/* 구분 표시 되살리기. 133 은 테두리 대신 옅은 바탕 + 왼쪽 안쪽 띠(관리자 «허브 점검» 줄과 같은 말) */
html.sp .fbrow.new{box-shadow:inset 4px 0 0 var(--sp-coral-700) !important;}
html.sp .todorow{background:var(--dk-well, #F6FAF7);}
html.sp .todorow.bad{background:var(--sp-coral-50); box-shadow:inset 4px 0 0 var(--sp-coral-700) !important;}
html.sp .todorow.bad .tdt b{color:var(--sp-coral-700);}

/* 생일: 오늘이면 옅은 라일락(홈에서 라일락은 이 카드뿐이라 축하 자리로 읽힌다), 곧 오는 생일만 있으면 흰 카드.
   테이프 · 기울인 아이콘 · 손글씨 제목 · 잉크 이름표는 133 이 안 쓰는 말이라 걷는다. 폭죽(색종이 비)은 그대로 */
html.sp .bdcard.on{background:var(--dk-lilwell, #F3EEFC);}
html.sp .bdcard::before{display:none;}
html.sp .bdi, html.sp .bdcard.popped .bdi{transform:none; animation:none;}
html.sp .bdparty{transform:scale(-1,1);}
html.sp .bdcard.popped .bdparty{animation-name:bdkicksp;}
@keyframes bdkicksp{
  0%{transform:translate3d(0,0,0) scale(-1,1);}
  10%{transform:translate3d(7px,5px,0) rotate(-14deg) scale(-1.16,1.16);}
  38%{transform:translate3d(-2px,-2px,0) rotate(8deg) scale(-1,1);}
  100%{transform:translate3d(0,0,0) scale(-1,1);}
}
html.sp .bdt{font-family:var(--f-disp); font-size:18px; font-weight:900; line-height:1.5; letter-spacing:-.01em; color:var(--ink);}
html.sp .bdt b{background:var(--card); border:0; border-radius:999px; box-shadow:none; transform:none; padding:1px 11px 2px 9px;}
html.sp .bdcard.popped .bdt b{animation-name:bdpopsp;}
@keyframes bdpopsp{0%{opacity:0; transform:scale(.8);} 55%{opacity:1; transform:scale(1.08);} 100%{opacity:1; transform:none;}}
html.sp .bds{color:var(--sp-sub);}
html.sp .bdsoon.tear{border-top:1px solid rgba(90,63,168,.16);}
html.sp .bdlab{color:var(--sp-sub); opacity:1;}
html.sp .bdn{border:0; background:var(--card); color:var(--ink);}
html.sp .bdcard:not(.on) .bdn{background:var(--page);}

/* 무대 배치: 판은 흰 면 + 옅은 선, 이름표는 끄는 것이라 누르는 옷(옅은 테두리 + 밑 단). 인도자만 잎 채움 */
html.sp .stage{border:1.5px solid var(--sp-line2); box-shadow:none; border-radius:20px;
  background:repeating-linear-gradient(90deg, transparent 0 39px, rgba(11,42,68,.035) 39px 40px), var(--card);}
html.sp .stagefront{border-top:1px solid var(--sp-line); color:var(--sp-sub); background:var(--sp-leaf-50);}
html.sp .stchip{border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card);}
html.sp .stchip.tier-lead{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600); color:#fff; box-shadow:0 2px 0 var(--sp-leaf-800);}
html.sp .stchip.tier-lead i{color:rgba(255,255,255,.82);}
html.sp .stage.locked .stchip{box-shadow:none;}
html.sp .stagestate{border:0; background:var(--dk-well, #F6FAF7); color:var(--sp-sub);}
html.sp .stagestate.done{background:var(--sp-leaf-50); color:var(--sp-leaf-700);}
html.sp .stagestate.done .stdot{background:var(--sp-leaf-600);}
html.sp .stagestate.draft{background:var(--sp-sun-50); color:var(--sp-sun-700);}
html.sp .stagestate.draft .stdot{background:var(--card); border-color:var(--sp-sun-700);}
html.sp .shotin{border:0; box-shadow:none; border-radius:22px;}
html.sp .shotin img{border:1px solid var(--sp-line);}
html.sp .recframe{border:0; box-shadow:none; border-radius:16px;}

/* 플레이어: 머리 · 넘김 줄이 찬양 분홍으로 칠해져 있었다(옛 찬양 칸 색). 다른 창처럼 흰 머리, 넘김 줄은 옅은 바탕.
   지금 듣는 곡 한 줄만 찬양 색(코랄)으로 남긴다. 줄 나눔은 1px */
html.sp .ythead{background:var(--card); border-bottom-width:1px;}
html.sp .plbar{background:var(--dk-well, #F6FAF7); border-top-width:1px;}
html.sp .pllist{border-top-width:1px;}
html.sp .ytfoot{border-top-width:1px;}
html.sp .plrow:hover{background:var(--dk-well, #F6FAF7);}
html.sp .plrow.on{background:var(--sp-coral-50); color:var(--sp-coral-700);}
html.sp .plbar .pllyr.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600); color:#fff; box-shadow:0 2px 0 var(--sp-leaf-800);}
html.sp .ytbox > .pllyrics{border-top:1px solid var(--sp-line);}

/* PDF 보기 */
html.sp .pdfbar{border-bottom:1px solid var(--sp-line); background:var(--card);}
html.sp .pdfpg input{border:1.5px solid var(--sp-line2); box-shadow:none; border-radius:10px;}
html.sp .pdfpg input:focus{border-color:var(--sp-leaf-600); box-shadow:none;}
html.sp .pdfpage{border:1px solid var(--sp-line2); border-radius:12px; box-shadow:0 2px 0 rgba(11,42,68,.06);}

/* 곡 정보: 가사 상자 · 부른 기록 */
html.sp .lyrbody{border:0; box-shadow:none; border-radius:18px; background:var(--dk-well, #F6FAF7);}
html.sp .sdhist{border-top:1px solid var(--sp-line);}
html.sp .sdh{border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); border-radius:14px; background:var(--card);}
html.sp .sdh:active{box-shadow:none;}
html.sp .lglog{border:0; background:var(--dk-well, #F6FAF7); border-radius:16px;}

/* 신청서 곡 줄 · 곡 찾기 담기 · 그 밖에 옛 잉크 선이 남아 있던 작은 부품들 */
html.sp .rsnew{border:0; background:var(--dk-well, #F6FAF7); border-radius:16px;}
html.sp .rsnewin input{border:1.5px solid var(--sp-line2); border-radius:14px; box-shadow:none;}
html.sp .rsnewin input:focus{border-color:var(--sp-leaf-600); box-shadow:none;}
html.sp .qadd:hover{border-color:var(--sp-line2);}
html.sp .qadd.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600); color:#fff;}
html.sp .infobtn:hover{border-color:var(--sp-line2);}
html.sp .rsvid{border-color:var(--sp-line2);}
html.sp .rsvid:hover{border-color:var(--sp-line2); background:var(--sp-leaf-50);}
html.sp .rsnow{border:0; background:var(--dk-well, #F6FAF7);}
html.sp .rsnow.hit{border:0; background:var(--sp-leaf-50);}
html.sp .scorethumb{border:1.5px solid var(--sp-line2);}
html.sp .hookbox{border:0; background:var(--dk-well, #F6FAF7);}
html.sp .hookbox.on{background:var(--sp-leaf-50);}
html.sp .hookst{border-color:var(--sp-line2);}
html.sp .hookst.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600);}
html.sp .kkrow{border-top:1px solid var(--sp-line);}
html.sp .kkrow:first-child{border-top:0;}
html.sp .systat{border:0;}
html.sp .syncrow.bad .systat{background:var(--sp-coral-fill);}
html.sp .qsum{border:0; background:var(--sp-coral-50);}
html.sp .fbbody.quote{border-left-color:var(--sp-line2);}
/* 특별예배 카드(커버가 없는 예배)의 머리: 위 4px 예배색 띠와 잉크 테두리 «내일» 칩이 옛 말이었다.
   커버 예배 칩과 같은 흰 알약으로. 그 밖의 작은 옛 선(새 글 · 콘티 알약 · 앨범 영상 표시 · 사용 기록 들어온 길) */
html.sp .spothead::before{display:none;}
html.sp .spot.ev .spotwhen{background:var(--card); border:0; color:var(--sp-leaf-700); font-size:13px; line-height:1.25; padding:3px 10px 4px; border-radius:999px;}
html.sp .newdot{border:0;}
html.sp .contilab{border:0; box-shadow:none; background:var(--dk-well, #F6FAF7); font-family:var(--f-body); font-weight:800; color:var(--sp-sub);}
html.sp a.contilab{border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card); color:var(--ink);}
html.sp .grptitle .vgi{border:0; box-shadow:none; background:var(--sp-leaf-100);}
html.sp .grptitle .vgi .ic{color:var(--sp-leaf-700);}
html.sp .stent{border:0; background:var(--dk-well, #F6FAF7);}
/* 넓은 화면도 본문은 720 한 기둥이다(133). 1180 폭에 맞춰 둔 두 칸 · 두 기둥(96차-i)이 720 안에 들어오면서
   신청 화면은 곡 이름이 네 줄로 접히고(«주님의 선하심 (Goodness of God)»), 곡 찾기는 긴 제목 줄 옆 칸이 같이 늘어나 빈 줄이 생겼다(1440 실측).
   그래서 이 셋은 폰처럼 한 줄씩. 자료실(280 칸) · 팀 세 장은 720 에서도 들어가서 그대로 둔다 */
@media (max-width:899px){   /* 133차-h 일곱째 판: 900 이상은 본문이 960 이라 133 전 두 칸 · 두 기둥으로 되돌린다 */
html.sp .reqsplit{display:block;}
html.sp .reqsplit > .reqcompose{position:static; margin-bottom:14px;}
html.sp .songtable{display:block;}
html.sp .songtable .srow:first-child{border-top:0;}
html.sp .rsgrp .rslist{display:flex; flex-direction:column;}
}
/* 넓은 화면 달력 칸 안의 줄 나눔(인도 · 방송 · 음향 · 같은 날 두 예배) */
html.sp .hcal .calstage{border-bottom:1px solid var(--sp-line);}
html.sp .hcal .teamhd{border-bottom:1px solid var(--sp-line);}
html.sp .hcal .multisvc{border-top:1px solid var(--sp-line);}
html.sp #toast{color:#fff; border:0; box-shadow:0 3px 0 rgba(11,42,68,.22);}
html.sp #toast.err{background:var(--sp-coral-fill);}

/* ══ 133차-d 응원 (2026-10-01) ═════════════════════════════════════════════
   다음 예배 카드 맨 아래. 그림 다섯이 곧 손잡이라 테두리 · 그림자를 안 입힌다(130 «누르는 것만 단추 모양» 을 그림이 대신한다).
   고른 것만 옅은 잎색 동그라미. 숫자는 경고가 아니라서 빨강을 안 쓴다(흰 알약). */
html.sp .spot .cheer{padding:10px 6px 12px; background:var(--card);}
.cheer .chrow{display:grid; grid-template-columns:repeat(5, minmax(0, 1fr)); gap:2px;}
.cheer .chb{display:flex; flex-direction:column; align-items:center; gap:3px; min-width:0; padding:4px 0 2px; border:0; background:none;
  border-radius:16px; cursor:pointer; font:inherit; color:var(--ink2); -webkit-tap-highlight-color:transparent;}
.cheer .chpic{position:relative; display:grid; place-items:center; width:52px; height:52px; border-radius:50%;
  transition:background-color .2s ease, transform .15s ease;}
.cheer .chpic img{display:block; width:44px; height:44px;}
.cheer .chb:active .chpic{transform:scale(.92);}
.cheer .chb.on .chpic{background:var(--sp-leaf-100); box-shadow:inset 0 0 0 2px var(--sp-leaf-600);}
.cheer .chko{font-size:11.5px; font-weight:700; letter-spacing:-.2px; white-space:nowrap;}
.cheer .chb.on .chko{color:var(--sp-leaf-700); font-weight:900;}
.cheer .chn{position:absolute; top:-3px; right:-5px; min-width:20px; height:20px; padding:0 6px; border-radius:999px;
  background:var(--card); box-shadow:0 0 0 1.5px var(--sp-line2); color:var(--sp-leaf-700);
  font:800 11.5px/20px var(--f-mono, ui-monospace); text-align:center;}
.cheer .chwho{margin:6px 8px 0; text-align:center; font-size:12.5px; line-height:1.4; color:var(--sp-sub);}
.cheer .chb.pop .chpic{animation:chpop .42s ease-out;}
@keyframes chpop{0%{transform:scale(1);} 40%{transform:scale(1.16) rotate(-6deg);} 100%{transform:scale(1);}}
@media (hover:hover) and (pointer:fine){ .cheer .chb:hover .chpic{background:var(--sp-leaf-50);} .cheer .chb.on:hover .chpic{background:var(--sp-leaf-100);} }
.cheer .chb:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:1px;}
/* 티켓 안 «강산, 현희 외 N명과 함께» 한 줄(133차-d. 첫 판 «같이 서요» 는 JH 가 AI 말투라고 물렸다). 이름표 모양을 안 입힌다(누르는 건 티켓 하나다) */
.tk-with{display:block; margin-top:9px; font-size:12.5px; font-weight:800; color:var(--ink2);}
/* 내 기록 (133차-d). 내 카드에만, 판 밖. 담는 상자는 흰 면 하나(133), 줄 나눔만 옅은 선 */
.wrec{margin:16px 0 4px; padding:12px 14px 10px; border-radius:18px; background:var(--page);}
.wrechd{display:flex; align-items:baseline; gap:8px;}
.wrechd b{font-size:15px; font-weight:900;}
.wrecn{margin-left:auto; font-size:13px; font-weight:800; color:var(--sp-sub);}
.wrecn em{font-style:normal; font-family:var(--f-disp); font-size:20px; font-weight:900; color:var(--sp-leaf-700); margin:0 1px;}
.wreclist{list-style:none; margin:8px 0 0; padding:0;}
.wrecrow{display:flex; align-items:center; gap:10px; padding:8px 0; border-top:1px solid var(--sp-line2); font-size:14px;}
.wrecrow .wrd{flex:none; width:58px; font-weight:900;}
.wrecrow .wrd small{font-size:12px; font-weight:800; color:var(--sp-sub);}
.wrecrow .wrs{flex:1; min-width:0; font-weight:700; color:var(--ink2);}
.wrecrow .wrr{flex:none; display:inline-flex; align-items:center; height:22px; padding:0 8px; border-radius:999px; font-size:12px; font-weight:900;
  background:var(--sp-leaf-100); color:var(--sp-leaf-700);}
.wrecrow .wrr.t-lead{background:var(--sp-sun-100); color:var(--sp-sun-700);}
.wrecrow .wrr.t-vocal{background:var(--sp-coral-100); color:var(--sp-coral-700);}
.wrecrow .wrr.t-bcast{background:var(--sp-sky-100); color:var(--sp-sky-700);}
.wrecrow .wrr.t-session{background:var(--dk-lilwell, #E9E1FA); color:var(--dk-liltx, #5A3FA8);}
.wrecnone, .wrecmore, .wrecnote{margin:8px 0 2px; font-size:12.5px; color:var(--sp-sub);}
.wrec.loading .wrecnone{opacity:.7;}
/* ══ 133차-d 이번 주 말씀 ══════════════════════════════════
   모두가 같은 말씀. 담는 상자는 흰 면 하나(133). 말씀 글자는 가사와 같은 둥근 글꼴(읽는 글이다), 한 줄은 본문 글꼴로 조금 진하게.
   한/EN 단추만 누르는 모양(옅은 테두리 + 밑 단). */
.sp-word{position:relative; padding:16px 18px 16px; border-radius:var(--sp-r); background:var(--card);}
.sp-word .wd-top{display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; padding-right:52px;}
.wd-lab{font-size:13px; font-weight:900; color:var(--sp-leaf-700);}
.wd-src{font-size:12px; font-weight:700; color:var(--sp-sub);}
.wd-lang{position:absolute; top:12px; right:12px; min-width:44px; height:30px; padding:0 10px; border-radius:999px; cursor:pointer;
  font:900 12px/1 var(--f-body); color:var(--ink2); background:var(--card); border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge);}
.wd-lang:active{transform:translateY(2px); box-shadow:none;}
.wd-verse{margin:10px 0 0; font-family:var(--f-lyric); font-size:16.5px; line-height:1.62; word-break:keep-all; color:var(--ink);}
.wd-verse[lang="en"]{font-family:var(--f-body); font-size:15.5px; line-height:1.55;}
.wd-ref{margin:6px 0 0; font-size:12.5px; font-weight:800; color:var(--sp-sub);}
/* 133차-e: 구절 아래는 설교에서 실제로 한 말(인용). 작은 이름표 «설교 중에서» + 따옴표 안의 말 */
.wd-said{margin:12px 0 0; padding-top:11px; border-top:1px solid var(--sp-line);}
.wd-saidlab{margin:0 0 4px; font-size:12px; font-weight:800; color:var(--sp-sub);}
.wd-line{margin:0; font-size:14.5px; font-weight:800; line-height:1.55; color:var(--ink); word-break:keep-all;}
.wd-play{display:inline-flex; align-items:center; gap:5px; margin-top:10px; font-size:12.5px; font-weight:800; color:var(--sp-leaf-700); text-decoration:none;}
.wd-play .ic{width:15px; height:15px;}
/* 관리자 카드 미리보기 */
.wd-pre{padding:12px 14px; margin:4px 0 10px; border-radius:14px; background:var(--page);}
.wd-pre .wd-verse{font-size:15px; margin-top:4px;}
.wd-pre .wd-en{margin:8px 0 0; font-size:13px; line-height:1.5; color:var(--ink2);}
.wd-pre .wd-en i{font-style:normal; color:var(--sp-sub);}

/* ══ 133차-d 창 다듬기 (화면 감사) ══════════════════════════════
   · 손잡이 = 진짜 끌 수 있는 막대(.grab, 예전 ::before 는 끌리지 않는 그림이었다). 폰에서 손잡이 · 창 머리를 끌어 내리면 닫힌다(sheetDrag).
   · 올라올 때 반투명으로 시작하지 않는다(첫 0.15초에 뒤 글자가 비쳐 겹쳤다). 밑에서 밀려 올라온다.
   · 닫힐 때 내려가고(넓은 화면은 살짝 가라앉으며 사라지고), 바탕 막도 서서히 꺼진다(예전엔 21개 창 모두 툭 사라졌다).
   · 넓은 화면(900 이상)은 가운데 창: 네 모서리 다 둥글게 · 손잡이 없음 · 위에 붙여 세운다(내용이 늦게 와도 위로 튀지 않게, 아래로만 자란다).
   · 창 위에 창: 새 창이 올라오는 동안 밑 창이 보인다(.peek). 어두운 뷰어 위의 시트는 뷰어를 계속 비춘다. */
html.sp .sheet::before{display:none;}
.sheet > .grab{display:none;}
html.sp .sheet > .grab{display:block; position:relative; height:22px; margin:-22px 0 0; touch-action:none; cursor:grab;}
html.sp .sheet > .grab::before{content:''; position:absolute; top:8px; left:50%; width:38px; height:5px; margin-left:-19px; border-radius:3px; background:var(--dk-skywell, #D5DFE5);}
html.sp .sheet > .shhead{touch-action:none;}
html.sp .sheet:focus{outline:none;}
html.sp .sheet{animation:sheetup2 .3s var(--e-glide);}
@keyframes sheetup2{from{transform:translateY(100%);} to{transform:none;}}
html.sp #layer{transition:background-color .22s ease;}
html.sp #layer:not([hidden]){animation:layerin .22s ease-out;}
@keyframes layerin{from{background-color:rgba(11,42,68,0);}}
html.sp #layer.closing{background-color:rgba(11,42,68,0) !important; pointer-events:none;}
#layer > .lvl.under.peek{visibility:visible;}
#layer > .lvl.leaving{pointer-events:none;}
html.sp #layer > .lvl.leaving > .sheet{animation:sheetdown .22s ease-in forwards;}
html.sp #layer > .lvl.leaving.dragged > .sheet{animation:none;}
@keyframes sheetdown{to{transform:translateY(100%);}}
html.sp #layer > .lvl.leaving:not(:has(> .sheet)){animation:lvlout .18s ease-in forwards;}
@keyframes lvlout{to{opacity:0;}}
@media (min-width:900px){
  html.sp #layer:not(.lightbox):not(.photo) > .lvl{align-items:flex-start;}
  html.sp .sheet{border-radius:26px; align-self:flex-start; margin-top:max(6vh, 40px);
    max-height:calc(100vh - max(6vh, 40px) - 32px); max-height:calc(100dvh - max(6vh, 40px) - 32px);}
  html.sp .sheet > .grab{display:block; height:0; margin:0;}
  html.sp .sheet > .grab::before{display:none;}
  html.sp .sheet > .shhead{touch-action:auto;}
  html.sp .sheet{animation:sheetpop .24s var(--e-glide);}
  html.sp #layer > .lvl.leaving > .sheet{animation:sheetout .18s ease-in forwards;}
}
@keyframes sheetpop{from{transform:translateY(16px) scale(.985);} to{transform:none;}}
@keyframes sheetout{to{transform:translateY(10px) scale(.985); opacity:0;}}
@media (prefers-reduced-motion: reduce){
  html.sp .sheet, html.sp #layer:not([hidden]), html.sp #layer > .lvl.leaving > .sheet{animation:none;}
}
/* ── 133차-d 실패 · 기다림 (화면 감사) ──
   받기 실패는 한 모양(.loadfail): 무엇을 못 불러왔는지 + 사람 말 이유 + «다시 불러오기» 하나.
   달을 넘기며 받는 동안은 옛 내용을 흐리게(.stale). 화면이 비었다 다시 차는 깜빡임은 안 만든다 */
.loadfail{display:flex; flex-direction:column; align-items:center; gap:10px; padding:22px 16px; text-align:center;
  border-radius:var(--sp-r, 22px); background:var(--card);}
.loadfail p{margin:0; font-size:14px; font-weight:700; line-height:1.5; color:var(--ink);}
.loadfail p span{font-size:12.5px; font-weight:600; color:var(--sp-sub, var(--ink2));}
.bootfail{padding:96px 4px 0;}
.stale{opacity:.45; transition:opacity .15s ease; pointer-events:none;}
.ytframe > .ytwait{display:flex;}
#contiNav .loadfail{margin-bottom:12px;}
/* ── 133차-d 화면 감사: 큰 것 셋 ──
   · 오른쪽 탭으로 미는 동안 레이아웃 뷰포트가 430x931 로 늘어나 탭바가 화면 밖으로 떨어졌다(body 의 clip 은 뷰포트로 넘어가 hidden 이 된다).
     html 에 clip 을 걸면 안 늘어나고 상단바 sticky 도 그대로다(실측).
   · 태블릿 세로(721~899)에서 하늘 머리가 720 상자로 잘렸다 → 그 폭에서도 창 폭으로 깐다. 글자 · 그림은 본문 기둥에 맞춘다.
   · 카드 바로 밑 구역 제목이 카드에 붙어 있었다(받은 피드백 0px · 온 신청 6px) → 화면 리듬 26 · 제목 밑 10 */
html{overflow-x:clip;}
@media (min-width:721px) and (max-width:899px){
  .sp-hero{width:calc(100vw - var(--sbw, 0px)); margin:0 0 0 calc(50% - 50vw + var(--sbw, 0px) / 2); border-radius:0;}
  .sp-herotx{left:calc(50% - 344px); right:calc(50% - 344px);}
  .sp-art{right:calc(50% - 350px);
    -webkit-mask-image:linear-gradient(90deg,#000 0 82%,transparent 100%); mask-image:linear-gradient(90deg,#000 0 82%,transparent 100%);}
}
html.sp #fbList{margin-top:26px;}
html.sp .reqfeed{margin-top:26px;}
html.sp .reqfeed > .secrow{margin-bottom:10px;}

/* ══ 133차-d 화면 감사: 보통 항목 첫 묶음 (CSS) ══════════════════════
   근거 = 감사 갈래(states · forms · visual · a11y · desktop · interactive · mobile · type · motion · perf)의 잰 값. 꾸미기 판(.whoboard · BOARD_W)은 손대지 않는다. */
/* 대비: 흐린 글자 토큰이 흰 바탕 4.09:1 이었다. 133 보조색으로 모으고 한 단 짙게(흰 5.6:1 · 옅은 칩 위 4.6:1) */
html.sp{--sp-sub:#4F687A; --faint:var(--sp-sub);}
html.sp .tabbar a{color:var(--dk-sub, #5C6F7B);}
html.sp .hello-hint small, html.sp .sp-leadin a{color:var(--dk-sub, #5C6F7B);}
/* 같은 숫자 배지는 한 빨강(리더 알림 띠의 배지와 같은 색) */
html.sp .tabbar .sp-tabdot, html.sp .sp-badge{background:var(--praise-fill);}
/* 상단바 제목: 화면을 아직 모르는 첫 그림(data-page 없음)에서는 앱 이름을 둔다(이름이 보였다 사라졌다 다시 나왔다) */
html.sp:not([data-page="home"]) .logo .nm{display:revert;}
html.sp[data-page]:not([data-page="home"]) .logo .nm{display:none;}
html.sp:not([data-page]) .sp-title{display:none;}
/* 홈 «전체 재생» 은 한 치수(콘티 쪽과 같게) */
html.sp .rsbundle .btn.rsall{min-height:36px; padding:6px 15px; font-size:12.5px; box-shadow:0 3px 0 var(--sp-leaf-800) !important;}
html.sp .rsbundle .btn.rsall .ic{width:13px; height:13px;}
/* 결단찬양 «넣는 자리» 는 어디서나 점선 빈칸 하나 */
html.sp .btn.resp:not(.has){border:1.5px dashed #B9C9D3; background:none; box-shadow:none; border-radius:14px;}
html.sp .songrow.uxslot .btn.resp:not(.has), html.sp .infobtn.up:not(.has){border-color:#B9C9D3; border-radius:14px;}
/* 입력칸 이름표는 한 색(코랄은 경고색이다) */
html.sp .formlab{color:var(--ink2);}
html.sp .formlab .ic{color:var(--sp-sub);}
/* 창 제목 앞 아이콘은 열 곳에만 있었다 → 다 뺀다(133 의 단순함) */
html.sp .sheet .shhead h3 > .ic{display:none;}
/* 콘티 창 본문만 양옆이 16px 더 들어가 있었다 */
html.sp .sheet #ctsBody > .setcard{padding:0; border-radius:0; background:none;}
/* 720 기둥 안에서 신청곡 두 칸 → 한 줄씩(곡 이름이 세 줄로 접혔다) */
@media (max-width:899px){ html.sp .rsbundlebody:has(.rsgrp + .rsgrp){display:block;} }
/* 끝난 신청 카드: 글자만 흐리게. 단추까지 흐리면(0.45×0.6) 꺼진 단추처럼 보였다 */
html.sp .req.done{opacity:1;}
html.sp .req.done :is(.kbadge, .rb > .rmeta, .rb > p, .rst, .svcchip){opacity:.55;}
/* 키보드 초점 링이 목록 상자(overflow:hidden)에 잘렸다 → 안쪽에 그린다 */
html.sp .sp-list > .sp-row:focus-visible, html.sp .reslist > .res:focus-visible, html.sp .ytfoot .ytout:focus-visible{outline-offset:-3px; border-radius:inherit;}
/* 지난 곡 창의 «더 보기» 가 hidden 인데도 보였다(단추 옷의 display 가 hidden 을 이겼다) */
html.sp .btn[hidden], html.sp .sp-btn[hidden], #rsArchiveMore[hidden]{display:none !important;}
/* 눌림: 주 동작은 밑 단이 꺼지며 내려앉는다(통째로 2~3px 떠 있던 것) */
html.sp .btn.primary:active, html.sp .btn.playall:active, html.sp .btn.danger:active, html.sp .sp-btn.primary:active,
html.sp .wfact:active, html.sp .dctab:active{box-shadow:none;}
html.sp .rsbundle .btn.rsall:active{box-shadow:none !important;}
/* 고르기 알약: 안 고른 칸은 바탕 없이(흰 알약끼리라 무엇이 골라졌는지 안 보였다) */
html.sp .subtabs button, html.sp .pvtoggle button, html.sp .lbtabs button, html.sp .lyrtabs button, html.sp .plsw button, html.sp .wd-tabs button{background:transparent;}
/* 눌림 표시가 없던 줄들(133 덮개가 지웠다) */
html.sp .todorow:active, html.sp .bkbar:active, html.sp .plreqgo:active, html.sp .ctwho:active, html.sp a.chkrow:active,
html.sp .albumcard:active{background:var(--sp-leaf-50); filter:none;}
html.sp .sp-save:active{transform:translateY(2px); box-shadow:none;}
/* 누름 자리: 보이는 모양은 글자 그대로, 손가락 자리만 넓힌다(이름 24~26px · 이웃과 8~10px 이라 옆 사람이 열렸다) */
.ptag[data-who], .uxteam[data-team], .teamchip.tap{position:relative;}
html.sp .ptag[data-who]::before{display:block; content:''; position:absolute; inset:-8px -4px; width:auto; height:auto; border-radius:0; background:none; transform:none;}
.uxteam[data-team]::after, .teamchip.tap::after{content:''; position:absolute; inset:-9px -6px;}
.iconbtn, .plmode, .plnav{position:relative;}
.iconbtn::after{content:''; position:absolute; inset:-5px;}
/* 꺼진 사진 칸은 점선(«더하기 자리») 말고 꺼진 모양 */
html.sp .wfact.off{border:1.5px solid var(--sp-line); background:var(--dk-well, #F6F9F7); color:var(--dk-sub, #8A9BA6); cursor:default; box-shadow:none;}
/* 안내문은 한 얼굴(12.5px 회청색과 15px 본문색이 섞여 있었다) */
html.sp .hint{font-size:12.5px; font-weight:500; line-height:1.55; color:var(--sp-sub);}
html.sp .hint b{color:var(--ink2);}
html.sp .srcnote{font-size:12.5px; font-weight:500; color:var(--sp-sub);}
/* 사용 기록 막대: 날짜 글자가 막대를 띄우고 마지막 날짜가 잘렸다 */
.stday, .sthour{position:relative; padding-bottom:13px;}
.stday em, .sthour em{position:absolute; bottom:0; left:50%; transform:translateX(-50%);}
.stday:last-child em, .sthour:last-child em{left:auto; right:0; transform:none;}
.stdays, .sthours{overflow:visible;}
/* 온 신청 곡 줄: 말줄임이 곡을 가르는 글자를 잘라 먹었다 */
html.sp .req .rst{white-space:normal; overflow-wrap:anywhere; line-height:1.5;}
html.sp .req .rst i{display:block; margin:0;}
/* 공지 · 모임 날짜가 두 줄로 쪼개지지 않게 */
html.sp .notice .nmeta{flex-wrap:wrap;}
html.sp .notice .nmeta > span{white-space:nowrap;}
/* 토스트: 짧은 말은 한 줄(화면 절반에 묶여 두 줄로 접혔다) · 홈 화면 앱에서 탭바를 안 덮게 */
html.sp #toast{width:max-content; max-width:min(86vw, 420px); bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 16px);}
body.tabhide #toast{bottom:calc(env(safe-area-inset-bottom) + 16px);}
/* 문서 · PDF 보기: 위 줄이 상단바 밑으로 사라졌다 → 상단바 밑에 붙인다 */
html.sp .docbar{top:56px;}
html.sp .pdfbar{top:108px;}
html.sp body:has(#view[data-view="doc"]) .syncbar, html.sp body:has(#view[data-view="pdf"]) .syncbar{display:none;}
/* 가로 모드: 뷰어 단추가 노치 · 둥근 모서리 자리에 섰다 */
.pvtop, .pvnav{padding-left:calc(12px + env(safe-area-inset-left)); padding-right:calc(12px + env(safe-area-inset-right));}
/* 플레이어: 곡 · 목록/가사를 바꿀 때 영상이 위아래로 튀었다 → 플레이어 칸은 위에 붙인다 */
#layer.lightbox > .lvl:has(> .ytbox){align-items:flex-start;}
/* 꾸미기 창: 키 낮은 카톡 창에서 저장 줄이 밖으로 밀렸다 → 저장 줄만 아래에 붙인다(판은 그대로) */
html.sp .sheet.dcsheet .formfoot{position:sticky; bottom:calc(-20px - env(safe-area-inset-bottom)); z-index:2; background:var(--card);
  padding:10px 0 calc(10px + env(safe-area-inset-bottom)); margin-bottom:calc(-20px - env(safe-area-inset-bottom));}
/* 곡 찾기 목록: 화면에 안 보이는 줄은 그리기를 미룬다(4배 느린 폰에서 하위 탭 전환 230~370ms) */
html.sp .songtable .srow{content-visibility:auto; contain-intrinsic-size:auto 32px;}
/* 주일(하늘 커버) 달력 칸의 이름: 하늘 위 작은 글자 대비가 2.8~4.2:1 */
td.svcover.col-sun .calmini .mnm{background:rgba(255,255,255,.86); border-radius:4px; padding:0 2px;}
/* 낮은 화면(카톡 창 · 가로 모드)의 «안녕, 나는»: 이름표 크기만 줄이고 이름 목록 바닥을 깐다 */
.hello-in{overflow-y:auto;}
.hello-list{min-height:min(150px, 38vh);}
@media (max-height:700px){
  .ht-band{padding:8px 16px 7px;} .ht-band b{font-size:30px;} .ht-band span{font-size:13px;}
  .ht-body{height:64px;} .ht-name{font-size:42px;} .ht-name.ht-blank{height:34px;}
  .hello-hint{margin:12px 0 6px;} .hello-hint small{display:none;}
}
@media (max-height:480px){ .hello-tag{display:none;} .hello-hint{margin-top:0;} }
/* 태블릿 상단바: 로고 · 돋보기가 본문 칸보다 14px 밖으로 나와 있었다 */
html.sp .topbar .in{max-width:692px;}
/* 넓은 화면: 마우스를 올리면 반응한다(교회 컴퓨터에서 거의 아무것도 안 바뀌었다) */
@media (hover:hover) and (pointer:fine){
  html.sp .btn:not(.primary):not(.playall):hover, html.sp .iconbtn:hover, html.sp .mbtn:hover, html.sp .fchip:not(.on):hover{border-color:var(--sp-leaf-600);}
  html.sp .btn.primary:hover, html.sp .btn.playall:hover{background:var(--sp-leaf-fill);}
  html.sp .sp-row:hover, html.sp .sp-mecard:hover, html.sp .fdrow:hover, html.sp .res:hover, html.sp .todorow:hover,
  html.sp a.chkrow:hover, html.sp .bkbar:hover, html.sp .ctwho:hover, html.sp .sp-ask:hover{background:var(--sp-leaf-50);}
  html.sp .deskNav a:hover{background:rgba(11,42,68,.06);}
  html.sp[data-page="home"] .deskNav a:hover{background:rgba(255,255,255,.5);}
  html.sp[data-page="home"][data-tod="dawn"] .deskNav a:hover, html.sp[data-page="home"][data-tod="evening"] .deskNav a:hover,
  html.sp[data-page="home"][data-tod="night"] .deskNav a:hover{background:rgba(255,255,255,.16);}
}
/* 넓은 화면: 자료실 두 칸 타일의 구분선이 한쪽에만 그어졌다 → 칸 틈 1px 을 선으로 */
@media (min-width:700px){
  html.sp .reslist{gap:1px; background:var(--sp-line);}
  html.sp .reslist > .res{background:var(--card); border-top:0 !important;}
  html.sp .reslist::after{content:''; background:var(--card);}
  html.sp .reslist:has(> .res:nth-child(even):last-child)::after{display:none;}
}
/* 넓은 화면: 리더 할 일 숫자를 위 메뉴의 «더보기» 에도 · PDF 가 넘치지 않게 */
@media (min-width:900px){
  html.sp .deskNav a[data-nav="#/more"]{position:relative;}
  html.sp .deskNav .sp-tabdot{position:absolute; top:-2px; right:-4px; min-width:17px; height:17px; padding:0 5px; border-radius:999px; box-sizing:border-box;
    display:flex; align-items:center; justify-content:center; background:var(--praise-fill); color:#fff; font-weight:700; font-size:10.5px; line-height:1;}
  html.sp .docstage.pdfstage{height:calc(100vh - 165px); height:calc(100dvh - 165px);}
  html.sp .pdfstage{overflow-y:scroll; scrollbar-gutter:stable;}
}

/* 넓은 화면: 상단 메뉴가 화면을 옮길 때마다 좌우로 48px 움직였다(왼쪽 제목 폭이 화면마다 달라서) → 칸 폭이 고정된 격자 */
@media (min-width:900px){
  html.sp .topbar .in{display:grid !important; grid-template-columns:30px 168px 1fr 128px; column-gap:6px;}
  html.sp .topbar .tile{grid-column:1; grid-row:1;}
  html.sp .topbar .logo, html.sp .topbar .sp-title{grid-column:2; grid-row:1; min-width:0; white-space:nowrap; overflow:hidden;}
  html.sp .topbar .deskNav{grid-column:3; grid-row:1; justify-self:center; margin:0;}
  html.sp .topbar .sp-tbacts{grid-column:4; grid-row:1; justify-self:end; margin-left:0;}
}

/* 133차-d: 고르기 칩 · 상단바 제목 · 자판 */
.uxsel select{position:absolute; inset:0; width:100%; height:100%; opacity:0; font-size:16px; padding:0; margin:0; cursor:pointer;}
.uxsel .uxval{font-weight:800;}
html.sp .sp-title{margin:0;}
body.kbopen .tabbar{transform:translateY(calc(100% + 8px)) !important;}
html.sp #layer{bottom:var(--kb, 0px);}
html.sp .sheet{max-height:calc((100vh - var(--kb, 0px)) * .88); max-height:calc((100dvh - var(--kb, 0px)) * .88);}
html.sp .sheet > .formfoot:last-child, html.sp .sheet > .formfoot:has(+ .formmsg:last-child){position:sticky; bottom:calc(-20px - env(safe-area-inset-bottom)); z-index:2; background:var(--card);
  padding-top:10px; padding-bottom:calc(10px + env(safe-area-inset-bottom)); margin-bottom:calc(-20px - env(safe-area-inset-bottom));}

/* 133차-d 감사: 작은 것들 */
/* 섬김표 «○○ 이름에 표시가 붙어 있어요» 견본이 실제 표시(초록 형광펜 + 나)와 달랐다 */
html.sp .mnm.me{background:var(--sp-leaf-100); color:var(--sp-leaf-700);}
html.sp .mnm.p.me{background:var(--sp-leaf-600); color:#fff;}
/* 두 줄로 접힌 곡 제목: 세모가 마지막 글자 뒤에 붙는다(두 줄 사이 오른쪽 끝에 떠 있었다) */
.songrow .stitle, .songtable .srow .stitle{display:inline; text-wrap:pretty;}
.stitle .ic.tiny{display:inline-block; vertical-align:-1px; margin-left:5px;}
html.sp .rsgo .ic{width:14px; height:14px; color:var(--ink);}
/* 익명을 켜면 보내기가 왼쪽으로 151px 튀었다 · 켜진 익명 칩이 보내기와 같은 초록 덩어리였다 */
.whorow #reqSend{margin-left:auto;}
html.sp #reqWho .fchip.on, html.sp #fbAnon.on{background:var(--sp-leaf-50) !important; border-color:var(--sp-leaf-600) !important; color:var(--sp-leaf-700) !important; box-shadow:none !important;}
/* 관리자 공지 목록: 단추 묶음은 글 아래 줄 오른쪽에 */
html.sp .mgcard .notice{flex-wrap:wrap;}
html.sp .mgcard .notice .nacts{flex-basis:100%; display:flex; justify-content:flex-end; gap:8px; margin-top:6px;}
html.sp .notice:not(.mgcard .notice) .nacts{display:contents;}
/* 신청 명단의 지우기는 휴지통 글자색(창 닫기 X 와 다르게) */
html.sp .jrow .jdel{border:0; box-shadow:none; background:transparent; color:var(--sp-coral-700);}
/* 연락처 저장 단추: 혼자 꽉 찬 폭이었다 */
#tlSave{align-self:flex-start;}

/* 홈 신청곡: 제목이 카드 밖으로 나가서 카드 머리에는 «지난 곡» 하나만 */
html.sp .rsbundle.home .rsbundlehead{justify-content:flex-end; min-height:0; padding-top:8px; padding-bottom:4px;}

/* 넓은 화면 홈을 내리면 위 메뉴가 하늘과 같이 사라졌다(133차-d 감사) → 붙여 두고, 하늘을 벗어나면 바탕을 깐다 */
@media (min-width:900px){
  html.sp[data-page="home"] .topbar{position:fixed; top:0;}
  html.sp.heroout[data-page="home"] .topbar{background:var(--page); box-shadow:0 1px 0 var(--sp-line);}
  html.sp.heroout[data-page="home"] .topbar :is(.deskNav a, .logo .nm, .sp-find){color:var(--ink) !important;}
  html.sp.heroout[data-page="home"] .deskNav a.on::after{background:var(--sp-leaf-600) !important;}
}

/* 133차-d 인사 밑 곁말(그날 꼭 알면 좋은 것 하나) */
.sp-sub{margin:6px 0 0; font-size:14px; font-weight:800; line-height:1.4; color:inherit; opacity:.86; max-width:min(100%, 420px); word-break:keep-all;}
.sp-sub[hidden]{display:none;}

/* 133차-d 감사: 창의 저장 줄은 한 모양 = [저장] [결과 글] ...... [지우기].
   지우는 동작이 창마다 다섯 모양 · 두 색이었다(남색 보조 단추 · 파란 링크 · 코랄 링크). 지우는 것은 코랄 글자, 줄 오른쪽 끝 */
html.sp .linkbtn.del{color:var(--sp-coral-700); font-weight:700;}
html.sp .formfoot .linkbtn.del{margin-left:auto; font-size:13px;}
html.sp .formfoot .formmsg{min-height:0;}
html.sp #recBody > .stagestate{margin-bottom:14px;}

/* 늦게 채워지는 창의 자리표시: 최종 높이에 가깝게 잡아 두어 들어올 때 덜 솟는다(나머지는 fillSheet 가 미끄러지게) */
.sheetwait{min-height:var(--wh, 300px); display:flex; align-items:center; justify-content:center;}
#rsArchiveList.sheetwait{--wh:280px;}

/* 133차-d 감사: 입력칸 작은 것들 (forms#10 · 11 · 12 · 19)
   체크 상자는 잎색 · 20px(기본 파랑 13px 이었다) · 한 줄 안의 칸 높이는 44 하나(날짜 · 고르기 42, 글 칸 40) ·
   칸 안 자리표시 글은 말줄임 · 자동완성 칸의 기본 검정 ▼ 는 숨긴다(제안은 그대로 뜬다) */
html.sp input[type=checkbox]{accent-color:var(--sp-leaf-600); width:20px; height:20px; margin:0; flex:none;}
html.sp .field input:not([type=checkbox]):not([type=file]), html.sp .field select{min-height:44px; box-sizing:border-box;}
html.sp .field input{text-overflow:ellipsis;}
html.sp input[list]::-webkit-calendar-picker-indicator{opacity:0; width:0; padding:0; margin:0;}
html.sp .fieldrow{align-items:flex-end;}
html.sp .fieldrow > .nechk{min-height:44px; margin-bottom:12px;}
html.sp .searchbar{cursor:text;}

/* 133차-d 감사: 모양 하나로 (visual-consistency 13 · 14 · 17 · 18 · 19 · 20 · 22 · 23)
   «새 글» 은 한 색(피드백 «새 글» · 숫자 배지와 같은 빨강) · 정보 딱지는 테두리 없는 옅은 바탕(테두리 알약은 누르는 것처럼 읽혔다) ·
   홈 카드 모서리는 하나(18 · 20 · 22 가 섞여 위아래 카드 모서리가 달랐다) · 옅은 안내 띠는 14 · 줄 끝 꺾쇠는 16px 한 색 · 옅은 줄은 1px */
html.sp .newdot{background:var(--praise-fill); color:#fff; padding:1px 7px; font-size:10.5px; line-height:1.5;}
html.sp .fbto, html.sp .badge, html.sp .ctself{border:0;}
html.sp .bkbar .bg{border-color:var(--sp-line2); color:var(--ink); box-shadow:0 2px 0 var(--sp-ledge);}
html.sp #nlist .notice, html.sp .rsbundle, html.sp .qcard, html.sp .svrow, html.sp .setcard, html.sp .teamcard, html.sp .reslist, html.sp .empty{border-radius:var(--sp-r);}
html.sp .todorow{border-radius:14px;}
html.sp .telsafe, html.sp .mecue, html.sp .ctnote, html.sp .stagestate, html.sp .hookbox, html.sp .lglog{border-radius:14px;}
html.sp .sp-row > .ic, html.sp .sp-mecard > .ic, html.sp .sp-ask > .ic, html.sp .fdrow > .ic:last-child, html.sp .chkgo .ic,
html.sp .todorow .tdgo .ic, html.sp .ctopen .go{width:16px; height:16px; color:var(--dk-sub, #9AAAB5);}
html.sp .sp-pickhd.praise-b{color:var(--praise2);}
html.sp .ythint{border-top-width:1px;}

/* 133차-d 감사: 창 작은 것들
   · 긴 창을 내려도 제목과 닫기(X)가 위에 남는다(390#11 · lifecycle#13 · mobile#10). 손잡이는 같이 올라간다
   · 넓은 화면: 창 안에서도 마우스를 올리면 반응한다(1440#8) · «나» 이름표에도 초점 테두리(1440#9)
   · 화면 끄고 듣는 안내는 폰 얘기라 마우스 화면에선 안 띄운다(1440#14) */
html.sp .sheet > .shhead{position:sticky; top:-22px; z-index:3; background:var(--card); margin:-22px -18px 14px; padding:22px 18px 0;}
html.sp .sheet > .grab{z-index:4;}
@media (hover:hover) and (pointer:fine){
  html.sp .sp-pick:hover, html.sp .plswb:hover{border-color:var(--sp-leaf-600);}
  html.sp .rsgo:hover, html.sp .sdh:hover, html.sp .ytout:hover{background:var(--sp-leaf-50);}
  html.sp .ptag[data-who]:hover{text-decoration:underline; text-underline-offset:3px;}
  .ythint{display:none;}
}
.ptag.me:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px; border-radius:6px;}

/* 133차-d 감사: 누름 · 초점 작은 것들 (interactive 8 · 10 · 11 · 14 · 15 · desktop-tablet 11)
   · 신청 곡 줄 칸도 누르면 초록 테두리(옆 이름 칸과 같게. 예전 규칙은 !important 에 져서 무력했다)
   · 공지의 «참여하기» · «N명» 은 모양은 그대로 두고 누르는 자리만 넓힌다
   · 홈이 아닌 화면의 첫 Tab 이 크기 0 인 로고 링크로 가서 초점이 사라졌다 → 그 화면에선 로고 링크를 뺀다(제목이 맡는다)
   · 보내는 동안 꺼진 단추는 꺼진 모양 · 점검 단계 딱지는 테두리 없이 · 태블릿 세로의 달력/목록 고르기는 글자만큼 */
html.sp .rsnewin input:focus{border-color:var(--sp-leaf-600) !important; box-shadow:0 0 0 3px var(--sp-leaf-100) !important;}
html.sp .gateform input:focus{box-shadow:0 0 0 3px var(--sp-leaf-100) !important;}
.btn.xs{position:relative;}
.btn.xs::after{content:''; position:absolute; inset:-8px -4px;}
html.sp[data-page]:not([data-page="home"]) .topbar .logo{display:none;}
html.sp .iconbtn:disabled, html.sp .fchip:disabled{opacity:.5; cursor:default; box-shadow:none;}
html.sp .hookst{border:0; background:var(--sp-leaf-50);}
@media (min-width:600px) and (max-width:899px){ html.sp .pvtoggle{flex:0 0 auto; margin:0 auto;} }

/* 133차-d 감사: 폰 가장자리 · 글자 작은 것들 (mobile 11 · 13 · 14 · 15 · 16, type 9 · 14 · 15 · 19 · 20 · 21)
   ⚠ 프로필 고치는 타일(.wfact)은 꾸미기 판 밖이다. 판 크기 · 좌표는 안 건드린다 */
html.sp .topbar{transition:box-shadow .2s ease;}
html.sp:not([data-page="home"]) body.scrolled:not(.gated) .topbar{box-shadow:0 1px 0 var(--sp-line);}
/* 홈 말고 다른 화면도 상단바가 글과 같이 올라간다(폰 · 태블릿 세로, 133차-h 아홉째 판).
   JH: *"홈은 ... 스크롤업하면 ... fade out 이 되잖아. 그런데 다른 탭에는 fade out 이 아니고 그냥 고정되어 버리거든.
   텍스트가 위에 둥 떠 있으니까 약간 그 위치에 걸린 것 같아."* 홈은 하늘 머리와 같이 흘러가는데 다른 화면만 «섬김표» 제목 띠가 붙어 있었다.
   폰은 아래 탭바가 길을 맡고, 맨 위로는 지금 탭을 한 번 더 누르면 간다. 넓은 화면(900 이상)은 위 메뉴가 길이라 홈도 붙여 둔다(그대로).
   ⚠ 글을 화면 위에 맞추는 곳(신청 «온 신청» 도착 · 피드백 받은 편지)은 `topCover()` 로 가릴 높이를 잰다(붙어 있을 때만 바 높이) */
@media (max-width:899px){
  html.sp[data-page]:not([data-page="home"]) .topbar{position:relative;}
  html.sp .reqsplit > .reqcompose{top:calc(var(--top-safe, 0px) + 12px);}   /* 태블릿 세로 신청 두 기둥: 붙던 84px 은 바 밑 자리였다 */
}
html.sp .wfact.off span{white-space:normal; text-align:center; line-height:1.25; font-size:12px;}
@media (max-width:340px){
  html.sp .wfact{flex-direction:column; gap:3px; padding:8px 4px;}
  html.sp .wfact span{white-space:normal; line-height:1.2; text-align:center;}
}
@media (max-height:480px){
  .gatecard{padding:18px 22px 14px;}
  .gatecard .bartip{transform:rotate(4deg) scale(.8); margin-top:0;}
  .gatewrap{padding-top:18px;}
}
html.sp .adminhero .btn{flex:none; white-space:nowrap;}
html.sp .hint, html.sp .sp-sheetlead, html.sp .sp-note, html.sp .chkhint, html.sp .req .rb{text-wrap:pretty;}
html.sp .req .kbadge{min-width:3.6em; text-align:center;}
.chktop{flex-wrap:wrap;}
.chkrow.bad .chkdetail, .chkrow.warn .chkdetail{text-align:left; flex-basis:100%; padding-left:29px; order:1;}
.chkrow.bad .chkgo, .chkrow.warn .chkgo{margin-left:auto;}
html.sp .mehint{display:flex; flex-wrap:wrap; align-items:center; column-gap:7px; row-gap:6px;}
html.sp .mehint .minechip{margin-left:0;}

/* 133차-d 감사: 응원 누름은 눌림에서 제자리로 미끄러진다(부풀고 기우는 것은 41차에 물린 말투다) */
@keyframes chpop{0%{transform:scale(.92);} 100%{transform:none;}}

/* 133차-d 아이패드: 화면이 바뀌면 화면 읽기 프로그램을 위해 본문(#view)으로 초점을 옮긴다. 아이패드는 그 초점에 테를 그려서 본문 둘레에 짙은 테가 떴다.
   손으로 Tab 을 눌러 갈 수 없는 자리(tabindex -1)는 테를 안 그린다. 단추 · 칸의 테는 그대로다. */
[tabindex="-1"]:focus{outline:none;}

/* ══════════════════════════════════════════════════════════════════════════════════════
   133차-e 시간대 옷 (2026-10-02) · 새벽 · 저녁 · 밤은 화면 전체가 어둡다
   JH(새벽 4시에 열어 보고): *"ui의 color가 시간대랑 상관없이 그냥 무조건 밝은색이고 맨 위에 교회 이미지만 색이 바뀌니까 안맞잖아.
   처음에 낮에 봤을땐 그럴싸 했었는데 지금 보니까 그냥 뭔가 만들다 만거같아."*
   → 133 은 시각을 **홈 하늘 머리 안에서만** 보여 줬다(위 never 의 한 줄). 이제 바탕 · 카드 · 글자도 그 하늘을 따른다.
   아침 · 낮 · 오후는 그대로 밝다. 새벽(05–07) · 저녁(18–20:30) · 밤(20:30–05)만 그 시각 하늘빛으로 어둡다.
   설계:
   - 글자용 토큰(-700 · 역할색 · 잉크)은 밝아지고, 칠용 토큰(-fill)은 그대로 진하다. 한 토큰이 글자와 칠을 같이 맡던 자리를 먼저 갈랐다.
   - 옅은 바탕(-50 · -100 · -soft)은 반투명이 된다. 밑의 카드색을 따라가니 세 시각 모두 같은 값으로 된다.
   - 잉크로 채운 띠 · 칩은 밝은 띠가 되고 그 위 글자는 `--on-ink`(그 시각 바탕색)다.
   - 꾸미기 판(.whoboard)도 어둡다(133차-h 에 바꿨다. 처음엔 흰 종이로 남겼다가 JH 가 "카드만 밝아서 눈뽕" 이라고 했다).
     낙서는 색 이름으로 저장되고 토큰으로 칠해져서 같이 밝아진다. 크기 · 좌표 · 저장값은 안 건드린다(사용자: "기존 꾸민것들은 건들이지 말아줘").
   - 값을 바꾸면 `node tools/qa/nightskin.mjs` 로 글자 대비와 남은 흰 면을 다시 잰다(눈으로는 안 보인다).
   ══════════════════════════════════════════════════════════════════════════════════════ */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]){
  color-scheme:dark;
  --line-a:rgba(255,255,255,.08);
  --sp-line:rgba(255,255,255,.085); --sp-line2:rgba(255,255,255,.16);
  --gridline:rgba(255,255,255,.05);
  --sh-sm:0 2px 0 rgba(0,0,0,.30);
  --sp-lift:0 3px 0 rgba(0,0,0,.32);
  /* 글자용 = 밝은 판(카드 위 6:1 넘게) */
  --sp-leaf-700:#92D6A3; --sp-sky-700:#A3C4EE; --sp-coral-700:#F4A6A7; --sp-sun-700:#EBDB7A;
  /* 옅은 바탕 = 반투명 */
  --sp-leaf-50:rgba(143,203,155,.10);  --sp-leaf-100:rgba(143,203,155,.18);
  --sp-sky-50:rgba(120,165,220,.12);   --sp-sky-100:rgba(120,165,220,.22);
  --sp-coral-50:rgba(220,114,115,.13); --sp-coral-100:rgba(220,114,115,.24);
  --sp-sun-50:rgba(242,224,107,.10);   --sp-sun-100:rgba(242,224,107,.18);
  --praise2:#EBA8C9; --praise2-soft:rgba(214,110,160,.22);
  --lilac:#C6B5F2;   --lilac-soft:rgba(150,120,230,.24);
  --rl-session:#C6B5F2; --rl-session-soft:rgba(150,120,230,.24);
  /* 생일 촛불 */
  --cd1:#F59A8A; --cd1s:rgba(232,84,60,.22);
  --cd2:#7FD0D6; --cd2s:rgba(14,150,160,.24);
  --cd3:#8FD6A8; --cd3s:rgba(46,158,91,.22);
  --cd4:#9CC6F2; --cd4s:rgba(46,130,216,.24);
  --cd5:#C7AEF2; --cd5s:rgba(139,92,214,.24);
  --cd6:#F2A5CB; --cd6s:rgba(214,71,143,.22);
  /* 손으로 박은 밝은 바탕 · 짙은 글자를 감싼 자리(`var(--dk-*, 원래 값)`). 밝은 시각엔 비어 있어 원래 값이 그대로 쓰인다 */
  --dk-well:rgba(255,255,255,.05); --dk-track:rgba(255,255,255,.09); --dk-line:rgba(255,255,255,.12);
  --dk-leafwell:rgba(143,203,155,.12); --dk-skywell:rgba(120,165,220,.14); --dk-corawell:rgba(220,114,115,.14);
  --dk-sunwell:rgba(242,224,107,.12); --dk-lilwell:rgba(150,120,230,.16);
  --dk-ink:var(--ink); --dk-sub:var(--sp-sub);
  --sp-ledge:rgba(0,0,0,.28); --dk-ledge:rgba(0,0,0,.28);
  --dk-leaftx:var(--sp-leaf-700); --dk-skytx:var(--sp-sky-700); --dk-coratx:var(--sp-coral-700); --dk-suntx:var(--sp-sun-700); --dk-liltx:var(--lilac);
}
/* 바탕 · 카드 · 글자 = 그 시각 하늘(홈 하늘 머리)의 빛 */
html.sp[data-tod="night"]{     /* 밤 · 남색 */
  --page:#0E1F3D; --page2:#0B1A34; --card:#172C4F;
  --ink:#E8EFF8; --ink2:#B9C8DE; --faint:#9DB0CB; --sp-sub:#9DB0CB; --on-ink:#0E1F3D;
  --paper:var(--page); --paper2:var(--page2);
}
html.sp[data-tod="dawn"]{      /* 새벽 · 쪽빛 */
  --page:#172950; --page2:#132343; --card:#1F345F;
  --ink:#EEF2FA; --ink2:#C3CEE6; --faint:#A8B6D6; --sp-sub:#A8B6D6; --on-ink:#172950;
  --paper:var(--page); --paper2:var(--page2);
}
html.sp[data-tod="evening"]{   /* 저녁 · 노을 진 뒤 보랏빛 */
  --page:#1F1B40; --page2:#1A1736; --card:#2B2652;
  --ink:#F3EEF8; --ink2:#CEC3E2; --faint:#B4A8D0; --sp-sub:#B4A8D0; --on-ink:#1F1B40;
  --paper:var(--page); --paper2:var(--page2);
}

/* ── 꾸미기 판도 그 시각 옷을 입는다 (133차-h, 2026-10-02) ──────────────────────────
   JH: "배경은 다크모드인데 프로필 누르면 뜨는 카드만 밝아서 눈뽕맞거든? 이 카드도 배경이랑 색이 맞게 해줘".
   133차-e 에는 판을 흰 종이로 남겼다(진한 잉크 낙서가 어두운 판에 묻힐까 봐). 그런데 낙서 색은 저장값이 이름(ink · coral …)이고
   화면이 토큰으로 칠한다(.decodraw .dl-*). 판이 어두워지면 잉크 낙서도 밝은 잉크로 같이 바뀌어 안 묻힌다.
   저장된 꾸미기(좌표 · 색 이름 · 스티커 · 고른 바탕색)는 한 글자도 안 바뀐다. 칠하는 법만 시각을 따른다.
   판 바탕색: 밝은 시각엔 고른 색을 흰색 쪽으로 눕힌 색(--deco), 어두운 시각엔 카드색 쪽으로 눕힌 색(--decohue 26%).
   ⚠ color-mix 를 모르는 브라우저는 앞줄(카드색)을 쓴다. 고른 색이 안 보일 뿐 판은 어둡다. */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .whoboard.tinted{
  background:var(--card);
  background:color-mix(in srgb, var(--decohue, var(--card)) 26%, var(--card));
}
/* 손그림 아이콘(/icons/*.png)은 전부 진한 선 한 가지 색이다(재 봤다: 색 있는 점 0, 평균 밝기 24~32).
   어두운 시각엔 선을 뒤집어 옅은 밝은 선으로 그린다. 그전엔 프로필 카드 역할 · 생일 줄, 팀 명단, 생일 카드 아이콘이 어두운 바탕에 묻혔다.
   ⚠ img 만 고른다. .wri 는 svg(소개 압정)에도 붙는데 그건 이미 글자색(밝은 잉크)이라 뒤집으면 도로 어두워진다 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) :is(img.rolei, img.whoi, img.wri){filter:invert(1) brightness(.92);}
/* 프로필 역할 아이콘은 칸(바탕)이 그림 자체에 칠해져 있어서 같이 뒤집힌다. 뒤집힌 뒤에 옅은 밝은 칸이 되도록 어두운 반투명을 깔고, 그림자는 뺀다 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) img.whoi{background:rgba(0,0,0,.14); box-shadow:none;}
/* 돋보기: 바탕은 카드색(판 복제가 그 위에 앉는다), 테두리는 밝아진 잉크, 밑 단은 어두운 그림자 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .dcloupe{box-shadow:0 4px 0 rgba(0,0,0,.45);}

/* ── 어두운 시각: 손으로 고친 부품 ─────────────────────────
   토큰만으로 안 되는 것(반투명 흰 알약 · 잉크 띠 위 흰 글자 · 밝은 단단한 그림자)은 여기서 하나씩. 어디를 고쳤는지는 nightskin.mjs 가 찾아 줬다 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-save{background:rgba(255,255,255,.13); color:var(--sp-leaf-700); box-shadow:none;}
/* 리더 알림 띠 = 잉크 띠(131차-c, 사용자가 고른 옷). 어두운 시각엔 잉크가 밝아지니 띠도 밝은 띠가 되고 글자는 바탕색이다. 밑 단은 어두운 그림자로 */
/* 133차-h: 밤엔 밝아진 잉크 띠가 화면에서 제일 밝은 면이 됐다(JH "리더들이 보는 피드백 신청 노티스도 너무 눈뽕 안나게 해줘").
   어두운 시각엔 붉은 기가 도는 어두운 띠 + 밝은 글자. 왼쪽 빨강 머리띠와 숫자 배지는 그대로라 알림인 건 여전히 먼저 보인다.
   ⚠ color-mix 를 모르는 브라우저는 앞줄(카드색)을 쓴다 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .fbalert{
  background:var(--card);
  background:color-mix(in srgb, var(--praise-fill) 24%, var(--card));
  color:var(--ink); border-color:rgba(255,255,255,.08); border-left-color:var(--praise-fill);
  box-shadow:0 4px 0 rgba(0,0,0,.35);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .fbalert:active{box-shadow:0 1px 0 rgba(0,0,0,.35);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .fbalert .fbt b,
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .fbalert .fbgo{color:var(--ink);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .fbalert .fbt i{color:var(--ink2); opacity:1;}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .fbalert .fbn{border-color:var(--card);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) #toast:not(.err){color:var(--on-ink); box-shadow:0 3px 0 rgba(0,0,0,.35);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .hint code{color:var(--ink2);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .teamcard .tcount{color:var(--ink2);}
/* 하늘 머리 아래 끝: 어두운 시각엔 지평선 빛(저녁 노을 · 새벽 볕)이 바탕으로 더 길게 풀린다. 46px 이면 넓은 화면에서 지평선이 칼로 자른 띠로 보였다 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-hero::after{height:72px;}
@media (min-width:900px){ html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-hero::after{height:124px;} }
/* 내 섬김 티켓(시그니처): 테두리는 밝아진 잉크 그대로, 밑 단은 어두운 그림자(밝은 단단한 그림자는 빛나는 띠로 읽혔다) */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-ticket{box-shadow:0 5px 0 rgba(0,0,0,.45);}
/* 새벽 해: 폰에서는 하늘 머리 왼쪽이 인사 글자 자리라, 왼쪽 해가 «정훈님» 뒤에서 빛나 글자가 묻혔다(흰 글자 1.2:1). 폰만 오른쪽 나무 뒤로 옮긴다(해는 하늘 층이라 교회 그림 뒤에 있다) */
@media (max-width:899px){
  html[data-tod="dawn"] .sp-sun{background:radial-gradient(58px 58px at 90% 52%, rgba(255,224,190,.98) 0 36%, rgba(255,184,138,.5) 58%, rgba(255,184,138,0) 74%),
    radial-gradient(280px 210px at 88% 58%, rgba(255,174,126,.42) 0, rgba(255,174,126,0) 70%);}
}
/* 입장권(입장 코드 화면)도 티켓과 같다: 밑 단은 어두운 그림자 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .gatecard{box-shadow:0 5px 0 rgba(0,0,0,.45);}

/* ── 133차-f 홈 화면 앱(아이폰)도 브라우저와 같은 모양 · 아래 탭바는 바탕이 비치는 판 ─────────────
   JH: "그 위에 이제 그 카리스 예배팀하고 돋보기가 떠 있잖아. 그쪽 부분이 색이 안 맞거든 ... 핸드폰은 그냥 하얀색이야 ...
   그 아래 탭 부분도 따로 하얗게 분류돼 있잖아. 그래서 위아래로 하얀색 노치가 가리니까 볼 때 좀 답답하게 느껴지거든."
   iOS 26 부터 홈 화면 앱은 상태바를 theme-color 로 칠한다(상태바 모양 default). 그래서 홈 화면 앱만 따로 두던 흰 상단바 · 흰 번짐을 걷고
   브라우저 규칙을 그대로 쓴다(홈은 하늘 윗색, 다른 화면은 바탕색. app.js paintThemeColor).
   ⚠ 상태바 모양을 black-translucent 로 바꾸지 말 것. iOS 26 부터 그 밑에 유리 흐림 띠를 깔아 머리가 뿌옇게 보인다.
   아래 탭바: 흰 판(테두리 한 줄)이 위아래로 화면을 가두는 띠로 읽혔다 → 바탕색이 비치는 판. 밑으로 지나가는 카드는 흐리게 비친다. */
html.sp .tabbar{border-top-color:transparent; background:var(--page);}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  html.sp .tabbar{background:color-mix(in srgb, var(--page) 90%, transparent); -webkit-backdrop-filter:saturate(1.4) blur(20px); backdrop-filter:saturate(1.4) blur(20px);}
}

/* ── 133차-g 아이폰 홈 화면 앱: 유리 흐림 띠 밑으로 ─────────────
   JH(아이폰 홈 화면 앱): "위가 약간 흐릿하게 처리돼서 카리스 예배팀하고 예배팀도 약간 흐리게 보이거든 ... iPad는 또 괜찮아".
   iOS 26 부터 아이폰 홈 화면 앱은 화면 맨 위 약 40pt 에 유리 흐림(Liquid Glass 가장자리 효과)을 덮는다. 시스템이 그리는 것이라
   meta 나 CSS 로 끌 수 없다(2026년 다른 PWA 들의 기록: github 의 dozzle #5222 · xdoubleu tools #1988 · TerminalLearning #411).
   그래서 글자가 있는 줄을 그 띠 밑으로 내린다. 홈은 하늘 머리를 그만큼 키워서 흐린 띠 안에는 하늘만 있다.
   `html.iphoneapp` 은 index.html 첫 스크립트가 단다(홈 화면 앱 + 아이폰). 시험은 주소에 `?app=iphone`. */
/* 28px = 상단바에서 가장 위에 있는 로고 아이콘(56px 줄 가운데라 윗끝 13px)이 흐림 띠(약 40pt) 밑으로 내려가는 가장 작은 값. 처음엔 40px 를 통째로 더했다가
   "위에 너무 공백을 만들어 버린 거 아니야?" 를 듣고 줄였다(같은 날). 가로 화면은 상태바가 없어서 안 더한다 */
@media (orientation:portrait){ html.iphoneapp{--top-safe:calc(env(safe-area-inset-top, 0px) + 28px);} }
html.sp.iphoneapp .topbar{padding-top:var(--top-safe);}

/* 133차-h: 줄을 넘기면 안 되는 숫자 덩어리(시각 · 기온과 붙은 조사). app.js keepNum */
.nobr{white-space:nowrap;}
/* 시각 한 줄(«예배 8:30 PM»)은 가운데서 안 갈린다(커버 머리 `timeLinesHTML`) */
.svln{white-space:nowrap;}
/* 133차-h 둘째 판: 화면 전체의 숫자 덩어리는 app.js guardNums · keepNum 이 <nobr> 로 감싼다(span 이면 기존 «.x span» 규칙이 꾸민다).
   flex 상자 바로 안의 짧은 글자는 감싸지 않으니(조각이 따로 칸이 된다) 그런 자리는 상자째 줄을 안 넘긴다: 가사 단추 «가사 1/4곡» · 섬김표 주 머리 «9/27 ~ 10/3» · 카드 날짜 «10/2» */
nobr{white-space:nowrap;}
.btn.lyrbookbtn, .wklabel, .spotdate{white-space:nowrap;}

/* ── 133차-h 예배 시작 전 · 진행 중 (app.js liveState) ─────────────
   JH: "예배 시작 10분 전 이런 식으로 그 인디케이터 같은 것도 작게 이렇게 지금 UI에 잘 어울리게".
   «오늘 예배» 제목 옆 작은 딱지 하나(누르는 것이 아니라 글자만, 테두리 · 그림자 없음). 시작 전은 하늘색, 진행 중은 빨간 점 + 산호색.
   진행 중에는 카드 위에 «예배 보러 가기» 한 줄. 누르는 것이라 «내 이름 고르기» 와 같은 단추 옷(.sp-ask)을 입는다. */
.sp-livebox{align-self:center; display:inline-flex;}
.sp-livebox:empty, .sp-watchbox:empty{display:none;}
.sp-live{display:inline-flex; align-items:center; gap:6px; padding:3px 9px; border-radius:999px; white-space:nowrap;
  font-size:12px; font-weight:800; line-height:1.35; background:var(--sp-sky-50); color:var(--sp-sky-700);}
.sp-live.on{background:var(--sp-coral-50); color:var(--sp-coral-700);}
.lvdot{position:relative; flex:none; width:7px; height:7px; border-radius:50%; background:#E0352B;}
.lvdot::after{content:''; position:absolute; inset:0; border-radius:50%; background:#E0352B; animation:lvpulse 1.8s ease-out infinite;}
@keyframes lvpulse{from{transform:scale(1); opacity:.55;} to{transform:scale(2.7); opacity:0;}}
@media (prefers-reduced-motion:reduce){ .lvdot::after{animation:none; opacity:0;} }
.sp-watchbox{margin:0 0 12px;}
.sp-watch .sp-askic{background:var(--sp-coral-100);}
/* 어두운 시각엔 누르는 줄의 밑 단도 어두운 그림자다(밝은 단단한 그림자는 빛나는 띠로 읽힌다. 티켓 · 입장권과 같은 규칙) */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-ask:not(.quiet){box-shadow:0 4px 0 rgba(0,0,0,.45);}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-ask:not(.quiet):active{box-shadow:0 1px 0 rgba(0,0,0,.45);}

/* ── 133차-h 응원한 사람(카톡 공감처럼) ─────────────
   JH: "지금은 누가 뭘 눌렀는지를 모르니까 느낌이 영 건조해 최소 카톡 리액션 느낌이면 좋겠어".
   카드 안: 다섯 그림 밑 한 줄 = 얼굴 넷(사진 또는 첫 글자) + 그 사람이 누른 그림 + 말 한 줄 + 꺾쇠. 누르는 것이라 옅은 테두리 알약(고르는 칩과 같은 옷).
   목록 창: 맨 위 탭(전체 · 그림마다 수, 곡 찾기 칩과 같은 옷) · 줄마다 얼굴 · 이름 · 누른 그림. */
.cheer .chwhob{display:flex; align-items:center; gap:8px; width:fit-content; max-width:100%; margin:8px auto 0; padding:5px 10px 5px 8px;
  border:1.5px solid var(--sp-line2); border-radius:999px; background:var(--card); color:var(--ink2); font:inherit; cursor:pointer;
  font-size:12.5px; font-weight:800; line-height:1.3; text-align:left;}
.cheer .chwhob:active{background:var(--sp-leaf-50);}
@media (hover:hover) and (pointer:fine){ .cheer .chwhob:hover{border-color:var(--sp-leaf-600);} }
.cheer .chwhob:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px;}
.cheer .chwhob > .ic{flex:none; width:14px; height:14px; color:var(--sp-sub);}
.cheer .chwt{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.chfaces{display:flex; flex:none; padding-left:7px;}
.chf{position:relative; margin-left:-7px;}
/* 동그라미 색은 카드 색 위에 칠한다. 어두운 시각의 -100 토큰은 반투명이라 그냥 두면 겹친 얼굴이 서로 비쳐 탁해진다 */
.chface{--chbg:var(--sp-leaf-100); display:grid; place-items:center; flex:none; width:30px; height:30px; border-radius:50%; overflow:hidden;
  background:linear-gradient(var(--chbg), var(--chbg)) var(--card); color:var(--sp-leaf-700); font-size:13px; font-weight:900; line-height:1; box-shadow:0 0 0 2px var(--card);}
.chface img{display:block; width:100%; height:100%; object-fit:cover;}
.chface.p{--chbg:var(--sp-coral-100); color:var(--sp-coral-700);}
.chface.b{--chbg:var(--sp-sky-100); color:var(--sp-sky-700);}
.chface.s{--chbg:var(--sp-leaf-100); color:var(--sp-leaf-700);}
.chfk{position:absolute; z-index:1; right:-6px; bottom:-5px; width:19px; height:19px; pointer-events:none;}   /* 다음 얼굴에 안 가리게 위로 */
/* 목록 창 */
/* 탭은 카톡처럼 한 줄. 넘치면 옆으로 민다(끝에 반 개가 걸려 «더 있다» 를 말한다) */
.chwbox .chtabs{display:flex; flex-wrap:nowrap; gap:5px; margin:0 0 8px; padding:1px 0 3px; overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch;}
.chwbox .chtabs::-webkit-scrollbar{display:none;}
.chwbox .chtab{flex:none; min-height:38px; gap:4px; padding:4px 9px 4px 7px; font-size:13px;}
.chwbox .chtab:first-child{padding:4px 11px;}
.chwbox .chtab img{width:22px; height:22px; display:block;}
.chwbox .chtab b{font-weight:900;}
.chlist{list-style:none; margin:0; padding:0;}
/* 줄 사이 선은 안 긋는다(카톡 공감 목록처럼). 누르는 줄이라 손가락 밑만 옅게 */
.chp{display:flex; align-items:center; gap:12px; padding:7px 6px; border-radius:14px;}
.chp[data-who]{cursor:pointer;}
.chp[data-who]:active{background:var(--sp-leaf-50);}
@media (hover:hover) and (pointer:fine){ .chp[data-who]:hover{background:var(--sp-leaf-50);} }
.chp .chface{width:42px; height:42px; font-size:17px; box-shadow:none;}
.chpn{flex:1; min-width:0; display:flex; align-items:center; gap:6px; font-size:15.5px; font-weight:800; color:var(--ink);}
.chme{font-style:normal; flex:none; padding:1px 7px; border-radius:999px; background:var(--sp-leaf-600); color:#fff; font-size:10.5px; font-weight:900; line-height:1.5;}
.chpk{flex:none; width:38px; height:38px;}
.chanon{margin:10px 4px 2px; font-size:12.5px; font-weight:700; color:var(--sp-sub);}

/* ── 133차-h 동명이곡 고르기 (app.js pickChipHTML · openSongPick) ─────────────
   곡 줄 딱지 자리의 칩 하나. 못 정했으면 점선(«아직 없지만 정할 수 있다», 악보 올리기 · 녹화 링크와 같은 문법), 정했으면 옅은 테두리 + «바꾸기».
   고르는 창은 같은 이름 곡이 한 줄씩(제목 · 부른 팀) + 들어보기. 지금 곡은 초록 테두리와 «지금 이 곡». */
.pickchip{display:inline-flex; align-items:center; gap:5px; min-height:26px; padding:2px 9px; border-radius:999px; cursor:pointer;
  border:1.5px dashed var(--sp-leaf-600); background:transparent; color:var(--sp-leaf-700); font:inherit; font-size:11.5px; font-weight:800; white-space:nowrap;}
.pickchip.on{border-style:solid; border-color:var(--sp-line2); color:var(--ink2);}
.pickchip i{font-style:normal; font-weight:800; color:var(--sp-leaf-700);}
.pickchip.on i::before{content:'·'; margin:0 4px 0 1px; color:var(--sp-sub);}
.pickchip:active{background:var(--sp-leaf-50);}
@media (hover:hover) and (pointer:fine){ .pickchip:hover{border-color:var(--sp-leaf-600);} }
.pickchip:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px;}
.pkhint{margin:0 2px 12px;}
.pklist{display:flex; flex-direction:column; gap:8px;}
.pkrow{display:flex; align-items:center; gap:8px; padding:4px; border-radius:16px; border:1.5px solid var(--sp-line2); background:var(--card);}
.pkrow.on{border-color:var(--sp-leaf-600); background:var(--sp-leaf-50);}
.pkpick{flex:1; min-width:0; display:flex; flex-direction:column; align-items:flex-start; gap:2px; padding:9px 10px; border:0; border-radius:12px;
  background:none; color:var(--ink); font:inherit; text-align:left; cursor:pointer;}
.pkpick b{font-size:15px; font-weight:900; line-height:1.35;}
.pkpick small{font-size:12.5px; font-weight:700; color:var(--sp-sub);}
.pkpick:active{background:var(--sp-leaf-50);}
.pknow{display:inline-flex; align-items:center; gap:4px; margin-top:3px; font-size:12px; font-weight:900; color:var(--sp-leaf-700);}
.pknow .ic{width:13px; height:13px;}
.pkplay{flex:none; margin-right:4px;}

/* ══ 133차-h: 메뉴 한눈에 (JH 피드백 #19) ═══════════════════════════════
   상단 오른쪽 단추가 돋보기에서 메뉴로 바뀌었다. 누르면 갈 곳이 칸으로 한눈에, 찾는 칸은 그 위(손가락 화면에선 바로 커서를 두지 않는다).
   칸은 누르는 것이라 옅은 테두리와 밑 단을 입는다(130 "누르는 것만 단추 모양"). */
.fdgrid{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px;}
.fdtile{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:7px; min-height:82px; padding:10px 6px;
  border-radius:16px; border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card);
  color:var(--ink); text-decoration:none; text-align:center;}
.fdtile .ic{width:22px; height:22px; color:var(--sp-leaf-700);}
.fdtile b{font-size:12.5px; font-weight:800; line-height:1.3; word-break:keep-all;}
.fdtile:active{transform:translateY(2px); box-shadow:0 0 0 var(--sp-ledge);}
.fdtile:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px;}
@media (hover:hover) and (pointer:fine){ .fdtile:hover{border-color:var(--sp-leaf-600); background:var(--sp-leaf-50);} }
.fdleadhd{margin-top:16px;}
.fdres:has(> .fdgrid){min-height:0;}

/* ══ 133차-h 여섯째 판: 그 날 예배만 명단 바꾸기 ═══════════════════════════
   카드: 이번만 들어온 사람 · 바꾼 방송 · 음향 자리에 작은 꼬리표, 빠지는 사람은 "빠짐" 한 줄.
   창: 이름 칩을 누르면 빠짐(점선 · 흐림), 방송 · 음향은 자리 한 줄씩. 누르는 것은 옅은 테두리와 밑 단(130). */
.ptag .lnsub{font-style:normal; margin-left:4px; font-size:10.5px; font-weight:800; color:var(--sp-leaf-700); letter-spacing:0;}
.ptiers.lngone{margin-top:2px;}
.ptiers.lngone .ptk.t-out{color:var(--sp-sub);}
.ptag.gone{color:var(--sp-sub); font-weight:700;}
.lnlead{margin:0 2px 14px; font-size:13px; font-weight:600; color:var(--ink2);}
.lnsec + .lnsec{margin-top:20px;}
.lnhd{display:flex; align-items:baseline; gap:8px; margin:0 2px 6px; font-size:14.5px; font-weight:900; color:var(--ink);}
.lnhd i{font-style:normal; font-size:12px; font-weight:700; color:var(--sp-sub);}
.lntip{margin:0 2px 8px; font-size:12px; font-weight:600; color:var(--sp-sub);}
.lnrow{display:flex; gap:10px; align-items:flex-start; padding:5px 0;}
.lnk{flex:none; width:42px; padding-top:10px; font-size:12px; font-weight:800; color:var(--ink2);}
.lnchips{display:flex; flex-wrap:wrap; gap:7px; min-width:0;}
.lnchip{display:inline-flex; align-items:center; gap:5px; min-height:38px; padding:0 13px; border-radius:999px; cursor:pointer;
  border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card); color:var(--ink);
  font:inherit; font-size:14px; font-weight:800;}
.lnchip i{font-style:normal; font-size:11px; font-weight:800; color:var(--sp-sub);}
.lnchip.out{border-style:dashed; box-shadow:none; background:var(--dk-well, #F6FAF7); color:var(--sp-sub);}
.lnchip.out i{color:var(--sp-coral-700);}
.lnchip.add{border-color:var(--sp-leaf-600);}
.lnchip.add i{color:var(--sp-leaf-700);}
.lnchip.add .ic{width:13px; height:13px; color:var(--sp-sub);}
.lnchip.plus{border-style:dashed; box-shadow:none; color:var(--sp-leaf-700);}
.lnchip.plus .ic{width:14px; height:14px;}
.lnchip:active{transform:translateY(2px); box-shadow:none;}
.lnchip:focus-visible, .lnslot:focus-visible, .lnpart:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px;}
.lnaway{margin:2px 2px 4px; font-size:12px; font-weight:600; color:var(--sp-sub);}
.lnslot{display:flex; align-items:center; gap:10px; width:100%; min-height:50px; padding:6px 12px; margin:0 0 8px; border-radius:14px; cursor:pointer;
  border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card); color:var(--ink); font:inherit; text-align:left;}
.lnslot .lnsk{flex:none; width:66px; font-size:12px; font-weight:800; color:var(--ink2);}
.lnslot b{font-size:15px; font-weight:900;}
.lnslot i{font-style:normal; font-size:11px; font-weight:800; color:var(--sp-leaf-700);}
.lnslot > .ic{margin-left:auto; width:14px; height:14px; color:var(--sp-sub);}
.lnslot.chg{border-color:var(--sp-leaf-600);}
.lnslot:active{transform:translateY(2px); box-shadow:none;}
.lnwho{margin:12px 2px 0; font-size:12px; font-weight:600; color:var(--sp-sub);}
.lnparts{display:flex; flex-wrap:wrap; gap:6px; margin:0 0 14px;}
.lnpart{min-height:34px; padding:0 12px; border-radius:999px; border:1.5px solid var(--sp-line2); background:transparent; color:var(--ink2);
  font:inherit; font-size:13px; font-weight:800; cursor:pointer;}
.lnpart.on{border-color:var(--sp-leaf-600); background:var(--sp-leaf-50); color:var(--sp-leaf-700); box-shadow:0 2px 0 var(--sp-ledge);}
.lnfree{display:flex; gap:8px; margin-top:14px;}
.lnfree input{flex:1; min-width:0; min-height:44px; padding:0 12px; border-radius:12px; border:1.5px solid var(--sp-line2); background:var(--card);
  color:var(--ink); font:inherit; font-size:16px;}
.lnppfoot{display:flex; justify-content:space-between; gap:10px;}
@media (hover:hover) and (pointer:fine){
  .lnchip:hover, .lnslot:hover, .lnpart:hover{border-color:var(--sp-leaf-600);}
}

/* ══ 133차-h 일곱째 판: 말씀 두 칸 · 유튜브 링크 공유 ═══════════════════════════
   말씀 카드 위 «금요예배 10/2 · 주일예배 9/27» = 다른 고르기 알약과 같은 옷(회녹색 홈 안의 흰 알약, 133 고르기 목록에 같이 들어 있다).
   공유: 말씀 카드는 «말씀 다시 보기» 옆 글자 단추, 예배 보러 가기 줄은 오른쪽에 옅은 테두리 타일(아이콘 위 · 글자 아래). */
.wd-tabs{display:flex; width:fit-content; max-width:100%; margin:12px 0 0;}
.wd-tab{flex:none; min-height:36px; padding:6px 13px; cursor:pointer; font-family:var(--f-body); font-size:13px; line-height:1.2; white-space:nowrap;}
.wd-tab:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px;}
.wd-title{margin:10px 0 0; font-size:12.5px; font-weight:800; color:var(--sp-sub);}
.wd-title + .wd-verse{margin-top:4px;}
.wd-foot{display:flex; align-items:center; flex-wrap:wrap; gap:4px 18px; margin-top:6px;}
.wd-foot .wd-play{margin-top:0; min-height:36px;}
.wd-share{border:0; background:none; padding:0; cursor:pointer; font-family:var(--f-body); line-height:1.2;}
.wd-share:active, .wd-foot a.wd-play:active{opacity:.6;}
.wd-adm + .wd-adm{margin-top:18px; padding-top:16px; border-top:1px solid var(--sp-line);}
.sp-watchrow{display:flex; gap:10px; align-items:stretch;}
.sp-watchrow > .sp-watch{flex:1; min-width:0;}
.sp-share{flex:none; width:66px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; cursor:pointer;
  border-radius:20px; border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge); background:var(--card); color:var(--ink2);
  font-family:var(--f-body); font-size:12px; font-weight:800;}
.sp-share .ic{width:20px; height:20px; color:var(--ink2);}
.sp-share:active{transform:translateY(2px); box-shadow:none;}
.sp-share:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:2px;}
@media (hover:hover) and (pointer:fine){ .sp-share:hover{border-color:var(--sp-leaf-600);} }

/* ══ 133차-h 일곱째 판: 플레이어를 끌어도 뒤 화면이 안 움직인다 (피드백 #15) ═══════════════
   "터치로 드래그하면 뒤에 배경이 움직이고 플레이리스트 화면의 텍스트랑 리스트가 드래그되는 버그". 창 칸은 손가락으로 끌어도
   아무 데도 안 밀리고(뒤 화면이 따라 올라가던 것), 위아래로 미는 것은 목록 · 가사만 한다. 목록 글자는 길게 눌러도 안 잡힌다.
   가사 글은 그대로 고를 수 있다(가사를 옮겨 적는 사람이 있다). */
#layer > .lvl:has(> .ytbox){touch-action:none;}
/* 그래도 유튜브 영상 칸(남의 문서, iframe) 위에서 민 손가락은 뒤 페이지로 넘어갔다(JH 10-03 "패치안된듯"). 창이 떠 있는 동안 뒤 페이지를 잠근다(app.js layerBackground).
   손가락 기기만: 마우스 화면은 스크롤바가 사라지며 본문이 옆으로 밀린다 */
@media (pointer:coarse){ html.layerlock, html.layerlock body{overflow:hidden;} }
#layer > .lvl:has(> .ytbox) .pllist, #layer > .lvl:has(> .ytbox) .pllyrics{touch-action:pan-y;}
.ytbox{-webkit-user-select:none; user-select:none; -webkit-touch-callout:none;}
.ytbox .pllyrtext{-webkit-user-select:text; user-select:text; -webkit-touch-callout:default;}
.ytbox a, .ytbox img{-webkit-user-drag:none;}

/* ══ 133차-h 일곱째 판: 넓은 화면은 화면마다 제 폭 (2026-10-03) ═══════════════════════════════
   JH: "그 달력 뷰가 테블릿이나 데스크톱으로 이전엔 큼지막하게 나왔는데 이젠 그냥 핸드폰뷰랑 다르지 않게 나와. 의도한거야? 이것 외에도 의도하지 않게 놓친 디테일들 있어?"
   133 은 넓은 화면 본문을 모든 화면에서 720 한 기둥으로 묶었고, 133차-c 는 그 안에 들어가게 큰 달력 · 섬김표 칸 · 콘티 두 칸 · 곡 찾기 두 칸 ·
   신청 두 기둥 · 신청곡 두 칸을 폰 모양으로 접었다(133 전 판과 같은 폭으로 찍어 맞대 본 결과, tools/qa/wideaudit.mjs).
   칸으로 나뉘는 화면만 133 전 폭으로 되돌린다: 섬김표 1200(큰 달력 940 + 섬김표 칸 세 장) · 찬양 · 팀 · 자료실 · 앨범 · 사용 기록 · 연락처 960
   (콘티 · 곡 찾기 두 칸, 신청 두 기둥, 팀 세 장, 자료실 세 칸).
   홈 · 더보기 · 하고 싶은 말 · 관리자처럼 한 줄씩 읽는 화면은 그대로 720 이다. 넓히면 줄만 길게 늘어난다(짝 없는 요소는 안 늘인다).
   상단바 안쪽도 본문 칸에 맞춘다(안쪽 여백 2px 를 더한 폭). 메뉴는 가운데 칸(1fr)의 가운데라 칸 폭이 바뀌어도 화면 가운데에서 안 움직인다.
   900 아래(폰 · 태블릿 세로)는 그대로다. */
@media (min-width:900px){
  html.sp:is([data-page="praise"],[data-page="team"],[data-page="docs"],[data-page="album"],[data-page="stats"],[data-page="contacts"]) .view{max-width:960px;}
  html.sp[data-page="plan"] .view{max-width:1200px;}
  html.sp:is([data-page="praise"],[data-page="team"],[data-page="docs"],[data-page="album"],[data-page="stats"],[data-page="contacts"]) .topbar .in{max-width:932px;}
  html.sp[data-page="plan"] .topbar .in{max-width:1172px;}
}
/* 예배 시각 줄의 장소(`timeMeta` 의 `.plc`)는 제 줄이다. 함수 주석은 «장소를 제 줄로 내린다» 인데 규칙이 없어서
   큰 달력 칸에 «예배 8:30 PM본당» 처럼 붙고 기울어져 나왔다(133차-h 일곱째 판 넓은 화면 감사에서 봤다) */
.plc{display:block; font-style:normal;}
/* 자료실 칸 사이 선: 예전엔 칸 틈 1px 을 회녹색 바탕으로 비춰 선을 그리고, 홀수일 때 흰 칸 하나(::after)로 메웠다.
   두 칸일 때만 맞는 셈이라, 넓은 화면이 세 칸이 되자 줄이 덜 찬 자리가 회색 덩어리로 보였다(133차-h 일곱째 판 넓은 화면 감사).
   이제 바탕은 흰색이고 선은 칸마다 왼쪽 · 위쪽에 긋는다(맨 왼쪽 · 맨 위 선은 상자 밖이라 잘린다). 빈자리는 그냥 흰 바탕이다 */
@media (min-width:700px){
  html.sp .reslist{gap:0; background:var(--card);}
  html.sp .reslist > .res{box-shadow:-1px 0 0 var(--sp-line), 0 -1px 0 var(--sp-line) !important;}
  html.sp .reslist::after{display:none;}
}
/* 신청 두 기둥(900 이상): 쓰는 칸은 좁게, 온 신청 · 신청곡 칸을 넓게. 반반이면 곡 이름 · 단추가 두 줄로 접혔다 */
@media (min-width:900px){
  html.sp .reqsplit{grid-template-columns:minmax(0,370px) minmax(0,1fr);}
}
/* 상단 메뉴 링크 여백은 넓은 화면 내내 9px. 13px(1100 이상)이면 메뉴 줄이 374px 라 720 화면의 가운데 칸(348px)을 넘쳐서
   오른쪽 메뉴 단추가 본문 끝보다 28px 밖으로 나가고 메뉴도 오른쪽으로 밀려 있었다(133 부터, 133차-h 일곱째 판에 잼).
   화면마다 같은 여백이라 화면을 옮겨도 메뉴 글자가 안 움직인다 */
@media (min-width:900px){ html.sp .topbar .deskNav a{padding-left:9px; padding-right:9px;} html.sp .topbar .deskNav a.on::after{left:9px; right:9px;} }

/* ══ 133차-h 여덟째 판: 하늘 머리는 인사 길이만큼 자란다 (2026-10-03) ═══════════════════════
   인사가 세 줄이 되는 날(섬기는 날 아침 "오늘 주일예배 방송 보조, 정훈님 차례예요")에는 곁말("모이는 시간까지 3시간 남았어요")이
   티켓 뒤로 숨었다(머리 높이가 232 로 박혀 있고 글자는 그 위에 떠 있었다). 이제 글자 상자가 흐름 안에 있어서 머리가 그만큼 자란다.
   아래 여백(--hero-tail) = 티켓이 머리에 걸치는 34 + 숨 쉴 틈. 한 줄 · 두 줄 인사는 예전 높이 그대로다. */
.sp-hero{--hero-tail:48px; height:auto; min-height:calc(232px + var(--top-safe));}
.sp-herotx{position:relative; top:auto; left:auto; right:auto; padding:calc(62px + var(--top-safe)) 16px var(--hero-tail);}
@media (min-width:721px) and (max-width:899px){
  .sp-herotx{margin:0 calc(50% - 344px); padding-left:0; padding-right:0;}
}
@media (min-width:900px){
  .sp-hero{min-height:284px; height:auto;}
  .sp-herotx{width:430px; margin-left:calc(50% - 344px); padding:96px 0 var(--hero-tail);}
}

/* ══ 133차-h 열째 판: 날씨 옷 ══════════════════════════════════════════════════════════
   JH(10-04 아침, 밖은 안개): "배경이 시간때에 계절에 따라 바뀌잖아? 근데 날씨는 영향을 안받는 모양이야 ... 앱에선 sunny하니까 이질감이 드네.
   ... 비 오면은 비 오는 배경으로 바뀌고 지금처럼 안개 껴 있으면 안개 낀 배경으로 바뀌고 써니 하면은 써니한 배경으로".
   시각(data-tod) · 계절(data-theme) 위에 날씨(data-wx, app.js applyWx) 하나를 더 얹는다. 맑음 · 구름 조금은 표시가 없다(지금 그대로).
   - 낮(아침 · 낮 · 오후) 하늘 = 날씨마다 사진 한 장. "청량" 사진을 넣어 날씨만 바꿔 그렸다(tools/gen_weather_sky.py).
   - 새벽 · 저녁 · 밤 하늘 = 그 시각 그라디언트를 날씨 빛으로 누른 것. 해 빛무리 · 별은 숨긴다(흐린 하늘에 별이 뜨면 거짓말이다).
   - 교회 그림 위에 날씨 층 하나(.sp-wxl): 안개 = 아래로 짙어지는 안개 + 천천히 흐르는 안개 띠, 비 = 빗줄기, 눈 = 내리는 눈.
   - 흐림 · 안개 · 비는 교회 그림 채도만 조금 뺀다(시각 옷처럼 어둡게 누르지 않는다. 필터로 누르면 칙칙하다는 교훈).
   ⚠ 그라디언트 첫 색 = app.js · index.html 의 HERO_TOP_WX(상태바 색). 바꾸면 셋 다 고친다(skyboot.mjs 가 맞대 본다).
   ⚠ 움직임 줄이기면 층이 멈춰 있다 */
html[data-wx="cloud"]:is([data-tod="morning"],[data-tod="midday"],[data-tod="afternoon"]) .sp-sky{background:url("/sky/sp-cloud.webp") 30% 40%/cover no-repeat, #C1D4DA; filter:none;}
html[data-wx="fog"]:is([data-tod="morning"],[data-tod="midday"],[data-tod="afternoon"]) .sp-sky{background:url("/sky/sp-fog.webp") 30% 40%/cover no-repeat, #DDE7ED; filter:none;}
html[data-wx="rain"]:is([data-tod="morning"],[data-tod="midday"],[data-tod="afternoon"]) .sp-sky{background:url("/sky/sp-rain.webp") 30% 40%/cover no-repeat, #9CAFC5; filter:none;}
html[data-wx="snow"]:is([data-tod="morning"],[data-tod="midday"],[data-tod="afternoon"]) .sp-sky{background:url("/sky/sp-snow.webp") 30% 40%/cover no-repeat, #DAE0F0; filter:none;}
html[data-wx="cloud"][data-tod="dawn"] .sp-sky{background:linear-gradient(180deg, #2A3450 0, #4A5370 52%, #747A8F 100%);}
html[data-wx="fog"][data-tod="dawn"] .sp-sky{background:linear-gradient(180deg, #3A4258 0, #5E6679 52%, #9097A6 100%);}
html[data-wx="rain"][data-tod="dawn"] .sp-sky{background:linear-gradient(180deg, #232B42 0, #3A4460 52%, #5C6680 100%);}
html[data-wx="snow"][data-tod="dawn"] .sp-sky{background:linear-gradient(180deg, #34405E 0, #56627E 52%, #8C95AD 100%);}
html[data-wx="cloud"][data-tod="evening"] .sp-sky{background:linear-gradient(180deg, #2B2840 0, #47425C 55%, #6E687E 100%);}
html[data-wx="fog"][data-tod="evening"] .sp-sky{background:linear-gradient(180deg, #383650 0, #5A566C 55%, #8E8A9C 100%);}
html[data-wx="rain"][data-tod="evening"] .sp-sky{background:linear-gradient(180deg, #211F33 0, #36334D 55%, #545068 100%);}
html[data-wx="snow"][data-tod="evening"] .sp-sky{background:linear-gradient(180deg, #322F4C 0, #504C6C 55%, #847F9E 100%);}
html[data-wx="cloud"][data-tod="night"] .sp-sky{background:linear-gradient(180deg, #141C2B 0, #222D40 60%, #384559 100%);}
html[data-wx="fog"][data-tod="night"] .sp-sky{background:linear-gradient(180deg, #1C2431 0, #323C4B 60%, #5A6472 100%);}
html[data-wx="rain"][data-tod="night"] .sp-sky{background:linear-gradient(180deg, #0F1622 0, #1B2534 60%, #2D394B 100%);}
html[data-wx="snow"][data-tod="night"] .sp-sky{background:linear-gradient(180deg, #1A2335 0, #2D3A52 60%, #4C5A75 100%);}
html[data-wx] .sp-sun, html[data-wx] .sp-stars{display:none;}
html[data-wx="cloud"] .sp-art, html[data-wx="fog"] .sp-art{filter:saturate(.84);}
html[data-wx="rain"] .sp-art{filter:saturate(.74) brightness(.95);}
/* 날씨 층: 교회 그림 위 · 글자 밑(같은 z -1 에서 DOM 이 뒤라 그림 위에 온다). 아래 끝은 .sp-hero::after 가 바탕색으로 덮는다 */
.sp-wxl{position:absolute; inset:0; z-index:-1; display:none; pointer-events:none; overflow:hidden;}
html[data-wx="fog"] .sp-wxl, html[data-wx="rain"] .sp-wxl, html[data-wx="snow"] .sp-wxl{display:block;}
/* 안개: 낮은 흰 안개, 새벽 · 저녁 · 밤은 잿빛 안개 */
html[data-wx="fog"] .sp-wxl{--mist:236,241,244;
  background:linear-gradient(180deg, rgba(var(--mist),.1) 0, rgba(var(--mist),.44) 46%, rgba(var(--mist),.8) 100%);}
html[data-wx="fog"]:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-wxl{--mist:132,141,156;}
html[data-wx="fog"] .sp-wxl::before, html[data-wx="fog"] .sp-wxl::after{content:''; position:absolute; top:0; bottom:0; left:-30%; right:-30%;
  background:radial-gradient(38% 20% at 26% 66%, rgba(var(--mist),.55), rgba(var(--mist),0) 72%),
    radial-gradient(30% 16% at 70% 78%, rgba(var(--mist),.5), rgba(var(--mist),0) 72%);
  animation:wxdrift 46s ease-in-out infinite alternate;}
html[data-wx="fog"] .sp-wxl::after{opacity:.8; animation-duration:68s; animation-direction:alternate-reverse;
  background:radial-gradient(42% 18% at 52% 46%, rgba(var(--mist),.42), rgba(var(--mist),0) 72%),
    radial-gradient(26% 14% at 12% 86%, rgba(var(--mist),.5), rgba(var(--mist),0) 72%);}
@keyframes wxdrift{from{transform:translateX(-9%);} to{transform:translateX(9%);}}
/* 비: 비스듬한 빗줄기 두 겹(가까운 것 · 먼 것). 세로로만 흘러 이음매가 안 튄다 */
html[data-wx="rain"] .sp-wxl{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='180'%3E%3Cg stroke='white' stroke-width='1.3' stroke-linecap='round' opacity='.55'%3E%3Cpath d='M12 8l-4 22M55 40l-4 22M98 15l-4 22M30 95l-4 22M78 110l-4 22M120 70l-4 22M40 150l-4 22M108 145l-4 22'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='120'%3E%3Cg stroke='white' stroke-width='1' stroke-linecap='round' opacity='.38'%3E%3Cpath d='M8 10l-2 12M40 50l-2 12M70 20l-2 12M22 80l-2 12M60 95l-2 12M84 65l-2 12'/%3E%3C/g%3E%3C/svg%3E");
  background-size:140px 180px, 90px 120px;
  animation:wxrain .62s linear infinite;}
@keyframes wxrain{from{background-position:0 0, 0 0;} to{background-position:0 180px, 0 120px;}}
html[data-wx="rain"]:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .sp-wxl{opacity:.7;}
/* 눈: 두 겹이 다른 빠르기로 내린다. 옅은 하늘에서도 보이게 가장자리에 옅은 잿빛 테 */
html[data-wx="snow"] .sp-wxl{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cg fill='white' stroke='rgb(120,135,170)' stroke-opacity='.35' stroke-width='.6'%3E%3Ccircle cx='14' cy='18' r='2.2'/%3E%3Ccircle cx='62' cy='8' r='1.8'/%3E%3Ccircle cx='118' cy='30' r='2.4'/%3E%3Ccircle cx='40' cy='70' r='1.7'/%3E%3Ccircle cx='96' cy='84' r='2.1'/%3E%3Ccircle cx='146' cy='100' r='1.8'/%3E%3Ccircle cx='22' cy='128' r='2.3'/%3E%3Ccircle cx='76' cy='140' r='1.9'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='110'%3E%3Cg fill='white' fill-opacity='.85'%3E%3Ccircle cx='10' cy='12' r='1.3'/%3E%3Ccircle cx='54' cy='30' r='1.1'/%3E%3Ccircle cx='92' cy='14' r='1.4'/%3E%3Ccircle cx='30' cy='66' r='1.2'/%3E%3Ccircle cx='78' cy='76' r='1.3'/%3E%3Ccircle cx='100' cy='98' r='1.1'/%3E%3C/g%3E%3C/svg%3E");
  background-size:160px 160px, 110px 110px;
  animation:wxsnow 9s linear infinite;}
@keyframes wxsnow{from{background-position:0 0, 0 0;} to{background-position:0 160px, 0 220px;}}
@media (prefers-reduced-motion:reduce){ .sp-wxl, .sp-wxl::before, .sp-wxl::after{animation:none !important;} }
/* 비 오는 낮 하늘은 중간 잿빛이라 작은 날짜 줄(ink2)이 흐리다 → 잉크 */
html[data-wx="rain"]:is([data-tod="morning"],[data-tod="midday"],[data-tod="afternoon"]) :is(.sp-date, .sp-wxko){color:var(--ink);}


/* ══ 133차-h 열두째 판: 멤버 일정(리더) · 리허설과 주일 «같이» 스위치 ═══════════════════════════
   JH: «1회만 빠지거나 장기간으로 빠지거나 하는 맴버들, 또 그 외에 맴버들 스케줄» 을 리더가 한곳에서.
   묶음은 연락처 화면의 .ctgrp(띠 머리 + 줄)를 그대로 쓴다. 줄 = 날짜 칸 · 예배 · 바뀐 것 꼬리표 · 꺾쇠.
   누르는 것은 예배 줄(그 예배 명단 바꾸기)과 삭제 · 못 서는 날 넣기뿐이다(130 누르는 것만 단추 모양). 꼬리표는 글자다 */
.aw .awtop{display:flex; align-items:center; gap:10px 12px; flex-wrap:wrap; margin:2px 2px 14px;}
.awlead{flex:1; min-width:180px; margin:0; font-size:13px; font-weight:600; color:var(--ink2); line-height:1.5;}
.aw .ctgrp + .ctgrp{margin-top:16px;}
.awgrp .ctgh .awwarn{margin-left:auto; font-size:11.5px; font-weight:800; color:var(--sp-coral-700);}
.awgrp .ctgh .awnote{margin-left:auto; font-size:11px; font-weight:700; color:var(--sp-sub);}
.awtip{margin:0; padding:8px 13px 4px; font-size:12px; font-weight:600; color:var(--sp-sub);}
.awsvc{display:flex; align-items:center; gap:12px; width:100%; min-height:56px; padding:10px 13px; margin:0; border:0; border-top:1px solid var(--sp-line);
  border-radius:0; background:transparent; color:var(--ink); font:inherit; text-align:left;}
button.awsvc{cursor:pointer;}
button.awsvc:active{background:var(--sp-leaf-50);}
.awsvc.warn{box-shadow:inset 4px 0 0 var(--sp-coral-fill);}
.awd{flex:none; width:44px; display:flex; flex-direction:column; line-height:1.2;}
.awd b{font-family:var(--f-latin); font-size:16px; font-weight:800; color:var(--ink); letter-spacing:-.2px;}
.awd i{font-style:normal; font-size:11.5px; font-weight:700; color:var(--sp-sub);}
.awm{flex:1; min-width:0; display:flex; flex-direction:column; gap:5px;}
.awt{font-size:14px; font-weight:900; color:var(--ink);}
.awt i{font-style:normal; margin-left:6px; font-size:12px; font-weight:800; color:var(--ink2);}
.awc{display:flex; flex-wrap:wrap; gap:5px 6px;}
.awx{display:inline-flex; align-items:center; min-height:22px; padding:1px 8px; border-radius:7px; font-size:12px; font-weight:700; line-height:1.35;
  background:var(--dk-well, #F3F6F4); color:var(--ink2);}
.awx.out{background:var(--sp-coral-50); color:var(--sp-coral-700);}
.awx.add{background:var(--sp-leaf-50); color:var(--sp-leaf-700);}
.awx.av{background:var(--sp-sky-50); color:var(--sp-sky-700);}
.awx.warn{background:var(--sp-coral-fill); color:#fff;}   /* 채움 토큰이라 밤에도 진하다(글자색 coral-700 은 밤에 밝아져 흰 글자가 묻혔다) */
.awx.sep{background:transparent; box-shadow:inset 0 0 0 1.5px var(--sp-line2); color:var(--ink2);}
.awx.none{background:transparent; padding-left:0; color:var(--sp-sub); font-weight:600;}
.awsvc > .ic{flex:none; width:15px; height:15px; color:var(--sp-sub);}
.awsub{padding:12px 13px 2px; font-size:12px; font-weight:800; color:var(--ink2); border-top:1px solid var(--sp-line);}
.awbk{display:flex; align-items:center; flex-wrap:wrap; gap:3px 10px; padding:8px 13px 10px;}
.awbk + .awbk{border-top:1px dashed var(--sp-line);}
.awbkw{display:flex; align-items:baseline; gap:6px; min-width:0;}
.awbkw b{font-size:15px; font-weight:900; color:var(--ink);}
.awbkw small{font-size:11.5px; font-weight:700; color:var(--sp-sub);}
.awbkt{font-size:13.5px; font-weight:800; color:var(--ink);}
.awdel{margin-left:auto; order:2;}
.awbkn{order:3; flex-basis:100%; font-size:12.5px; font-weight:600; color:var(--ink2);}
.awbkb{order:4; flex-basis:100%; font-size:11.5px; font-weight:600; color:var(--sp-sub);}
.awgrp > .empty{padding:14px 13px;}
.awwho.on{border-color:var(--sp-leaf-600) !important;}
@media (hover:hover) and (pointer:fine){ button.awsvc:hover{background:var(--sp-leaf-50);} }
/* 명단 바꾸기 창: 리허설 ↔ 주일 «같이». 켜져 있으면(기본) 둘이 한 명단 */
.lnlink{display:flex; align-items:center; gap:6px 10px; flex-wrap:wrap; margin:2px 2px 12px;}
.lnlinkt{font-size:12px; font-weight:600; color:var(--sp-sub);}
.lnlinkbtn{display:inline-flex; align-items:center; gap:4px;}
.lnlinkbtn .ic{width:14px; height:14px;}

/* 달력 오늘 동그라미(10-07 nightskin): 낮엔 잉크 동그라미 그대로. 어두운 시각엔 잉크가 밝아져서 평일 오늘 칸에 밝은 점이 떴다
   (주말 · 예배 날은 커버가 덮어서 안 보였다). 오늘 칸 테두리(잎 초록)와 같은 진한 잎 칠 + 흰 글자로 */
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) table.hcal td.today .dt{background:var(--sp-leaf-fill); color:#fff;}

/* ══ 133차-h 열다섯째 판: 킥오프 자기소개 (2026-10-07) ════════════════════════════════════
   JH: 부담 없이 가볍고 재밌게, 닌텐도처럼 단순하게. 한 화면에 질문 하나, 화면마다 친구 하나(앱의 동물 친구 스티커 그대로).
   누르는 것(고르기 · 다음 · 저장)만 단추 옷(옅은 테두리와 밑 단, 고른 것은 잎 초록), 프로필의 답 · 딱지는 테두리 · 그림자 없는 글자.
   색은 전부 토큰이라 새벽 · 저녁 · 밤 옷을 그대로 입는다(nightskin.mjs 로 잰다). */
/* 홈 카드 = «내 이름 고르기» 칸(.sp-ask)과 같은 옷. 왼쪽 그림만 손 흔드는 토끼 */
.sp-introst{flex:none; width:52px; height:52px; margin:-6px -2px -6px -4px; object-fit:contain;}
/* 카드 밑 티켓이 붙었다(.sp-ticket{margin:0} 이 홈 칸 간격 규칙과 무게가 같고 뒤에 있다. 10-05 신청곡 줄과 같은 일). 카드 바로 밑만 한 단 무겁게 */
.sp-home > .sp-introask + *{margin-top:22px;}
/* 마감 딱지는 카드 윗선에 걸쳐 단다(옆에 두면 320 폭에서 제목이 «자기소개 써 / 주세요» 로 갈렸다). 칠은 진한 산호(밤에도 그대로 진하다) */
.sp-introask{position:relative;}
.sp-introdue{position:absolute; top:-12px; right:20px; display:inline-flex; align-items:center; height:22px; padding:0 9px; border-radius:999px;
  background:var(--sp-coral-fill); color:#fff; font-size:11.5px; font-weight:900; white-space:nowrap;}
/* 쓰는 창 머리: 이전 · 제목(몇 번째) · 닫기. 밑에 진행 막대 */
.itr-head{display:flex; align-items:center; gap:8px;}
.itr-head h3{flex:1; min-width:0; margin:0; display:flex; align-items:baseline; justify-content:center; gap:7px; text-align:center;}
.itr-n{font-family:var(--f-latin); font-size:13px; font-weight:700; color:var(--sp-sub); letter-spacing:.02em;}
.itr-bar{height:6px; margin:6px 2px 4px; border-radius:3px; background:var(--sp-line); overflow:hidden;}
.itr-bar i{display:block; height:100%; width:0; border-radius:3px; background:var(--sp-leaf-600); transition:width .3s ease;}
.itr-body{min-height:430px;}   /* 걸음마다 창 높이가 안 출렁이게. vh 는 자판에 따라 바뀌는 폰이 있어서 px 로 */
.itr-step{display:flex; flex-direction:column; align-items:stretch; text-align:center; padding:8px 2px 6px;}
.itr-st{align-self:center; width:92px; height:92px; object-fit:contain; animation:itrpop .38s ease-out;}
/* (10-08) 칸에 쓰는 동안 친구를 줄이던 규칙(:focus-within)은 뺐다. 다음을 누르는 순간 칸이 초점을 잃어 친구가 커지면서
   단추가 34px 아래로 밀려 손가락이 놓쳤다(JH: 두 번 눌러야 넘어가고 화면이 아래로 텔레포트한다) */
@keyframes itrpop{0%{transform:scale(.84) rotate(-5deg);} 60%{transform:scale(1.06) rotate(2deg);} 100%{transform:none;}}
.itr-q{margin:10px 6px 0; font-family:var(--f-disp); font-size:22px; font-weight:900; line-height:1.38; letter-spacing:-.5px;
  color:var(--ink); word-break:keep-all; overflow-wrap:anywhere;}
.itr-sub{margin:6px 6px 0; font-size:14px; font-weight:700; color:var(--sp-sub); word-break:keep-all;}
/* 고르기 = 둘 중 하나. 누르면 고른 쪽이 잎 초록으로 차고 한 박자 뒤 다음 질문 */
.itr-picks{display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:22px;}
.itr-pick{min-height:96px; padding:10px 8px; border-radius:20px; cursor:pointer;
  font-family:var(--f-disp); font-size:19px; font-weight:900; letter-spacing:-.4px; color:var(--ink); word-break:keep-all;
  background:var(--card); border:1.5px solid var(--sp-line2); box-shadow:0 4px 0 var(--sp-ledge);
  transition:transform .08s ease, box-shadow .08s ease, background-color .12s ease;}
.itr-pick:active{transform:translateY(4px); box-shadow:none;}
.itr-pick.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600); color:#fff; box-shadow:0 4px 0 var(--sp-leaf-800);}
.itr-picks.four .itr-pick{min-height:74px;}     /* 보기 넷(형제 순서)은 두 줄 두 칸 */
.itr-picks.three{grid-template-columns:repeat(3, 1fr); gap:10px;}   /* 보기 셋(학생 · 직장인 · 기타, 스무째 판)은 한 줄 세 칸(두 줄이면 하나가 혼자 남는다) */
.itr-picks.three .itr-pick{min-height:84px; padding:10px 4px; font-size:18px;}
/* 생년월일 8자리: 숫자판, 1998.03.15 로 보여 준다. 밑 한 줄은 무엇이 보이는지(연도만 모두에게) */
.itr-in.itr-bd{text-align:center; font-family:var(--f-latin); font-size:22px; letter-spacing:.06em;}
.itr-in.itr-bd::placeholder{font-family:var(--f-body); font-size:17px; letter-spacing:0;}
.itr-hint{margin:8px 4px 0; text-align:center; font-size:13px; font-weight:700; color:var(--sp-sub);}
/* 나이 보여 줄래요 · 비밀이에요(스무째 판). 고르기 단추와 같은 옷(옅은 테두리와 밑 단, 고른 것은 잎 초록), 한 줄 두 칸 */
.itr-seg{display:grid; grid-template-columns:1fr 1fr; gap:10px; width:100%; max-width:320px; margin:14px auto 0;}
.itr-segb{min-height:50px; padding:0 8px; border-radius:16px; cursor:pointer; font-family:var(--f-disp); font-size:17px; font-weight:900; letter-spacing:-.3px;
  color:var(--ink); background:var(--card); border:1.5px solid var(--sp-line2); box-shadow:0 3px 0 var(--sp-ledge);
  transition:transform .08s ease, box-shadow .08s ease, background-color .12s ease;}
.itr-segb:active{transform:translateY(3px); box-shadow:none;}
.itr-segb.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600); color:#fff; box-shadow:0 3px 0 var(--sp-leaf-800);}
.itr-hint b{color:var(--sp-leaf-700); font-weight:900;}
/* 사진 걸음: 넣은 사진(또는 빈 칸)을 가운데 크게 */
.itr-photo{display:flex; justify-content:center; margin-top:18px;}
.itr-photo img{width:132px; height:132px; border-radius:28px; object-fit:cover; background:var(--page);}
.itr-photo0{display:inline-flex; align-items:center; justify-content:center; width:132px; height:132px; border-radius:28px;
  border:2px dashed var(--sp-line2); color:var(--sp-sub);}
.itr-photo0 .ic{width:38px; height:38px;}
.itr-rv.soft{color:var(--sp-sub); font-weight:700;}
/* MBTI = 네 줄, 줄마다 둘 중 하나 */
.itr-mbti{display:grid; gap:10px; width:100%; max-width:300px; margin:20px auto 0;}
.itr-mrow{display:grid; grid-template-columns:1fr 1fr; gap:10px;}
.itr-mb{min-height:54px; border-radius:16px; cursor:pointer; font-family:var(--f-latin); font-size:22px; font-weight:700; color:var(--ink);
  background:var(--card); border:1.5px solid var(--sp-line2); box-shadow:0 3px 0 var(--sp-ledge);}
.itr-mb:active{transform:translateY(3px); box-shadow:none;}
.itr-mb.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600); color:#fff; box-shadow:0 3px 0 var(--sp-leaf-800);}
/* 쓰는 칸 한 줄. 16px 넘게(아이폰이 칸을 누를 때 화면을 키우지 않게) */
.itr-in{display:block; width:100%; min-height:56px; margin-top:22px; padding:0 16px; border-radius:16px;
  border:1.5px solid var(--sp-line2); background:var(--card); color:var(--ink);
  font-family:var(--f-body); font-size:18px; font-weight:700; text-align:left;}
.itr-in::placeholder{color:var(--sp-sub); font-weight:600; opacity:.85;}
.itr-in:focus{outline:none; border-color:var(--sp-leaf-600);}
.itr-count{margin:6px 4px 0; text-align:right; font-family:var(--f-latin); font-size:12px; color:var(--sp-sub);}
.itr-count.over{color:var(--sp-coral-700); font-weight:700;}
.itr-foot{display:flex; flex-direction:column; align-items:center; gap:8px; margin-top:20px;}
.itr-foot .sp-btn.wide{width:100%;}
.itr-foot .sp-btn[disabled]{opacity:.45; cursor:default; box-shadow:none; transform:none;}
.itr-skip{margin:0; min-height:40px; padding:0 14px; font-size:14px; font-weight:800; color:var(--sp-sub);}
.itr-note{margin:0; font-size:12.5px; font-weight:700; color:var(--sp-sub);}
.itr-foot .formmsg{margin:0; min-height:0;}
/* 최애 찬양 = 찾기 칸 + 곡 줄(많이 부른 곡 · 찾은 곡 · 친 그대로 쓰기) */
.itr-step .searchbar{margin-top:22px;}
.itr-songs{margin-top:10px; border-radius:18px; background:var(--page); overflow:hidden; text-align:left;}
.itr-songs:empty{display:none;}
.itr-songhd{margin:0; padding:10px 14px 2px; font-size:12px; font-weight:900; color:var(--sp-sub);}
.itr-song{display:flex; align-items:center; gap:10px; width:100%; min-height:52px; padding:8px 14px; margin:0; cursor:pointer;
  border:0; background:none; text-align:left; color:var(--ink); font-family:var(--f-body);}
.itr-song + .itr-song{border-top:1px solid var(--sp-line);}
.itr-song > .ic{flex:none; width:17px; height:17px; color:var(--sp-sub);}
.itr-song.on{background:var(--sp-leaf-50);}
.itr-song.on > .ic:last-child{color:var(--sp-leaf-700);}
.itr-songt{flex:1; min-width:0; display:flex; flex-direction:column; gap:1px;}
.itr-songt b{font-size:15px; font-weight:800; word-break:keep-all;}
.itr-songt small{font-size:12px; font-weight:700; color:var(--sp-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.itr-song.free b{font-weight:700; color:var(--ink2);}
@media (hover:hover) and (pointer:fine){ .itr-song:hover, .itr-rrow:hover{background:var(--sp-leaf-50);} .itr-pick:hover:not(.on), .itr-mb:hover:not(.on){background:var(--sp-leaf-50);} }
/* 확인 화면: 쓴 답 넷은 줄(누르면 그 질문으로), 고른 것은 알약(누르면 그 질문으로) */
.itr-rows{margin-top:16px; border-radius:18px; background:var(--page); overflow:hidden; text-align:left;}
.itr-rrow{display:flex; align-items:center; gap:10px; width:100%; min-height:54px; padding:9px 14px; margin:0; cursor:pointer;
  border:0; background:none; text-align:left; color:var(--ink); font-family:var(--f-body);}
.itr-rrow + .itr-rrow{border-top:1px solid var(--sp-line);}
.itr-rk{flex:none; width:84px; font-size:12.5px; font-weight:900; color:var(--sp-sub);}
.itr-rv{flex:1; min-width:0; font-size:15px; font-weight:800; line-height:1.4; word-break:keep-all; overflow-wrap:anywhere;}
.itr-rv.none{color:var(--sp-coral-700);}
.itr-rrow > .ic{flex:none; width:16px; height:16px; color:var(--sp-sub);}
.itr-chips{display:flex; flex-wrap:wrap; justify-content:center; gap:8px; margin-top:12px;}
.itr-chip{min-height:38px; padding:0 14px; border-radius:999px; cursor:pointer; font-family:var(--f-body); font-size:13.5px; font-weight:800; color:var(--ink);
  background:var(--card); border:1.5px solid var(--sp-line2); box-shadow:0 2px 0 var(--sp-ledge);}
.itr-chip:active{transform:translateY(2px); box-shadow:none;}
.itr-chip.none{color:var(--sp-sub); border-style:dashed;}
/* 프로필 칸(판 밖). «내 기록» 과 같은 담는 상자 */
.wintro{margin:16px 0 4px; padding:12px 14px; border-radius:18px; background:var(--page);}
.wintrohd{display:flex; align-items:center; gap:8px; min-height:26px;}
.wintrohd b{font-size:15px; font-weight:900;}
.wintrohd .linkbtn{margin-left:auto; min-height:32px; padding:0 4px; font-size:13px; font-weight:800;}
.witr{display:flex; align-items:baseline; gap:10px; padding:9px 0; border-top:1px solid var(--sp-line2);}
.wintrohd + .witr{margin-top:6px;}
/* 이름표 칸 폭 = 가장 긴 이름표가 한 줄에 드는 폭. "잘 안 먹는 음식" 이 77px(10-08 밤 측정)이라 76px 에서 두 줄로 꺾였다 */
.witk{flex:none; width:82px; font-size:12px; font-weight:900; color:var(--sp-sub);}
.witv{flex:1; min-width:0; font-size:14.5px; font-weight:700; line-height:1.45; color:var(--ink); word-break:keep-all; overflow-wrap:anywhere;}
.wisong{display:inline-flex; align-items:baseline; gap:5px; margin:0; padding:0; border:0; background:none; cursor:pointer; text-align:left;
  font-family:var(--f-body); color:var(--sp-leaf-700); font-weight:800;}
.wisong .ic{flex:none; width:13px; height:13px; align-self:center;}
.witcs{display:flex; flex-wrap:wrap; gap:6px; margin-top:4px; padding-top:10px; border-top:1px solid var(--sp-line2);}
.wintrohd + .witcs{margin-top:8px;}
.witc{display:inline-flex; align-items:center; height:26px; padding:0 10px; border-radius:999px;
  background:var(--sp-leaf-100); color:var(--sp-leaf-700); font-size:12.5px; font-weight:800; white-space:nowrap;}
.wintroask{margin:16px 0 4px;}
/* 리더 현황 */
.itrs-top{display:flex; align-items:center; gap:10px; margin:4px 2px 14px;}
.itrs-n{margin:0; font-size:15px; font-weight:800; color:var(--ink2);}
.itrs-n b{font-family:var(--f-disp); font-size:24px; font-weight:900; color:var(--sp-leaf-700); margin-right:2px;}
.itrs-top .btn{margin-left:auto;}
.itrs-txt{margin:0 2px 14px; padding:10px 12px; border-radius:14px; background:var(--card); font-size:14px; line-height:1.5;
  -webkit-user-select:text; user-select:text;}
.itrs-sec + .itrs-sec{margin-top:18px;}
.itrs-gn{margin-left:auto; font-family:var(--f-latin); font-size:12px; font-weight:700;}
.itrs-lead{font-style:normal; margin-left:6px; padding:1px 7px; border-radius:999px; vertical-align:2px;
  background:var(--sp-sun-100); color:var(--sp-sun-700); font-size:11.5px; font-weight:900;}
.itrs-st{flex:none; display:inline-flex; align-items:center; gap:3px; font-size:13px; font-weight:900; color:var(--sp-sub);}
.itrs-st.ok{color:var(--sp-leaf-700);}
.itrs-st .ic{width:14px; height:14px;}
.itrs-row[disabled]{cursor:default; opacity:.65;}
/* 음식 챙길 것(스무셋째 판): 누르는 줄이 아니라 읽는 줄. 이름은 왼쪽 한 칸, 답은 그 옆 */
.itrs-food{margin-top:18px;}
.itrs-food:empty{display:none;}
.itrs-frow{display:flex; align-items:baseline; gap:12px; padding:12px 14px; font-size:15px;}
.itrs-frow + .itrs-frow{border-top:1px solid var(--sp-line);}
.itrs-frow b{flex:none; min-width:4.5em; font-weight:900; letter-spacing:-.3px;}
.itrs-frow span{flex:1; min-width:0; font-weight:700; color:var(--ink2); overflow-wrap:anywhere;}
.itrs-fnote{margin:0 4px; font-size:13px; font-weight:700; color:var(--sp-sub);}
@media (prefers-reduced-motion:reduce){ .itr-st{animation:none;} .itr-bar i, .itr-pick{transition:none;} }

/* ══ 133차-h 열여덟째 판: 사진 자르기 (2026-10-08) ════════════════════════════════════
   JH: 단체 사진밖에 없어서 거기 나온 내 얼굴만 넣고 싶다. 어두운 판 위에 사진, 가운데 네모 틀 밖은 어둡게 눌러 둔다.
   판은 제 손가락을 쓴다(touch-action:none, 창의 스크롤 막기와 끌어 내리기가 판을 건드리지 않는다). 높이는 JS 가 폭과 같게 넣는다. */
.crp-stage{position:relative; width:100%; max-width:400px; margin:12px auto 0; overflow:hidden; border-radius:20px;
  background:#16201B; touch-action:none; user-select:none; -webkit-user-select:none; -webkit-touch-callout:none; cursor:grab; outline:none;}
.crp-stage:active{cursor:grabbing;}
.crp-stage:focus-visible{box-shadow:0 0 0 3px var(--sp-leaf-600);}
.crp-img{position:absolute; left:0; top:0; display:block; max-width:none; transform-origin:0 0; pointer-events:none; -webkit-user-drag:none;}
/* 틀 = 판의 80%(JS 의 F 와 같다). 모서리는 프로필 사진 칸처럼 둥근 네모, 밖은 어둡게 */
.crp-frame{position:absolute; inset:10%; border-radius:18%; pointer-events:none;
  box-shadow:0 0 0 2px rgba(255,255,255,.95), 0 0 0 999px rgba(10,18,14,.58);}
/* 크게 보기 막대: 작은 사진 · 큰 사진 그림 사이. 줄도 판처럼 제 손가락(창이 옆 끌기를 막지 않게) */
.crp-zoom{display:flex; align-items:center; gap:12px; max-width:400px; margin:14px auto 0; padding:0 6px; color:var(--sp-sub); touch-action:none;}
.crp-zs .ic{display:block; width:16px; height:16px;}
.crp-zb .ic{display:block; width:24px; height:24px;}
.crp-zoom input[type=range]{flex:1; min-width:0; height:32px; margin:0; background:none; -webkit-appearance:none; appearance:none; cursor:pointer;}
.crp-zoom input[type=range]::-webkit-slider-runnable-track{height:6px; border-radius:3px; background:var(--sp-line2);}
.crp-zoom input[type=range]::-webkit-slider-thumb{-webkit-appearance:none; width:26px; height:26px; margin-top:-10px; border-radius:50%;
  background:var(--sp-leaf-600); border:3px solid var(--card); box-shadow:0 2px 0 var(--sp-leaf-800);}
.crp-zoom input[type=range]::-moz-range-track{height:6px; border-radius:3px; background:var(--sp-line2);}
.crp-zoom input[type=range]::-moz-range-thumb{width:20px; height:20px; border-radius:50%; background:var(--sp-leaf-600); border:3px solid var(--card);}
.crp-zoom input[type=range]:focus-visible{outline:2px solid var(--sp-leaf-600); outline-offset:4px; border-radius:8px;}
.crp-foot{margin-top:16px;}

/* ══ 2026-10-09: 생일 친구 · 가랜드 ══════════════════════════════════════════════
   JH: "생일 아이콘이 뭔가 밍밍해. 좀 더 special한 느낌을 살려서". 잉크 선 케이크(46px) 자리에 색 든 친구 스티커가 선다
   (흰 칼선 · 그림자는 파일에 구웠다, make_bday_stickers.py). 오늘 생일 카드만 머리에 가랜드(촛불 여섯 색 깃발)를 단다.
   곧 생일은 친구 하나로 조용히 둔다(오늘과 곧이 한눈에 갈린다). 밤에도 친구 그림은 뒤집지 않는다(색 그림이다). */
html.sp .bdcard{gap:8px; padding:10px 16px 10px 8px; overflow:hidden;}
html.sp .bdi{width:76px; height:76px; margin:-4px 0 -6px; object-fit:contain;}
html.sp .bdcard.on{padding-top:26px;}
html.sp .bdcard.on .bdi{align-self:flex-start; margin-top:-2px;}
.bdflags{position:absolute; top:0; left:12px; right:12px; height:24px; display:flex; justify-content:center; gap:10px;
  overflow:hidden; pointer-events:none;}
/* 줄 = 깃발이 매달린 끈. 카드 끝까지 간다 */
.bdflags::before{content:''; position:absolute; left:0; right:0; top:6px; height:1.5px; background:rgba(90,63,168,.28);}
.bdflags i{position:relative; flex:none; width:13px; height:15px; margin-top:6px; background:var(--cdc);
  clip-path:polygon(0 0, 100% 0, 50% 100%);}
.bdflags i:nth-child(even){margin-top:7px; height:13px;}
html.sp:is([data-tod="dawn"],[data-tod="evening"],[data-tod="night"]) .bdflags::before{background:rgba(255,255,255,.22);}
/* 누르면 폭죽(오늘만). 친구가 한 번 들썩인다 */
html.sp .bdcard.on .bdi[data-bdpop]{cursor:pointer;}
html.sp .bdcard.popped .bdi{animation:bdhop .7s cubic-bezier(.3,.9,.3,1) both;}
@keyframes bdhop{0%{transform:none;} 22%{transform:translateY(-7px) rotate(-6deg) scale(1.06);} 48%{transform:translateY(0) rotate(3deg);} 72%{transform:rotate(-2deg);} 100%{transform:none;}}
@media (prefers-reduced-motion:reduce){ html.sp .bdcard.popped .bdi{animation:none;} }

/* ══ 2026-10-09: 부르고 싶은 곡 검토(수락 · 보류 · 거절) ══════════════════════════════════
   JH: "수락, 보류, reject 이렇게 나눠서 찬양팀 리더들이 실제로 신청곡들을 관리할 수 있게". 부르고 싶은 곡을 단계 셋으로 나눈다
   (새로 온 곡 · 콘티 후보 · 보류). 단계 머리는 «예배 전에 틀 곡 / 부르고 싶은 곡» 머리보다 한 단 작게, 밑줄 없이. */
.rsstage + .rsstage{margin-top:12px; padding-top:10px; border-top:1px dashed var(--sp-line2);}
.rsghd + .rsstage, .rsghd + .rsrevline{margin-top:2px;}
.rssthd{display:flex; align-items:center; flex-wrap:wrap; gap:4px 8px; margin:0 0 4px; min-height:28px;}
.rssthl{display:inline-flex; align-items:baseline; gap:5px; font-size:12.5px; font-weight:900; color:var(--ink); white-space:nowrap;}
.rssthl b{font-size:11px; font-weight:800; color:var(--sp-sub);}
.rssthd small{font-size:11.5px; font-weight:700; color:var(--sp-sub);}
.rsstage[data-rsstep="ok"] .rssthl{color:var(--sp-leaf-700);}
.rsstage[data-rsstep="hold"] .rssthl{color:var(--sp-sun-700);}
.rssthd .rsrevgo{margin-left:auto;}
/* 단계 머리 단추는 «전체 재생» 과 같은 치수. 채운 초록은 전체 재생 하나로 두고, 검토하기는 초록 테(줄의 «검토» 와 같은 말) */
html.sp .rsbundle .btn.rsrevgo{min-height:36px; padding:6px 13px; gap:4px; font-size:12.5px; font-weight:900; flex:none; white-space:nowrap;}
html.sp .rsbundle .btn.rsrevgo .ic{width:13px; height:13px; margin:0;}
html.sp .rsbundle .btn.rsrevgo.new{color:var(--sp-leaf-700); border-color:var(--sp-leaf-600);}
.rsong.st-open .rsrep{color:var(--sp-sub);}
/* 홈: 콘티 후보가 있을 때 새로 온 곡은 한 줄 알림(찬양팀 리더만) */
.rsrevline{display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%; margin:0 0 10px; padding:8px 8px 8px 12px;
  border:0; border-radius:14px; background:var(--sp-leaf-50); cursor:pointer; font:inherit; color:var(--ink); text-align:left;}
.rsrevline > span:first-child{font-size:13px; font-weight:800;}
.rsrevline b{font-weight:900; color:var(--sp-leaf-700); margin-left:3px;}
.rsrevline .rsrevgo{display:inline-flex; align-items:center; gap:4px; flex:none; padding:5px 10px; border-radius:10px; font-size:12px; font-weight:900;
  background:var(--sp-leaf-600); color:#fff;}
.rsrevline .rsrevgo .ic{width:13px; height:13px;}
/* 줄의 «검토» 는 새로 온 곡에만 잎 색(정할 일), «바꾸기» 는 보통 단추 */
.rsacts .rsrevb.new{color:var(--sp-leaf-700); border-color:var(--sp-leaf-600);}
.rsong.st-ok .rsrep{color:var(--sp-leaf-700);}
.rsong.st-hold .rsrep{color:var(--sp-sun-700);}
.rsong.st-no .rsrep, .rsong.st-done .rsrep{color:var(--sp-sub);}

/* 검토 창: 한 화면에 한 곡. 맨 위 진행 막대는 자기소개 창과 같은 것(.itr-bar) */
.rsrv-head h3{flex:1; min-width:0; display:flex; align-items:baseline; gap:8px;}
.rsrv-n{font-family:var(--f-latin); font-size:13px; font-weight:700; color:var(--sp-sub); letter-spacing:.02em;}
.rsrv{padding:12px 2px 4px; text-align:center;}
.rsrv-meta{display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:6px 10px; font-size:12.5px; font-weight:700; color:var(--sp-sub);}
.rsrv-t{margin:14px 0 0; font-family:var(--f-disp); font-size:26px; font-weight:900; line-height:1.3; letter-spacing:-.5px;
  color:var(--ink); word-break:keep-all; overflow-wrap:anywhere;}
.rsrv-a{margin:4px 0 0; font-size:14px; font-weight:700; color:var(--ink2);}
.rsrv-note{margin:12px auto 0; max-width:340px; padding:10px 14px; border-radius:14px; background:var(--dk-well, #F4F7F5);
  font-size:13.5px; font-weight:600; line-height:1.55; color:var(--ink2); text-align:left; white-space:pre-line; word-break:keep-all; overflow-wrap:anywhere;}
.rsrv-next{display:inline-block; margin:12px 0 0; padding:4px 11px; border-radius:999px; background:var(--sp-leaf-100);
  font-size:12.5px; font-weight:800; color:var(--sp-leaf-700);}
.rsrv-play{margin:18px auto 0; max-width:340px; min-height:46px; font-size:15px;}
.rsrv-picks{display:grid; grid-template-columns:repeat(3, 1fr); gap:10px; margin:18px 0 0;}
.rsrv-pick{display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; min-height:92px; padding:10px 4px;
  border-radius:20px; cursor:pointer; font-family:var(--f-body); color:var(--ink);
  background:var(--card); border:1.5px solid var(--sp-line2); box-shadow:0 4px 0 var(--sp-ledge);
  transition:transform .08s ease, box-shadow .08s ease, background-color .12s ease;}
.rsrv-pick:active{transform:translateY(4px); box-shadow:none;}
.rsrv-pick[disabled]{opacity:.6; cursor:default;}
.rsrv-pick .ic{width:22px; height:22px;}
.rsrv-pick b{font-family:var(--f-disp); font-size:19px; font-weight:900; letter-spacing:-.4px;}
.rsrv-pick small{font-size:11px; font-weight:700; color:var(--sp-sub); word-break:keep-all;}
.rsrv-pick.ok .ic{color:var(--sp-leaf-700);}
.rsrv-pick.hold .ic{color:var(--sp-sun-700);}
.rsrv-pick.no .ic{color:var(--sp-coral-700);}
/* 지금 이 곡의 단계(이전 곡으로 돌아왔을 때 무엇을 골랐는지 보인다) */
.rsrv-pick.on{color:#fff; box-shadow:0 4px 0 rgba(0,0,0,.22);}
.rsrv-pick.on .ic, .rsrv-pick.on small{color:#fff;}
.rsrv-pick.ok.on{background:var(--sp-leaf-600); border-color:var(--sp-leaf-600);}
.rsrv-pick.hold.on{background:var(--sp-sun-fill); border-color:var(--sp-sun-fill);}
.rsrv-pick.no.on{background:var(--sp-coral-fill); border-color:var(--sp-coral-fill);}
.rsrv-nav{display:flex; justify-content:space-between; align-items:center; margin:16px 2px 2px; min-height:32px;}
.rsrv-nav .linkbtn{display:inline-flex; align-items:center; gap:3px; margin:0; font-size:13.5px; font-weight:800; color:var(--sp-sub);}
.rsrv-nav .linkbtn:last-child{margin-left:auto;}
.rsrv-nav .linkbtn[hidden]{display:none;}
.rsrv-done{padding:18px 4px 6px; text-align:center;}
.rsrv-st{display:block; width:96px; height:96px; margin:0 auto;}
.rsrv-dt{margin:10px 0 0; font-family:var(--f-disp); font-size:24px; font-weight:900; color:var(--ink);}
.rsrv-ds{margin:6px 0 0; font-size:14px; font-weight:800; color:var(--sp-sub);}
.rsrv-foot{display:flex; flex-direction:column; align-items:center; gap:12px; margin-top:22px;}
.rsrv-foot .linkbtn{margin:0; font-size:13.5px; font-weight:800; color:var(--sp-sub);}

/* ══ 2026-10-09: 프로필 옆으로 넘기기 ══════════════════════════════════════════
   머리: 제목 · 앞 사람 · 몇 번째 · 다음 사람 · 닫기. 넘어오면 내용이 그 쪽에서 미끄러져 들어온다(위치만, 보이게 하는 일은 안 맡긴다) */
.whohead h3{flex:1; min-width:0;}
.whonav{display:inline-flex; align-items:center; gap:4px; flex:none;}
.whonav .iconbtn{width:34px; height:34px;}
.whonavn{min-width:42px; text-align:center; font-family:var(--f-latin); font-size:12.5px; font-weight:700; color:var(--sp-sub);
  font-variant-numeric:tabular-nums;}
.whohead #whClose{margin-left:4px;}
.sheet.whoslide-r > :not(.grab):not(.shhead){animation:whoslr .26s cubic-bezier(.2,.8,.3,1);}
.sheet.whoslide-l > :not(.grab):not(.shhead){animation:whosll .26s cubic-bezier(.2,.8,.3,1);}
@keyframes whoslr{from{transform:translateX(28px);}}
@keyframes whosll{from{transform:translateX(-28px);}}
@media (prefers-reduced-motion:reduce){ .sheet.whoslide-r > *, .sheet.whoslide-l > *{animation:none;} }

/* ══ 2026-10-09: 더보기 «자기소개 다시 하기» ══ 내 이름 카드 바로 밑 한 줄 */
.sp-mecard + .sp-melist{margin-top:10px;}
.sp-melist .sp-ri img{width:34px; height:34px; object-fit:contain;}
