/* ─────────────────────────────────────────────────────────────
   Tenline — 디자인 시스템

   두 세계로 나눈다. 이건 취향이 아니라 기능이다.
     · 고르는 화면(홈·보관함·의견): 밝고 부드럽게.
     · 찍는 화면: 어둡게. 촬영 중엔 화면이 얼굴을 비추는 조명이 되고,
       밝은 UI 가 남아 있으면 영상에 반사돼 들어온다.

   ── 우리 것이 뭔가 ──

   ⚠️ **남의 앱 스타일을 그대로 가져오지 않는다.** 참고할 건 "정성이 느껴지는가"이지
     그 앱의 크림색이나 그 앱의 별·구름 그림이 아니다. 그건 그 앱의 얼굴이다.

   Tenline 의 얼굴은 두 개에서 나온다. 둘 다 제품 자체에서 나온 것이다.

     ① **말풍선** — 제품이 "대사를 주면 말이 나온다"이니 말풍선이 곧 제품이다.
        미션 카드가 말풍선이고(꼬리까지 달렸다), 마스코트도 말풍선이다.
     ② **주황 빈칸 밑줄(`___`)** — 이미 우리 시그니처다. 대사의 빈칸, 마스코트의 입,
        섹션 제목 밑줄이 전부 같은 획이다. 하나의 몸짓이 화면 전체를 묶는다.

   형식은 **스티커**다. 얇은 외곽선(2px) + 살짝 어긋난 그림자(2px).
   ⚠️ 선·그림자는 글자색(--ink)이 아니라 **--edge**(한 톤 흐린 먹)를 쓴다.
     둘 다 검정이면 카드가 쌓였을 때 화면이 테두리로 가득 차 조잡해진다.
   테두리 없이 부드러운 회색 면을 쓰는 앱들과 정반대라, 옆에 놓아도 헷갈리지 않는다.
   손으로 붙인 것 같아서 아기자기하고, 외곽선이 있어서 말풍선이 말풍선으로 읽힌다.

   색은 하나만 세게 쓴다 — 주홍(#FF5A3C). 버터(#FFCF5C)와 민트(#2ED3B7)는
   점 찍는 용도로만. 셋을 같은 크기로 쓰면 셋 다 죽는다.
   ───────────────────────────────────────────────────────────── */

:root {
  /* 키보드 높이. app.js 의 watchKeyboard 가 재서 채운다.
     ⚠️ **기본값이 반드시 있어야 한다.** 없으면 `calc()` 가 통째로 무효가 되어
        여백이 사라지는 게 아니라 그 규칙 자체가 안 먹는다. */
  --kb: 0px;
  /* 🎲 주사위가 멈춰 설 각도. app.js 의 rollThenShow 가 굴릴 때마다 채운다.
     ⚠️ **여기 기본값이 없으면** 그 순간 `calc()` 가 통째로 무효가 되고, 없어지는
        게 여백 하나가 아니라 **transform 규칙 전체**다 — 주사위가 안 구르는 게
        아니라 아예 안 움직인다. 바로 위 `--kb` 와 똑같은 함정이다. */
  --rx: 0deg; --ry: 0deg;
  color-scheme: light;

  --paper:#FFF8F2; --sheet:#FFFFFF; --sunk:#F2EAE2;
  --ink:#221E1C; --ink-2:#6E655D; --ink-3:#A79C92;

  --hot:#FF5A3C; --hot-ink:#FFFFFF; --hot-soft:#FFE6DF;
  --butter:#FFCF5C; --mint:#2ED3B7;
  --bad:#D93A2B;
  /* 💰 CASH — 나머지 아홉과 성격이 다른 하나. 놀이가 아니라 돈을 받는 일이다. */
  --cash:#C67A00;

  --stage:#161311; --stage-2:#2B2521; --on-stage:#FFF8F2; --on-stage-2:#A79C92;

  --sans:-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Pretendard",
         "Malgun Gothic","맑은 고딕",system-ui,sans-serif;
  /* 통통한 제목용. 한글을 지원하는 몇 안 되는 라운드 계열이다. */
  --round:"Jua",var(--sans);
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --r-card:22px; --r-pill:999px;

  /* 스티커 — 외곽선과 어긋난 그림자가 한 세트다. 따로 쓰면 어색하다.
     ⚠️ **테두리 색을 글자색과 따로 둔다.** 둘 다 잉크(#221E1C)로 두니
       카드가 열 개쯤 쌓였을 때 굵은 검은 테두리 + 3px 검은 그림자가 화면을
       가득 채워서 조잡했다. 글자는 또렷해야 하니 --ink 그대로 두고,
       **선과 그림자만 한 톤 흐리게(--edge)** 한다.
     ⚠️ 얇게도 만든다(2.6→2px, 3→2px). 스티커라는 성격은 남기되
       "손으로 붙인 것"이지 "테두리로 그린 것"이 아니다. */
  /* ⚠️ **한 번 더 흐리게 했다(#4A423D → #DCD2C6).** 한 톤 낮춘 것으로는 부족했다 —
       카드가 열 개쯤 쌓이면 굵은 어두운 테두리가 격자처럼 보여서, 정작 봐야 할
       **사진과 글씨보다 테두리가 먼저 눈에 들어왔다.**
     ⚠️ **어긋난 하드 그림자를 부드러운 것으로 바꿨다.** `2px 2px 0` 은 스티커
       느낌이지만 카드가 많으면 전부 이중선처럼 보인다. 살짝 띄우는 정도면
       "만질 수 있는 것"이라는 신호는 그대로 남는다.
     ⚠️ **글자색(--ink)은 안 건드린다.** 흐리게 할 것은 선이지 내용이 아니다.
     ⚠️ 눌러야 할 것(주요 버튼·미션 카드)에는 `--edge-strong` 을 쓴다. 전부
       흐리게 하면 이번엔 **뭘 눌러야 하는지가 안 보인다.** */
  --edge:#DCD2C6;
  --edge-strong:#3A322D;
  --line:1.5px solid var(--edge);
  --pop:0 1px 2px rgba(34,30,28,.05), 0 6px 16px rgba(34,30,28,.06);
  --pop-sm:0 1px 2px rgba(34,30,28,.05), 0 3px 8px rgba(34,30,28,.05);
}

* { box-sizing:border-box; -webkit-tap-highlight-color:transparent; }

/* ⚠️⚠️⚠️ **한글이 낱말 한가운데서 잘리고 있었다** — 「주사위가 정해줍니/다」,
   「쌓입니/다」. 브라우저 기본값은 한글을 **글자 단위로** 끊는다(영어처럼
   띄어쓰기를 안 봐도 된다고 여긴다). 좁은 화면·모달에서 특히 심하게 티가 난다.
   ⚠️ `keep-all` 이 낱말을 통째로 넘긴다. 대신 **아주 긴 낱말 하나가 상자를
      넘칠 수 있어서** `overflow-wrap:anywhere` 를 짝으로 둔다 — 그건 다른
      방법이 없을 때만 끊는다(주소·긴 영문에만 걸린다).
   ⚠️ 여기 한 곳에서 못박는다. 자리마다 붙이면 새로 만드는 화면에서 또 빠진다.
   ⚠️ **`body` 규칙을 새로 만들지 않는다** — 아래에 이미 있다. 두 벌이 되면
      나중에 한쪽만 고쳐서 갈라지고, check.mjs 의 「같은 CSS 규칙이 두 번」이
      바로 잡아낸다(실제로 잡혔다). 아래 규칙 안에 넣었다. */

/* ⚠️⚠️ **아이콘은 절대 줄어들면 안 된다.**
   `<button>` 을 flex 컨테이너로 쓰면 안쪽이 브라우저가 만든 익명 상자를 거치는데,
   viewBox 없는 SVG 는 거기서 기본 폭을 잃고 **폭 0 으로 찌그러진다.**
   실제로 「저장·공유·삭제 버튼이 사라졌다」로 며칠을 갔다 — 버튼도 있고 자리도
   맞는데 안의 그림만 폭이 0 이었다(재보고 알았다: computed width = 0px).
   ⚠️ 그때는 `.act .ti` 한 줄만 고쳤는데, **같은 모양의 버튼이 앱에 여덟 군데 더
     있다**(탭바·헤더 동그라미·방 칩·＋ 버튼…). 한 곳씩 고치면 반드시 빠뜨린다.
     **여기서 통째로 못박는다.** */
/* ⚠️⚠️⚠️ **`.ti` 에 크기가 없었다.** SVG 는 크기를 안 주면 **300×150 기본값**으로
   그려진다 — 새로 붙인 종류 아이콘이 화면을 뒤덮은 검은 덩어리가 된 이유다
   ("아이콘 완전히 패망함"). 여태 안 터진 건 쓰던 자리마다 크기를 따로 줬기
   때문이고, **크기를 안 준 자리에 하나라도 쓰는 순간** 그렇게 된다.
   ⚠️ **바닥값을 여기서 준다.** 필요한 자리는 각자 덮어쓴다. 그러면 새로 쓰는
      자리가 생겨도 최소한 화면은 안 깨진다. */
.ti {
  flex:0 0 auto; width:1.15rem; height:1.15rem;
  fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round;
}
html,body { margin:0; height:100%; }
body {
  background:var(--paper); color:var(--ink); font-family:var(--sans);
  line-height:1.5; overflow:hidden;
  -webkit-font-smoothing:antialiased; -webkit-text-size-adjust:100%;
  /* 한글 줄바꿈 — 위 설명 참고(낱말 한가운데서 끊기던 것) */
  word-break:keep-all; overflow-wrap:anywhere;
}

/* ── 화면 ── */
.screen { display:none; position:fixed; inset:0; flex-direction:column; }
.screen[data-active] { display:flex; }
.screen.center { justify-content:center; align-items:center; text-align:center; }
.pad { padding:.35rem 1.05rem 1.15rem; }
.grow { flex:1; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.spacer { width:2.6rem; flex:0 0 auto; }

/* 촬영·완성 화면은 어두운 세계 */
#s-shoot, #s-review, #s-making { background:var(--stage); color:var(--on-stage); }

/* ── 상단 ── */
.top {
  display:flex; align-items:center; justify-content:space-between; gap:.5rem;
  padding:calc(env(safe-area-inset-top) + .9rem) 1.05rem .5rem;
}
.brand {
  font-family:var(--round); font-size:1.45rem; color:var(--hot);
  letter-spacing:.01em; line-height:1;
  /* 로고에도 잉크 외곽선을 아주 얇게 — 스티커 문패처럼 보이게 */
  -webkit-text-stroke:.6px var(--ink);
}
.brand.sm { font-size:1.2rem; color:var(--ink); -webkit-text-stroke:0; }

.badge {
  display:inline-block; min-width:1.3rem; padding:.02rem .38rem; margin-left:.15rem;
  background:var(--hot); color:var(--hot-ink); border-radius:var(--r-pill);
  font-family:var(--mono); font-size:.67rem; font-weight:700;
  font-variant-numeric:tabular-nums;
}

/* ── 오늘의 나 ──
   ⚠️ 남과 비교하지 않는다. 등수도 랭킹도 없다. 어제의 나와만 비교한다. */
.stats {
  display:flex; align-items:center; gap:.35rem; flex-wrap:wrap;
  margin:0 0 .9rem; font-size:.76rem; font-weight:700; color:var(--ink-2);
}
.stats span {
  background:var(--sheet); border:1.5px solid var(--edge); box-shadow:var(--pop-sm);
  padding:.3rem .65rem; border-radius:var(--r-pill);
}
.stats .flame { background:var(--hot); color:var(--hot-ink); }
.stats .lvl { background:var(--butter); }
/* 점수 — 불꽃·단계와 달리 **그냥 숫자**다. 색을 하나 더 쓰면 셋 다 경고처럼 보인다. */
.stats .pts { background:var(--sunk); color:var(--ink-2); }

/* ── 말풍선 ──
   미션 카드는 그냥 카드가 아니라 **말풍선**이다. 왼쪽 아래 꼬리를 겹친 두 겹으로
   그린다(바깥은 잉크색, 안쪽은 종이색). 외곽선이 이어져 보이게 하는 흔한 수법이다. */
.bubble {
  position:relative; background:var(--sheet); border:var(--line);
  border-radius:var(--r-card); box-shadow:var(--pop);
  padding:1.3rem 1.15rem 1.15rem; margin-bottom:1.1rem;
}
.bubble::before, .bubble::after {
  content:""; position:absolute; bottom:-13px; left:2rem;
  border:7px solid transparent; border-top-color:var(--edge); border-bottom:0;
}
.bubble::after {
  bottom:-9px; left:calc(2rem + 2px);
  border-width:6px; border-top-color:var(--sheet);
}
.bubble.lead p { margin:0; font-size:.96rem; color:var(--ink-2); line-height:1.7; }
.bubble.lead strong { color:var(--ink); }

/* 마스코트 — 카드 오른쪽 위에 붙인 스티커처럼. 화면당 하나만. */
.mascot {
  position:absolute; top:-1.15rem; right:.8rem; width:3.5rem; height:3.2rem;
  pointer-events:none; transform:rotate(6deg);
}
.mascot.big {
  position:static; width:5.2rem; height:4.8rem; margin:0 auto 1.1rem;
  display:block; transform:none;
}
/* 만드는 중에는 말풍선이 살짝 들썩인다. 몇 십 초를 기다려야 해서 화면이 죽으면 안 된다. */
.bob { animation:bob 1.4s ease-in-out infinite; }
@keyframes bob { 50% { transform:translateY(-9px) rotate(-4deg); } }

/* ── 제목 ──
   eyebrow 밑에 주황 획을 깐다. 대사의 빈칸(`___`)과 같은 획이다. */
.eyebrow {
  display:inline-block; font-size:.72rem; font-weight:700; letter-spacing:.02em;
  color:var(--ink); margin-bottom:.5rem; padding-bottom:.1rem;
  border-bottom:3px solid var(--hot);
}
.eyebrow.mt { margin-top:1.35rem; }
h1 {
  margin:0 0 1rem; font-family:var(--round); font-weight:400;
  font-size:clamp(1.6rem,7.2vw,2.15rem); letter-spacing:-.01em;
  line-height:1.28; text-wrap:balance;
}
#s-making h1 { color:var(--on-stage); }

/* ── 대사 ── 화면의 주인공.
   ⚠️ 여기만은 통통한 글꼴을 안 쓴다. 읽으면서 말해야 하는 문장이라
      **또렷함이 귀여움보다 우선**이다. */
.script {
  background:var(--paper); border:1.5px solid var(--edge); border-radius:16px;
  padding:.95rem 1rem; display:flex; flex-direction:column; gap:.6rem;
}
.script p {
  margin:0; font-size:1.14rem; font-weight:800; letter-spacing:-.03em;
  line-height:1.35;
}
/* 빈칸 — "여기는 네가 채운다"가 한눈에. 마스코트 입과 같은 획이다. */
.script b, .cue b {
  display:inline-block; min-width:3.4em; height:1.05em;
  border-bottom:3.5px solid var(--hot); vertical-align:-.1em;
}
.tip { margin:.8rem 0 0; font-size:.82rem; color:var(--ink-3); line-height:1.6; }
.tip strong { color:var(--ink-2); font-weight:700; }
/* ⚠️ `.quiet` 은 **이름만 있고 규칙이 없었다.** 사업자 정보·기기 안내처럼
   "필요하면 읽으시라"인 것이 본문과 같은 크기로 떠 있었다. 작은 글씨다. */
.tip.quiet { font-size:.76rem; line-height:1.55; opacity:.8; }
.tip.quiet a { color:inherit; text-underline-offset:3px; }
/* ⚠️ **막는 말은 막힌 자리에 적는다.** 토스트는 화면 맨 아래에 뜨는데 누르는
   버튼도 아래라 손가락에 가려서 안 읽힌다 — 그러면 "왜 아무 일도 안 나지"가 된다. */
/* ── 토스트 ────────────────────────────────────────────────────────────────
   ⚠️⚠️⚠️ **`.toast` 는 이름만 있고 규칙이 하나도 없었다.** `<div class="toast">` 가
      `<body>` 흐름에 그대로 놓여서 **화면 맨 위 왼쪽에 작은 검은 글씨**로 떴고,
      헤더에 가려 반쯤 잘렸다. 이 세션에서 나온 「메시지가 안 보인다」가 전부
      이것이었다:
        · "쌩뚱맞게 최상단에 조그만 텍스트로 나온다"
        · "저장했습니다 문구 어디 떠있니"
      **앱이 사람에게 말하는 유일한 통로가 몇 달째 망가져 있었다** — 말은 하고
      있었는데 아무도 못 읽는 자리에서 하고 있었다.
   ⚠️ 이 사고를 이 파일에서만 다섯 번째 낸다(`.quiet`·`.scrollx`·`.pwbox`·`.picks`).
      **class 를 새로 지으면 그 자리에서 규칙도 같이 적는다.** CSS 는 없는 규칙에
      대해 조용하다.
   ⚠️ **아래에 띄운다.** 위는 헤더가 있고, 누르는 버튼은 대개 아래에 있어서
      방금 누른 것 근처에서 답이 나와야 읽는다. 탭 막대는 피한다. */
.toast {
  position:fixed; left:50%; bottom:calc(5.2rem + env(safe-area-inset-bottom));
  transform:translateX(-50%);
  z-index:80; max-width:min(22rem, calc(100vw - 2rem));
  padding:.7rem 1rem; border-radius:14px;
  background:rgba(28,24,22,.94); color:#FFF8F2;
  font-size:.86rem; font-weight:700; line-height:1.5; text-align:center;
  white-space:pre-line; box-shadow:0 6px 24px rgba(0,0,0,.28);
  animation:toastin .22s cubic-bezier(.2,1.2,.4,1) both;
}
.toast[hidden] { display:none; }
@keyframes toastin {
  0%   { opacity:0; transform:translate(-50%, .8rem); }
  100% { opacity:1; transform:translate(-50%, 0); }
}

/* ── 숫자 타일 ─────────────────────────────────────────────────────────────
   ⚠️⚠️⚠️ **`.sums`·`.sum` 이 관리자 CSS 에만 있고 앱 CSS 에는 없었다.** 그래서
      앱에서는 규칙 없는 div 로 그려져 「0명찍어준 사람」처럼 **붙어서 한 줄로**
      흘렀다 — 띄어쓰기도 없고 숫자와 이름이 구분도 안 됐다.
   ⚠️⚠️ **「아는 것 16개」로 얼려둔 목록에 이게 들어 있었다.** 얼려둔 것 중에도
      진짜 사고가 있었다 — 그 목록은 「나중에 볼 것」이지 「괜찮은 것」이 아니다.
      얼릴 때는 **하나씩 눈으로 확인하고** 넣어야 한다. */
.sums { display:flex; gap:.5rem; flex-wrap:wrap; margin:.3rem 0 .9rem; }
.sums[hidden] { display:none; }
.sum {
  flex:1 1 6rem; min-width:0; text-align:center;
  background:var(--sheet); border:var(--line); box-shadow:var(--pop-sm);
  border-radius:var(--r-card); padding:.6rem .5rem;
}
.sum b { display:block; font-family:var(--round); font-size:1.35rem; line-height:1.15; }
.sum span { display:block; margin-top:.1rem; font-size:.74rem; font-weight:700; color:var(--ink-3); }

.tip.bad { color:var(--bad); }
.tip.bad strong { color:var(--bad); }
.tip[hidden] { display:none; }

/* ── 미션 종류 ── */
.where { margin-top:1.5rem; }
.cats { display:grid; grid-template-columns:repeat(3,1fr); gap:.45rem; }
.chips { display:flex; flex-wrap:wrap; gap:.42rem; }
.chip {
  border:1.5px solid var(--edge); background:var(--sheet); color:var(--ink);
  padding:.66rem .5rem; border-radius:14px; box-shadow:var(--pop-sm);
  font-family:var(--sans); font-size:.89rem; font-weight:800; letter-spacing:-.02em;
  cursor:pointer; white-space:nowrap; text-align:center; min-width:0;
  transition:transform .1s, box-shadow .1s, background .12s, color .12s;
}
/* ⚠️⚠️ **종류 이름 앞이 전부 이모지였다.** 기기마다 그림이 다르고 색이 제멋대로라
   우리 화면이 **우리 것으로 안 보였다.** 한 벌로 그린 선 아이콘으로 바꾼다.
   ⚠️ **글씨보다 작게, 같은 색으로.** 그림이 이름보다 크면 이름을 안 읽는다. */
.chip, .opts .opt { display:inline-flex; align-items:center; justify-content:center; gap:.3rem; }
.chip .ti, .opts .opt .ti, .place .ti, .gcat .ti {
  width:1.05rem; height:1.05rem; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round;
}
/* 💰 CASH — ⚠️ **하나만 성격이 다르다.** 나머지 아홉은 놀이인데 이건 **돈을
   받는 일**이다(광고를 찍고 SNS 에 올려야 지급된다). 같은 색으로 늘어놓으면
   그 차이가 안 읽혀서, 놀이인 줄 알고 눌렀다가 「올려야 돈이 나온다」를 뒤늦게 안다.
   ⚠️ **색만 다르게 한다** — 자리를 옮기거나 크게 만들면 이 앱이 돈 버는 앱으로
      보인다. 그건 이 앱이 파는 것이 아니다. */
.chip[data-cat="gig"], .roomtypes button[data-cat="gig"], .opts .opt[data-cat="gig"] {
  color:var(--cash, #C67A00); border-color:var(--cash, #C67A00);
}
.chip[data-cat="gig"][data-on] {
  background:var(--cash, #C67A00); border-color:var(--cash, #C67A00); color:#fff;
}
/* 누르면 그림자만큼 내려앉는다 — 진짜 눌린 것처럼 */
.chip:active { transform:translate(2px,2px); box-shadow:none; }
.chip[data-on] { background:var(--hot); color:var(--hot-ink); }

/* 곡 목록 — 17곡이라 가로로 흘린다. 격자로 넣으면 화면을 다 먹는다.
   ⚠️ 그림자가 잘리지 않게 좌우·아래 여백을 준다. */
.songs {
  display:flex; gap:.42rem; overflow-x:auto; padding:.2rem .2rem .45rem;
  margin:0 -.2rem; scrollbar-width:none; -webkit-overflow-scrolling:touch;
}
.songs::-webkit-scrollbar { display:none; }
.songs .chip { flex:0 0 auto; padding:.52rem .9rem; font-size:.84rem; border-radius:var(--r-pill); }

.lyr { margin-top:1.2rem; }
.lyr summary {
  font-size:.85rem; font-weight:800; color:var(--ink-2); cursor:pointer;
  list-style:none; padding:.5rem 0;
}
.lyr summary::-webkit-details-marker { display:none; }
.lyr summary::before { content:"＋ "; color:var(--hot); font-weight:800; }
.lyr[open] summary::before { content:"− "; }
.lyr .row { display:flex; gap:.4rem; margin-top:.5rem; }
.lyr .row button { flex:1; }

.geo { margin-top:1.1rem; font-size:.66rem; color:var(--ink-3); }

/* ── 버튼 ── */
.dock {
  margin-top:auto; display:flex; gap:.5rem;
  padding:.7rem 1.05rem calc(env(safe-area-inset-bottom) + .9rem);
}
.dock.col { flex-direction:column; }
#s-shoot .dock.col, #s-review .dock.col { gap:.42rem; }
.dock .row { display:flex; gap:.5rem; }
.dock .row > * { flex:1; }

button {
  font-family:var(--sans); font-size:1rem; font-weight:800; letter-spacing:-.02em;
  padding:.95rem 1rem; border:var(--line); border-radius:var(--r-pill);
  background:var(--sheet); color:var(--ink); cursor:pointer; flex:1;
  box-shadow:var(--pop); transition:transform .1s, box-shadow .1s, opacity .12s;
}
button:active { transform:translate(3px,3px); box-shadow:none; }
button.primary { background:var(--hot); color:var(--hot-ink); }
button.ghost { background:var(--sheet); color:var(--ink-2); }
button.sm { padding:.45rem .8rem; font-size:.82rem; flex:0 0 auto; box-shadow:var(--pop-sm); }
button.pill { padding:.44rem .85rem; font-size:.82rem; flex:0 0 auto; box-shadow:var(--pop-sm); }
button.circle {
  flex:0 0 auto; width:2.6rem; height:2.6rem; padding:0; border-radius:50%;
  font-size:1.02rem; font-weight:700; display:flex; align-items:center; justify-content:center;
  box-shadow:var(--pop-sm);
}
/* 부차적인 것에는 스티커를 안 붙인다. 전부 튀어나오면 아무것도 안 튀어나온 것과 같다. */
button.sub {
  padding:.72rem; font-size:.87rem; background:transparent; color:var(--ink-3);
  border:0; box-shadow:none;
}
button.sub:active { transform:scale(.97); }
button:disabled { opacity:.4; box-shadow:var(--pop-sm); }
button:focus-visible { outline:3px solid var(--mint); outline-offset:2px; }
button.danger { color:var(--bad); }

/* 어두운 화면 위의 버튼 — 검은 배경에 검은 외곽선은 안 보인다. 종이색으로 그린다. */
#s-shoot button, #s-review button, #s-shoot .pickfile {
  background:var(--stage-2); color:var(--on-stage);
  border-color:var(--on-stage); box-shadow:2px 2px 0 rgba(255,248,242,.5);
}
#s-shoot button:active, #s-review button:active { box-shadow:none; }
#s-shoot button.primary, #s-review button.primary { background:var(--hot); color:var(--hot-ink); }

/* ── 뷰포트 ── */
.viewport {
  position:relative; flex:1; background:#000; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
}
.viewport canvas, .viewport video {
  max-width:100%; max-height:100%; width:auto; height:auto; display:block;
}
/* 촬영 화면 위 줄.
   ⚠️⚠️ **오른쪽 위는 로고 자리다 — 아무것도 두지 않는다.**
      로고(`recorder._drawBrand`)는 **영상 안에** 구워지는 것이라 자리를 못 옮긴다
      (아래는 인스타·틱톡이 자기 UI 로 덮어서 오른쪽 위가 유일하게 안 가려진다).
      길이 배지를 왼쪽으로 옮겨놓고 REC 를 오른쪽에 뒀더니 **찍는 순간 다시
      겹쳤다** — 지적받은 자리만 고치면 이렇게 된다.
   → 오른쪽 38% 는 아예 줄 밖으로 뺀다. 나중에 뭘 더 붙여도 로고를 못 덮는다. */
.hud {
  position:absolute; top:calc(env(safe-area-inset-top) + .7rem); left:.8rem; right:38%;
  display:flex; align-items:center; justify-content:flex-start; gap:.45rem;
  flex-wrap:nowrap;
}
.rec {
  display:flex; align-items:center; gap:.35rem; background:var(--hot);
  color:#fff; padding:.3rem .7rem; border-radius:var(--r-pill);
  font-size:.71rem; font-weight:700; letter-spacing:.08em;
  border:2px solid var(--on-stage);
}
/* ⚠️⚠️ **「REC」가 오른쪽으로 치우쳐 보였다.** 앞의 점이 깜빡일 때 `opacity:0`
   으로 **완전히 사라지는데 자리는 그대로 차지**해서, 왼쪽에 빈칸만 남고 글자가
   밀려난 것처럼 보인다(스크린샷이 딱 그 순간이었다).
   → 사라지지 않고 **흐려지기만** 한다. 「찍는 중」은 그대로 읽히고 자리는 안 흔들린다. */
.rec i {
  width:.45rem; height:.45rem; border-radius:50%; background:#fff;
  animation:blink 1s ease-in-out infinite;
}
@keyframes blink { 50% { opacity:.25; } }
/* 길이 배지 — ⚠️ **누르면 10→20→30 으로 돈다.** 아래 칩 세 개를 여기 합쳤다.
   찍는 동안에는 **남은 시간**이 뜨고 그때는 안 눌린다.
   ⚠️ 단위는 **소문자 `s`** 다. 대문자 `S` 는 지멘스(전기 단위)고, 시간의
      국제 표기는 소문자다. 화면에서도 대문자는 숫자만큼 커 보여서 튄다. */
.timer {
  background:rgba(0,0,0,.5); backdrop-filter:blur(6px);
  padding:.3rem .8rem; border-radius:var(--r-pill); color:#fff;
  font-family:var(--mono); font-size:.94rem; font-weight:700;
  font-variant-numeric:tabular-nums; border:2px solid rgba(255,248,242,.55);
  flex:0 0 auto; box-shadow:none; cursor:pointer; line-height:1.2;
}
.timer:active { transform:scale(.94); }
/* 찍는 중에는 고르는 것이 아니라 **읽는 것**이다 — 눌리는 티를 없앤다. */
.timer[data-live] { cursor:default; border-color:var(--hot); }
/* ⏱ 「이 미션은 20초를 권해요」 — 길이 배지 바로 밑. ⚠️ 배지에서 멀면 무엇을
   눌러야 하는지 모른다. 늘리고 나면 사라진다(할 말이 없어진다). */
.durhint {
  position:absolute; z-index:2; left:.8rem; top:calc(env(safe-area-inset-top) + 3.1rem);
  margin:0; padding:.24rem .6rem; border-radius:var(--r-pill);
  background:rgba(0,0,0,.5); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  color:#fff; font-size:.7rem; font-weight:700; white-space:nowrap;
}
.durhint[hidden] { display:none; }

/* ── 3 · 2 · 1 ────────────────────────────────────────────────────────────
   ⚠️⚠️ **숫자만 바뀌고 아무 일도 안 일어났다.** 크기는 컸는데 800ms 마다 글자만
      갈아끼우니 **세는 느낌이 없다** — 시작한다는 신호인데 시작하는 티가 안 났다.
   → 숫자마다 **밖에서 확 들어와 꽂히고**, 뒤로 **테가 한 번 퍼진다.**
     마지막 「1」이 지나면 화면이 한 번 번쩍한다(찍기 시작하는 지점).
   ⚠️ 애니메이션을 **다시 태우려면 클래스만 떼었다 붙여선 안 된다** — 브라우저가
      같은 프레임의 변화를 묶는다. JS 가 레이아웃을 한 번 읽어서 끊는다. */
.count {
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  font-family:var(--round); font-size:40vw; color:#fff; letter-spacing:-.04em;
  text-shadow:0 10px 60px rgba(0,0,0,.75), 0 0 0 rgba(255,90,60,0);
  pointer-events:none;
}
/* 숫자 자신 — 밖에서 들어와 꽂힌다. */
.count b {
  display:block; font-weight:400; line-height:1;
  animation:countpunch .8s cubic-bezier(.15,.85,.3,1) both;
}
/* 뒤로 퍼지는 테. ⚠️ 숫자와 **같이** 커지면 안 보인다 — 숫자가 멈춘 뒤에 퍼진다.
   ⚠️⚠️⚠️ **애니메이션을 `[data-tick]` 뒤로 옮겼다.** 이 테는 숫자(`b`)와 달리
   `#count` **자기 자신**에 붙는 `::after` 다 — 숫자는 매번 새 요소로 갈아
   끼워서 애니메이션이 다시 도는데, `::after` 는 그 그릇(`#count`)이 안
   바뀌니 "3"에서 한 번 돈 뒤로는 다시 안 돌았다("3만 애니메이션 되고
   2·1은 가만히 있다"). → `[data-tick]` 을 매 숫자마다 껐다 켜서
   (`countdown()` 참고) 여기서도 다시 트리거되게 한다. */
.count::after {
  content:""; position:absolute; top:50%; left:50%;
  width:44vw; height:44vw; margin:-22vw 0 0 -22vw;
  border:.55rem solid var(--hot); border-radius:50%;
}
.count[data-tick]::after { animation:countring .8s ease-out both; }
.count[data-go] { background:rgba(255,255,255,.9); animation:countflash .32s ease-out both; }
.count[data-go] b, .count[data-go]::after { display:none; }
@keyframes countpunch {
  0%   { transform:scale(2.6); opacity:0; filter:blur(6px); }
  22%  { transform:scale(.92); opacity:1; filter:blur(0); }
  34%  { transform:scale(1.06); }
  46%  { transform:scale(1); }
  100% { transform:scale(1); opacity:1; }
}
@keyframes countring {
  0%   { transform:scale(.35); opacity:0; }
  24%  { transform:scale(.62); opacity:.85; }
  100% { transform:scale(1.5); opacity:0; }
}
/* 「시작」 순간 한 번 번쩍. ⚠️ **짧아야 한다** — 길면 첫 장면이 하얗게 날아간다. */
@keyframes countflash {
  0%   { opacity:.9; }
  100% { opacity:0; }
}
/* ⚠️ 흔들리는 화면을 못 견디는 사람에게는 숫자만. 세는 일 자체는 그대로 된다. */
@media (prefers-reduced-motion: reduce) {
  .count b { animation:none; }
  .count::after, .count[data-go] { display:none; }
}
/* ⚠️ display 를 직접 준 요소는 [hidden] 규칙을 같이 써야 한다.
      브라우저 기본 `[hidden]{display:none}` 은 우리가 준 display 에 밀린다.
      네 번째는 `.rec`(촬영 끝나도 REC 배지가 안 사라졌다),
      다섯 번째는 이 주석 자체였다 — 닫힌 주석 뒤에 설명을 덧붙이는 바람에
      그 글자가 선택자에 붙어서 **아래 규칙 전체가 통째로 죽었다.**
      CSS 는 규칙 하나가 깨져도 조용하다. 그래서 브라우저에서 computed style 로
      확인하지 않으면 모른다(소스를 grep 하는 검사는 이걸 못 잡는다).

      규칙: `display:` 를 주는 선택자를 쓸 때 그 자리에서 `[hidden]` 도 같이 적는다. */
.count[hidden], .cue[hidden], .status[hidden], .rec[hidden],
.optrow[hidden], .stats[hidden], .mascot[hidden],
button[hidden], .row[hidden], .opts[hidden] { display:none; }

/* ⚠️⚠️ **읽을 문장이 촬영 버튼을 덮고 있었다.** 「다 했으면 씩 웃기」가 버튼
   한가운데 겹쳐서, 글자도 안 읽히고 버튼도 안 보였다.
   ⚠️ 촬영 버튼은 **카메라 화면 안쪽 아래**에 얹혀 있다(위아래 검은 띠를 쓰려고).
      그래서 `.cue` 의 「아래」는 버튼이 이미 쓰는 자리다 — 그 위로 올린다.
      효과 이름표(7.4rem)보다도 위여야 한다. 재서 맞춘 값이다(check.mjs 📷). */
.cue {
  position:absolute; left:0; right:0; bottom:9.6rem; padding:0 1.2rem;
  text-align:center; font-size:1.1rem; font-weight:800; color:#fff;
  letter-spacing:-.02em; text-shadow:0 2px 16px rgba(0,0,0,.95); pointer-events:none;
}
.status {
  position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:1rem; padding:2rem 1.5rem;
  text-align:center; pointer-events:none;
}
.status p {
  margin:0; font-size:.94rem; font-weight:700; color:var(--on-stage-2);
  max-width:22rem; line-height:1.65; white-space:pre-line;
}
.status button { pointer-events:auto; flex:0 0 auto; }

/* ── 옵션 줄 ──
   ⚠️ 처음엔 버튼 하나를 계속 눌러 순환시켰다. 뭐가 있는지 안 보여서
      "선택 화면이 없다"는 말을 들었다. 고를 수 있는 건 펼쳐 보여야 한다. */
.optrow { display:flex; align-items:center; gap:.55rem; }
.optlabel {
  flex:0 0 3rem; font-size:.73rem; font-weight:700; color:var(--on-stage-2);
  letter-spacing:-.01em;
}
.opts { display:flex; gap:.35rem; flex:1; min-width:0; }
/* ⚠️ 방에서 고르는 미션 종류는 **줄로 접어서 다 보인다.** 가로 스크롤이면
   오른쪽 것이 화면 밖에 있어서 **고를 수 있는 줄도 모른다** — 9개가 3줄로
   한눈에 들어와야 "여러 개 고르는 자리"라는 게 읽힌다. */
#roomCats, #roomNewCats {
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:.4rem;
  overflow:visible; flex:none;
}
#roomCats .opt, #roomNewCats .opt {
  flex:none; width:100%; min-width:0; padding:.55rem .3rem; font-size:.82rem;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
@media (max-width:22rem){
  #roomCats, #roomNewCats { grid-template-columns:repeat(2,minmax(0,1fr)); }
}
#roomOwnerOps { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.4rem; flex:none; }
#roomOwnerOps .opt { flex:none; width:100%; font-size:.8rem; }
.prompt-now {
  font-family:var(--round); font-size:1.15rem; margin:.25rem 0 .5rem;
}
.opt {
  flex:1; padding:.5rem .3rem; font-size:.78rem; font-weight:700;
  border-radius:var(--r-pill); white-space:nowrap; text-align:center;
  overflow:hidden; text-overflow:ellipsis; cursor:pointer;
  background:var(--stage-2) !important; color:var(--on-stage-2) !important;
  border:2px solid rgba(255,248,242,.35) !important; box-shadow:none !important;
}
.opt[data-on] {
  background:var(--hot) !important; color:#fff !important;
  border-color:var(--on-stage) !important;
}
.opt:active { transform:translate(1px,1px); }
.pickfile { display:flex; align-items:center; justify-content:center; }

/* 밝은 화면(보관함)에 놓인 옵션 줄 */
.optrow.light .optlabel { color:var(--ink-2); }
.optrow.light .opt {
  background:var(--sheet) !important; color:var(--ink-2) !important;
  border:1.5px solid var(--edge) !important; box-shadow:var(--pop-sm) !important;
}
.optrow.light .opt[data-on] { background:var(--hot) !important; color:#fff !important; }

/* ── 고르기만 하는 것 = 드롭다운 ──
   ⚠️⚠️ **고를 칸이 너무 많아 조잡했다.** 장르 5칸 + 크기 3칸 + 곡 5칸이 전부
      같은 도장 버튼이라 **세 줄이 같은 무게로** 쌓였고, 화면이 칸으로만 찼다.
      「고를 수 있는 건 펼쳐 보여야 한다」는 규칙은 **눈으로 훑어야 하는 것**
      (미션 종류·곡)에만 해당한다. 장르·크기처럼 **답이 짧고 하나만 고르는 것**은
      드롭다운 하나가 지금 상태까지 같이 말해준다.
   ⚠️ 어두운 촬영 화면과 밝은 화면 양쪽에 놓인다. 기본은 어두운 쪽. */
.pickrow { display:flex; gap:.5rem; align-items:flex-end; }
.pickrow[hidden] { display:none; }
.pick { flex:1; min-width:0; display:flex; flex-direction:column; gap:.22rem; }
.pick[hidden] { display:none; }
.pick > span {
  font-size:.73rem; font-weight:700; color:var(--on-stage-2); letter-spacing:-.01em;
}
.pick select {
  width:100%; box-sizing:border-box; appearance:none;
  padding:.5rem 1.7rem .5rem .7rem;
  font-family:var(--sans); font-size:.85rem; font-weight:800; letter-spacing:-.02em;
  border-radius:var(--r-pill); cursor:pointer;
  background:var(--stage-2); color:var(--on-stage);
  border:2px solid rgba(255,248,242,.35);
  /* 화살표는 그려서 넣는다 — 기본 화살표는 기기마다 다르게 생겨서 한 벌로 안 보인다. */
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23FFF8F2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right .65rem center; background-size:.7rem;
}
.pickrow.light .pick > span { color:var(--ink-2); }
.pickrow.light select {
  background-color:var(--sheet); color:var(--ink); border:1.5px solid var(--edge);
  box-shadow:var(--pop-sm);
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%237A6F66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* ── 한 줄 좌우 스크롤 (곡 고르기) ──
   ⚠️ 곡 다섯 개가 **세 줄로 접혀** 흘렀다. 줄바꿈은 칸이 다섯을 넘으면 화면을
      통째로 먹는다.
   ⚠️ 예전에 「가로 스크롤이면 오른쪽 것이 화면 밖이라 있는 줄도 모른다」고
      줄바꿈으로 바꿨었다. **그 걱정은 오른쪽 끝 그림자로 푼다** — 잘린 그림자가
      보이면 "더 있다"가 읽힌다. 스크롤바는 폰에서 안 보이므로 그것만 믿지 않는다. */
.rail { position:relative; overflow:hidden; }
.rail[hidden] { display:none; }
.rail > .opts {
  flex-wrap:nowrap; overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x proximity; padding-right:1.2rem;
  -ms-overflow-style:none; scrollbar-width:none;
}
.rail > .opts::-webkit-scrollbar { display:none; }
.rail > .opts > .opt { flex:0 0 auto; scroll-snap-align:start; padding:.5rem .8rem; }
/* 오른쪽 끝 그림자 — "더 있다"를 말한다. */
.rail::after {
  content:""; position:absolute; top:0; right:0; bottom:0; width:1.6rem;
  pointer-events:none;
  background:linear-gradient(to right, rgba(24,22,21,0), var(--stage));
}
.rail.light::after { background:linear-gradient(to right, rgba(255,248,242,0), var(--paper)); }

/* ── 보관함 ── */

.clip video {
  width:3.2rem; height:5.6rem; object-fit:cover; background:#000; flex:0 0 auto;
  border-radius:12px; border:1.5px solid var(--edge);
}
.clip .meta { flex:1; min-width:0; }
.clip .meta b { display:block; font-size:.92rem; font-weight:800; letter-spacing:-.02em; }
.clip .meta span {
  display:block; font-size:.69rem; color:var(--ink-3); margin-top:.22rem;
}

/* 올린 뒤 시트 */


/* 하단 탭 — 3개 + 가운데 ⬤
   ⚠️ 그림문자(🏠🙂)를 쓰다가 선 아이콘으로 바꿨다. 그림문자는 기기마다 모양과
      크기가 달라서 셋을 나란히 놓으면 높이가 안 맞고 지저분해진다. */
/* ⚠️ 키보드가 올라오면 탭바가 그 뒤로 숨는다. `--kb` 만큼 띄운다.
   (입력 중에 탭을 누를 일은 없지만, 안 띄우면 키보드와 겹쳐 보여서 지저분하다) */
.tabbar {
  position:fixed; left:0; right:0; bottom:var(--kb, 0px); z-index:40;
  display:grid; grid-template-columns:1fr 4.6rem 1fr; align-items:center;
  padding:.35rem .5rem calc(.35rem + env(safe-area-inset-bottom));
  background:var(--sheet); border-top:2px solid var(--ink-2, rgba(0,0,0,.12));
}
.tabbar .tab {
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.15rem; background:none; border:0; box-shadow:none; padding:.4rem 0;
  font-size:.68rem; font-weight:700; color:var(--ink-3); cursor:pointer;
  letter-spacing:-.02em;
}
.tabbar .tab .ti {
  width:1.45rem; height:1.45rem; display:block;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}
.tabbar .tab[data-on] { color:var(--hot); }
/* ⚠️ 가운데 칸을 고정폭으로 두고 그 안에서 가운데 정렬한다.
      1fr auto 1fr 로 두면 좌우 글자 길이("홈" vs "나")에 따라 ⬤ 가 밀린다. */
.tabbar .fab {
  display:flex; align-items:center; justify-content:center;
  width:3.5rem; height:3.5rem; margin:-1.6rem auto 0; padding:0;
  border-radius:50%; background:var(--hot); color:#fff;
  border:2px solid var(--edge-strong); box-shadow:var(--pop); cursor:pointer;
}
.tabbar .fab svg {
  width:1.6rem; height:1.6rem; display:block;
  fill:none; stroke:currentColor; stroke-width:2.6; stroke-linecap:round;
}
.tabbar .fab:active { transform:translateY(2px); }
/* ⚠️ 탭이 화면 아래를 덮는다. 안 비우면 「만들기」 같은 버튼이 뒤에 깔려
      "메뉴가 없다"로 보인다 — 실제로 그렇게 보였다. */
.screen[data-tabbed] .pad { padding-bottom:6rem; }
.screen[data-tabbed] > .dock { padding-bottom:5.2rem; }

/* ⚠️ **display 를 준 요소는 [hidden] 도 같이 적어야 한다**(289줄 규칙).
      이걸 빠뜨려서 촬영 화면에서도 탭이 떠서 버튼을 가렸다. 규칙이 있는데도
      또 밟았다 — display 를 쓰는 순간 같은 줄에서 [hidden] 을 적을 것. */
.tabbar[hidden] { display:none; }

/* 출석 도장 — ⚠️ 규칙이 통째로 지워져서 "도장누르면2점" 으로 붙어 나왔다.
   ⚠️ 한 줄로 낮춘다. 매일 누르는 것에 카드 한 장을 통째로 주면 화면만 먹는다. */
.stamp {
  display:flex; align-items:center; gap:.55rem; width:100%; text-align:left;
  background:var(--sheet); border:1.5px solid var(--edge); box-shadow:var(--pop-sm);
  border-radius:var(--r-pill); padding:.5rem .8rem; margin-bottom:.45rem; cursor:pointer;
}
.stamp[hidden] { display:none; }
/* ⚠️ 줄 아이콘은 **주황**이다 — 줄마다 다른 그림이라 색까지 다르면 소란스럽다.
   하는 일은 그림이 말하고, 색은 「여기가 누를 자리」만 말한다. */
.stamp .ico { font-size:1.05rem; line-height:1; flex:0 0 auto; display:flex; color:var(--hot); }
.stamp .txt { flex:1; min-width:0; display:flex; align-items:baseline; gap:.4rem;  flex-wrap:wrap; }
.stamp .txt b  { font-size:.88rem; font-weight:800; white-space:nowrap;  white-space:normal; }
.stamp .txt em {
  font-size:.75rem; font-weight:700; font-style:normal; color:var(--ink-3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.stamp .go { font-size:1rem; font-weight:800; color:var(--ink-3); flex:0 0 auto; }
.stamp[data-done] { background:var(--hot-soft); }
.stamp[data-done] .go { color:var(--hot); }

/* 광고 고르기 — 길이·포인트가 광고마다 다르니 고르기 전에 보여야 한다. */
.adcard {
  display:flex; flex-direction:column; align-items:flex-start; gap:.08rem;
  text-align:left; padding:.55rem .8rem; border-radius:16px; line-height:1.3;
  max-width:100%;
}
.adcard[hidden] { display:none; }
.adcard b   { font-size:.92rem; font-weight:800; }
.adcard span{ font-size:.8rem; font-weight:800; }
.adcard em  {
  font-size:.7rem; font-style:normal; font-weight:700; color:var(--ink-3);
  max-width:11rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.adcard[data-on] { outline:3px solid var(--hot); }

/* 팔로워 등급 — ⚠️ 이 규칙도 같이 지워져서 "씨앗1,000 미만300P" 로 붙어 나왔다. */
.tiers { display:flex; flex-direction:column; gap:.3rem; margin:.45rem 0 .7rem; }
.tiers[hidden] { display:none; }
.tierrow {
  display:flex; align-items:center; gap:.5rem; font-size:.82rem; font-weight:800;
  border:1.5px solid var(--edge); border-radius:var(--r-pill); padding:.38rem .75rem;
  background:var(--sheet);
}
.tierrow b   { flex:0 0 auto; }
.tierrow .who{ flex:1; min-width:0; color:var(--ink-3); font-weight:700; font-size:.74rem;
               overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tierrow .mul{ flex:0 0 auto; font-weight:800; color:var(--hot); }
.tierrow[data-me] { background:var(--hot-soft); }

/* ⚠️ 「올린 영상」 규칙이 **여기 또 있었다.** 위(713행)에 이미 있는데 통째로
   한 벌 더 붙어서, 버튼을 가로로 눕히는 규칙을 **뒤에서 다시 세로로** 돌려놨다.
   고쳤는데 화면이 안 바뀌던 이유가 이것이다. 지웠다 — 진짜는 위에 있다. */

/* 올린 뒤 시트 */
.sheet { border:2px solid var(--edge-strong); border-radius:22px; padding:1.1rem;
  width:min(21rem,90vw); background:var(--sheet); color:var(--ink);
  box-shadow:var(--pop); }
.sheet::backdrop { background:rgba(0,0,0,.5); }

/* ── 영상 크게 보기 ──
   ⚠️ **세로 영상은 화면을 꽉 채워야 한다.** 9:16 을 가로로 넓은 상자에 넣으면
      위아래가 잘리거나 양옆에 검은 띠만 남는다. 높이를 기준으로 잡고 폭은
      비율이 정한다.
   ⚠️ 배경을 **검게** 한다. 종이 질감 위에 영상을 얹으면 영상이 카드처럼 보여서
      "보고 있다"는 느낌이 안 난다. */
.viewer {
  border:0; padding:0; background:transparent; max-width:100vw; max-height:100vh;
  width:100vw; height:100dvh; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:.6rem; overflow:hidden;
}
.viewer::backdrop { background:rgba(0,0,0,.92); }
.viewer:not([open]) { display:none; }
/* ⚠️⚠️ **반응 줄이 영상 밖 검은 띠에 떠 있었다.** 영상은 9:16 인데 화면은 20:9 라
   위아래에 검은 자리가 남는데, 자리를 **화면 기준**으로 잡으니 그 검은 데 얹혔다.
   → **영상과 똑같은 크기의 틀**을 두고 그 안에 얹는다. 어떤 폰에서도 영상 위다. */
.viewer .vstage {
  position:relative; width:100vw; max-width:calc(100dvh * 9 / 16);
  aspect-ratio:9/16; max-height:100dvh; background:#000; overflow:hidden;
}
.viewer video {
  width:100%; height:100%; object-fit:contain; background:#000; display:block;
}
/* ⚠️⚠️ **크게 보는 자리에서 할 수 있는 게 아무것도 없었다.** 하트·댓글이 카드에만
   있어서 반응하려면 닫고 내려가서 눌러야 했다 — 그 사이에 반응할 마음이 사라진다.
   숏폼 앱이 전부 영상 위 오른쪽에 두는 이유다(엄지가 닿고 그림을 안 먹는다).
   ⚠️ 아래는 재생 막대가 덮으므로 **위에서부터** 쌓는다. */
/* ⚠️⚠️ **오른쪽 세로 → 아래 가로로 옮겼다가 되돌린다.** 얼굴을 덮는 게 싫어서
   아래로 내렸는데, 그건 **틱톡·스냅챗이 왜 오른쪽에 두는지**를 무시한 것이다 —
   영상을 전체로 띄우고 그 위 **오른쪽 아래**에 세로로 쌓으면, 그림의 가운데는
   안 가리면서 엄지가 닿는다. 아래 가로 줄은 영상을 그만큼 줄인다.
   ⚠️ **아래에서부터** 쌓는다(위가 아니라). 재생 막대 위, 엄지가 닿는 높이다. */
/* ⚠️ 자리는 **영상 틀 기준**이다(`.vstage`). 화면 기준으로 잡으면 검은 띠에 얹힌다. */
.viewer .vrail {
  position:absolute; right:.7rem; bottom:4.4rem; z-index:4;
  display:flex; flex-direction:column; gap:1.1rem; align-items:center;
}
.viewer .vrbtn {
  background:none; border:0; box-shadow:none; padding:0; cursor:pointer; flex:0 0 auto;
  display:flex; flex-direction:column; align-items:center; gap:.2rem;
  color:#fff; filter:drop-shadow(0 1px 4px rgba(0,0,0,.8));
}
/* ⚠️ **그림이 안 보였다.** `.ti` 에는 색 규칙이 없어서 어두운 배경에 검은 그림이
   그려졌다 — 숫자만 떠 있고 뭐가 뭔지 알 수가 없었다. 여기서 못박는다. */
.viewer .vrbtn .ti {
  width:1.65rem; height:1.65rem; display:block;
  fill:currentColor; stroke:none;
}
/* 👁 눈과 ↥ 공유는 **선으로 그린 그림**이라 채우면 뭉개진다. */
.viewer .vrbtn.line .ti, .viewer .vrbtn:has(use[href="#i-up"]) .ti {
  fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round;
}
.viewer .vrbtn em { font-style:normal; font-size:.72rem; font-weight:700; }
.viewer .vrbtn:active { transform:scale(.9); }
/* 눌렀으면 **채워진다.** 색만 바뀌면 눌렀는지 아닌지 헷갈린다. */
.viewer .vrbtn[data-on] { color:var(--hot); }
/* 조회수는 **누르는 것이 아니다.** 흐리게 두어 눌러볼 마음이 안 들게 한다. */
.viewer .vrbtn:disabled { opacity:.7; }
/* 👁 카드 아래 줄의 조회수도 같은 이유로 버튼이 아니다. */
.reacts .react.seen { cursor:default; opacity:.75; }

/* ⚠️ 영상이 화면을 꽉 채우므로 제목도 **영상 위**에 얹는다. 아래 왼쪽 —
   오른쪽은 반응 줄 자리다. */
.viewer .vtitle {
  position:absolute; left:1rem; right:5rem; bottom:4.6rem; z-index:4;
  margin:0; color:#fff; font-size:.86rem; font-weight:700; text-align:left;
  text-shadow:0 1px 4px rgba(0,0,0,.9);
}
/* ⚠️ 닫는 버튼은 **영상 위**에 띄운다. 아래에 두면 컨트롤 막대와 겹쳐서
   누를 때마다 재생이 멈춘다. */
.viewer .vclose {
  position:fixed; top:max(.7rem, env(safe-area-inset-top)); right:.7rem; z-index:2;
  width:2.4rem; height:2.4rem; border-radius:50%; border:0; box-shadow:none;
  background:rgba(0,0,0,.55); color:#fff; font-size:1.1rem; font-weight:800;
  display:grid; place-items:center; cursor:pointer; padding:0;
}
.sheet h3 { font-size:1.05rem; font-weight:800; margin-bottom:.25rem; }
.sheet .muted { color:var(--ink-3); margin-bottom:.8rem; }
.sheet button { width:100%; margin-top:.45rem; }
.sheet button[hidden] { display:none; }
.linkrow { display:flex; gap:.4rem; margin-bottom:.5rem; }
.linkrow input { flex:1; min-width:0; font-size:.78rem; font-weight:700;
  border:1.5px solid var(--edge); border-radius:var(--r-pill); padding:.5rem .7rem;
  background:var(--sunk); color:var(--ink); }
.linkrow button { width:auto; margin:0; flex:0 0 auto; }

/* 상황극 배역 */
.roles { display:flex; flex-direction:column; gap:.4rem; margin-top:.55rem; }
.roles[hidden] { display:none; }
.role {
  display:flex; align-items:center; gap:.55rem; background:var(--sheet);
  border:1.5px solid var(--edge); box-shadow:var(--pop-sm); border-radius:var(--r-pill);
  padding:.45rem .5rem .45rem .85rem; font-size:.86rem; font-weight:800;
}
.role[data-done] { background:var(--hot-soft); }
.rname { flex:0 0 auto; }
.rwho { flex:1; min-width:0; font-size:.76rem; font-weight:700; color:var(--ink-3);
        overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.role[data-done] .rwho { color:var(--hot); }
.role button { flex:0 0 auto; }

/* 방 채팅 */
/* ── 이야기(채팅) ──
   ⚠️ **화면을 다 쓴다.** 예전엔 11rem 짜리 상자가 위쪽에만 붙어 있어서 대화가
      여섯 줄만 보이고 화면 3분의 2가 비어 있었다. 채팅은 **읽는 화면**이다.
   ⚠️ `--kb` 는 키보드 높이다(app.js). 키보드가 올라온 만큼 화면을 줄여야
      입력칸이 그 위에 남는다. 안 그러면 글을 쓰는 칸이 키보드에 가린다. */
/* ⚠️⚠️ **`display:` 를 여기 적으면 안 된다.** `#s-chat` 은 id 라 `.screen` 보다
   세다. `display:flex` 를 적었더니 `.screen { display:none }` 을 이겨서
   **이야기 화면이 모든 화면 위에 늘 떠 있었다** — 홈에도 마이페이지에도
   「이야기」 글자가 겹쳐 나오고 홈으로 아예 못 들어갔다.
   `.screen[data-active]` 가 이미 `display:flex` + `flex-direction:column` 을
   준다. **여기서는 크기만 정한다.**
   ⚠️ 이 파일 위쪽에 `[hidden]` 으로 같은 실수를 세 번 했다고 적어뒀는데,
     그때는 전부 class 였다. **id 로 또 밟았다** — 규칙을 "hidden 조심"이 아니라
     **"화면 선택자에 display 를 쓰지 않는다"** 로 넓혀 적는다. */
#s-chat { height:100dvh; overflow:hidden; }
.chatwrap {
  flex:1; min-height:0; display:flex; flex-direction:column;
  padding:0 .9rem calc(.7rem + var(--kb, 0px));
}
.chat {
  flex:1; min-height:0; display:flex; flex-direction:column; gap:.5rem;
  overflow-y:auto; padding:.2rem .1rem .6rem;
}
/* ⚠️ **`justify-content:flex-end` 를 쓰면 안 된다.** 대화가 짧을 때 아래로
   붙이려고 넣었는데, 넘칠 때 **위쪽이 스크롤로 닿지 않는 곳으로 잘려나간다** —
   지난 대화를 보려고 올려도 안 올라갔다. 같은 일을 첫 칸의 `margin-top:auto`
   로 하면 짧을 때는 아래로 붙고 넘칠 때는 정상으로 스크롤된다. */
.chat > :first-child { margin-top:auto; }
.chat[hidden] { display:none; }
.chatsend {
  flex:0 0 auto; display:flex; gap:.45rem; align-items:center;
  padding-top:.5rem; border-top:1px solid var(--line);
}
.chatsend .field { flex:1; min-width:0; }
.chatsend button { flex:0 0 auto; }

/* ── 말 한 줄 ──
   ⚠️ **누가 말했는지 왼쪽에 얼굴이 있어야 한다.** 이름만 앞에 붙여두니
      「잭희 (나) 어디냐」가 줄줄이 이어져서 누가 말했는지 훑기가 어려웠다.
      사진이 없으면 **이름 첫 글자**로 만든다 — 빈 동그라미보다 낫다. */
.msg { display:flex; align-items:flex-start; gap:.5rem; font-size:.88rem; line-height:1.45; }
.msg .face {
  flex:0 0 auto; width:2rem; height:2rem; border-radius:50%;
  border:1.5px solid var(--edge); background:var(--ink-3); color:#fff;
  display:grid; place-items:center; overflow:hidden;
  font-size:.82rem; font-weight:800; text-transform:uppercase;
}
.msg .face img { width:100%; height:100%; object-fit:cover; }
.msg .said { flex:1; min-width:0; }
.msg .said b { display:block; font-size:.7rem; font-weight:700; color:var(--ink-3); }
.msg .said span {
  display:inline-block; background:var(--sunk); border-radius:12px 12px 12px 4px;
  padding:.35rem .6rem; overflow-wrap:anywhere;
}
/* ⚠️ 내 말은 **오른쪽**으로. 그래야 훑을 때 남의 말만 눈에 들어온다. */
.msg[data-me] { flex-direction:row-reverse; }
.msg[data-me] .said { text-align:right; }
.msg[data-me] .said span {
  background:var(--hot); color:#fff; border-radius:12px 12px 4px 12px; text-align:left;
}/* 설정 */

/* ── 줄을 누르면 열리는 칸 ──
   ⚠️⚠️ **`.pwbox` 규칙이 아예 없었다.** `.danger` 일 때 테두리 색만 있고 정작
      기본 모양이 없어서, 안내문·입력칸 셋·버튼이 **여백 없이 그대로 겹쳐 붙었다** —
      비밀번호 칸 세 개가 한 덩어리로 보여서 몇 칸인지도 안 읽혔다.
      (`.field` 에는 margin 이 없다. 사이 여백은 담는 쪽이 준다.)
   ⚠️ **누른 줄에 딸린 것으로 보여야 한다.** 그래서 안쪽으로 한 칸 들여쓰고
      왼쪽에 줄을 세운다 — 다른 줄과 같은 높이로 두면 별개의 목록으로 읽힌다. */
/* ⚠️⚠️ **왼쪽 여백 `.55rem`(8.8px) 때문에 세로 선이 본문 열에서 밀려 있었다.**
   이 상자의 정체는 「왼쪽에 선을 긋고 안으로 들여쓴 곁가지」인데, 그 **선 자체가**
   위아래 형제들(입력칸·버튼)의 왼쪽 끝과 안 맞으니 화면이 통째로 어긋나 보였다.
   → 선을 본문 열에 **붙인다.** 들여쓰기는 선 안쪽 `padding` 이 이미 하고 있다.
   ⚠️ 여백을 조금 주면 "떠 있는 느낌"이 날 것 같지만, 기준선이 둘이 되는 게 더 나쁘다. */
.pwbox {
  display:flex; flex-direction:column; gap:.45rem;
  margin:-.1rem 0 .7rem; padding:.15rem 0 .15rem .75rem;
  border-left:2px solid var(--edge);
}
.pwbox[hidden] { display:none; }
/* 안내문은 칸 바로 위에 붙는다 — 기본 여백이 남아 있으면 줄과 따로 논다. */
.pwbox .tip { margin:0 0 .1rem; }
/* ⚠️ **버튼이 「카드」로 보일 만큼 두꺼웠다** — "인증번호받기 카드는 왜이렇게
   세로로 두꺼운거야". 전역 버튼 여백(.95rem)은 화면의 **주된 행동**용이다.
   여기 것들은 막혔을 때 쓰는 곁길이라 `.sm` 으로 낮춘다.
   ⚠️ 다른 이야기가 시작되는 버튼(「이메일이 기억 안 나요」)만 한 칸 띄운다. */
.pwbox button.mt { margin-top:.55rem; }

/* ✍️ 빈칸 채우기 — ⚠️ **읽었던 그 문장을 그대로 보여주고** 그 밑에 칸을 둔다.
   문장 없이 칸만 있으면 뭘 적으라는 건지 모른다. */
.fillrow { margin-bottom:.5rem; }
.fillsay {
  display:block; font-size:.84rem; font-weight:700; color:var(--ink-2);
  margin-bottom:.2rem;
}
.fillrow .field { font-size:.88rem; padding:.5rem .7rem; }
/* ── ✂️ 다듬기 (확인 화면) ──
   ⚠️ 어두운 화면 위라 밝은 화면용 `.pwbox` 색을 그대로 쓰면 안 보인다. */
#s-review .trimbox { border-left-color:rgba(255,248,242,.35); margin:.2rem 0 .6rem; }
#s-review .trimbox summary {
  font-size:.85rem; font-weight:800; color:var(--on-stage); cursor:pointer;
  list-style:none; padding:.15rem 0;
}
#s-review .trimbox summary::-webkit-details-marker { display:none; }
#s-review .trimbox summary::before { content:"＋ "; color:var(--hot); font-weight:800; }
#s-review .trimbox[open] summary::before { content:"－ "; }
#s-review .trimbox summary .quiet { font-weight:700; opacity:.55; font-size:.76rem; }
#s-review .trimbox .eyebrow { color:var(--on-stage-2); }
#s-review .trimbox .tip { color:var(--on-stage-2); margin:.35rem 0 0; }
.trimrow { display:flex; align-items:center; gap:.5rem; margin-top:.3rem; }
.trimrow .lab {
  flex:0 0 2.1rem; font-size:.74rem; font-weight:700; color:var(--on-stage-2);
}
/* ⚠️ 잡는 높이가 24px 뿐이었다(자로 재서 찾았다). 보이는 선 굵기(3px)와
   손잡이 크기는 그대로 두고 **잡을 수 있는 높이만** 넓힌다. */
.trimrow input[type=range] {
  flex:1; min-width:0; height:2.4rem; margin:0; appearance:none; background:none;
}
.trimrow input[type=range]::-webkit-slider-runnable-track {
  height:3px; border-radius:3px; background:rgba(255,255,255,.32);
}
.trimrow input[type=range]::-webkit-slider-thumb {
  appearance:none; width:1.05rem; height:1.05rem; border-radius:50%;
  background:var(--hot); border:2px solid #fff; margin-top:-.52rem;
}
.trimrow input[type=range]::-moz-range-track {
  height:3px; border-radius:3px; background:rgba(255,255,255,.32);
}
.trimrow input[type=range]::-moz-range-thumb {
  width:1.05rem; height:1.05rem; border-radius:50%;
  background:var(--hot); border:2px solid #fff;
}

/* 탈퇴 사유 — ⚠️ 세로로 쌓는다. 문장이라 가로로 늘어놓으면 글자가 잘린다. */
.quitwhy { display:flex; flex-direction:column; gap:.3rem; margin:.15rem 0 .1rem; }
.quitwhy .opt {
  flex:none; width:100%; text-align:left; padding:.5rem .7rem; font-size:.82rem;
  white-space:normal;
  background:var(--sheet) !important; color:var(--ink-2) !important;
  border:1.5px solid var(--edge) !important; box-shadow:var(--pop-sm) !important;
}
.quitwhy .opt[data-on] {
  background:var(--bad) !important; color:#fff !important; border-color:var(--bad) !important;
}

.pwbox.danger { border-left-color:var(--bad); }
.pwbox.danger summary { color:#b42318; }

/* ⚠️ 상황·문제팩 칩이 한 줄에 욱여넣어져 글자가 잘렸다("택배 기|", "동창회(6)").
      flex 기본값이 줄여도 된다(shrink:1)라 여섯 개를 한 줄에 밀어넣은 탓이다.
      줄이지 말고 **줄바꿈**하게 둔다 — 가로 스크롤보다 눈에 다 보이는 게 낫다. */
.chips .chip, .opts .opt { flex:0 0 auto; white-space:nowrap; }

/* ⚠️ **`scrollx` 는 이름만 있고 규칙이 없었다.** `overflow-x` 를 준 곳이 어디에도
   없어서, 곡을 5~6개 올리면 오른쪽 것들이 그냥 **화면 밖으로 나가 안 보였다** —
   스크롤도 안 되니 고를 방법이 아예 없었다. 이름이 하는 일을 말해주지 않으면
   있는 줄 알고 넘어간다.
   ⚠️ 고치는 방향은 **가로 스크롤이 아니라 줄바꿈**이다. 이 파일 위쪽에 이미
   같은 결론이 적혀 있다 — "가로 스크롤이면 오른쪽 것이 화면 밖에 있어서
   **고를 수 있는 줄도 모른다**". 곡은 두세 줄로 다 보이는 게 맞다. */
.opts.scrollx { flex-wrap:wrap; row-gap:.35rem; }
.opts.scrollx .opt { flex:0 0 auto; max-width:100%; overflow:hidden; text-overflow:ellipsis; }
/* 그래도 긴 것은 줄인다. 잘리더라도 칩 모양은 유지돼야 한다. */
.chips .chip { max-width:100%; overflow:hidden; text-overflow:ellipsis; }

/* 하루 고정 표시 */
.daytag {
  font-size:.66rem; font-weight:700; color:var(--ink-3);
  border:2px solid var(--ink-3); border-radius:var(--r-pill);
  padding:.12rem .5rem; white-space:nowrap;
}
.daytag[hidden] { display:none; }

/* 🎲 뽑힌 미션 카드 */
.sheet.card { text-align:center; }

/* ── 🎲 진짜 주사위 ─────────────────────────────────────────────────────────
   ⚠️⚠️ **이모지 한 글자(🎲)를 흔들고 있었다.** 이 앱에서 제일 중요한 순간이
      "굴러서 정해지는" 그 1초인데, 정작 굴러가는 것이 2.4rem 짜리 **글자**였다.
      이모지는 기기마다 그림이 달라서 어떤 폰에서는 흰 네모가 흔들렸다.
   → **여섯 면짜리 육면체.** 튀어오르고, 돌고, 착지할 때 한 번 눌린다.
     그림자가 같이 커졌다 작아져야 **떠 있는 것**으로 보인다.
   ⚠️ **한 번의 애니메이션으로 끝낸다.** 「무한 회전 → 멈춤」으로 만들면 멈추는
      순간 각도가 툭 튄다(돌던 자리를 CSS 가 모른다). 시작부터 착지까지를
      한 타임라인에 적고, 마지막 각도는 `--rx`·`--ry` 로 매번 바꾼다.
   ⚠️ 착지 각도는 **여섯 면 중 하나**여야 한다. 아무 각도나 주면 모서리로 선다. */
.dicebox {
  --d: 5rem;
  position:relative; height:calc(var(--d) * 1.75);
  display:flex; align-items:flex-end; justify-content:center;
  perspective:600px; margin-bottom:.2rem;
}
/* 🎲 종류 꼬리표 — ⚠️ 가운데 글 무더기에서 빼내 **주사위 왼쪽 위**에 둔다.
   `position:absolute` 라 `.dicebox` 의 가운데 정렬(주사위)에는 안 끼어든다.
   ⚠️ `.sheet.card .eyebrow` 의 가운데 정렬·여백은 여기서 다시 눌러야 한다 —
   아이디 규칙(`#rollCat`)이 더 세서 이긴다.
   ⚠️ **미션 종류라는 걸 알려주는 꼬리표인데 글씨가 너무 작았다**(`.eyebrow`
      기본 .72rem). 카드에서 가장 먼저 읽히는 정보라 한 단계 키운다. */
#rollCat {
  position:absolute; top:0; left:0; margin:0; font-size:.92rem;
}
/* 🎲 이번 굴림 점수 — `#rollCat` 과 짝지어 **오른쪽 위**에 둔다.
   ⚠️ 방금 받은 것이라 **눈에 띄어야** 한다 — 종류 꼬리표와 같은 자리·모양
      이지만 색은 주황(hot)으로 구별한다. */
.eyebrow.score {
  position:absolute; top:0; right:0; left:auto; margin:0;
  font-size:.92rem; color:var(--hot); border-bottom-color:var(--hot);
}
.eyebrow.score[hidden] { display:none; }
.dicehop { transform-style:preserve-3d; }
.dice {
  position:relative; width:var(--d); height:var(--d);
  transform-style:preserve-3d;
  transform:rotateX(-24deg) rotateY(-32deg);
}
.dice .side {
  position:absolute; inset:0; border-radius:22%;
  background:linear-gradient(150deg, #FFFDFA, #F3E9DF);
  border:2px solid var(--ink);
  display:grid; grid-template-columns:repeat(3, 1fr); grid-template-rows:repeat(3, 1fr);
  padding:11%;
  backface-visibility:hidden;
}
/* 눈. ⚠️ 칸 안에서 가운데 — 칸을 채우면 눈이 아니라 네모가 된다. */
.dice .side i { width:76%; height:76%; border-radius:50%; background:var(--ink); place-self:center; }
/* ⚠️ 1 만 주황. 진짜 주사위가 그렇고, **우리 색이 한 번은 나와야** 우리 것으로 보인다. */
.dice .f1 i { background:var(--hot); width:88%; height:88%; }
/* 여섯 면을 세워 붙인다. 앞·뒤·오른·왼·위·아래 순서. */
.dice .f1 { transform:translateZ(calc(var(--d) / 2)); }
.dice .f6 { transform:rotateY(180deg) translateZ(calc(var(--d) / 2)); }
.dice .f3 { transform:rotateY(90deg)  translateZ(calc(var(--d) / 2)); }
.dice .f4 { transform:rotateY(-90deg) translateZ(calc(var(--d) / 2)); }
.dice .f2 { transform:rotateX(90deg)  translateZ(calc(var(--d) / 2)); }
.dice .f5 { transform:rotateX(-90deg) translateZ(calc(var(--d) / 2)); }
/* 눈 자리 — 3×3 칸에 못박는다. */
.dice .f1 i:nth-child(1) { grid-area:2/2; }
.dice .f2 i:nth-child(1) { grid-area:1/1; } .dice .f2 i:nth-child(2) { grid-area:3/3; }
.dice .f3 i:nth-child(1) { grid-area:1/1; } .dice .f3 i:nth-child(2) { grid-area:2/2; }
.dice .f3 i:nth-child(3) { grid-area:3/3; }
.dice .f4 i:nth-child(1) { grid-area:1/1; } .dice .f4 i:nth-child(2) { grid-area:1/3; }
.dice .f4 i:nth-child(3) { grid-area:3/1; } .dice .f4 i:nth-child(4) { grid-area:3/3; }
.dice .f5 i:nth-child(1) { grid-area:1/1; } .dice .f5 i:nth-child(2) { grid-area:1/3; }
.dice .f5 i:nth-child(3) { grid-area:2/2; } .dice .f5 i:nth-child(4) { grid-area:3/1; }
.dice .f5 i:nth-child(5) { grid-area:3/3; }
.dice .f6 i:nth-child(1) { grid-area:1/1; } .dice .f6 i:nth-child(2) { grid-area:2/1; }
.dice .f6 i:nth-child(3) { grid-area:3/1; } .dice .f6 i:nth-child(4) { grid-area:1/3; }
.dice .f6 i:nth-child(5) { grid-area:2/3; } .dice .f6 i:nth-child(6) { grid-area:3/3; }

/* 바닥 그림자 — ⚠️ 이게 없으면 **떠 있는 게 아니라 그냥 도는 것**으로 보인다.
   높이 뜰수록 작고 흐리게. 착지할 때 제일 진하다. */
.dicebox .diceshadow {
  position:absolute; left:50%; bottom:.15rem; width:calc(var(--d) * .8); height:.5rem;
  transform:translateX(-50%); border-radius:50%;
  background:rgba(34,30,28,.22); filter:blur(3px);
}
/* 착지 순간 퍼지는 테. ⚠️ 평소엔 없다 — 굴릴 때만 한 번. */
.dicebox .dicering {
  position:absolute; left:50%; bottom:0; width:var(--d); height:var(--d);
  transform:translate(-50%, 30%) scale(0); opacity:0;
  border:3px solid var(--hot); border-radius:50%; pointer-events:none;
}

/* 굴리는 동안 — 한 타임라인. 마지막 각도(`--rx`·`--ry`)는 JS 가 매번 바꾼다. */
.dicebox[data-roll] .dice { animation:diceroll 1.1s cubic-bezier(.2,.62,.3,1) forwards; }
.dicebox[data-roll] .dicehop { animation:dicehop 1.1s cubic-bezier(.4,0,.55,1) forwards; }
.dicebox[data-roll] .diceshadow { animation:diceshadow 1.1s cubic-bezier(.4,0,.55,1) forwards; }
.dicebox[data-roll] .dicering { animation:dicering .5s ease-out .82s forwards; }

@keyframes diceroll {
  0%   { transform:rotateX(-24deg) rotateY(-32deg); }
  70%  { transform:rotateX(calc(var(--rx) - 140deg)) rotateY(calc(var(--ry) - 90deg)); }
  100% { transform:rotateX(var(--rx)) rotateY(var(--ry)); }
}
/* 두 번 튄다. ⚠️ 착지에서 **한 번 눌러야**(scaleY) 무게가 느껴진다. */
@keyframes dicehop {
  0%   { transform:translateY(0)      scale(.7); }
  22%  { transform:translateY(-3.1rem) scale(1.04); }
  48%  { transform:translateY(0)      scaleY(.84) scaleX(1.1); }
  68%  { transform:translateY(-1.1rem) scale(1); }
  86%  { transform:translateY(0)      scaleY(.9) scaleX(1.06); }
  100% { transform:translateY(0)      scale(1); }
}
@keyframes diceshadow {
  0%   { transform:translateX(-50%) scale(.7);  opacity:.5; }
  22%  { transform:translateX(-50%) scale(.45); opacity:.16; }
  48%  { transform:translateX(-50%) scale(1.15); opacity:.5; }
  68%  { transform:translateX(-50%) scale(.75); opacity:.28; }
  100% { transform:translateX(-50%) scale(1);   opacity:.42; }
}
@keyframes dicering {
  0%   { transform:translate(-50%, 30%) scale(.2); opacity:.7; }
  100% { transform:translate(-50%, 30%) scale(1.9); opacity:0; }
}
/* ⚠️ **흔들리는 화면을 못 견디는 사람이 있다.** 그 사람에게는 결과가 먼저다 —
   구르는 맛보다 앱을 쓸 수 있는 게 위다(rollThenShow 가 시간도 줄인다). */
@media (prefers-reduced-motion: reduce) {
  .dicebox[data-roll] .dice,
  .dicebox[data-roll] .dicehop,
  .dicebox[data-roll] .diceshadow,
  .dicebox[data-roll] .dicering { animation:none; }
}
.sheet.card .eyebrow { justify-content:center; margin:.3rem 0 .1rem; }
.sheet.card h3 { font-size:1.25rem; line-height:1.3; margin-bottom:.35rem; }
.sheet.card .facts {
  /* ⚠️⚠️ **`<ul>` 은 지워도 `padding-left`(브라우저 기본 40px쯤)는 안 지워진다.**
     `list-style:none` 은 점만 없앨 뿐이다 — 그 자리를 남겨두는 여백은 그대로
     남아서, 안의 칸들이 왼쪽은 그 여백만큼 비고 **오른쪽으로 쏠려** 보였다. */
  list-style:none; text-align:left; margin:.7rem 0 .3rem; padding:0;
  display:flex; flex-direction:column; gap:.28rem;
}
.sheet.card .facts li {
  font-size:.82rem; font-weight:700; color:var(--ink-2);
  background:var(--sunk); border-radius:12px; padding:.4rem .65rem;
}
/* ⏱ **길이를 여기서 바꾼다.**
   ⚠️ 예전엔 「⏱ 5초」가 그냥 글씨라 **정해진 값처럼 보였다.** 실제로 바꾸는
      자리는 카메라 안의 작은 배지뿐이었는데, 거기까지 가야 바꿀 수 있다는 걸
      아는 사람이 없다. 눌리는 자리는 **눌리게 생겨야** 한다.
   ⚠️ 칸(li) 여백을 0 으로 두고 버튼이 그 여백을 갖는다 — 안 그러면 글씨
      주변만 눌리고 칸 가장자리는 안 눌려서 "안 눌린다"가 된다.
   ⚠️ button 에 걸린 전역 `flex:1` 이 여기까지 오면 폭이 어그러진다. 못 박는다. */
.sheet.card .facts li.pickrow { padding:0; background:none; }
/* 📣 이 카드에서 **가장 먼저 따라야 할 것 한 줄** — "3줄 대사를 읽어주세요"
   같은 지시문. ⚠️⚠️ **예전엔 「⏱ 길이 바꾸기」가 맨 위였다.** 목록 맨 위는
   "이거부터 확인·조작하라"로 읽히는데, 정작 맨 위에 있던 건 길이 조절이라는
   **부가 설정**이었다 — "뭔가 바꿔야 할 것 같은 느낌"이라는 말이 그래서
   나왔다. 진짜 할 일(대사 읽기)을 맨 위·눈에 띄게, 길이 조절은 그 밑에
   조용한 팁으로 내린다(`.tip` 참고).
   ⚠️ 이 class 는 원래 "오늘 받은 점수"(`gotpt`) 자리였는데, 점수는 이제
      주사위 옆 배지(`#rollScore`)로 옮겨서 여기가 비었다 — **같은 "눈에
      띄어야 하는 한 줄"** 이라는 성격이 통하므로 이름만 `lead` 로 바꿔
      그대로 물려받는다. */
.sheet.card .facts li.lead {
  color:var(--hot); background:var(--hot-soft);
  border:1.5px solid var(--hot); font-size:.88rem;
}
/* ⏱ **부가 팁으로 낮춘다.** 조용한 문장처럼 보이되, 정작 누르면 바뀐다 —
   조작을 숨기지 않으면서도 "가장 먼저 할 일"과 무게를 다르게 준다. */
.secpick {
  flex:0 0 auto; width:100%; display:block; text-align:left;
  font:inherit; font-size:.78rem; font-weight:600; color:var(--ink-3);
  background:none; border:none; border-radius:12px;
  padding:.4rem .65rem; cursor:pointer;
}
.secpick:active { transform:scale(.98); }

#rollGo span { font-weight:700; opacity:.75; font-size:.82rem; }
/* ⚠️⚠️ **`#rollAgain` 은 위 규칙에서 뺐다.** `#rollGo`(큰 주사위 버튼 밑 작은
   설명)와 같은 선택자를 썼는데, `#rollAgain`("다시 뽑기")은 옆의 `#rollClose`
   ("그만두기")와 **같은 급의 ghost 버튼**이다. 예전엔 "다시 뽑기" 네 글자라
   작아도 티가 안 났는데, 종류 이름이 붙어 "연기에서 다시 뽑기"로 길어지면서
   글씨만 유난히 작고 흐리게 보였다 — 옆 버튼과 맞춘다. */

/* 알림 종 */
.top .circle { position:relative; }
.top .circle .ti { width:1.3rem; height:1.3rem; fill:none; stroke:currentColor;
  stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.top .circle .dot {
  position:absolute; top:.35rem; right:.35rem; width:.55rem; height:.55rem;
  border-radius:50%; background:var(--hot); border:2px solid var(--sheet);
}
.top .circle .dot[hidden] { display:none; }
.bigcode.sm { font-size:1.5rem; letter-spacing:.22em; margin:.4rem 0; }

/* 마이페이지 — ⚠️ 덧붙이기만 해서 같은 정보가 두 번씩 나왔다. 간격부터 잡는다. */
#s-me .eyebrow.mt { margin-top:1.35rem; }
#s-me .opts { gap:.5rem; margin-top:.5rem; }
#s-me .stamp { margin-bottom:.5rem; }
#s-me .bubble.profile { margin-bottom:.9rem; }
#s-me .bubble.profile .pinfo h1 { font-size:1.4rem; }
button.stats { width:100%; cursor:pointer; text-align:left; }
button.stats .go { margin-left:auto; font-weight:800; color:var(--ink-3); }

/* 상단 프로필 사진 버튼 */
.avatar.sm {
  position:relative; width:2.4rem; height:2.4rem; flex:0 0 auto; cursor:pointer;
  border-radius:50%; border:1.5px solid var(--edge); overflow:visible;
  display:flex; align-items:center; justify-content:center;
  font-weight:800; background:var(--sheet);
}
.avatar.sm img { width:100%; height:100%; object-fit:cover; border-radius:50%; }
.avatar.sm img[hidden] { display:none; }
.avatar.sm .plus {
  position:absolute; right:-.2rem; bottom:-.2rem;
  width:1.1rem; height:1.1rem; border-radius:50%;
  background:var(--hot); color:#fff; font-size:.7rem; line-height:1.05rem;
  text-align:center; border:2px solid var(--sheet);
}
.sheet .facts { list-style:none; display:flex; flex-direction:column; gap:.3rem;
  margin:.5rem 0 .7rem; padding:0; text-align:left; }
.sheet .facts li { font-size:.84rem; font-weight:700; background:var(--sunk);
  border-radius:12px; padding:.42rem .65rem; }

/* 지금 혼자인지 어느 방인지 */
.nowline {
  font-size:.78rem; font-weight:700; color:var(--ink-3);
  padding:.1rem .2rem .5rem;
}
.nowline[data-in] { color:var(--hot); }
/* ⚠️ **어디에 올릴지 여기서 바꾼다.** 말해주기만 하고 못 바꾸면, 다른 방에
   올리려고 홈으로 나갔다가 다시 들어와야 한다 — 세 번 눌러야 하는 일은 안 한다. */
.wherepick { display:flex; align-items:center; gap:.5rem; margin-bottom:.5rem; }
.wherepick .nowline { flex:1; min-width:0; padding:0; }
.wherepick select {
  flex:0 0 auto; max-width:9.5rem; padding:.4rem .6rem; font-size:.8rem;
  border-radius:var(--r-pill);
}
.wherepick select[hidden] { display:none; }

/* 🎲 구르는 동안은 결과를 가린다 */
.sheet.card[data-rolling] #rollCat,
.sheet.card[data-rolling] #rollScore,
.sheet.card[data-rolling] #rollTitle,
.sheet.card[data-rolling] #rollSummary,
.sheet.card[data-rolling] #rollFacts,
.sheet.card[data-rolling] #rollTake,
.sheet.card[data-rolling] #rollAgain,
/* ⚠️ **버튼을 새로 만들면 여기 이름도 넣어야 한다.** `#rollOther` 를 나중에
   추가하고 이 목록에 안 넣어서, **구르는 동안 그 버튼만 혼자 떠 있었다** —
   결과를 가려놓는 이유가 "굴러가는 걸 봐야 뽑은 게 된다"인데 한 개가 새면
   그 자리만 어색해진다. 재서 확인했다: rollOther=visible (나머지는 hidden). */
.sheet.card[data-rolling] #rollOther,
.sheet.card[data-rolling] #rollClose { visibility:hidden; }

/* 여러 방 — 눌러서 옮겨 다닌다 */






.bubble.profile.big { text-align:center; }
.bubble.profile.big .avatar { margin:0 auto .5rem; }

/* ⚠️ 이 방에서 안 되는 종류는 **지우지 않고 흐리게.** 지우면 왜 없어졌는지
      모르고, 흐리면 "여기선 안 되는구나"가 읽힌다. */
.chips .chip[data-locked], .cats .chip[data-locked] {
  opacity:.32; cursor:not-allowed; box-shadow:none;
}
#pickWhere { padding-bottom:.7rem; }

/* ── ⚠️⚠️ **이름만 붙이고 규칙을 안 쓴 것들** ────────────────────────────────
   이 앱에서 제일 자주 난 버그가 이것이다 — `.quiet` `.scrollx` `.pwbox` `.picks`
   `.toast` `.ti` 가 전부 **class 이름은 붙어 있는데 CSS 규칙이 없어서** 아무
   모양도 안 나왔다. 화면을 봐도 "왜 이러지"로만 보이지 원인이 안 보인다.
   ⚠️ **이름을 붙였으면 규칙을 쓴다.** 안 쓸 거면 이름도 붙이지 않는다.
      (check.mjs 가 이제 규칙 없는 이름을 세서 막는다.) */

/* 내 색 고르기 — ⚠️ 글씨가 없는 버튼이라 크기를 안 주면 **전역 button 의
   알약 모양·큰 여백**을 그대로 뒤집어쓴다. 동그란 점이어야 색이 색으로 읽힌다. */
.colors { display:flex; flex-wrap:wrap; gap:.5rem; margin:.2rem 0 .3rem; }
.swatch {
  flex:0 0 auto; width:2.2rem; height:2.2rem; padding:0; border-radius:50%;
  border:2px solid transparent; box-shadow:var(--pop-sm);
}
.swatch[data-on] { border-color:var(--ink); transform:scale(1.08); }

/* 마이의 숫자 줄 — ⚠️ 이름과 값이 **양 끝**으로 가야 눈이 훑어진다.
   규칙이 없으면 「찍은 것0개」처럼 붙어서 한 덩어리로 읽힌다. */
.melist { display:flex; flex-direction:column; gap:.1rem; margin:.5rem 0 .2rem; }
.merow {
  display:flex; align-items:baseline; justify-content:space-between; gap:.8rem;
  padding:.55rem .2rem; border-bottom:1px solid var(--edge);
}
.merow:last-child { border-bottom:0; }
.merow span { font-size:.88rem; font-weight:700; color:var(--ink-2); }
.merow b { font-size:1rem; font-weight:800; }
.merow.cash b { color:var(--cash); }

/* 💰 공개하고 받는 순서 — 번호가 앞에 붙은 세 줄이다. */
.gigclaim { display:flex; flex-direction:column; gap:.45rem; margin:.5rem 0; }
.step {
  display:flex; align-items:baseline; gap:.5rem;
  font-size:.86rem; font-weight:700; color:var(--ink-2);
  background:var(--sunk); border-radius:12px; padding:.5rem .65rem;
}
.step b {
  flex:0 0 auto; width:1.35rem; height:1.35rem; border-radius:50%;
  background:var(--cash); color:#fff; font-size:.78rem;
  display:flex; align-items:center; justify-content:center;
}

/* 한 종류를 고른 뒤 **한 단계 더** 고르는 자리(언어·곡·문제팩). */
.pickmore { margin:.6rem 0 .2rem; }

/* ⚠️ **일부러 안 보여주는 자리다**(퀴즈 문제·외국어 문장). 미리 보면 그 미션이
   통째로 무의미해진다. 「비어 있다」가 아니라 **「곧 나온다」로 읽혀야** 한다. */
.spoil {
  font-size:.9rem; font-weight:700; color:var(--ink-2);
  background:var(--sunk); border-radius:12px; padding:.6rem .7rem; margin:.2rem 0;
}
.spoil.dim { font-size:.82rem; font-weight:700; color:var(--ink-3); background:none; padding:.1rem .2rem; }

/* 설문 한 묶음(질문 + 답 칩). 묶음끼리 떨어져야 어디까지가 한 질문인지 보인다. */
.q { margin:.9rem 0; }

/* 미션 카드 머리 — 「오늘의 미션」과 날짜표가 양 끝이다. */
.cardhead { display:flex; align-items:center; justify-content:space-between; gap:.6rem; }

/* 🎬 상황극 지문. ⚠️ 대사가 아니라 **어떻게 하라는 말**이라 다르게 보여야 한다. */
.skitcard { margin:.6rem 0 .2rem; }
.dir {
  font-size:.86rem; font-weight:700; color:var(--ink-2); font-style:italic;
  border-left:3px solid var(--edge); padding:.15rem 0 .15rem .6rem; margin:.4rem 0;
}


#postsFilm { margin:.6rem 0 .9rem; }
#postsFilm[hidden] { display:none; }
.wide { width:100%; }
/* 칸 사이 여백. 방 만들기에서 이름·소개 칸이 붙어 있었다. */
.field.mt { margin-top:.45rem; }

/* ── 마이페이지 프로필 카드 ──
   ⚠️ 내 프로필이 한 화면에 셋이었다(상단 아바타 · 이 카드 · 점수줄 이름칩).
      **여기 하나만 남긴다.** 사진은 왼쪽에 크게, 이름·이메일은 오른쪽. */
.me-card {
  display:flex; align-items:center; gap:.9rem; width:100%; text-align:left;
  cursor:pointer; font:inherit; color:inherit;
}
.me-card .pinfo { display:flex; flex-direction:column; gap:.1rem; min-width:0; flex:1; }
.me-card .pinfo b { font-family:var(--round); font-weight:400; font-size:1.45rem; line-height:1.2; }
.me-card .pinfo em {
  font-style:normal; margin:0; font-size:.82rem; color:var(--ink-3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.me-card .pinfo em:empty { display:none; }
.me-card .go { margin-left:auto; color:var(--ink-3); font-size:1.3rem; }
.avatar.big {
  flex:0 0 auto; width:4.2rem; height:4.2rem; border-radius:50%;
  border:var(--line); box-shadow:var(--pop-sm); overflow:hidden;
  display:grid; place-items:center; background:var(--butter);
  font-family:var(--round); font-size:1.45rem; color:#221E1C; text-transform:uppercase;
}
.avatar.big img { width:100%; height:100%; object-fit:cover; }

/* ⚠️ 관리자 줄만 `<a>` 다(주소로 나가야 해서). 그대로 두면 전역 `a` 규칙이
   먹어서 **주황 글씨에 밑줄**이 그어지고, 옆 카드와 다른 물건처럼 보인다.
   생긴 건 다른 줄과 같아야 한다 — 하는 일이 같으니까. */
a.stamp { color:inherit; text-decoration:none; }
a.stamp b, a.stamp em { color:inherit; }
a.stamp em { color:var(--ink-3); }
/* 두 칸짜리 줄(친구에게 보내기·의견 남기기) 다음 줄이 붙어 보였다. */
#meAdminBox { margin-top:.45rem; }

/* 안 읽은 글 배지. ⚠️ 줄의 오른쪽 끝에 붙는다 — 이름이 길어도 안 밀린다. */


.stamp .badge { flex:0 0 auto; margin-left:.3rem; }
.circle .badge {
  position:absolute; top:-.15rem; right:-.15rem; min-width:1.1rem;
  padding:.02rem .28rem; font-size:.6rem; line-height:1.5;
}
.ghost.circle { position:relative; }
.badge[hidden] { display:none; }

/* ⚠️ **`display:` 를 준 선택자는 그 자리에서 `[hidden]` 도 같이 적는다.**
   브라우저 기본 `[hidden]{display:none}` 은 우리가 준 display 에 밀린다.
   style.css 289줄에 규칙으로 적어뒀는데도 `.tabbar` 에서 한 번, 여기서 또 밟았다. */
.chips[hidden] { display:none; }


/* ── 방에서 오늘 할 종류 고르기 ──
   ⚠️ **격자로 다 펼친다.** 가로 스크롤이면 오른쪽 것이 화면 밖에 있어서
      고를 수 있는 줄도 모른다 — 이 파일에서 이미 두 번 배운 것이다.
   ⚠️ 이름 밑에 **한 줄 설명**을 같이 둔다. 「☀️ 일상」만 있으면 그게 뭘 찍는
      건지 눌러봐야 안다. 눌러봐야 아는 버튼은 안 눌린다. */
/* ⚠️ **9개를 2열로 놓으니 5줄이 되어 화면이 통째로 밀렸다.** 오늘 할 일
   (누가 찍었나·올라온 영상)이 스크롤 한참 밑으로 갔다.
   **9개는 3열이 정확히 3줄**이다 — 한눈에 들어오고 밑도 안 밀린다.
   ⚠️ 좁아진 만큼 설명은 **두 줄까지**만. 잘려도 이름은 남아야 한다. */
.roomtypes {
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:.35rem;
  margin-top:.7rem;
}
/* ⚠️ **가운데로 모은다.** 그림과 글씨가 왼쪽에 붙어 있으니 칸 안이 한쪽으로
   쏠려서 아홉 개가 들쭉날쭉해 보였다 — 격자는 **가운데 정렬이라야 줄이 선다.** */
.roomtypes button {
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.15rem; padding:.55rem .4rem; text-align:center; min-width:0;
  background:var(--sheet); color:var(--ink); border:1.5px solid var(--edge);
  border-radius:12px; box-shadow:var(--pop-sm); cursor:pointer;
}
/* 그림은 글씨보다 조금 크게 — 격자에서는 그림이 먼저 읽힌다. */
.roomtypes button .ti { width:1.25rem; height:1.25rem; }
.roomtypes button:active { transform:translate(2px,2px); box-shadow:none; }
.roomtypes button b {
  font-size:.78rem; font-weight:700; letter-spacing:-.02em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%;
}
.roomtypes button em {
  font-style:normal; font-size:.6rem; font-weight:700; color:var(--ink-3);
  line-height:1.22; overflow-wrap:anywhere;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
/* ⚠️ 고를 게 하나 더 있는 종류(퀴즈·외국어·노래·CASH)는 **바로 안 굴러간다.**
   같은 모양이면 눌렀을 때 화면이 바뀌는 걸 예상 못 한다. 꼬리표로 알린다. */
.roomtypes button[data-more] b::after {
  content:" ›"; color:var(--hot); font-weight:800;
}

/* ── 오늘 우리 미션 카드 ──
     ┌───────────────────┬──────┐
     │ ☀️ 일상            │  🎬  │
     │ 여기 한 바퀴        │ 도전 │
     └───────────────────┴──────┘
   ⚠️⚠️ **「도전하기」가 카드 밖 화면 너비 버튼이었다.** 어느 미션을 찍는다는
      건지 붙어 있질 않았고, 큰 주황 막대 하나가 화면을 통째로 먹어서 바로 밑의
      「🎲 다시 뽑기」가 곁다리로 보였다. **할 일은 그 일이 적힌 자리 옆에 둔다.**
   ⚠️ 방과 「내 자리」가 **같은 규칙**을 쓴다 — 같은 일이 화면마다 다르게 생기면
      매번 다시 배워야 한다. */
.roommission {
  display:flex; align-items:center; gap:.8rem;
  padding:1rem 1rem 1rem 1.15rem;
}
.roommission[hidden] { display:none; }
.roommission .mtext { flex:1; min-width:0; }
/* ⚠️ 카드 안에서는 제목 밑 여백을 뺀다. h1 기본값 1rem 이 남으면 버튼과 높이가
   어긋나서 오른쪽 박스만 위로 떠 보인다. */
.roommission h1 { margin:0; font-size:clamp(1.35rem,5.8vw,1.8rem); }
.roommission .script { margin-top:.5rem; }

/* 미션 카드 위의 종류 딱지. ⚠️ 제목만 있으면 무슨 종류인지 알 수가 없다. */
.roommission .mcat {
  font-size:.7rem; font-weight:700; color:var(--hot);
  background:var(--hot-soft); border-radius:999px; padding:.12rem .5rem;
  display:inline-block; margin-bottom:.35rem;
}
.roommission .mcat:empty { display:none; }

/* 카드 오른쪽의 주황 박스.
   ⚠️ 처음엔 「🎬」 아이콘 + 「도전/하기」 두 줄로 좁게 만들었는데, **두 줄로 접힌
      글씨는 잘린 것처럼 보이고** 아이콘은 「도전하기」가 이미 하는 말을 한 번 더
      할 뿐이었다. 한 줄로 펴고 **폭을 글자에 맞춰 넓힌다.**
   ⚠️ 그래도 카드 폭의 40% 를 넘기지 않는다 — 넘으면 미션 이름이 잘린다
      (`check.mjs` 가 잰다). */
.mgo {
  flex:0 0 auto; display:block; white-space:nowrap;
  padding:.75rem .95rem; border-radius:16px;
  font-size:.86rem; font-weight:800; letter-spacing:-.02em; line-height:1;
}
/* ⚠️ display 를 쓰면 같은 줄에서 [hidden] 을 적는다 — 안 그러면 안 숨는다. */
.mgo[hidden] { display:none; }

/* ── 방의 오늘 한 줄 ──
   ⚠️ **이 블록이 통째로 없어진 적이 있다.** 중복 규칙을 정리하다 `.member`·`.dot`·
      `.nick` 기본형이 같이 날아갔고, 그 결과 span 세 개가 그냥 이어 붙어서
      화면에 **「잭희찍음」·「주지금 손에 든 것」** 으로 나왔다. 무슨 말인지 아무도
      못 알아본다. `.post` 에서 똑같이 당한 적이 있는데 여기서 또 밟았다 —
      **줄 하나가 span 여러 개로 되어 있으면 간격은 CSS 가 유일한 근거다.** */
.members { display:flex; flex-direction:column; gap:.3rem; }
.member {
  display:flex; align-items:center; gap:.5rem;
  background:var(--sheet); border:var(--line); border-radius:12px;
  padding:.45rem .6rem; font-size:.86rem; font-weight:700;
}
.member .dot {
  flex:0 0 auto; width:.6rem; height:.6rem; border-radius:50%;
  background:var(--ink-3); border:1.5px solid var(--edge);
}
.member .nick {
  flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.member[data-me] .nick::after {
  content:" (나)"; color:var(--hot); font-size:.72rem;
}
.member .thumb {
  margin-left:auto; width:2.4rem; height:3.2rem; object-fit:cover;
  border-radius:8px; border:1.5px solid var(--edge); flex:0 0 auto;
}
.member[data-shot][role="button"] { cursor:pointer; }
/* ⚠️ **찍었나 안 찍었나만 말한다.** 여기에 미션 제목을 넣었더니 이름 옆에
   「지금 손에 든 것」이 붙어서 그게 사람 이름인지 미션인지 구분이 안 됐다.
   미션은 바로 위 카드에 크게 떠 있다 — 같은 말을 세 번 반복할 자리가 아니다. */
.member .tag {
  flex:0 0 auto; font-size:.72rem; font-weight:700; color:var(--ink-3);
  background:var(--sunk); border-radius:999px; padding:.16rem .5rem;
}
.member[data-shot] .tag { color:var(--hot); background:var(--hot-soft); }

/* ⚠️ **`[hidden]` 은 무엇보다 세다.**
   `display:` 를 준 선택자마다 `[hidden]` 을 같이 적으라고 규칙을 적어뒀는데도
   `.tabbar`(촬영 버튼을 가림) · `.chips`(대본 목록이 안 숨음) · `.script`(대사가
   안 접힘) 에서 **세 번** 밟았다. 사람이 매번 기억하는 것으로는 못 막는다.
   여기서 통째로 못박는다 — 이 앱에서 `hidden` 은 "안 보인다" 한 가지 뜻뿐이다. */
[hidden] { display:none !important; }
.stamp.mt { margin-top:.7rem; }
/* 「박자」가 녹음에 안 들어간다는 걸 라벨 옆에 작게 붙인다. */
.optlabel .optnote {
  display:block; font-style:normal; font-size:.62rem; font-weight:700;
  color:var(--on-stage-2); margin-top:.1rem;
}

/* 보관함에서 **이미 올린 것**. ⚠️ 표가 없으면 같은 걸 두 번 올리고 나서야 안다. */
.clip[data-shared] { border-color:var(--hot); }
.clip[data-shared]::after {
  content:"✓ " attr(data-shared);
  position:absolute; top:.35rem; right:.45rem;
  background:var(--hot); color:#fff; border-radius:999px;
  padding:.1rem .45rem; font-size:.62rem; font-weight:700;
  max-width:60%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* ⚠️ 여기 `position:relative` 만 남아 있었다 — 중복 정리에서 **뒤엣것만
   남기는** 규칙 때문에, 나중에 덧붙인 한 줄이 원래 레이아웃을 통째로
   밀어냈다. 합쳐 둔다. */
.clip {
  position:relative;
  display:flex; gap:.75rem; align-items:center; background:var(--sheet);
  border:var(--line); box-shadow:var(--pop);
  border-radius:var(--r-card); padding:.6rem; margin:0 .2rem .7rem 0;
}
/* 방 화면의 「🎲 미션 뽑기」는 아직 안 뽑았을 때 혼자 넓게 선다. */
.opts .wide { width:100%; flex:1 1 100%; }

/* ── 홈 줄 정리 ──
   ⚠️ **출석·나 혼자·방들이 전부 같은 알약**이라 한 덩어리로 보였다. 하는 일이
      다른 줄은 다르게 생겨야 눈이 나눈다. 그림(SVG)·굵기·바탕으로 셋을 가른다.
   ⚠️ 이모지를 안 쓴다 — 기기마다 그림이 달라서 우리 화면이 아니게 된다. */
.stamp .ico .ti, .roombar .ico .ti {
  width:1.15rem; height:1.15rem; display:block;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}
/* 출석은 **오늘 한 번 하는 일**이라 조금 크고 바탕이 있다. */
.stamp.big { padding:.7rem .85rem; }
.stamp.big .ico { color:var(--hot); }

/* 방 목록 — 아이콘 + 이름 + 오른쪽 설명. */
.roomchip .ti {
  width:1.1rem; height:1.1rem; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}

/* 지금 있는 자리만 채운 색. 나머지는 흰 바탕이라 목록으로 읽힌다. */

.roombar .ico { display:flex; color:var(--hot); }

/* ⚠️ 방 목록과 「새 방 만들기」 사이를 띄운다. 붙어 있으면 새 방 만들기가
   목록의 마지막 방처럼 보인다. */
#roomList + .roombar { margin-top:.5rem; }

/* ⋯ 방 메뉴 안의 줄 — 위험한 것은 눈에 띄게. */
#roomMenuList .stamp { margin-bottom:.4rem; }
#roomMenuList .stamp.danger { border-color:var(--bad); }
#roomMenuList .stamp.danger b { color:var(--bad); }

/* ── 마이페이지 메뉴 ──
   ⚠️ **가로로 꽉 찬 바가 일곱 줄** 이어서 화면이 계단처럼 보였다. 줄마다 폭은
      같은데 하는 일은 제각각이라, 길기만 하고 무엇이 중요한지 안 읽힌다.
      2열 카드로 접으면 한눈에 들어오고 손가락도 덜 움직인다.
   ⚠️ 관리자 줄은 **격자에 안 넣는다.** 아무나 보는 것이 아니라 튀어야 한다. */
.tiles { display:grid; grid-template-columns:1fr 1fr; gap:.5rem; }
.tile {
  display:flex; flex-direction:column; align-items:flex-start; gap:.15rem;
  text-align:left; cursor:pointer; min-width:0;
  background:var(--sheet); border:var(--line); box-shadow:var(--pop-sm);
  border-radius:18px; padding:.75rem .8rem;
}
.tile .ico { font-size:1.25rem; line-height:1.1; }
.tile .txt { display:flex; flex-direction:column; gap:.1rem; width:100%; min-width:0; }
.tile .txt b { font-size:.86rem; font-weight:800; letter-spacing:-.02em; }
.tile .txt em {
  font-style:normal; font-size:.7rem; font-weight:700; color:var(--ink-3);
  line-height:1.35; overflow:hidden; display:-webkit-box;
  -webkit-line-clamp:2; -webkit-box-orient:vertical;
}
/* ⚠️ 카드에는 › 를 안 쓴다. 줄이 아니라 면이라 오른쪽 화살표가 갈 자리가 없다. */
.tile .go { display:none; }
.tile:active { transform:translate(2px,2px); box-shadow:none; }

/* ═══ 홈 — 성격이 다르면 생김새도 다르다 ═══
   ⚠️ 출석·자리 고르기·새 방 만들기·찍으러 가기가 **전부 같은 알약**이라
      화면이 계단처럼 보였고, 무엇이 무엇인지 안 읽혔다.
      네 가지를 각각 다른 형태로 나눈다. */

/* ① 오늘 할 일 — 얇은 줄. 다 하면 색이 빠진다. */
.today {
  display:flex; align-items:center; gap:.55rem; width:100%; text-align:left;
  background:var(--hot-soft); border:var(--line); box-shadow:var(--pop-sm);
  border-radius:var(--r-pill); padding:.6rem .85rem; margin-bottom:.45rem;
  cursor:pointer; color:var(--ink);
}
.today[data-done] { background:var(--sheet); }
.today[data-done] .go { color:var(--hot); }
.today.key { background:var(--sheet); }
/* 🎁 초대 — ⚠️ 출석 도장과 **같은 줄 모양**이되 색은 다르다. 하는 일이 달라서
   (출석은 매일, 초대는 어쩌다 한 번) 같은 색이면 매일 눌러야 할 것으로 읽힌다. */
.today.gift { background:var(--sheet); }
.today.gift .ico { color:var(--ink-2); }
.today[hidden] { display:none; }
.today .ico { display:flex; color:var(--hot); font-size:1.05rem; }
.today .ico .ti {
  width:1.15rem; height:1.15rem; fill:none; stroke:currentColor;
  stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
}
.today .txt { flex:1; min-width:0; display:flex; align-items:baseline; gap:.4rem; flex-wrap:wrap; }
.today .txt b { font-size:.88rem; font-weight:800; }
.today .txt em {
  font-style:normal; font-size:.75rem; font-weight:700; color:var(--ink-3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.today .go { color:var(--ink-3); font-weight:800; flex:0 0 auto; }

/* ② 어디에 올릴까 — **타일**. 누르면 뭔가 일어나는 게 아니라 자리를 고르는 곳이다. */
.places { display:grid; grid-template-columns:1fr 1fr; gap:.5rem; }
.place {
  display:flex; flex-direction:column; align-items:flex-start; gap:.12rem;
  text-align:left; cursor:pointer; min-width:0; position:relative;
  /* ⚠️ 사진을 깔 자리다(아래 .shot). 글자만 있을 때도 같은 키로 서 있어야
     한 줄에 사진 타일과 나란히 놓여도 들쭉날쭉하지 않다. 글자는 아래로. */
  min-height:6.8rem; justify-content:flex-end;
  background:var(--sheet); border:var(--line); box-shadow:var(--pop-sm);
  border-radius:18px; padding:.7rem .75rem; color:var(--ink);
}
.place .ti {
  width:1.15rem; height:1.15rem; margin-bottom:.15rem;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; color:var(--ink-3);
}
.place b { font-size:.88rem; font-weight:800; letter-spacing:-.02em;
  max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.place em {
  font-style:normal; font-size:.72rem; font-weight:700; color:var(--ink-3);
  max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* 지금 있는 자리만 채운다 — 하나만 켜져야 "지금 여기"가 읽힌다. */
.place[data-on] { background:var(--hot); color:#fff; border-color:var(--hot); }
.place[data-on] .ti, .place[data-on] em { color:rgba(255,255,255,.85); }
/* ⚠️⚠️ **홈이 휑했다.** 글자만 든 네모가 나열돼 있으니 어느 게 내 방인지
   **눈으로 못 고르고**, 앱 전체가 「할 일 목록」처럼 보였다.
   ⚠️ 배경 사진을 **따로 올리게 하면 아무도 안 올린다** — 올릴 이유가 없고,
      안 올린 방은 영영 휑하다. **이미 찍어둔 것**을 쓴다: 그 방 최근 영상의
      표지. 새로 찍으면 저절로 바뀌니 아무도 관리하지 않아도 된다.
   ⚠️ **`overflow:hidden` 을 쓰지 않는다.** 타일 *밖으로* 튀어나온 안읽음
      표시(.badge — top/right 가 음수)가 통째로 잘려 사라진다.
      대신 사진과 막에 **각자** 같은 둥근 모서리를 준다. */
.place .shot {
  position:absolute; inset:0; z-index:0; border-radius:inherit;
  width:100%; height:100%; object-fit:cover;
}
/* 사진 위에 글씨를 그냥 얹으면 **밝은 사진에서 안 읽힌다.** 아래쪽만 어둡게. */
.place[data-shot]::before {
  content:""; position:absolute; inset:0; z-index:0; border-radius:inherit;
  background:linear-gradient(180deg, rgba(0,0,0,.04) 34%, rgba(0,0,0,.74) 100%);
}
.place > b, .place > em, .place > .ti { position:relative; z-index:1; }
.place[data-shot] { color:#fff; }
.place[data-shot] .ti, .place[data-shot] em { color:rgba(255,255,255,.92); }
.place[data-shot] b { text-shadow:0 1px 3px rgba(0,0,0,.55); }
/* ⚠️ 사진이 깔리면 「지금 여기」의 **배경색이 사진에 가려 안 보인다.**
   칠하는 대신 **둘러싼다** — 사진을 안 가리면서 지금 자리가 읽힌다. */
.place[data-shot][data-on] {
  border-color:var(--hot); box-shadow:0 0 0 2px var(--hot), var(--pop-sm);
}
.place .badge { position:absolute; top:-.3rem; right:-.3rem; z-index:2; }
.place:active { transform:translate(2px,2px); box-shadow:none; }
/* ⚠️ **모르는 것을 「없다」고 말하지 않는다.** 서버에 내 방을 물어보는 동안
   빈 화면을 보여주면 "방이 하나도 없다"로 읽히고, 목록이 도착하는 순간 툭
   나타난다 — "방이 없다가 나중에 나타났어". 물어보는 중이라고 적어둔다. */
.loadingrooms {
  flex-basis:100%; margin:.2rem 0 0; font-size:.82rem; font-weight:700;
  color:var(--ink-3);
}

/* ③ 새 방 만들기 — 어쩌다 한 번. **점선**으로 낮춰 위의 자리들과 안 섞이게. */
.addroom {
  display:flex; align-items:center; gap:.5rem; width:100%; text-align:left;
  margin-top:.5rem; padding:.6rem .85rem; cursor:pointer;
  background:transparent; color:var(--ink-2);
  border:2px dashed var(--ink-3); border-radius:var(--r-pill);
  font-size:.85rem; font-weight:800;
}
.addroom .ti {
  width:1.1rem; height:1.1rem; flex:0 0 auto; color:var(--hot);
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}
.addroom:active { background:var(--sunk); }

/* ④ 찍으러 가기 — 주 액션 하나 + 아래 작은 길. */
.sublink {
  display:block; width:100%; margin:.45rem 0 0; padding:.35rem;
  background:none; border:0; box-shadow:none; cursor:pointer;
  font-size:.8rem; font-weight:700; color:var(--ink-3);
  text-decoration:underline; text-underline-offset:3px;
}
.sublink:active { color:var(--hot); }



/* ── 로그인·가입 ──
   ⚠️ `.eyebrow` 는 inline-block 이라 라벨 뒤에 칸이 **옆으로 붙는다.**
      「이메일 [칸] 비밀번호 [칸]」이 한 줄로 흘러서 90년대 폼처럼 보였다.
      여기서는 **칸 하나에 한 줄씩** — 폰에서 유일하게 편한 형태다. */
.authpad { display:flex; flex-direction:column; }
.fieldrow { display:flex; flex-direction:column; gap:.3rem; margin-bottom:.9rem; }
.fieldrow.mt { margin-top:.4rem; }
.flabel {
  font-size:.78rem; font-weight:700; color:var(--ink); letter-spacing:-.01em;
  padding-left:.15rem;
}
/* ⚠️ **왼쪽 여백 `.15rem` 이 붙어 있었다.** 2.4px — 없앨 수도 있는 값처럼 보이지만
   바로 위 `input`·`label` 은 0 이라, 안내문만 혼자 2.4px 들어가서 **줄이 안 맞았다.**
   눈으로는 "뭔가 어긋났는데"까지만 오고 원인이 안 보이는 종류다(자로 재서 찾았다). */
.fhint { margin:.1rem 0 0; font-size:.74rem; color:var(--ink-3); font-weight:700; }
.fhint b { color:var(--ink-2); }

/* 비밀번호 — ⚠️ 폰에서 오타가 나면 왜 안 되는지 알 길이 없다. 눈으로 보여준다. */
.pwwrap { position:relative; }
.pwwrap .field { padding-right:2.9rem; width:100%; }
/* ⚠️ **28×30px 이라 손가락으로 정확히 못 눌렀다**(자로 재서 찾았다). 비밀번호를
   확인하려다 입력칸이 눌리면 커서만 움직이고 아무 일도 안 난 것처럼 보인다.
   → 그림 크기는 그대로 두고 **누를 수 있는 넓이만** 40px 로 넓힌다.
   ⚠️ `padding` 만 키우면 아이콘이 왼쪽으로 밀리므로 가운데 정렬을 같이 준다. */
.peek {
  position:absolute; right:.25rem; top:50%; transform:translateY(-50%);
  background:none; border:0; box-shadow:none; cursor:pointer;
  font-size:1.05rem; line-height:1; opacity:.55;
  width:2.5rem; height:2.5rem; padding:0;
  display:flex; align-items:center; justify-content:center;
}
.peek[data-on] { opacity:1; }

/* 「처음이신가요? 가입하기」 — 버튼이 아니라 한 줄의 말이다. */
.authswitch {
  display:flex; align-items:center; justify-content:center; gap:.4rem;
  margin:.2rem 0 1rem; font-size:.85rem; color:var(--ink-3); font-weight:700;
}
/* ⚠️⚠️ **「처음이신가요?」와 「가입하기」가 화면 양끝으로 벌어져 있었다.**
   `.authswitch` 는 가운데 정렬에 gap 까지 줬는데도 그랬다 — 원인은 **전역
   `button { flex:1 }`** 이다. 이 링크도 button 이라 혼자 늘어나서 옆의 글자를
   왼쪽 끝까지 밀어냈다. 묻는 말과 답하는 버튼은 **붙어 있어야 한 문장**이다.
   ⚠️ 전역 flex 를 끄는 것은 여기 하나로 안 끝난다 — 링크꼴 버튼에서만 끈다. */
/* ⚠️ 높이가 24px 이라 누르기 좁았다(자로 재서 찾았다). 글자 크기는 그대로 두고
   **위아래 여백만** 키운다 — 밑줄 친 한 줄로 보이는 모양은 안 바뀐다. */
.linkbtn {
  background:none; border:0; box-shadow:none; padding:.55rem .3rem; cursor:pointer;
  flex:0 0 auto;
  font-size:.85rem; font-weight:800; color:var(--hot);
  text-decoration:underline; text-underline-offset:3px;
}
/* ⚠️ `<details>` 기본 삼각형(▶)이 그대로 보여서 조잡했다. 우리 획으로 바꾼다. */
#authForgot summary { list-style:none; }
#authForgot summary::-webkit-details-marker { display:none; }
#authForgot summary::before { content:"＋ "; color:var(--hot); font-weight:800; }
#authForgot[open] summary::before { content:"－ "; }

/* ── 입력칸 ──
   ⚠️ **`.field` 규칙이 아예 없었다.** 브라우저 기본 input 이 그대로 나와서,
      스티커(굵은 선 + 어긋난 그림자)로 통일된 화면에 혼자 90년대 폼처럼 떠 있었다.
      화면 전체가 한 벌로 보이려면 입력칸도 같은 옷을 입어야 한다. */
.field {
  width:100%; box-sizing:border-box;
  background:var(--sheet); color:var(--ink);
  border:var(--line); box-shadow:var(--pop-sm); border-radius:var(--r-pill);
  padding:.72rem .95rem; font-family:var(--sans); font-size:.95rem; font-weight:700;
  letter-spacing:-.01em; outline:none;
  transition:box-shadow .12s, border-color .12s;
}
.field::placeholder { color:var(--ink-3); font-weight:600; }
/* ⚠️ 지금 어디를 치고 있는지 보여준다. 칸이 여럿이면 이게 없으면 헤맨다. */
.field:focus { border-color:var(--hot); box-shadow:2px 2px 0 var(--hot); }
/* 방 코드처럼 또박또박 읽어야 하는 칸. */
.field.code {
  font-family:var(--mono); font-size:1.05rem; letter-spacing:.18em; text-align:center;
}
/* 이름·코드처럼 옆에 버튼이 붙는 줄. */
.joinrow { display:flex; gap:.45rem; align-items:center; }
.joinrow .field { flex:1; min-width:0; }
.joinrow button { flex:0 0 auto; white-space:nowrap; }

/* ═══ 올린 영상 카드 ═══
   ┌──────┐  제목
   │ 9:16 │  누가 · 언제 사라짐
   │ 세로 │  ♡3  💬2        ⬆ ⬇ 🔗 🗑
   └──────┘

   ⚠️ **썸네일은 세로 9:16 을 지킨다.** 숏폼인데 가로로 짜부라지면 뭘 찍은
      건지 알아볼 수가 없다 — 목록에서 알아보는 게 썸네일의 유일한 일이다.
   ⚠️ 글과 버튼은 **오른쪽 한 칸에 세로로** 쌓는다. 좌우로 흩어놓으면 눈이
      왔다갔다 하고 카드가 쌓이면 화면이 어지럽다.
   ⚠️ 아래 한 줄에서 **왼쪽은 반응(하트·댓글), 오른쪽은 처리(올리기·저장·링크·삭제)**.
      자주 하는 것과 어쩌다 하는 것이 섞이면 매번 찾아야 한다. */
/* ── 누가 올렸나 ──
   ⚠️ **썸네일만 있으면 누가 올린 건지 모른다.** 그룹방에 6개가 쌓였는데 전부
      "그냥 찍기"라는 제목이면 화면에 남는 정보가 사진 한 장뿐이다. 그래서
      **사람으로 묶고 이름을 맨 왼쪽 맨 위에** 둔다 — 카드마다 이름을 반복하는
      것보다 짧고, "누구 것"이 한 번에 보인다.
   ⚠️ 이름 옆 점은 **그 사람 색**이다. 방 사람 줄(.member)과 같은 색이라
      목록과 명단이 서로를 가리킨다. */
/* ⚠️ **이름을 카드 위가 아니라 왼쪽에 둔다.** 위에 얹었더니 제목처럼 읽혀서
   "누가 올렸나"가 아니라 "무슨 묶음인가"로 보였다. 왼쪽 세로 띠에 두면
   **카드와 나란히** 있어서 이 줄들이 그 사람 것이라는 게 눈으로 붙는다.
   ⚠️ 띠는 `sticky` 다 — 한 사람이 다섯 개를 올리면 스크롤하는 동안 이름이
   화면 밖으로 나가서 누구 건지 다시 모른다. */
/* ⚠️ **왼쪽 세로 띠로 옮겼다가 되돌렸다.** 폰에서 띠가 3.2rem 을 가져가니
   카드가 그만큼 좁아져서, **오른쪽 아이콘 넉 줄(올리기·저장·링크·삭제)이
   카드 밖으로 밀려나 통째로 안 보였다.** 재보고 알았다:
       .postbar  x=175~361 (폭 186)
       .acts     x=254~389  ← 28px 삐져나감
   이름도 「multimov / e」로 줄바뀜이 났다. **좁은 화면에서 세로 띠는
   가로 폭을 사는 값이 너무 비싸다.** 이름은 위에 한 줄로 얹는다. */
.pgroup { margin-bottom:1rem; }
.pgroup > .who {
  display:flex; align-items:center; gap:.4rem;
  margin:0 0 .35rem .15rem; font-size:.82rem; font-weight:800; color:var(--ink-2);
}
.pgroup > .who .dot {
  flex:0 0 auto; width:.66rem; height:.66rem; border-radius:50%;
  background:var(--ink-3); border:1.5px solid var(--edge);
}
.pgroup > .who .name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* 아이디는 이름보다 흐리게 — 부르는 이름이 먼저고 아이디는 확인용이다. */
.pgroup > .who .at {
  font-weight:700; color:var(--ink-3); font-size:.72rem;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
}
.pgroup > .who .cnt {
  margin-left:auto; flex:0 0 auto;
  font-weight:800; color:var(--ink-3); font-size:.72rem;
}
.pgroup[data-me] > .who .name { color:var(--hot); }

.post {
  display:flex; gap:.75rem; align-items:stretch;
  background:var(--sheet); border:var(--line); box-shadow:var(--pop-sm);
  border-radius:18px; padding:.65rem; margin-bottom:.6rem;
  flex-wrap:wrap;
}
.post[hidden] { display:none; }
/* 🎵 개사 멜로디 들어보기. ⚠️ 미션 문장 **아래**에 붙는다 — 문장보다 먼저 눈에
   들어오면 「듣는 것」이 미션인 줄 안다. 듣는 것은 거들 뿐이다. */
.hear {
  align-self:flex-start; margin-top:.5rem; cursor:pointer;
  padding:.42rem .8rem; border-radius:var(--r-pill);
  background:transparent; color:var(--ink-2);
  border:2px solid var(--edge); font-size:.82rem; font-weight:800;
}
.hear[data-on] { background:var(--hot); color:#fff; border-color:var(--hot); }

/* ⚠️ 지난 것은 <video> 가 아니라 <img> 다(영상은 지웠고 표지만 남았다).
   **둘이 똑같이 생겨야 한다** — 목록에서 크기가 다르면 줄이 들쭉날쭉해진다. */
.post video, .post .gone {
  /* 9:16 — 폭을 고정하고 비율로 높이를 잡는다. 값 두 개를 손으로 맞추면 어긋난다. */
  width:4.7rem; aspect-ratio:9/16; flex:0 0 auto;
  object-fit:cover; border-radius:12px; border:1.5px solid var(--edge);
  background:#000;
}
/* 영상이 지난 것은 **빛을 뺀다.** 눌러도 안 열리는 것이 눌리는 것과 똑같이
   생겨 있으면 「왜 안 되지」가 된다 — 보기만 하는 것임이 눈에 보여야 한다. */
.post .gone { filter:grayscale(.55) brightness(.82); cursor:default; }
.post .meta {
  flex:1; min-width:0; display:flex; flex-direction:column; gap:.15rem;
}
.post .meta b {
  font-size:.95rem; font-weight:800; letter-spacing:-.02em; line-height:1.3;
  /* 제목이 길어도 두 줄까지만 — 카드 높이가 들쭉날쭉하면 목록이 안 읽힌다. */
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.post .meta > span { font-size:.75rem; color:var(--ink-3); font-weight:700; }
/* 만료 안내는 한 단계 더 흐리게 — 언제 올렸나가 먼저 읽혀야 한다. */
.post .meta > span.faint { font-size:.68rem; opacity:.7; }

/* 아래 한 줄 — 반응은 왼쪽, 처리는 오른쪽. 세로 가운데를 맞춘다. */
.postbar {
  display:flex; align-items:center; justify-content:space-between;
  gap:.5rem; margin-top:auto; padding-top:.4rem;
}
/* ⚠️ **양쪽 높이를 같은 값으로 못박는다.** 하트는 글자 높이, 아이콘 버튼은
   1.9rem 이라 가운데정렬만 믿었더니 반 줄쯤 어긋나 보였다 — 한 줄에 있는
   것들이 안 맞으면 두 줄로 읽힌다. 같은 줄이라고 말하려면 높이가 같아야 한다. */
.reacts, .acts { display:flex; align-items:center; }
.reacts { gap:.6rem; }
.acts { gap:.15rem; }
.reacts .react, .acts .act { height:1.9rem; }

/* ⚠️ 반응에는 **테두리를 안 준다.** 버튼처럼 생기면 또 하나의 버튼 줄이 된다. */
.react {
  display:inline-flex; align-items:center; gap:.22rem;
  background:none; border:0; box-shadow:none; padding:.2rem .1rem; cursor:pointer;
  font-size:.8rem; font-weight:800; color:var(--ink-3); line-height:1;
}
.react .ti { width:1.05rem; height:1.05rem; flex:0 0 auto; }
.react[data-on] { color:var(--hot); }
.react[data-on] .ti { fill:var(--hot); stroke:var(--hot); }

/* ⚠️ **button 에 `inline-grid` + `place-items` 를 쓰면 안이 안 가운데로 온다.**
   바깥 상자는 하트와 정확히 같은 높이·같은 중심인데, **안의 아이콘만 8px 아래**로
   내려앉아서 두 줄로 보였다(측정값: .react .ti mid=130.9 / .act .ti mid=139.2).
   버튼 안쪽은 브라우저가 만든 익명 상자라 grid 정렬이 거기까지 안 닿는다.
   바로 위 `.react` 는 `inline-flex` 라 멀쩡했다 — **되는 쪽에 맞춘다.** */
.act {
  display:inline-flex; align-items:center; justify-content:center;
  width:1.9rem; height:1.9rem;
  background:none; border:0; box-shadow:none; cursor:pointer;
  border-radius:9px; color:var(--ink-3);
}
/* ⚠️⚠️ **`flex:0 0 auto` 가 없으면 아이콘이 폭 0 으로 찌그러진다.**
   버튼이 「저장·공유·삭제가 사라졌다」로 보인 진짜 이유가 이것이다 —
   버튼 상자(1.9rem)도 있고 위치도 맞는데 **안의 그림만 폭이 0** 이었다.
   재서 확인했다:  computed width = 0px  (`.react .ti` 는 16.8px)
   `<button>` 을 flex 컨테이너로 쓰면 안쪽이 브라우저가 만든 익명 상자를 거치는데,
   viewBox 없는 SVG 는 거기서 기본 폭을 잃고 그대로 줄어든다.
   `.react` 가 멀쩡했던 건 옆에 `<span>` 이 있어서 줄어들 자리가 없었을 뿐이다.
   ⚠️ 세 가지를 다 시험해봤다:
       지금 그대로          w=0.0   ✗
       flex:0 0 auto       w=16.8  ✓
       viewBox 를 붙임      w=0.0   ✗
       block + margin auto  w=16.8  ✓
   ⚠️ **아이콘만 있는 버튼에는 반드시 `flex:0 0 auto`.** 이 앱에서 두 번째다
     (앞엔 `inline-grid` 로 세로가 어긋났다). 버튼은 flex 컨테이너로 믿을 게 못 된다. */
.act .ti { width:1.05rem; height:1.05rem; flex:0 0 auto; }
.act:active { background:var(--sunk); color:var(--ink); }
.act.danger { color:var(--ink-3); }
.act.danger:active { background:var(--hot-soft); color:var(--bad); }

/* 카드 안의 모든 아이콘은 같은 획으로 그린다. */
.post .ti, .react .ti, .act .ti {
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}

/* ── 댓글 ── ⚠️ **카드 안에서 이어진다.** 밖으로 튀어나오면 어느 영상의
   댓글인지 알 수가 없다. 위에 실선을 그어 "여기부터 댓글"을 못박는다. */
.post .thread {
  flex:1 0 100%; margin-top:.55rem; padding-top:.55rem;
  border-top:1px solid var(--ink-3);
}
.thread[hidden] { display:none; }
.thread-list {
  display:flex; flex-direction:column; gap:.35rem;
  max-height:13rem; overflow-y:auto; margin-bottom:.55rem;
}
.thread-list .bub {
  position:relative; align-self:flex-start; max-width:85%;
  background:var(--sunk); border-radius:14px 14px 14px 4px;
  padding:.4rem .6rem .4rem .6rem;
}
.thread-list .bub.mine {
  align-self:flex-end; background:var(--hot); color:#fff;
  border-radius:14px 14px 4px 14px;
}
.thread-list .bub .who {
  display:block; font-size:.66rem; font-weight:700; color:var(--ink-2); margin-bottom:.05rem;
}
.thread-list .bub p { margin:0; font-size:.85rem; line-height:1.45; overflow-wrap:anywhere; }
.thread-list .bub:not(.mine) { padding-right:1.5rem; }
.bubmore {
  position:absolute; top:.15rem; right:.2rem; border:0; background:none;
  color:var(--ink-3); font-size:.8rem; line-height:1; cursor:pointer; padding:.1rem .15rem;
}
/* 입력칸 — ⚠️ 카드 안이라 작게. 밖의 칸과 같은 크기면 카드가 터진다. */
.thread .joinrow .field { padding:.5rem .75rem; font-size:.85rem; }
.thread .joinrow button { padding:.5rem .85rem; font-size:.82rem; }

/* ── 더 보기 / 접기 ──
   ⚠️ 「다 같이 보기」라는 큰 도장 버튼이었는데 **뭘 하는 건지 몰랐다.**
      목록을 펴고 접는 것뿐이라 생김새도 그만큼이면 된다 — 크게 만들면
      옆의 「우리 것 이어붙여 공유하기」와 어느 게 중요한지 겨룬다. */
.more {
  display:flex; align-items:center; justify-content:center; gap:.35rem;
  width:100%; padding:.5rem; margin-top:.1rem;
  background:none; border:0; box-shadow:none; cursor:pointer;
  font-size:.8rem; font-weight:800; color:var(--ink-3);
}
.more[hidden] { display:none; }
.more .go { font-size:.9rem; line-height:1; }
.more:active { color:var(--hot); }

/* 「이 사람 누구지」 카드의 얼굴. ⚠️ 채팅의 작은 동그라미와 **같은 규칙**으로
   그린다 — 사진이 없으면 이름 첫 글자, 있으면 사진. 두 곳이 다르게 보이면
   같은 사람인지 헷갈린다. */
.whoface {
  width:4.5rem; height:4.5rem; margin:0 auto .5rem; border-radius:50%;
  border:2px solid var(--edge-strong); background:var(--ink-3); color:#fff;
  display:grid; place-items:center; overflow:hidden;
  font-size:1.45rem; font-weight:800; text-transform:uppercase;
}
.whoface img { width:100%; height:100%; object-fit:cover; }

/* ⚠️ **목록 안에서도 좌우 두 칸이다.** 격자를 가로질러 한 줄을 차지하되,
   그 안은 다시 2열이다 — s-pick 과 **같은 모양**이라야 한다. */
.roomtypes .sidepick { grid-column:1 / -1; margin-top:.15rem; }

/* 명단의 사진. ⚠️ 색 점과 **같은 자리·같은 크기**로 바뀐다 — 사진이 있는 사람만
   갑자기 커지면 줄이 들쭉날쭉해진다. */
.member .dot.face {
  width:1.6rem; height:1.6rem; padding:0; overflow:hidden;
  background:var(--sunk); border-width:2px;
}
.member .dot.face img { width:100%; height:100%; object-fit:cover; display:block; }

/* ── 이 앱 쓰는 법 ── */
.howto { margin:.6rem 0 0; padding-left:1.2rem; font-size:.88rem; line-height:1.7; }
.howto li { margin-bottom:.35rem; color:var(--ink-2); }
.howto li b { color:var(--ink); font-weight:800; }
.guidecats { display:flex; flex-direction:column; gap:.35rem; margin-top:.5rem; }
.gcat {
  display:flex; align-items:baseline; gap:.5rem;
  background:var(--sheet); border:var(--line); border-radius:12px; padding:.45rem .65rem;
}
.gcat b { flex:0 0 5.2rem; font-size:.85rem; font-weight:800; }
.gcat span { flex:1; min-width:0; font-size:.76rem; font-weight:700; color:var(--ink-3); }

/* ── 주사위를 안 쓰는 두 가지 (그냥 찍기 · 갤러리) ──
   ⚠️ **곁길이라는 것이 크기로 읽혀야 한다.** 세로로 쌓고 설명까지 붙였더니
      종류 격자보다 커 보여서 이게 주된 길처럼 읽혔다. 좌우로, 설명 없이. */
.sidepick { display:grid; grid-template-columns:1fr 1fr; gap:.35rem; margin-top:.55rem; }
.sidepick > * {
  display:flex; align-items:center; justify-content:center; gap:.35rem;
  padding:.55rem .4rem; cursor:pointer; min-width:0;
  background:var(--sunk); color:var(--ink-2);
  border:1.5px dashed var(--edge); border-radius:12px; box-shadow:none;
  font-size:.82rem; font-weight:800;
}
.sidepick > *:active { background:var(--hot-soft); color:var(--hot); }
.sidepick .ico { font-size:1rem; }
.sidepick b { font-weight:800; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* ── 촬영 필터 — 밀어서 바꾼다 ──
   ⚠️ 카드 여덟 장을 늘어놓으니 촌스럽고 화면을 먹었다. 인스타·틱톡처럼
      **화면을 밀어서** 바꾼다 — 고르는 게 아니라 넘겨보는 것이라 지금 무엇이
      걸렸는지가 그림으로 바로 보인다.
   ⚠️ 이름은 **잠깐만** 뜬다. 늘 떠 있으면 그것도 영상 위의 방해물이다. */
/* ── 📷 카메라 도구 — 오른쪽 세로 열 ──
   ⚠️⚠️ **가로 한 줄에 일곱 개를 늘어놨더니 조잡했다.** 카메라 앱들이 오른쪽
      세로 열을 쓰는 데는 이유가 있다:
        ① 영상이 세로라 **가로를 먹으면 그림이 줄어든다**
        ② 오른손 엄지가 닿는 자리다
        ③ 위에서 아래로 읽어서 **몇 개인지 한눈에** 들어온다
   ⚠️ HUD(✕·REC·길이) **아래**에서 시작한다. 위에 겹치면 닫기를 누르려다 눌린다.
   ⚠️ 효과 화살표(‹ ›)는 화면 **세로 가운데**라 여기와 안 겹친다. */
/* ⚠️⚠️ **오른쪽 위에 카드로 붙여놨더니 화면 끝에서 잘렸다.** 오른쪽 아래로
   내리고 **배경 카드를 없앤다** — 아이콘만 흰색으로 떠 있으면 영상을 안 가리고,
   엄지가 제일 편한 자리이기도 하다. 어두운 그림에서도 보이게 **그림자**를 준다. */
#s-shoot .camrail {
  position:absolute; z-index:3; right:.9rem; bottom:9.4rem;
  /* ⚠️ 아이콘마다 위아래 여백을 줘서 누를 넓이를 넓혔으므로(아래 `.camtool`),
     `gap` 은 그만큼 줄인다 — 안 줄이면 줄이 통째로 길어진다. 눈에 보이는
     사이 간격은 여백이 대신 만들어주므로 전체 모양은 그대로다. */
  display:flex; flex-direction:column; gap:.45rem; align-items:center;
}
/* ⚠️ **높이가 23px 뿐이었다**(자로 재서 찾았다). 찍는 손은 폰을 들고 있는
   손이라 더 부정확한데, 도구 줄이 제일 작았다.
   → 아이콘 크기는 그대로 두고 **위아래 여백으로** 누를 넓이를 넓힌다.
   ⚠️ 열의 `gap` 을 줄여서 상쇄한다(2499줄) — 안 그러면 줄이 통째로 길어져
      맨 아래 것이 촬영 버튼과 겹친다. */
#s-shoot .camtool {
  width:2.4rem; min-height:2.4rem; padding:.35rem 0;
  border:0; background:none; box-shadow:none; cursor:pointer;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.1rem;
  font-size:1.3rem; line-height:1; color:#fff; opacity:.62;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.75));
}
/* ⚠️ **한 벌의 선 아이콘.** 이모지는 기기마다 그림이 다르고 색이 제멋대로라
   흑백 카메라 UI 에서 혼자 알록달록하고, 크기·굵기가 안 맞아 줄이 안 맞아 보인다.
   갤럭시·아이폰 카메라가 전부 선 아이콘을 쓰는 이유다. */
#s-shoot .camtool svg {
  width:1.45rem; height:1.45rem; display:block;
  fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round;
}
/* 🎙 사선은 **꺼졌을 때만** 그린다 — 색만으로는 켜졌는지 꺼졌는지 헷갈린다. */
#s-shoot .camtool svg .slash { opacity:0; }
#s-shoot .camtool[data-off] svg .slash { opacity:1; }
/* 📝 자막 자리 — ⚠️⚠️ **켜진 줄 하나만 보이게 했더니 어디인지 몰랐다.**
   줄 하나만 떠 있으면 그게 「위」인지 「가운데」인지 비교할 대상이 없다.
   → **세 줄을 다 그리고 지금 것만 진하게.** 흐린 두 줄이 「여기도 갈 수 있다」와
     「지금은 여기가 아니다」를 동시에 말한다. 아래 `em` 이 글씨로 한 번 더. */
#s-shoot .camtool svg .capline { opacity:.24; }
#s-shoot .camtool[data-pos="top"] svg .capline[data-at="top"],
#s-shoot .camtool[data-pos="mid"] svg .capline[data-at="mid"],
#s-shoot .camtool[data-pos="bottom"] svg .capline[data-at="bottom"] {
  opacity:1; stroke-width:2.6;
}
/* ⚠️ 글씨는 **값이 있는 것에만**(타이머의 「3s」). 아이콘으로 읽히는 것에 이름은 소음이다. */
#s-shoot .camtool em {
  font-style:normal; font-size:.62rem; font-weight:700; letter-spacing:-.02em;
  font-family:var(--mono); white-space:nowrap;
}
#s-shoot .camtool em:empty { display:none; }
/* ⚠️ **색으로 칠하지 않는다.** 카드도 색도 없이 **밝기만** 다르게 — 꺼진 것은
   흐리게, 켜진 것은 또렷하게. 주황 카드가 다섯 개면 그게 다시 조잡해진다. */
#s-shoot .camtool[data-on] { opacity:1; }
/* 마이크만 예외 — **꺼진 것이 사고**라 그때만 빨갛다. */
#s-shoot .camtool[data-off] { opacity:1; color:#FF7A66; }
#s-shoot .camtool[hidden] { display:none; }
#s-shoot .camtool:active { transform:scale(.9); }

/* 🔄 앞뒤 전환 — 도구들과 마주 보는 왼쪽 아래. 같은 무게, 같은 모양. */
/* ⚠️⚠️ **자리를 두 군데서 정하고 있었다.** 이 버튼은 `.camleft` 열 **안**에
   있는데 `left`·`bottom` 을 따로 갖고 있어서 열 밖으로 튀어나갔고, 자막 도구보다
   **위**에 앉아 순서가 거꾸로 보였다.
   → 열에 넣었으면 자리는 **열이** 정한다. 여기서는 크기와 모양만 정한다.
   ⚠️ DOM 에서 맨 **뒤**라 열의 맨 아래에 놓인다 — 오른쪽 열 맨 아래(마이크)와
      같은 높이다. 「화면을 바꾸는 것」끼리 한 줄에 선다. */
/* ⚠️⚠️ **`height:2.4rem`(38px)를 줬는데 실제로는 26px 로 눌려 있었다**(자로 재서
   찾았다). 세로 열 안의 flex 아이템이라 **전역 `button { flex:1 }` 의 shrink 가
   높이를 깎은 것**이다 — 높이를 적어놔도 그 값이 지켜진다는 보장이 없다.
   ⚠️ 같은 열의 `.camtool` 은 `min-height` 가 있어서 안 눌렸다. 여기도 못 박는다. */
#s-shoot .camflip {
  position:static; z-index:3; flex:0 0 auto;
  width:2.4rem; height:2.4rem; min-height:2.4rem; padding:0; border:0; background:none;
  box-shadow:none; cursor:pointer; display:grid; place-items:center;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.75));
}
#s-shoot .camflip svg {
  width:1.6rem; height:1.6rem; fill:none; stroke:#fff; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round;
}
#s-shoot .camflip:disabled { opacity:.35; }
#s-shoot .camflip:active { transform:scale(.9); }

/* 💡 화면 조명 — 앞카메라용. ⚠️⚠️ **화면을 통째로 하얗게 덮으면 안 된다.**
   자기 얼굴을 보면서 찍는 앱인데 10~30초 동안 화면이 안 보이면 못 찍는다.
   → **테두리만** 밝힌다(링라이트와 같은 원리). 가운데는 그대로 보인다.
   ⚠️ 화면 위에 얹은 것이라 **영상에는 안 들어간다** — 우리는 캔버스를 담는다.
   ⚠️ 눌러서 조작할 것이 아니다. `pointer-events:none` 이 없으면 이게 화면
      전체를 덮어서 **촬영 버튼도 효과 밀기도 다 죽는다.** */
#s-shoot .frontlight {
  position:absolute; inset:0; z-index:1; pointer-events:none;
  box-shadow:
    inset 0 0 0 2.2rem rgba(255,255,255,.95),
    inset 0 0 2.4rem 3rem rgba(255,255,255,.5);
}
#s-shoot .frontlight[hidden] { display:none; }
/* ⚠️ 조명은 캔버스 **위**라서, 그 위에 떠야 하는 것들에는 자리를 따로 준다.
      (이것들은 DOM 에서 조명보다 **앞**에 있어서 z-index 가 없으면 밑에 깔린다.) */
#s-shoot .hud, #s-shoot .count, #s-shoot .cue,
#s-shoot .status { z-index:2; }

/* ── 🧠 퀴즈 보기 ──────────────────────────────────────────────────────────
   ⚠️⚠️⚠️ **`.picks` 는 이름만 있고 규칙이 하나도 없었다.** 그래서 `.viewport`
      (가로 flex)의 **칸 하나**가 되어 캔버스 **옆으로 밀려났고**, `overflow:hidden`
      에 잘려서 오른쪽 끝에 보일락 말락 걸쳐 있었다 —
      "정답 보기가 우측 끝에 보일랑말랑하게 3개가 떴던거같아".
      `.pickbtn` 에도 규칙이 없어서 전역 버튼 모양(크림색·검은 글씨) 그대로였다.
   ⚠️ 이 사고를 **이 파일에서만 네 번째** 낸다(`.quiet`·`.scrollx`·`.pwbox`·여기).
      **class 를 새로 지으면 그 자리에서 규칙도 같이 적는다.** 이름만 짓는 것은
      아무 일도 안 한 것이고, CSS 는 없는 규칙에 대해 **조용하다.**
   ⚠️ 캔버스 **위에 얹은 버튼**이라 영상에는 안 들어간다. 고른 결과만 자막이 된다.
   ⚠️ 셀피로 찍는 중이라 **화면을 보는 것이 곧 카메라를 보는 것**이다 —
      크게, 가운데 가까이 둬야 시선이 안 벗어난다. */
#s-shoot .picks {
  position:absolute; z-index:6; left:1rem; right:1rem; bottom:5.6rem;
  display:flex; flex-wrap:wrap; gap:.5rem; justify-content:center;
}
#s-shoot .picks[hidden] { display:none; }
#s-shoot .pickbtn {
  flex:1 1 6.5rem; max-width:11rem; min-height:3.1rem; padding:.6rem .7rem;
  font-size:.95rem; font-weight:800; line-height:1.25;
  color:#fff; background:rgba(20,17,16,.72); border:2px solid rgba(255,248,242,.6);
  border-radius:16px; box-shadow:none;
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
}
#s-shoot .pickbtn:active { transform:scale(.96); }
/* 고른 것만 주황. ⚠️ 나머지는 **흐려진다** — 뭘 골랐는지 영상 찍는 중에도 보여야 한다. */
#s-shoot .pickbtn[disabled] { opacity:.35; }
#s-shoot .pickbtn[data-picked] {
  opacity:1; background:var(--hot); border-color:#fff; color:#fff;
}
/* ⚠️⚠️ **답을 고르는 동안 카메라 도구를 치운다.** 도구 열·앞뒤 전환·바가
   보기와 같은 자리를 다투는데, 그 3~4초에 확대를 만질 일은 없다.
   한 번에 한 가지만 시킨다 — 그게 이 화면의 규칙이다. */
#s-shoot[data-picking] .camrail,
#s-shoot[data-picking] .camflip,
#s-shoot[data-picking] .bars { display:none; }

/* 🔍 확대 · 🔆 밝기 — ⚠️ **핀치를 없앴다.** 두 손가락으로 당기면 브라우저가
   통째로 확대돼버려서(주소창까지) 찍을 수가 없었다. 바 두 개로 나란히. */
#s-shoot .bars {
  position:absolute; z-index:3; left:.9rem; right:.9rem; bottom:6.2rem;
  display:flex; gap:.7rem;
}
#s-shoot .bar {
  flex:1; min-width:0; display:flex; align-items:center; gap:.4rem;
  padding:.3rem .6rem; border-radius:999px; background:rgba(0,0,0,.34);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
/* 왼쪽 끝 그림(돋보기·해). ⚠️ **작게.** 끄는 손잡이보다 크면 그림이 주인공이
   되는데, 여기서 정하는 것은 그림이 아니라 값이다. */
#s-shoot .bar .ico {
  flex:0 0 auto; width:.95rem; height:.95rem; display:block;
  fill:none; stroke:#fff; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  opacity:.82;
}
/* 지금 값. ⚠️ 폭을 고정한다 — `+50`↔`0` 으로 글자 수가 바뀔 때마다 바가
   덜컹거리면 끌던 손이 값을 놓친다. */
#s-shoot .bar .tag {
  flex:0 0 auto; font-size:.72rem; line-height:1; color:#fff;
  font-family:var(--mono); font-weight:700; min-width:2.1rem; text-align:right;
  font-variant-numeric:tabular-nums;
}
/* ⚠️ 잡는 높이가 24px 뿐이었다. 다만 이 줄은 **위로 도구 열이, 아래로 촬영
   버튼이** 있어서 마음껏 못 키운다 — 2rem 까지만 넓힌다(그 이상은 겹친다,
   check.mjs 의 「도구가 서로 겹치는가」가 지킨다). */
#s-shoot .bar input[type=range] {
  flex:1; min-width:0; height:2rem; margin:0; appearance:none; background:none;
}
#s-shoot .bar input[type=range]::-webkit-slider-runnable-track {
  height:3px; border-radius:3px; background:rgba(255,255,255,.45);
}
#s-shoot .bar input[type=range]::-webkit-slider-thumb {
  appearance:none; width:1.05rem; height:1.05rem; border-radius:50%;
  background:#fff; border:0; margin-top:-.48rem;
  box-shadow:0 1px 4px rgba(0,0,0,.4);
}
#s-shoot .bar input[type=range]::-moz-range-track {
  height:3px; border-radius:3px; background:rgba(255,255,255,.45);
}
#s-shoot .bar input[type=range]::-moz-range-thumb {
  width:1.05rem; height:1.05rem; border-radius:50%; background:#fff; border:0;
}

/* ── 촬영 버튼 ──
   ⚠️⚠️ **카메라 화면 *바깥* 아래에 있었다.** 영상은 9:16 이고 요즘 폰은 20:9 라
      **위아래에 검은 띠가 남는다** — 어차피 비는 자리다. 거기 얹으면 영상은
      그대로 크고 화면이 한 덩어리가 된다(9:16 이 깨지지 않는다).
   ⚠️ 동그란 큰 버튼은 카메라라면 누구나 아는 모양이라 **설명이 필요 없다.** */
#s-shoot .shootrow {
  position:absolute; z-index:4; left:0; right:0; bottom:.5rem;
  display:flex; flex-direction:column; align-items:center; gap:.25rem;
  pointer-events:none;
}
#s-shoot .shootrow > * { pointer-events:auto; }
#s-shoot .shootrow[hidden] { display:none; }

/* 🌏 외국어 — 먼저 듣는 자리. ⚠️ 촬영 버튼과 **같은 자리**에 둔다(둘이 같이
   있으면 뭘 눌러야 할지 모른다). 듣는 동안은 이것만, 끝나면 저것만. */
#s-shoot .listen {
  position:absolute; z-index:4; left:1rem; right:1rem; bottom:.9rem;
  display:flex; flex-direction:column; align-items:center; gap:.5rem;
  padding:.8rem .9rem; border-radius:18px; background:rgba(0,0,0,.55);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
}
#s-shoot .listen[hidden] { display:none; }
#s-shoot .listen .say {
  margin:0; font-size:.86rem; font-weight:800; color:var(--on-stage); text-align:center;
}
#s-shoot .listen .row { display:flex; gap:.5rem; width:100%; }
#s-shoot .listen .row button { flex:1; }
#s-shoot .shootbig {
  width:4.6rem; height:4.6rem; flex:0 0 auto; padding:0; border-radius:50%;
  background:none; border:3.5px solid var(--on-stage); box-shadow:none;
  display:grid; place-items:center; cursor:pointer;
}
#s-shoot .shootbig i {
  display:block; width:3.5rem; height:3.5rem; border-radius:50%;
  background:var(--hot); transition:transform .12s, border-radius .12s;
}
#s-shoot .shootbig:active i { transform:scale(.88); }
#s-shoot .shootbig:disabled { opacity:.4; }
/* 찍는 중에는 **네모**로. 어느 카메라 앱에서나 「멈춤」이라 새로 배울 게 없다. */
#s-shoot .shootbig[data-live] i { border-radius:22%; transform:scale(.6); }
#s-shoot .shoothint {
  font-size:.76rem; font-weight:700; color:var(--on-stage-2); min-height:1em;
}
#s-shoot .shoothint:empty { display:none; }

/* ⚠️⚠️ **화살표가 영상 밑에 띠(.lookbar)로 따로 있었다** — "좌우 버튼 누르는
   방식이 넘 촌스럽고". 미는 것은 이미 화면 전체가 받고 있었는데 **표만 엉뚱한
   데** 있어서, 밀 수 있다는 걸 아무도 몰랐다.
   → 화면 **안** 좌우 끝에 작은 세모. 밀어도 되고 눌러도 된다. */
/* ⚠️ **세로 가운데다.** 위로 올렸더니 "너무 상단으로 옮겨졌다"는 말을 들었다 —
   화면을 미는 자리는 가운데가 맞다. 도구 열·앞뒤 전환을 촬영 버튼 위로 올려서
   자리를 비웠다(겹치면 효과를 바꾸려다 마이크가 꺼진다). */
/* ⚠️⚠️ **화살표가 화면 좌우 가운데에 있어서 도구 열과 겹쳤다.**
   조명·타이머 위에 얹혀서 효과를 바꾸려다 마이크가 꺼졌다.
   ⚠️ 가장자리는 **이미 두 열이 쓰고 있다**(왼쪽=화면에 뭐가 보이나, 오른쪽=카메라).
      화살표를 거기 두면 어디에 놓든 무언가와 부딪힌다.
   → **효과 이름 옆으로 모은다.** ‹ 뽀샤시 › 하나로 읽히고, 미는 것을 모르는
     사람도 여기서 바꿀 수 있다. 자리를 다투지도 않는다. */
/* ⚠️⚠️ **양쪽 끝 세로 가운데다.** 한 덩어리로 묶어 아래에 뒀더니 「하단에
   몰려 있다」가 됐다 — 화면을 좌우로 **미는** 일에 쓰는 버튼이 아래 구석에 있으면
   미는 동작과 이어지지 않는다.
   ⚠️ 예전에 도구 열과 겹쳤던 것은 **열이 화면 중앙 높이에 있던 시절** 얘기다.
      지금 두 열은 아래에 붙어 위로 쌓이므로(bottom:9.4rem 부터) 가운데는 비어 있다.
      겹치는지는 check.mjs 가 네 쌍을 재서 확인한다. */
#s-shoot .lookarrow {
  position:absolute; top:50%; transform:translateY(-50%); z-index:3;
  width:2.1rem; height:2.6rem; padding:0; border:0; box-shadow:none; cursor:pointer;
  border-radius:12px; background:rgba(0,0,0,.28);
  display:grid; place-items:center;
  /* ⚠️ 영상 위에 얹는 것이라 **밝은 그림에서도 보여야** 한다. 반투명 검정 + 흰 획. */
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
}
#s-shoot .lookarrow svg {
  width:1.15rem; height:1.15rem;
  fill:none; stroke:#fff; stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round;
}
#s-shoot .lookarrow:active { background:rgba(0,0,0,.5); transform:translateY(-50%) scale(.94); }
#s-shoot .lookarrow[hidden] { display:none; }

/* 효과 이름 — 화면 아래 가운데에 **잠깐만** 떴다 사라진다.
   ⚠️ 늘 떠 있으면 그것도 영상 위의 방해물이다. */
/* ⚠️⚠️ **화면 맨 아래 구석에 작게 떠서 아무도 못 봤다.** 효과를 바꾸는 순간
   눈은 **얼굴(가운데)** 을 보고 있는데, 이름은 발밑에 있었다 — 뭐가 바뀌었는지
   모르니 미는 재미도 없고 고를 수도 없다.
   → **화면 한가운데**, 크게. 잠깐 떴다 사라진다(늘 떠 있으면 그게 방해물이다). */
.lookname {
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%) scale(1);
  /* ⚠️ **우리 글꼴로 작게.** 이모지를 붙여 크게 띄우면 촌스럽고, 무엇보다
     영상 위에 얹는 글씨는 **작고 조용해야** 그림을 안 가린다. */
  z-index:5; padding:.4rem .95rem; border-radius:999px;
  background:rgba(0,0,0,.5); -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  color:#fff; font-family:var(--round); font-size:.95rem; font-weight:400;
  letter-spacing:.02em; white-space:nowrap;
  text-shadow:0 2px 10px rgba(0,0,0,.5);
  opacity:0; transition:opacity .2s, transform .2s; pointer-events:none;
}
/* 방금 바뀐 것만 보인다 — 미는 동안 뭐가 걸렸는지는 알아야 한다. */
.lookname[data-show] { opacity:1; transform:translate(-50%,-50%) scale(1.06); }

/* ── 가져올 부분 고르기 ──
   ⚠️ **결과와 같은 9:16 틀 안에서** 보여준다. 원본을 보여주고 "여기가 잘립니다"라고
      적으면 잘린 뒤를 상상해야 한다 — 상상하게 만들면 안 고른다. */
.trimstage {
  width:100%; max-width:15rem; margin:.4rem auto 0; aspect-ratio:9/16;
  background:#000; border:var(--line); border-radius:16px; overflow:hidden;
}
.trimstage video { width:100%; height:100%; object-fit:cover; display:block; }
/* ⚠️ **높이가 16px 이라 손잡이를 못 잡았다**(자로 재서 찾았다). 손가락은 16px 를
   정확히 못 짚는다 — 잡으려다 빗나가면 "안 움직인다"가 된다.
   → 보이는 굵기는 그대로(브라우저 기본 트랙), **잡는 높이만** 40px 로 넓힌다. */
.slider {
  width:100%; margin:.35rem 0 .1rem; accent-color:var(--hot);
  background:transparent; height:2.5rem;
}

/* ── 마이크 막대 ──
   ⚠️ **말이 들어가고 있는지 보여준다.** 말하는 서비스인데 찍는 동안 마이크가
      살아 있는지 확신할 방법이 없었다 — 다 찍고 나서 소리가 없는 걸 알면
      그때는 다시 못 찍는 순간이다. */
.wave {
  display:flex; align-items:flex-end; gap:2px; height:1.1rem;
  padding:0 .45rem; border-radius:999px; background:rgba(0,0,0,.35);
}
.wave[hidden] { display:none; }
.wave i {
  width:3px; height:20%; border-radius:2px; background:var(--on-stage);
  transition:height .09s linear;
}
/* ⏱ **고른 길이를 채운 순간의 배지** — 「✓ +1.2」.
   ⚠️⚠️ 예전(`data-over`)엔 **넘긴 것을 흐리게** 만들어서 「지금 잘못하고 있다」로
      읽혔다. 실제로는 여유 안이라 괜찮은 상태이고, 오히려 **여기가 끊기 좋은
      자리**라고 말해줘야 하는 순간이다.
   → 흐리게가 아니라 **또렷하게.** 우리 주홍으로 바꿔서 눈이 가게 하고,
     한 번 튀어서 「지금 됐다」를 알린다(움직임을 못 견디는 사람에겐 색만). */
.timer[data-done] {
  background:var(--hot); color:#fff; border-color:#fff;
  animation:timerdone .34s ease-out;
}
@keyframes timerdone {
  0%   { transform:scale(1); }
  45%  { transform:scale(1.14); }
  100% { transform:scale(1); }
}
@media (prefers-reduced-motion: reduce) { .timer[data-done] { animation:none; } }

/* ⚠️ 막대만 있으면 뭔지 모른다("점 네개는 뭐야?"). 마이크 옆에서 오르내려야
   설명 없이 「소리가 들어오는 중」으로 읽힌다. */
.wave .wmic {
  width:.72rem; height:.72rem; align-self:center; margin-right:.16rem;
  fill:none; stroke:var(--on-stage); stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}

/* ── 🎲 굴리기 ──
   ⚠️⚠️ **화면 맨 밑 띠에 납작한 버튼으로 붙어 있었다.** 이 화면에서 할 일이
      그것 하나뿐인데 생김새는 곁버튼이었고, 눌렀을 때 무슨 일이 일어나는지도
      안 적혀 있었다("주사위 굴리기가 무슨 의민지 설명이 없는데").
   ⚠️ **동그란 큰 버튼**을 종류 바로 밑에 둔다 — 스크롤 없이 눈에 들어오는 자리다.
      살짝 들썩여서 여기를 누르는 것임을 말한다. */
.rollzone { display:flex; flex-direction:column; align-items:center; margin:1.4rem 0 .4rem; }
/* ⚠️ **이 화면에서 할 일은 이것 하나다.** 그러니 제일 커야 하고, 안의 그림도
   버튼만큼 커야 한다 — 작은 그림이 큰 원 안에 있으면 원만 크고 빈 느낌이 난다. */
.rollbig {
  width:8.4rem; height:8.4rem; flex:0 0 auto; padding:0; border-radius:50%;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.25rem;
  background:var(--hot); color:#fff;
  border:2.5px solid var(--edge); box-shadow:0 6px 0 rgba(34,30,28,.14), var(--pop);
  cursor:pointer; animation:rollbob 2.2s ease-in-out infinite;
}
.rollbig .face { display:flex; line-height:1; animation:rolltilt 2.2s ease-in-out infinite; }
/* ⚠️ **주사위 그림은 흰 선으로 크게.** 주황 위에 주황빛 그림이면 안 보인다 —
   눈은 무늬가 아니라 **모양**을 보고 "주사위"를 읽는다. */
.rollbig .face .ti {
  width:2.7rem; height:2.7rem;
  stroke:#fff; stroke-width:1.7;
}
.rollbig .face .ti circle { fill:#fff; stroke:none; }
.rollbig .go { font-size:1.02rem; font-weight:800; letter-spacing:-.02em; color:#fff; }
.rollbig:active {
  transform:translateY(4px); box-shadow:0 2px 0 rgba(34,30,28,.14); animation:none;
}
/* ⚠️ 움직임을 끈 사람에게는 안 움직인다. 멀미·주의력 문제로 끄는 설정이다. */
@media (prefers-reduced-motion:reduce) {
  .rollbig, .rollbig .face { animation:none; }
}
@keyframes rollbob  { 50% { transform:translateY(-6px); } }
@keyframes rolltilt { 25% { transform:rotate(-14deg); } 75% { transform:rotate(14deg); } }
.rollsay {
  margin:.7rem 0 0; text-align:center; font-size:.82rem; color:var(--ink-3);
  line-height:1.55; font-weight:700;
}
.rollsay b { color:var(--ink-2); }
/* 「(포인트 30점 필요)」는 **그 밑에 더 작게.** 버튼 이름 옆에 붙이면 그것도 이름으로 읽힌다. */
.rollsay.sm { margin-top:.2rem; font-size:.74rem; opacity:.8; }
.rollsay.sm:empty { display:none; }

/* 버튼 이름 옆의 곁말(「(3번 남음)」). ⚠️ 이름과 **같은 크기로 두면 둘 다 이름으로
   읽혀서** 버튼이 무슨 일을 하는지가 흐려진다. 곁말은 곁말처럼 보여야 한다. */
button .sub { font-size:.78rem; font-weight:700; opacity:.72; }
button .sub:empty { display:none; }

/* 되돌릴 수 없는 줄. ⚠️ **색으로만 구분한다.** 모양까지 다르면 그건 다른 종류의
   물건으로 읽혀서, 무엇이 무엇인지 알 수가 없어진다. */
.stamp.danger .txt b { color:var(--bad); }
.stamp.danger { border-color:var(--bad); }

/* 켜짐/꺼짐 스위치. ⚠️ **지금 켜져 있는지만 보이면 된다** — 글씨로 설명하지 않는다. */
.sw {
  flex:0 0 auto; width:2.6rem; height:1.5rem; border-radius:999px;
  background:var(--sunk); border:1.5px solid var(--edge); position:relative;
  transition:background .15s;
}
.sw::after {
  content:""; position:absolute; top:2px; left:2px;
  width:1.05rem; height:1.05rem; border-radius:50%; background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.2); transition:transform .15s;
}
.stamp[data-on] .sw { background:var(--hot); border-color:var(--hot); }
.stamp[data-on] .sw::after { transform:translateX(1.1rem); }
.sw[hidden] { display:none; }


/* ══ 넓은 화면 ══════════════════════════════════════════════════════════
   ⚠️⚠️ **폭 규칙을 두 벌 만들었다가 탭바를 깼다.** 34rem 짜리와 46rem 짜리가
     같은 것을 다르게 정해서, 나중 것의 `max-width` 가 `width` 없이 걸리자
     **고정 요소가 내용 크기로 쪼그라들었다.** 이 저장소에서 제일 자주 난 사고가
     「같은 것을 두 군데서 관리」인데 **폭에서도 냈다.**
     → **폭은 이 블록 하나에서만 정한다. 다른 데 쓰지 말 것.**

   ⚠️ 왜 아주 넓게 안 늘리나 — 이 앱의 산출물이 **9:16 세로 영상**이다. 촬영·확인
     화면은 폰 비율이어야 하고, 목록도 그 영상의 세로 썸네일이 주인공이다.
     다만 **딱 붙는 폰 폭은 데스크톱에서 답답하다** → 상한을 넉넉히 두고
     **그 안에서는 고무줄처럼** 늘어나게 한다(min(100%, 42rem)).
   ⚠️ **방 목록만 열을 늘린다.** 그건 읽는 화면이라 넓을수록 좋다 —
     촬영·확인은 안 건드린다. */
@media (min-width: 40rem) {
  body { background:var(--sunk); }

  .screen:not(#s-shoot) {
    background:var(--paper);
    width:min(100%, 42rem);
    margin:0 auto;
    box-shadow:0 0 0 1px var(--edge), 0 8px 40px rgba(34,30,28,.07);
  }

  /* ⚠️ `width` 를 같이 준다. `max-width` 만 주면 고정 요소가 내용 크기로 쪼그라든다. */
  .tabbar {
    width:min(100%, 42rem);
    left:50%; right:auto; transform:translateX(-50%);
  }

  /* 방 목록은 넓어진 만큼 열을 늘린다. 읽는 화면이라 넓을수록 좋다. */
  .places { grid-template-columns:repeat(3, minmax(0, 1fr)); }
}

/* 처음 온 사람 안내. ⚠️ **한 번만 뜬다** — 매번 뜨면 안내가 아니라 문이다. */
.helloicon { font-size:2.4rem; text-align:center; line-height:1; margin-bottom:.3rem; }

/* 🚪 **세 걸음.** ⚠️⚠️ 예전엔 `<ol class="howto">` 였다 — 기본 마커에 설명을
   em대시로 이어 붙였더니, 줄이 접히는 순간 **둘째 줄이 마커 밑으로 파고들어**
   항목마다 왼쪽이 어긋났다. 대시는 왼쪽에 **짝대기 하나가 떠 있는** 모양이라
   더 어수선했다("글씨가 뒤죽박죽").
   → 번호는 **동그란 칩**, 제목과 설명은 **위아래로**. 격자라 몇 줄이 접히든
     왼쪽 끝이 항상 맞고, 설명이 제목 밑에 오니 대시가 필요 없다.
   ⚠️ 기본 마커를 반드시 끈다(`list-style:none`) — 안 끄면 칩과 숫자가 겹쳐 뜬다. */
.hsteps {
  list-style:none; margin:1rem 0 .2rem; padding:0;
  display:flex; flex-direction:column; gap:.7rem; text-align:left;
}
.hsteps li {
  display:grid; grid-template-columns:1.55rem 1fr; gap:.6rem; align-items:start;
}
.hnum {
  width:1.55rem; height:1.55rem; border-radius:50%;
  background:var(--hot-soft); color:var(--hot);
  font-size:.8rem; font-weight:800; line-height:1.55rem; text-align:center;
  /* ⚠️ 숫자 칩은 절대 안 줄어든다 — 줄면 옆 글씨와 붙어서 격자가 무너진다. */
  flex:0 0 auto;
}
.hsteps b { display:block; font-size:.94rem; line-height:1.45; }
.hsteps em {
  display:block; font-style:normal; margin-top:.1rem;
  font-size:.82rem; line-height:1.5; color:var(--ink-3);
}
.helloline {
  margin-top:1rem; padding-top:.75rem; border-top:1px solid var(--line);
  text-align:left; line-height:1.65;
}

/* ── 촬영 화면 왼쪽 열 — 「화면에 무엇이 얹히나」 ──
   ⚠️ 오른쪽 열(조명·타이머·격자·마이크)은 **카메라를 다루는 것**이고,
      왼쪽은 **화면에 무엇이 보이나**(자막 자리·굽기·앞뒤)다. 성격이 달라서
      섞여 있으면 매번 찾아야 한다.
   ⚠️ 화면 효과를 좌우로 미는 것도 「화면에 무엇이 보이나」라 같은 편이다. */
/* ⚠️ **오른쪽 열과 같은 바닥에서 시작한다**(둘 다 bottom:9.4rem). 값이 다르면
   맨 아래 두 개(앞뒤 전환 · 마이크)가 어긋난 채로 놓인다 — 한 줄로 읽히지 않는다.
   ⚠️ 사이 간격도 오른쪽(1rem)과 같게. 한쪽만 촘촘하면 두 열이 다른 물건이 된다. */
#s-shoot .camleft {
  position:absolute; left:.9rem; bottom:9.4rem; z-index:3;
  /* ⚠️ 오른쪽 열(`.camrail`)과 같은 이유로 줄인다 — 두 열의 간격이 다르면
     같은 도구인데 한쪽만 성글어 보인다. */
  display:flex; flex-direction:column; align-items:center; gap:.45rem;
}
#s-shoot .camleft .camtool { margin:0; }

#s-shoot .lookarrow.left  { left:.5rem; }
#s-shoot .lookarrow.right { right:.5rem; }
/* 이름표는 **화면 한가운데**에 따로 둔다(기본 `.lookname` 과 같은 자리).
   ⚠️ 화살표에 붙여두면 화살표를 옮길 때마다 같이 끌려간다 — 방금 그랬다.
   그렇다고 자리를 따로 정해야 하는 건 아니다 — `position:absolute` 로
   떼어놓기만 하면 되고, 어디에 뗄지는 기본값(가운데)을 그대로 쓴다.
   ⚠️⚠️⚠️ **한때 `bottom:7.4rem` 으로 아래에 두면서 `top` 을 안 지워서
   세로로 늘어진 막대가 됐었다**("흑백"·"차갑" 두 글자가 화면 절반을 잇는
   알약). 그다음엔 `top:auto` 로 늘어짐만 고치고 아래 자리는 그대로
   뒀는데, "왜 아래에 뜨냐 가운데에 뜨게 해달라"는 요청이 왔다 — 애초에
   기본 `.lookname` 이 가운데를 쓰던 이유(카메라 도구 화면에서 잘 보이게)와
   같다. → 아예 `top`·`bottom` 을 안 건드리고 기본값(가운데)을 물려받는다. */
#s-shoot .lookname {
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); z-index:3;
  padding:.16rem .6rem; border-radius:999px; background:rgba(0,0,0,.32);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
}
/* ⚠️ 아이디 규칙이 `transform` 을 다시 정하므로, "떴을 때 살짝 커지는" 효과
   (`.lookname[data-show]`)도 여기서 같이 정해야 한다 — 안 그러면 이 화면
   에서만 그 효과가 조용히 사라진다(더 센 규칙이 transform 을 덮으므로). */
#s-shoot .lookname[data-show] { transform:translate(-50%,-50%) scale(1.06); }
