/* ===========================================================================
   보부상 게임 — 협상 화면 외 나머지 화면 (P0 확정본)
   2026-08-11 · bobusang-ui.css 와 함께 쓴다 (팔레트·픽셀 규칙은 그쪽에 있다)

   담긴 화면
     .bs-shop    아침 · 도매상(매입)
     .bs-road    길 · 마을 이동
     .bs-night   밤 · 정산
     .bs-ending  엔딩 · 회고록

   전부 .bs-screen 을 뿌리로 쓴다. 마을 전환도 .groknar 하나로 똑같이 먹는다.
   시안 이미지: graphics/output/screens/*.png
   =========================================================================== */

/* ── 상시 HUD ───────────────────────────────────────────────────────────────
   어느 화면에서도 같은 자리다. 일차·빚·골드는 항상 보여야 결정이 무거워진다. */
.bs-screen .bs-topbar{
  position:absolute; top:3%; left:2.4%; right:2.4%; z-index:6;
  display:flex; justify-content:space-between; align-items:flex-start; gap:8px;
}
.bs-screen .bs-chip b{ color:var(--gold) }
.bs-screen .bs-chip b.bad{ color:var(--danger-txt) }
/* 목표 칩이 달성된 순간 [개편 2026-08-23 · 하루흐름개편 【5】] — 로비 배지의 .bs-goal.ok 와 같은 신호다.
   ⚠️ 상단바는 일차(왼) · 목표(가운데) · 골드(오른) 세 칸을 space-between 으로 벌린다.
      목표 칩을 골드 칩 **뒤에** 넣으면 골드가 가운데로 밀려 자리가 흔들린다 — 순서를 지켜라 */
.bs-screen .bs-topbar .bs-chip.ok{ border-color:var(--gold); color:var(--c8) }

/* 일차 막대 — 12칸. 지나간 날 골드, 오늘 흰색, 남은 날 흐림 */
.bs-screen .bs-days{ display:flex; gap:2px; align-items:center }
.bs-screen .bs-days i{
  display:block; width:clamp(4px,.7cqw,7px); height:clamp(8px,1.3cqw,14px);
  background:var(--c4);
}
.bs-screen .bs-days i.past{ background:var(--gold) }
.bs-screen .bs-days i.today{ background:var(--c8) }

/* ── 공통 부품 ──────────────────────────────────────────────────────────────*/
.bs-screen .bs-plate{
  background:var(--c1); color:var(--c7);
  border:2px solid var(--c5); box-shadow:4px 4px 0 var(--c1);
}
.bs-screen .bs-plate.light{ background:var(--c7); color:var(--c1); border-color:var(--c1) }
.bs-screen .bs-plate.warn { border-color:var(--danger) }
.bs-screen .bs-h{
  font-weight:700; letter-spacing:.06em; color:var(--c8);
  border-bottom:2px solid var(--c3);
  padding-bottom:clamp(3px,.6cqw,6px); margin-bottom:clamp(5px,1cqw,10px);
}
.bs-screen .bs-btn{
  background:var(--c7); color:var(--c1); border:2px solid var(--c1);
  font:inherit; font-weight:700; cursor:pointer; white-space:nowrap;
  padding:clamp(3px,.6cqw,7px) clamp(8px,1.5cqw,16px);
}
.bs-screen .bs-btn.ghost{ background:var(--c2); color:var(--c7); border-color:var(--c5) }
.bs-screen .bs-btn.gold { background:var(--gold); color:var(--c1); border-color:var(--c1) }
.bs-screen .bs-btn:disabled{ background:var(--c2); color:var(--c4); border-color:var(--c3); cursor:default }
.bs-screen .gold-t{ color:var(--gold); font-weight:700 }
.bs-screen .bad-t { color:var(--danger-txt); font-weight:700 }
.bs-screen .dim-t { color:var(--c5) }
.bs-screen .bs-veil{ position:absolute; inset:0; background:rgba(20,26,14,.34) }
.bs-screen .bs-veil.deep{ background:rgba(12,16,8,.62) }

/* ── 1 · 아침 도매상 ────────────────────────────────────────────────────────
   ⚠️ 품목이 8종이면 목록이 화면을 넘친다. 6종으로 맞추거나 목록에 스크롤을 준다. */
.bs-screen .bs-shop-list{ position:absolute; left:2.4%; top:13%; width:53%; z-index:5 }
.bs-screen .bs-bagbox  { position:absolute; right:2.4%; top:13%; width:41%; z-index:5 }

.bs-screen .bs-item{
  display:flex; align-items:center; gap:clamp(6px,1.1cqw,12px);
  padding:clamp(4px,.75cqw,8px) clamp(6px,1.1cqw,12px);
  border-bottom:2px solid var(--c2);
}
.bs-screen .bs-item:last-child{ border-bottom:0 }
.bs-screen .bs-icon{
  flex:none; width:clamp(20px,3.4cqw,38px); height:clamp(20px,3.4cqw,38px);
  background:var(--c2); border:2px solid var(--c5);
  display:flex; align-items:center; justify-content:center;
  color:var(--c4); font-size:clamp(7px,1.1cqw,11px);
}
.bs-screen .bs-item .nm{ flex:1; color:var(--c8); font-weight:700 }
.bs-screen .bs-item .ds{
  display:block; font-weight:400; color:var(--c5); font-size:clamp(7.5px,1.15cqw,12px);
}

/* 봇짐 8칸 — 매입 화면과 봇짐 오버레이가 같은 부품을 쓴다
   ⚠️ 2026-08-12 감수 — repeat(4,1fr) 로 되돌리지 마라. 1fr 은 minmax(auto,1fr) 이라
   트랙이 자식의 min-content 아래로 줄지 않는다. 칸에 아이템이 들어가면(64px 아이콘 +
   이름 + 가격) min-content 가 커져서 그리드가 컨테이너를 뚫는다.
   실측: 컨테이너 428px 인데 트랙 합이 111.188×4 + gap 8.944×3 = 471.6px → 43.6px 넘침.
   4번째 열과 아랫줄이 판 밖으로 삐져나갔다. minmax(0,1fr) 이라야 컨테이너에 맞춰 줄어든다. */
.bs-screen .bs-bag{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:clamp(4px,.8cqw,9px) }
.bs-screen .bs-cell{
  aspect-ratio:1; position:relative; padding:2px; text-align:center; min-width:0; overflow:hidden;
  background:var(--c2); border:2px solid var(--c5); color:var(--c6);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px;
  font-size:clamp(6.5px,1.05cqw,11px);
}
.bs-screen .bs-cell.empty{ background:transparent; border-style:dashed; border-color:var(--c3); color:var(--c3) }
/* 아직 안 열린 칸 [2026-08-23 · 지시문_봇짐레벨링 【4-1】]. 「비었다」와 달라야 한다 —
   빈 칸이 아니라 **없는 칸**이다. 칸은 늘 8개(BAG_MAX)를 그리고, bagCap 밖이 이 꼴이 된다 */
.bs-screen .bs-cell.dead{ background:rgba(0,0,0,.5); border:2px solid transparent; color:transparent }
.bs-screen .bs-cell.pick { border-color:var(--gold) }
.bs-screen .bs-cell .pr  { color:var(--gold); font-weight:700 }
/* .bs-cell .spoil — 은퇴 [2026-08-17 · 상함 시스템 폐지] */

.bs-screen .bs-footbar{
  position:absolute; left:2.4%; right:2.4%; bottom:3.4%; z-index:5;
  display:flex; gap:clamp(5px,1cqw,11px); align-items:stretch;
}
.bs-screen .bs-rumor{ flex:1; padding:clamp(5px,1cqw,11px) clamp(8px,1.5cqw,16px) }

/* ── 2 · 길 · 마을 이동 — 은퇴 [2026-08-18] ─────────────────────────────────
   .bs-ask / .bs-roads(밤의 「어느 길로 갈 텐가」). EARLY_FLOW_SPEC 3-9 로
   phase road 를 없애고 낮 로비의 국경 관문 하나로 합쳤다. */

/* ── 3 · 밤 정산 ────────────────────────────────────────────────────────────
   빚 잔액이 줄어드는 걸 실감하는 유일한 자리다. 빚을 가장 크게 둔다.

   2026-08-12 감수 — 밤 램프를 여기서 입힌다.
   STYLE_SPEC 2-4 에 「밤·비 변주」 램프가 정의돼 있는데 쓰이질 않아서, 화면 제목이
   "밤에 들은 소문"인데 그림은 대낮이었다. 여섯 화면이 전부 같은 밝기라 하루가
   흘렀다는 감각이 없었다. 램프만 바꾸면 아침(그린) → 낮(그린/앰버) → 밤(블루)으로
   리듬이 생긴다. 마을 구분은 배경 그림이 이미 하고 있다.

   밤 화면의 .bs-screen 에는 따로 클래스가 없어서 :has() 로 판별한다 — JSX 를
   건드리지 않아도 되고, :has() 를 모르는 브라우저에서는 그냥 예전 모습이 나온다.
   신호색(--gold/--danger)은 팔레트 밖이라 밤에도 그대로 둔다. */
.bs-screen:has(.bs-night-wrap){
  --c1:#141c26; --c2:#22303f; --c3:#3f5a6b; --c4:#6b8f9e;
  --c5:#9cbcc2; --c6:#c2d6d4; --c7:#dde9e4; --c8:#eef4f0;
}
/* 배경까지 밤으로 눌러야 UI만 파랗고 배경은 낮인 어긋남이 안 생긴다.
   그라데이션 금지 규칙에 맞춰 단색 반투명 한 겹으로만 깐다. */
.bs-screen:has(.bs-night-wrap) .bs-veil.deep{ background:rgba(16,22,32,.78) }

/* [개편 2026-08-23 · 기획\ux시안\인계_여관정산_프로그래밍.md] 펼친 두 페이지 장부.
   ⚠️ 좌우 18% + 비율 1.585 + 가로 상한 1000px 은 **셋이 한 세트**다.
      하나만 빼면 큰 창에서 장부가 세로로 늘어진다(버튼 줄 70px 이 고정이라 생기는 일). */
.bs-screen .bs-night-wrap{
  position:absolute; left:18%; right:18%; top:11.5%; bottom:7%; z-index:5;
  display:flex; flex-direction:column; gap:14px;
  justify-content:center; align-items:center;
}
/* 2026-08-12 감수 — 밤 화면에만 상시 HUD(.bs-topbar)가 빠져 있다. 화면을 넘길 때마다
   일차·빚·골드가 사라졌다 나타난다. 빌드가 <TopBar /> 를 넣을 예정인데(TASK_BUILD_0812 4번),
   지금 top:7% 그대로면 HUD 하단(약 8.8%)과 장부 판이 겹친다.
   그래서 「HUD 가 있을 때만」 아래로 비키게 미리 깔아 둔다 — JSX 가 들어오는 순간 자동으로 맞는다.
   HUD 가 없는 지금은 아무 일도 일어나지 않는다. */
.bs-screen:has(.bs-night-wrap):has(.bs-topbar) .bs-night-wrap{ top:11.5% }
/* 은퇴 [2026-08-23 · 펼침 장부 개편] — `.bs-ledger` · `.bs-side` · `.bs-debt` ·
   제네릭 `.bs-total` 넷은 **밤 정산 전용**이었고(전수 grep 확인) 그 화면이 통째로 바뀌었다.
   ⚠️ 특히 제네릭 `.bs-total{font-weight:700}` 을 되살리지 마라 — 아래 새 `.bs-total` 은
      font-weight 를 안 적으므로 볼드가 새어 나온다(bobusang-font.css 「굵게 금지」 위반). */

/* ── 밤 장부 · 펼침 장부 [개편 2026-08-23 · 기획\ux시안\인계_여관정산_프로그래밍.md 2·3절
      · 배치 확정본 확정_여관정산_B안_값표.html · 연출 확정본 확정_여관정산_연출.html] ──
   제본 구멍이 **가운데 접힘선**으로 갔다. 왼쪽 구멍이 글자를 먹던 문제가 구조로 사라진다.
   옛 판(border-image 9-slice · 왼쪽 86px)은 통째로 걷어냈다 — 되돌리려면 인계서 「되돌리는 법」.
   그림 bg_ledger.png 는 낮 정산서(.bs-led)가 아직 써서 안 지웠다.
   ⚠️ 굵게 금지 — 강조는 크기와 색으로만 (bobusang-font.css 규칙).
   ⚠️ :has(.bs-topbar) 로 top 을 11.5% 로 미는 규칙(위 145행)은 그대로 둔다. */
.bs-screen .bs-night-wrap .bs-book{
  flex:none; width:min(100%, 1000px); aspect-ratio:1.585;
  max-height:calc(100% - 70px);      /* 세로 좁은 창에서 넘치지 않게 — 빼지 마라 */
  position:relative; display:flex; min-height:0;
  border:2px solid #6b5334; image-rendering:pixelated;
  background:url("output/ui/ledger/bg_ledger_spread.png") 0 0/100% 100% no-repeat;
  /* ⚠️ [인계서에 없어 보탠 줄 · 2026-08-23] 확정 시안이 **전부 Galmuri11** 로 짜여 있다.
     bobusang-type.css 의 바닥값은 Galmuri14 라, 이 줄이 없으면 12~15px 본문만 다른 글꼴로
     그려져 결재받은 그림과 달라진다(.bs-total 만 type.css 129행이 Galmuri11 로 끌어올린다). */
  font-family:"Galmuri11",system-ui,"Malgun Gothic",sans-serif;
}
/* 가운데 접힘 띠 — 그림이 아니라 CSS 다(늘어나도 폭이 안 변해야 한다) */
.bs-screen .bs-night-wrap .bs-seam{
  position:absolute; left:calc(50% - 20px); top:0; bottom:0; width:40px;
  background:rgba(150,124,80,.16);
  border-left:1px solid rgba(110,88,54,.45); border-right:1px solid rgba(110,88,54,.45);
}
.bs-screen .bs-night-wrap .bs-seam::before{   /* 구멍끼리 잇는 실 */
  content:""; position:absolute; left:19px; top:0; bottom:0; width:2px; background:#9c8258;
}
/* 구멍은 1:1 이다 — 늘리면 타원으로 뭉갠다. 그래서 종이에 안 그리고 여기서 얹는다.
   top(18/50/82%)은 JSX 가 인라인으로 준다 — 시안 확정값 */
.bs-screen .bs-night-wrap .bs-hole{
  position:absolute; left:0; width:40px; height:48px; transform:translateY(-50%);
  background:url("output/ui/ledger/ledger_hole.png") center/40px 48px no-repeat;
  image-rendering:pixelated;
}
/* 두 페이지 — 가운데 쪽 여백 50px 이 구멍과 글자를 갈라 놓는다. 줄이지 마라 */
.bs-screen .bs-night-wrap .bs-pg{
  flex:1; min-width:0; padding:26px 24px; display:flex; flex-direction:column; color:#4a3620;
}
.bs-screen .bs-night-wrap .bs-pg.l{ padding-right:50px }
.bs-screen .bs-night-wrap .bs-pg.r{ padding-left:50px }

.bs-screen .bs-night-wrap .bs-h{
  font-size:15px; color:#3d2c18; border-bottom:1px solid #a58f68;
  padding-bottom:6px; margin-bottom:4px;
}
/* 괘선은 종이 그림이 아니라 이 border-bottom 이 그린다 — 30px 줄 높이에 정확히 붙는다.
   (옛 bg_ledger.png 의 인쇄 괘선은 글자 줄과 안 맞았다. 실물 캡처 확인) */
.bs-screen .bs-night-wrap .bs-item{
  display:flex; justify-content:space-between; align-items:center;
  height:30px; font-size:14px; border-bottom:1px solid #d9c9a6; white-space:nowrap;
}
.bs-screen .bs-night-wrap .bs-item .who{ color:#6d5a3c }
.bs-screen .bs-night-wrap .gold-t{ color:#8a6210 }
.bs-screen .bs-night-wrap .bad-t { color:#a03524 }
.bs-screen .bs-night-wrap .dim-t { color:#8a7a5c }
.bs-screen .bs-night-wrap .bs-total{
  margin-top:auto; border-top:3px double #6b5334; padding-top:10px;
  display:flex; justify-content:space-between; align-items:baseline; font-size:15px;
}
.bs-screen .bs-night-wrap .bs-total .v{ font-size:27px; color:#8a6210 }

/* 오른쪽 세 뭉텅이 */
.bs-screen .bs-night-wrap .bs-blk{ margin-bottom:14px }
.bs-screen .bs-night-wrap .bs-blk:last-child{ margin-bottom:0 }
/* b2 는 머리말이 없다 [2026-08-23 · 사용자 지시] — .bs-h 가 물던 margin-bottom:4px 자리를 메운다.
   ⚠️ 크게 주지 마라. b1 의 .bs-blk margin-bottom:14px 가 이미 뭉텅이 사이를 벌려 놨다 */
.bs-screen .bs-night-wrap .bs-blk.b2{ margin-top:2px }
.bs-screen .bs-night-wrap .bs-stamp{
  border:2px solid #a03524; padding:10px 14px; color:#a03524;
}
.bs-screen .bs-night-wrap .bs-stamp .k{ font-size:12px; color:#7a4b3a }
.bs-screen .bs-night-wrap .bs-stamp .v{ font-size:30px; line-height:1.2 }
.bs-screen .bs-night-wrap .bs-stamp .v span{ font-size:.5em }
/* 날짜 눈금 12칸 — 지난 날은 채우고, 마지막 칸(마감일)은 늘 붉다 */
.bs-screen .bs-night-wrap .bs-gauge{ display:flex; gap:2px; margin:8px 0 4px }
.bs-screen .bs-night-wrap .bs-gauge i{
  width:14px; height:11px; border:1px solid #a58f68; background:transparent;
}
.bs-screen .bs-night-wrap .bs-gauge i.used{ background:#a58f68 }
.bs-screen .bs-night-wrap .bs-gauge i.warn{ background:#a03524; border-color:#a03524 }

.bs-screen .bs-night-wrap .bs-kv{
  display:flex; justify-content:space-between; align-items:center;
  height:28px; font-size:13px; border-bottom:1px solid #d9c9a6; color:#5a462c;
}
.bs-screen .bs-night-wrap .bs-kv b{ color:#8a6210; font-weight:400 }
.bs-screen .bs-night-wrap .bs-rumor{ font-size:12px; color:#5a462c }

/* 「잠을 청한다」 — 기존 종이 버튼 그림 그대로. 자리만 장부 아래 가운데로.
   ⚠️ press 그림은 이미 2px 내려간 그림이다 */
.bs-screen .bs-night-wrap .bs-btn.gold{
  align-self:center; flex:none; width:260px; height:56px; border:0; padding:0;
  font-size:15px; color:#f6ecd2; image-rendering:pixelated;
  background:url("output/ui/ledger/btn_paper_primary.png") center/100% 100% no-repeat;
}
.bs-screen .bs-night-wrap .bs-btn.gold:hover{
  background-image:url("output/ui/ledger/btn_paper_primary_hover.png");
}
.bs-screen .bs-night-wrap .bs-btn.gold:active{
  background-image:url("output/ui/ledger/btn_paper_primary_press.png");
}

/* ── 밤 장부 등장·퇴장 [2026-08-23 확정 · 인계서 3절] ──
   등장 = 내려놓는다 · 퇴장 = 치운다. 왼쪽은 줄 하나씩, 오른쪽은 파트별 뭉텅이.
   ⚠️ 모든 움직임 steps(). ease·블러·회전 금지 (STYLE_SPEC)
   ⚠️ backwards — both 면 애니메이션이 없을 때 판이 안 보이는 채로 얼어붙는다
      (낮 정산서 .bs-led 주석과 같은 사고)
   ⚠️ **지연(delay)은 여기 적지 않는다.** 줄 수가 6~9 로 변해서 JSX 가 인라인으로 준다
      (game.jsx 의 nightTiming() — 소리 타이머와 **같은 함수**를 쓴다. 갈라놓지 마라) */
/* 암막 — **화면 전체**를 덮는다. 그래서 .bs-night-wrap 안이 아니라 **형제**다.
   ⚠️ [인계서와 다른 곳 · 2026-08-23] 인계서 CSS 는 선택자가 `.bs-night-wrap .bs-dim` 이지만,
      .bs-night-wrap 은 left/right 18% · top 11.5% · bottom 7% 짜리 **작은 상자**다.
      그 안에 inset:0 으로 넣으면 화면의 64%×81% 만 덮는 **검은 직사각형**이 된다.
      확정 연출 시안(확정_여관정산_연출.html:144)에서도 .dim 은 .area 의 형제이고 무대 전체를 덮는다.
   ⚠️ 이 층이 옛 `.bs-veil.deep`(78%)을 **대신한다.** 둘을 겹치면 94% 라 배경이 통째로 죽고,
      무엇보다 「암막이 걷힌다」(bsDimOut)가 정적인 veil 밑에 깔려 **보이지 않는다.**
      그래서 밤 렌더에서 <div className="bs-veil deep" /> 를 뺐다. 되살리려면 둘 중 하나만 써라. */
.bs-screen .bs-night-dim{
  position:absolute; inset:0; z-index:4; background:rgba(10,8,5,.72);
  animation:bsNightDim .45s steps(3) both;
}
@keyframes bsNightDim{ from{ opacity:0 } to{ opacity:1 } }

.bs-screen .bs-night-wrap .bs-book{ animation:bsBookDrop .40s steps(5) .45s backwards }
@keyframes bsBookDrop{ from{ opacity:0; transform:translateY(-14%) } to{ opacity:1; transform:none } }

.bs-screen .bs-night-wrap .bs-hole{ animation:bsFadeIn .01s backwards }
.bs-screen .bs-night-wrap .bs-hole:nth-child(1){ animation-delay:.92s }
.bs-screen .bs-night-wrap .bs-hole:nth-child(2){ animation-delay:1.02s }
.bs-screen .bs-night-wrap .bs-hole:nth-child(3){ animation-delay:1.12s }
@keyframes bsFadeIn{ from{ opacity:0 } to{ opacity:1 } }

.bs-screen .bs-night-wrap .bs-pg.l .bs-h{ animation:bsLineIn .28s steps(3) .95s backwards }
.bs-screen .bs-night-wrap .bs-pg.l .bs-item{ animation:bsLineIn .28s steps(3) backwards }
@keyframes bsLineIn{ from{ opacity:0; transform:translateX(-8px) } to{ opacity:1; transform:none } }

.bs-screen .bs-night-wrap .bs-total{ animation:bsTotIn .30s steps(4) backwards }
@keyframes bsTotIn{ from{ opacity:0; transform:translateY(6px) } to{ opacity:1; transform:none } }

/* 오른쪽 — 파트 하나가 통째로. 낱줄로 쪼개지 마라 */
.bs-screen .bs-night-wrap .bs-blk{ animation:bsBlkIn .30s steps(4) backwards }
@keyframes bsBlkIn{ from{ opacity:0; transform:translateY(8px) } to{ opacity:1; transform:none } }

.bs-screen .bs-night-wrap .bs-btn.gold{ animation:bsFadeIn .30s steps(3) backwards }

/* ── 퇴장 — 치운다 ── */
.bs-screen .bs-night-wrap.out .bs-book,
.bs-screen .bs-night-wrap.out .bs-btn.gold{ animation:bsBookAway .32s steps(4) .15s both }
@keyframes bsBookAway{ from{ opacity:1; transform:translateY(0) }
                       to  { opacity:0; transform:translateY(26%) } }
.bs-screen .bs-night-dim.out{ animation:bsDimOut .30s steps(3) .40s both }
@keyframes bsDimOut{ from{ opacity:1 } to{ opacity:0 } }

/* 연출을 끈 상태(건너뛰기 뒤) — 전부 제자리에.
   ⚠️ [인계서와 다른 곳 · 2026-08-23] 퇴장에 쓰이는 셋(암막·장부·버튼)에는 `:not(.out)` 을 건다.
      인계서대로 `.done` 을 무조건 걸면 `animation:none !important` 가 **퇴장 연출까지 죽인다** —
      건너뛴 뒤 「잠을 청한다」를 누르면 치우는 동작 없이 0.7초 멈췄다 하드컷 된다(실측).
      나머지(구멍·머리·줄·순익·뭉텅이)는 그대로 무조건 고정한다. `.out` 을 걸면 등장 애니메이션이
      지연째로 **다시 돌아** 줄이 사라졌다 나타난다 — 저것들은 .bs-book 안에 있어 판이 미끄러질 때
      같이 딸려 간다. 그래서 셋만 푸는 것이 맞다. */
.bs-screen .bs-night-dim.done:not(.out),
.bs-screen .bs-night-wrap.done:not(.out) .bs-book,
.bs-screen .bs-night-wrap.done:not(.out) .bs-btn.gold,
.bs-screen .bs-night-wrap.done .bs-hole,
.bs-screen .bs-night-wrap.done .bs-h,
.bs-screen .bs-night-wrap.done .bs-item,
.bs-screen .bs-night-wrap.done .bs-total,
.bs-screen .bs-night-wrap.done .bs-blk{ animation:none !important; opacity:1; transform:none }

/* ── 4 · 엔딩 회고록 ────────────────────────────────────────────────────────
   주인공은 등급이 아니라 글이다. 등급 도장은 서명 옆에 작게 찍는다.
   ⚠️ API 실패로 회고록이 없을 때도 같은 틀에 한 문단만 넣는다. 레이아웃을 바꾸지 마라. */
.bs-screen .bs-memo{
  position:absolute; left:8%; right:8%; top:5%; bottom:13%; z-index:5;
  display:flex; flex-direction:column;
}
.bs-screen .bs-memo .band,
.bs-screen .bs-memo .foot{
  height:clamp(14px,2.4cqw,26px); background:var(--c1); border:2px solid var(--c5);
}
.bs-screen .bs-memo .band{
  display:flex; align-items:center; justify-content:center; gap:clamp(6px,1.2cqw,13px);
}
.bs-screen .bs-memo .band i{
  display:block; width:clamp(5px,.9cqw,10px); height:clamp(5px,.9cqw,10px);
  background:var(--c5); transform:rotate(45deg);
}
.bs-screen .bs-memo .band i.g{ background:var(--gold) }
.bs-screen .bs-memo .body{
  flex:1; overflow-y:auto; color:var(--c1);
  background:var(--c7); border:2px solid var(--c1); border-top:0; border-bottom:0;
  padding:clamp(8px,1.6cqw,18px) clamp(10px,2cqw,22px);
  display:flex; flex-direction:column;
}
.bs-screen .bs-memo p{
  margin:0 0 clamp(4px,.9cqw,10px); font-size:clamp(8px,1.3cqw,14px); line-height:1.5;
}
/* 사랑의 도피(엔딩 #21) 결말 카드 — 회고록보다 먼저 오는 고정 한 줄.
   ⚠️ 굵게 금지(type.css ②)라 무게가 아니라 **가로줄**로 층을 나눈다. 도트 규칙상 둥근 모서리·그라데이션도 없다 */
.bs-screen .bs-memo p.card{
  border-bottom:2px solid var(--c3);
  padding-bottom:clamp(5px,1cqw,11px);
  margin-bottom:clamp(7px,1.3cqw,14px);
}
.bs-screen .bs-memo .sig{
  margin-top:auto; display:flex; justify-content:space-between; align-items:flex-end;
}
.bs-screen .bs-endbtns{
  position:absolute; left:8%; right:8%; bottom:4%; z-index:7;
  display:flex; justify-content:center; gap:clamp(8px,1.6cqw,18px);
}

/* ── 도장 — 등급 / 경고 ─────────────────────────────────────────────────────*/
.bs-screen .bs-mark{
  display:inline-block; transform:rotate(-7deg); letter-spacing:.1em;
  border:4px solid var(--danger); color:var(--danger); font-weight:700;
  padding:clamp(3px,.7cqw,8px) clamp(9px,1.7cqw,18px); font-size:clamp(11px,1.9cqw,20px);
}
.bs-screen .bs-mark.ok{ border-color:var(--gold); color:var(--gold) }

/* .bs-modal(이벤트 모달) · .bs-curtain(손님 등장 줄무늬 전환) — 은퇴 [2026-08-18].
   독촉은 편지 연출(.bs-op.bs-let)로, 손님 등장은 charanim.css 로 옮겨 갔다. */


/* ── 상품 패널 [2026-08-16 · HANDOFF_item_panel.md] ──────────────────────────
   좌판(stall)에서 파는 물건 카드. 우상단, 골드 칩(top 3.2%) 아래 10.5%.
   등장은 game.jsx 의 .bs-ui.bs-slow 게이트(⑥, 대사 완료 +800ms · 1.1s 페이드)가 맡는다.
   눈금 바: 축 0~풍문상한×1.4. 초록 = 풍문 구간, 주황 눈금 = 매입가, 흰 눈금 = 손님이 부른 값 */
/* [개정 2026-08-16 · HANDOFF_ui_style 표] 면·테두리는 type.css 의 중립 프레임이 맡는다.
   MoneyPixel 색(#d89050 / #f4ecd2). */
/* [재조정 2026-08-25 · 사용자 확정 · 기획\ux시안\상품패널_조절_목업_0825.html]
   폭 22→18.5% · 위 10.5→12.3% · 우 2.5→3.6% · 아이콘 64→32px(격자 정수배 유지) ·
   설명 13px / 값 줄 17px (12배수 아님 — 사용자가 목업에서 보고 고른 값이다. 흐릿하면 12/18 로 상의) */
.bs-screen .bs-ip{
  position:absolute; top:12.3%; right:3.6%; width:18.5%; z-index:6; padding:1cqw;
}
.bs-ip-top{ display:flex; gap:.8cqw; align-items:flex-start; }
.bs-ip-frame{
  position:relative; width:3.2cqw; height:3.2cqw; flex:0 0 auto;
  background:rgba(10,14,6,.7); border:1px solid #6b6b4a;
  display:flex; align-items:center; justify-content:center;
}
/* 정수배 고정 [2026-08-17 · GFX_BUGS #5] — 아이콘은 32칸 격자라 32/64/96/128 정수배만
   허용(iconSrc 주석). 4.2cqw(≈54px 비정수)는 pixelated 최근접 축소로 격자가 깨졌다.
   무대가 1280 고정(type.css ①)이라 cqw 를 px 로 바꿔도 반응형이 안 무너진다.
   [2026-08-25 · 사용자 확정] 64 → 32px — 패널 축소(폭 18.5%)에 맞췄다. 여전히 정수배다 */
.bs-ip-frame img{ width:32px; height:32px; image-rendering:pixelated; }
.bs-ip-n{
  position:absolute; right:-.3cqw; bottom:-.3cqw; line-height:1.3;
  background:#3a3010; border:1px solid #c09040; color:#f0c060; padding:0 .3cqw;
}
.bs-ip-nm{ color:#e8e2c8; }
.bs-ip-ds{ color:#c2bb96; margin-top:.25cqw; line-height:1.35; word-break:keep-all; }
.bs-ip-rows{ border-top:1px solid #4a4a30; margin-top:.9cqw; padding-top:.7cqw; }
.bs-ip-row{ display:flex; justify-content:space-between; color:#a8a288; }
.bs-ip-row + .bs-ip-row{ margin-top:.3cqw; }
.bs-ip-row b{ color:#f0c060; }
.bs-ip-row b.rum{ color:#8ad07a; }
/* 글자 크기 — 픽셀 고정 (clamp·cqw 금지 · HANDOFF_남은작업 전역 점검)
   [2026-08-25 · 사용자 확정] 설명(13)과 값 줄(17)을 갈랐다 — 목업에서 고른 값 그대로 */
.bs-ip-nm{ font-size:24px; font-family:"Galmuri11",system-ui,"Malgun Gothic",sans-serif; }
.bs-ip-ds{ font-size:13px; font-family:"Galmuri11",system-ui,"Malgun Gothic",sans-serif; }
.bs-ip-row, .bs-ip-n, .bs-ip-lab{
  font-size:17px; font-family:"Galmuri11",system-ui,"Malgun Gothic",sans-serif;
}
.bs-ip-bar{
  position:relative; height:1.1cqw; margin-top:.6cqw;
  background:#1a1a10; border:1px solid #4a4a30;
}
.bs-ip-bar .zone{ position:absolute; top:0; bottom:0; background:rgba(160,190,110,.4); }
.bs-ip-bar .buy{
  position:absolute; top:-.25cqw; bottom:-.25cqw; width:.22cqw;
  background:#d89050; transform:translateX(-50%);
}
.bs-ip-bar .me{
  position:absolute; top:-.5cqw; bottom:-.5cqw; width:.22cqw;
  background:#f4ecd2; transform:translateX(-50%);
  transition:left .25s cubic-bezier(.2,.7,.4,1);   /* 손님이 새 값을 부르면 슬라이드 */
}
.bs-ip-bar .me > i{ position:absolute; inset:0; }
.bs-ip-bar .me > i.fl{ animation:bs-ip-flash .4s ease 1; }   /* 풍문 구간 첫 진입 1회 반짝 */
@keyframes bs-ip-flash{
  0%  { box-shadow:0 0 0 0 rgba(244,236,210,.9); }
  100%{ box-shadow:0 0 .9cqw .5cqw rgba(244,236,210,0); }
}
.bs-ip-lab{ display:flex; justify-content:space-between; color:#6b6b4a; margin-top:.3cqw; }

/* .bs-ip-spoil / .bs-ip-row b.bad — 은퇴 [2026-08-17 · 상함 시스템 폐지].
   구 N6(상한 물건 배지 + 경고 행)이 쓰던 규칙이다. 상함이 없으니 쓰는 자리도 없다. */

/* ── 여관 · 화롯가 [2026-08-23 · 기획\지시문_여관화롯가] ────────────────────
   밤 정산과 **같은 배경**을 쓴다 — 불이 켜진 방(여기) → 소등 → 불 꺼진 같은 방(정산).
   대사창(.bs-tutsay)·버튼(.bs-footbar/.bs-btn)은 기존 규격을 그대로 빌린다. 신규는 둘뿐이다.
   ⚠️ 초상이 없는 인물(여관지기 무르자·돈놀이꾼 하겐)은 이 칸 자체가 안 그려진다 —
      대사만 나오는 「목소리」 연출이 확정 폴백이다 [최소안 §2]. 그림 발주 0장. */
/* [개정 2026-08-23 · 기획\TASK_PROG_여관마루 · 시안 inn_NPC배치_시안.html]
   배경이 손님방 → **1층 바**로 바뀌었다. 화면에 사람은 언제나 한 명이고,
   주인은 바 안쪽(34%)에 서고 동석자는 탁자 너머(66%)에 마주 앉는다 — 자리와 크기로 화자를 가른다.
   ⚠️ bottom:-4% 가 핵심이다. 초상 29장이 **전부 아래가 잘린 무릎 컷**이다(실측 8/23).
      띄우면 잘린 면이 허공에 뜬다 — 화면 경계와 만나야 「잘렸다」가 아니라 「이어진다」로 읽힌다.
      좌판 손님이 쓰는 규약 그대로다(bobusang-charanim.css:16 · bobusang-type.css:329).
      19% 로 되돌리지 마라 — 분기·선택지처럼 **대사창이 사라지는 단계**에서 바로 드러난다. */
.bs-screen.bs-inn .bs-innpor{
  position:absolute; bottom:-4%; transform:translateX(-50%);
  height:80%; width:auto; z-index:4;
  image-rendering:auto;   /* 초상은 pixelated 금지 — charanim.css 와 같은 계열 */
  /* 그림자 뺌 [2026-08-23 · 사용자 요청] — drop-shadow(4px 4px 0 rgba(0,0,0,.45)) 이었다.
     흐림 0 이라 인물 윤곽을 그대로 4px 밀어 찍는 꼴이었고, 벽·벽난로 위에 **검은 선이 그어진 것**처럼 보였다.
     좌판 손님(charanim.css)에는 원래 그림자가 없다 — 빼는 쪽이 두 화면이 같아진다.
     ⚠️ 되살릴 거면 흐림 0 은 쓰지 마라. 무릎 컷이라 잘린 아랫면에도 선이 생긴다 */
}
/* 🚨 26/74 는 초상 29장 · 60쌍 실측값이다 [2026-08-25 · 지시문_여관연출 2-1].
   34/66 은 **60쌍 전부 겹쳤다**(최악 −215px · 무르자 vs 오크 손님). 26/74 는 최소 여백 +31px.
   ⚠️ 위 height:80% · bottom:-4% 가 이 실측의 전제다 — 셋을 따로 만지지 마라. */
.bs-screen.bs-inn .bs-innpor.k{ left:26% }   /* 주인 — 바 안쪽 */
.bs-screen.bs-inn .bs-innpor.g{ left:74% }   /* 동석자 — 탁자 너머 */
/* 안 말하는 쪽 — 자리 대신 **밝기**로 화자를 가른다. 둘이 같이 서 있는 화롯가 전용이다.
   ⚠️ spk 가 없으면(지문 sys · 큐가 빈 end) 이 클래스를 **아무에게도 붙이지 않는다** —
      「없으면 둘 다 어둡게」로 짜면 「잠을 청한다」만 뜬 화면이 캄캄해진다(game.jsx 렌더 주석). */
.bs-screen.bs-inn .bs-innpor.off{ filter:brightness(.42) saturate(.55); z-index:3 }

/* 전경 탁자 [납품 2026-08-23 · 1536×199 투명] — 무릎 컷 초상 앞을 한 겹 가려
   「마주 앉았다」를 만든다. 앉은 그림 없이 앉은 구도가 성립하는 장치다. 모든 단계에 깐다.
   ⚠️ z-index 는 **5** 다. 6 으로 올리면 선택지 버튼을 덮는다 — 탁자는 바닥에서 23%(880 무대에서
      114px)를 차지하는데 .bs-footbar 는 bottom:3.4%·높이 40px 안팎이라 통째로 먹힌다.
      탁자 5 + 여관 footbar 6 이 짝이다(바로 아래 규칙). */
.bs-screen.bs-inn .bs-inntable{
  position:absolute; left:0; right:0; bottom:0; height:23%; z-index:5;
  background-size:100% 100%; background-repeat:no-repeat; pointer-events:none;
}
/* 🔴 버튼띠를 탁자 위로. .bs-footbar 도 z-index:5(106행)라 같은 값이면 원본 순서로 갈린다 —
   명시적으로 6 을 준다. (.bs-tutsay 는 이미 6 이라 손댈 것이 없다 · build.css:386) */
.bs-screen.bs-inn .bs-footbar{ z-index:6 }

/* 어둠 베일을 뺀다 — 새 배경을 **이미 그 밝기로 구웠다**(평균 명도 58.8~60.5 · 기존 59.7).
   겹치면 두 번 어두워진다.
   🚨 `.bs-veil` 을 **전역으로 끄지 마라.** 밤 정산(phase "night")이 같은 inn_*.png 를 쓰고
      .bs-veil.deep(78% · 134행)로 눌러서 장부를 읽게 만든다 — 전역으로 끄면 장부 글씨가 배경에 묻힌다.
      밤 화면엔 bs-inn 클래스가 없으니 이 선택자에는 안 걸린다. 범위를 넓히지 마라. */
.bs-screen.bs-inn .bs-veil{ display:none }

/* ⚠️ 화롯불 radial-gradient 는 넣지 마라 [기획 확정] — 초기 시안의 호흡 연출은 불이 없던
   옛 객실 배경 기준이었다. **새 배경엔 벽난로가 그려져 있다.** 얹으면 불이 두 개가 된다. */
/* 분기·선택지 버튼은 가운데로 모은다. .bs-footbar 의 :first-child{margin-left:auto} 는
   버튼 하나짜리 띠(도매 「가게를 나선다」)를 오른쪽에 붙이려는 규칙이라 여기선 풀어 준다 */
.bs-screen.bs-inn .bs-innbar{ justify-content:center }
.bs-screen.bs-inn .bs-innbar > .bs-btn{ margin-left:0; flex:0 1 auto; min-width:26% }

/* ══ 여관 등장·퇴장 연출 ══ [2026-08-23 · 사용자 결재 · 원화 graphics\output\INN_FX_APPLY_0823.md]
   좌판에는 SI 3막과 fx-enter/fx-leave 가 있는데 여관은 초상이 툭 켜지고 툭 갈렸다.
   신규 그림 0장. 전부 steps() — 도트를 부드럽게 밀면 픽셀이 반 칸 걸치며 어른거린다. */

/* ── ① 여관 등장 ── 방이 계단으로 밝아지고, 탁자가 아래에서 올라와 앉는다.
   ⚠️ **배경을 filter 로 밝히지 마라.** inn_*.png 는 평균 명도를 수치로 맞춰 구운 파일이고
      (inn_bridel 58.8) 여관 .bs-veil 은 그 이유로 꺼져 있다(위 480줄). 덮개 한 겹만 걷어라. */
.bs-screen.bs-inn .bs-innfade{
  position:absolute; inset:0; background:#0a0b07; z-index:8; pointer-events:none;
  animation:bsInnFade .55s steps(5) forwards;
}
@keyframes bsInnFade{ from{opacity:1} to{opacity:0} }
/* 등장 건너뛰기 판 [2026-08-25] — 덮개(8)보다 위여야 걷히는 도중에도 눌린다.
   짝: game.jsx 의 innBeat. innBeat < 2 일 때만 그려진다 */
.bs-screen.bs-inn .bs-innskip{ position:absolute; inset:0; z-index:9; cursor:pointer }
/* z-index 8 인 이유 — 탁자 5 · 여관 footbar 6 · 대사창 6 이라 그 위를 덮어야 한다(467·473줄) */

/* 덮개가 다 걷힌 **뒤에** 올라온다 [2026-08-25 · 지시문_여관연출 1-1]. .18s 였을 때는
   0.55s 덮개 밑에서 대부분 끝나 「연출이 없다」로 보였다.
   탁자는 phase "inn" 동안 한 번도 remount 되지 않는 단일 div 라 CSS 딜레이가 안전하다 —
   ⚠️ 같은 수법을 .bs-innpor 에는 쓰지 마라(key={por} 로 화자마다 remount 된다 · 아래 ② 주석). */
.bs-screen.bs-inn .bs-inntable{ animation:bsInnTable .45s steps(4) .55s both }
@keyframes bsInnTable{ from{transform:translateY(14px)} to{transform:translateY(0)} }

/* ── ② NPC 등장 + 상시 호흡 ── 탁자 뒤에서 올라와 앉는다.
   초상 29장이 전부 **무릎 컷**이라(450줄 주석) 아래에서 올리면 잘린 면이 탁자에 가려진다 —
   이 화면에서만 되는 수법이다. ⚠️ 위에서 내려오게 만들지 마라. 허공에서 떨어진다.
   ⚠️ translateX(-50%) 를 **키프레임마다 다시 써라.** .bs-innpor 의 위치 규칙이다(451줄).
      빼면 인물이 화면 왼쪽으로 반쯤 밀린다.
   ⚠️ 등장과 호흡을 한 요소에 몰면 둘 다 transform 이라 서로 덮어써서 등장이 끝나는 순간 인물이 툭 튄다
      (charanim.css 가 래퍼를 두 겹 쓰는 이유). 여기서는 **호흡을 .5s 늦춰** 같은 사고를 피한다. */
.bs-screen.bs-inn .bs-innpor{
  animation:bsInnPorIn .45s steps(4) both, bsInnBreath 3.4s steps(2) .5s infinite;
}
@keyframes bsInnPorIn{ from{opacity:0; transform:translateX(-50%) translateY(26px)}
                       to{opacity:1; transform:translateX(-50%) translateY(0)} }
@keyframes bsInnBreath{ 0%,100%{transform:translateX(-50%) translateY(0)}
                        50%{transform:translateX(-50%) translateY(-0.8%)} }

/* ── ③ 퇴장 ── 앉았던 사람이 내려가 사라진다. 짝: game.jsx 의 innOut 상태(350ms).
   ⚠️ 350 은 CSS 와 JS 가 손으로 맞춘 짝이다. 한쪽만 고치면 두 사람이 한 화면에 겹치거나
      나가던 초상이 사라지기 전에 잘린다. */
.bs-screen.bs-inn .bs-innpor.out{ animation:bsInnPorOut .35s steps(3) forwards }
@keyframes bsInnPorOut{ from{opacity:1; transform:translateX(-50%) translateY(0)}
                        to{opacity:0; transform:translateX(-50%) translateY(26px)} }

/* ── 좌판 진열판 — 기존 UI 팝업(.bs-plate) 그대로 ─────────────────────────
   [확정 2026-08-23 · 기획\TASK_PROG_좌판진열판_2026-08-23.md
    · 정지 화면 정본 graphics\발주서_진열판_0823.md 2부
    · 연출 정본 기획\ux시안\stall_open_연출_시안.html]
   새 그림 0건. 판·칸·버튼 모두 게임에 이미 있는 부품이다.
   ⚠️ .bs-plate/.bs-btn/.bs-h 를 새로 만들지 마라 · border-radius·gradient 금지 ·
      .bs-cell 의 aspect-ratio·display 는 **.bs-shelf.grid 안에서만** 푼다
      (전역으로 풀면 봇짐 오버레이와 매입 화면이 같이 깨진다). */
.bs-screen .bs-shelf{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:clamp(300px,56cqw,560px); z-index:20;
  padding:clamp(8px,1.4cqw,15px) clamp(9px,1.6cqw,17px) clamp(10px,1.8cqw,19px);
  /* 아래에서 밀려 올라온다(0.38s) — 시안 .shelf(-42% → -50%)와 같은 궤적.
     ⚠️ fill-mode 는 backwards 다. both 로 두면 끝난 뒤에도 keyframe 의 transform 이
        남아 .out 트랜지션을 통째로 덮어쓴다(판이 안 접힌다). */
  animation:bsShelfIn .38s steps(6) backwards;
  transition:transform .9s steps(9), opacity .8s steps(8);
}
@keyframes bsShelfIn{
  from{ transform:translate(-50%,-42%) scale(.96); opacity:0 }
  to  { transform:translate(-50%,-50%) scale(1);   opacity:1 }
}
/* 「장사를 시작한다」를 누르면 판이 물러난다(0.9s · 시안 .shelf.out) */
.bs-screen .bs-shelf.out{ transform:translate(-50%,-60%) scale(.97); opacity:0 }
.bs-screen .bs-shelf .bs-h{ text-align:center; letter-spacing:.28em }
.bs-screen .bs-shelf .bs-btn{ display:block; margin:clamp(8px,1.4cqw,15px) auto 0 }

/* 봇짐 격자 — .bs-bag/.bs-cell 을 그대로 쓴다.
   ⚠️ 두 군데만 손댄다:
   ① aspect-ratio:1 을 푼다 — 칸에 이름·가격이 들어가서 정사각이면 글자가 넘친다.
   ② grid → flex — repeat(4,1fr) 격자는 3칸일 때 **왼쪽 3칸만 채우고 오른쪽이 빈다.**
      봇짐 화면은 8칸이 늘 다 있어서 문제가 없었지만, 진열판은 칸 수가 그날그날 다르다.
      flex + justify-content:center 면 몇 칸이든 판 가운데로 모이고, 마지막 줄도 가운데다. */
.bs-screen .bs-shelf.grid .bs-bag{
  --g:clamp(4px,.8cqw,9px);
  display:flex; flex-wrap:wrap; justify-content:center; align-content:flex-start; gap:var(--g);
}
.bs-screen .bs-shelf.grid .bs-cell{
  width:calc((100% - var(--g) * 3) / 4);          /* 한 줄에 4칸 */
  aspect-ratio:auto; padding:clamp(4px,.8cqw,9px) 2px; gap:1px; justify-content:flex-start;
}
.bs-screen .bs-shelf.grid .bs-cell img{
  width:clamp(26px,4.4cqw,46px); height:clamp(26px,4.4cqw,46px); display:block;
}
.bs-screen .bs-shelf.grid .bs-cell .nm{ color:var(--c8); font-weight:400; line-height:1.3 }
.bs-screen .bs-shelf.grid .bs-cell .rm{ color:var(--c5) }
.bs-screen .bs-shelf.grid .bs-cell .rm.up  { color:#8fc98a }
.bs-screen .bs-shelf.grid .bs-cell .rm.risk{ color:var(--gold) }
.bs-screen .bs-shelf.grid .bs-cell .rm.bad { color:var(--danger-txt) }
/* 「도매가」·「소문」 라벨 — 값이 무슨 값인지 칸마다 밝힌다.
   한 줄 안에 붙이므로 세로는 1px 도 안 늘어난다. */
.bs-screen .bs-shelf .lb{
  font-style:normal; color:var(--c4); font-size:.8em; margin-right:.3em; letter-spacing:0;
}
.bs-screen .bs-shelf.grid .bs-cell .pr,
.bs-screen .bs-shelf.grid .bs-cell .rm{ white-space:nowrap }
/* 값은 칸 **바닥**에 붙인다 — 「오크 이빨 목걸이」처럼 이름이 두 줄로 넘어가는 칸이 있으면
   위에서부터 쌓을 경우 값 줄이 옆 칸과 어긋난다. 한 줄로 훑어 읽히게 아래로 맞춘다. */
.bs-screen .bs-shelf.grid .bs-cell .pr{ margin-top:auto }
/* 같은 물건이 여러 개일 때 — 칸을 하나로 묶고 오른쪽 위에 개수를 박는다.
   inv 는 낱개 배열이라(uid 마다 한 칸) 우유 6개면 똑같은 칸이 6개 뜬다.
   도매가·소문은 id 기준이라 여섯 칸의 숫자가 **완전히 같다** — 반복할 이유가 없다. */
.bs-screen .bs-shelf .qty{
  position:absolute; right:3px; top:3px; font-weight:700;
  color:var(--c1); background:var(--gold); border:2px solid var(--c1);
  padding:0 4px; line-height:1.45; letter-spacing:0;
  font-size:clamp(10px,1.6cqw,16px);         /* 880 무대에서 약 14px.
     9.7px 는 안 보이고 18px 는 그림을 먹었다 — 그 사이. 테두리가 읽히는 몫을 나눠 진다 */
}
/* ⚠️ .bs-cell 은 overflow:hidden 이라 배지를 칸 밖(-2px)으로 못 뺀다. 안쪽에 붙인다. */

/* 칸 하나가 「툭」 놓인다 — 한 칸씩 180ms 간격으로 마운트되므로 등장만 얹으면 된다.
   ⚠️ 도트 규칙 — steps() 만 쓴다(사용자 확정 2026-08-22). */
.bs-screen .bs-shelf.grid .bs-cell{ animation:bsShelfCell .16s steps(3) backwards }
@keyframes bsShelfCell{
  from{ opacity:0; transform:translateY(-5px) }
  to  { opacity:1; transform:none }
}
/* 값이 다 굴러 오르면 판 전체가 한 번 「탁」 — 버튼이 뜨는 비트와 같이 온다 */
.bs-screen .bs-shelf .bs-btn.gold{ animation:bsShelfGo .22s steps(4) backwards }
@keyframes bsShelfGo{
  from{ opacity:0; transform:translateY(4px) }
  to  { opacity:1; transform:none }
}
/* 판이 떠 있는 동안 화면 클릭으로는 못 넘어간다 — 문은 버튼 하나뿐이다(§7).

   ── 손님 등장 가림막 + 건너뛰기 [개정 2026-08-24 · 사용자 확정] ──
   예전엔 이 판 **자체가** onClick=skipIntro 였다. inset:0 전체화면이라 어디를 눌러도 넘어갔고,
   그래서 **실수로 장면 연출이 날아갔다.** 이제 판은 **막기만 하고**, 넘기려면 버튼을 눌러야 한다.
   🚨 판을 지우지 마라 — 이건 스킵 장치이기 전에 **가림막**이다.
      대사창(.bs-vn)이 2막부터 **빈 프레임으로 떠 있고** 그 창은 누르면 advance() 다
      (game.jsx 의 `if (!e.target.closest(".bs-vnctl")) advance()`).
      판을 걷으면 등장 연출 중에 아무 데나 누른 클릭이 그리로 새서 장이 넘어간다.
   ⚠️ cursor:pointer 를 다시 붙이지 마라 — 판은 이제 눌리는 것이 아니다. 손가락 커서가
      「여기 누르면 넘어감」이라고 거짓말을 한다. */
.bs-screen .bs-skipfx{ position:absolute; inset:0; z-index:19; background:transparent }

/* 생김새는 오프닝 건너뛰기(.bs-op-skip · opening.css:141)와 같은 규약이다.
   ⚠️ 1초 뒤에 뜬다 — 연출이 시작하자마자 뜨면 그것부터 눈에 들어온다.
   ⚠️ 오른쪽 **아래**다. 위는 TopBar(일차·목표·골드)가 이미 쓰고 있다. */
.bs-screen .bs-skipbtn{
  position:absolute; right:clamp(10px,2.4cqw,30px); bottom:clamp(10px,2.4cqw,30px);
  font:inherit; font-weight:800; cursor:pointer;
  /* ⚠️ 오프닝(.bs-op-skip)의 회색 배색을 그대로 가져오지 마라 — 거긴 배경이 검은 화면이다.
     좌판은 **밝은 장터**라 rgba(0,0,0,.55)+#6b6b62 로는 글자가 안 읽힌다(실측 2026-08-24).
     장터 위에서도 읽히는 어두운 판 + 밝은 글자로 간다 */
  background:rgba(12,16,8,.78); color:#d8d2bd; border:2px solid #6b7355;
  padding:clamp(3px,.5cqw,6px) clamp(9px,1.4cqw,17px);
  font-size:clamp(9px,1.2cqw,14px); letter-spacing:.06em;
  white-space:nowrap; line-height:1.35;
  animation:bsSkipIn .2s steps(2) 1s backwards;
}
.bs-screen .bs-skipbtn:hover{ color:#fff; border-color:var(--gold) }
@keyframes bsSkipIn{ from{opacity:0} to{opacity:1} }

/* 판이 화면을 넘으면 통째로 줄인다 — 실측상 8칸도 79px 남아 안 걸린다. 보험으로만 둔다 */
.bs-screen .bs-shelf.fit{ transform:translate(-50%,-50%) scale(var(--fit,1)) }

@media (prefers-reduced-motion:reduce){
  .bs-screen .bs-skipbtn{ animation:none }   /* 기본이 보이는 상태라 안전 */
  .bs-screen .bs-shelf,
  .bs-screen .bs-shelf.grid .bs-cell,
  .bs-screen .bs-shelf .bs-btn.gold{ animation:none }
  .bs-screen .bs-shelf{ transition:none }
}

/* ── 불빛 연출 · 여관 [2026-08-23 · LIGHT_APPLY_0823.md 4절] ─────────────────
   마을(bobusang-town.css)과 같은 장치를 여관에도 건다. @keyframes bsFireB 는
   town.css 가 정의한 것을 그대로 쓴다 — 이름을 바꾸면 여기가 죽는다.

   🚨 지시서 4절과 **두 군데 다르다. 실물을 재고 고친 것이다.**

   [1] 세로 자리 — 지시서는 center 라고 하지만 여관은 center 64% 다.
       여관 배경은 1536x1024(3:2)인데 무대는 16:9 라 cover 로 **세로가 잘린다**.
       그런데 .bs-bg 는 object-position:center 64% 로 걸려 있다(ui.css:68).
       마스크를 center(50%)로 두면 잘리는 자리가 달라져 빛 지도가 통째로 어긋난다 —
       실측 어긋남 무대 높이의 2.6%(880 무대에서 약 23px). 창·벽난로를 비껴간다.
       ⚠️ ui.css:68 의 64% 를 바꾸면 여기 64% 도 같이 바꿔야 한다. 짝이다.
       (마을은 1536x864 = 16:9 라 잘리는 데가 없어 center 가 맞다. 그래서 town.css 는 그대로다.)

   [2] 감광막은 **아직 안 걸었다.** 아래 보류 블록에 사유가 있다.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── 숨쉬기 ── (감광막과 무관하게 혼자 성립한다 — 이미 그려져 있는 벽난로·등불이 밝아졌다 어두워진다)
   ⚠️ .bs-veil 앞(위 형제)에 두지 마라 — 지금은 여관 veil 이 꺼져 있어 티가 안 나지만,
      아래 보류 블록을 되살리는 순간 불투명 복제가 막을 뚫어 얼룩이 된다 [지시서 함정 1] */
.bs-screen.bs-inn .bs-breath{
  position:absolute; inset:0; pointer-events:none; --fa:.20;
  animation:bsFireB 2.4s steps(1) infinite;
}
.bs-screen.bs-inn .bs-breath > img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center 64%;    /* ← .bs-bg(ui.css:68)와 반드시 같은 값 */
  display:block; image-rendering:auto;
  -webkit-mask-size:cover;      mask-size:cover;
  -webkit-mask-position:center 64%;  mask-position:center 64%;   /* ← 위와 같은 값 */
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
}
.bs-screen.bs-inn:not(.groknar) .bs-breath > img{
  -webkit-mask-image:url(output/backgrounds/breath_inn_bridel.png);
          mask-image:url(output/backgrounds/breath_inn_bridel.png);
}
.bs-screen.bs-inn.groknar .bs-breath > img{
  -webkit-mask-image:url(output/backgrounds/breath_inn_groknar.png);
          mask-image:url(output/backgrounds/breath_inn_groknar.png);
}
@media (prefers-reduced-motion: reduce){
  .bs-screen.bs-inn .bs-breath{ animation:none; filter:brightness(calc(1 + .45*var(--fa))) }
}

/* ── 🔴 보류 · 여관 감광막 — 기획 판단 대기 [2026-08-23] ───────────────────────
   지시서 4절은 여관 .bs-veil 의 배경을 darkveil_inn_*.png 로 갈아끼우라고 한다.
   **그대로 켜면 여관이 통째로 어두워진다.** 지시서가 못 본 규칙이 위에 있다:

     349행  .bs-screen.bs-inn .bs-veil{ display:none }
            사유 — 「새 배경을 이미 그 밝기로 구웠다(평균 명도 58.8~60.5). 겹치면 두 번 어두워진다」

   실측(2026-08-23, PIL):
     inn_bridel.png 평균 명도 58.8 · inn_groknar.png 60.5   ← 349행 주석의 수치와 일치한다
     darkveil_inn_*.png 알파 평균 34.0%                      ← 지시서 수치와 일치한다
     켜면 58.8 → 약 39 로 내려앉는다. 재분포가 아니라 34% 감광이다.

   마을은 사정이 다르다 — 거기는 평평한 34% 막이 **이미 켜져 있어서** 같은 평균의
   기울어진 막으로 바꾸면 총량이 그대로다. 그래서 마을만 먼저 켰다.

   켜려면 349행의 display:none 을 걷어야 하는데, 그건 다른 대화가 수치까지 재서
   확정한 노출을 뒤집는 일이라 여기서 혼자 정하지 않는다.
   → 원화가께: 여관은 「이미 구운 밝기」가 기준이니, 평균 34% 가 아니라
     **평균 0% 언저리로 기울인 막**(밝은 데는 걷고 먼 데만 눌러 총량 보존)이 맞다.
     그 판을 주시면 아래 두 줄과 349행만 손대면 끝난다.

.bs-screen.bs-inn:not(.groknar) .bs-veil{
  background:none;
  background-image:url(output/backgrounds/darkveil_inn_bridel.png);
  background-size:cover; background-position:center 64%;
}
.bs-screen.bs-inn.groknar .bs-veil{
  background:none;
  background-image:url(output/backgrounds/darkveil_inn_groknar.png);
  background-size:cover; background-position:center 64%;
}
   ───────────────────────────────────────────────────────────────────────── */

/* ── 소식지 [2026-08-24 · 기획\TASK_PROG_소식지_2026-08-24.md] ────────────────
   여관 위에 얹는 오버레이다. 새 화면이 아니라 편지와 같은 계열.
   ⚠️ 종이 바탕은 지금 CSS 다 — 발주 B(1200x840 투명 PNG)가 오면 .bs-paper 의
      background 만 갈아 끼우면 된다. 자리·비율은 그대로 둔다.
   ⚠️ 「신문」이라 쓰지 마라. 근대 일간지를 떠올리게 해서 세계관이 흔들린다 — **소식지**다. */
.bs-screen .bs-pdim{ position:absolute; inset:0; z-index:11; background:rgba(8,10,5,.55); cursor:pointer }
.bs-screen .bs-paper{
  position:absolute; left:50%; top:50%; z-index:12; cursor:default;
  width:76%; height:84%; transform:translate(-50%,-50%); transform-origin:50% 50%;
  background:#cfc79a; border:3px solid #6b6247; box-shadow:7px 7px 0 rgba(0,0,0,.55);
  padding:clamp(8px,1.6cqw,17px) clamp(10px,2cqw,21px) clamp(7px,1.4cqw,15px);
  color:#2b2a18; display:flex; flex-direction:column;
}
/* 펴짐 — 세로로 눌렸다 튕긴다. 접힘은 그 반대 */
.bs-screen .bs-paper.in { animation:bsUnfold .42s cubic-bezier(.2,.9,.3,1.1) both }
.bs-screen .bs-paper.out{ animation:bsFold .34s ease-in both }
@keyframes bsUnfold{
  0%  { transform:translate(-50%,-50%) scaleY(.05) rotate(-2.5deg); opacity:0 }
  55% { transform:translate(-50%,-50%) scaleY(1.06) rotate(.8deg);  opacity:1 }
  100%{ transform:translate(-50%,-50%) scaleY(1) rotate(0);         opacity:1 }
}
@keyframes bsFold{
  0%  { transform:translate(-50%,-50%) scaleY(1); opacity:1 }
  100%{ transform:translate(-50%,-50%) scaleY(.05) rotate(1.5deg); opacity:0 }
}
.bs-screen .bs-phead{ text-align:center; font-weight:700; letter-spacing:.22em;
  font-size:clamp(11px,2.2cqw,22px); border-bottom:3px double #6b6247;
  padding-bottom:.5cqw; margin-bottom:.2cqw }
.bs-screen .bs-pdate{ text-align:center; color:#6b6247; letter-spacing:.14em;
  font-size:clamp(6.5px,1.1cqw,11px); margin-bottom:.9cqw }
/* 오크가 오른쪽 위에 덧쓴 큰 낙서 */
.bs-screen .bs-pscrawl{ position:absolute; right:1.6cqw; top:.9cqw; color:#7a3f2a; font-weight:700;
  font-size:clamp(7px,1.35cqw,14px); transform:rotate(-7deg); opacity:.85 }
.bs-screen .bs-pcols{ flex:1; display:flex; gap:1.4cqw; min-height:0; cursor:pointer }
.bs-screen .bs-pcol{ flex:1; border-left:1px solid #a89c6d; padding:0 .9cqw;
  display:flex; flex-direction:column; transition:opacity .3s ease }
.bs-screen .bs-pcol:first-child{ border-left:0; padding-left:0 }
.bs-screen .bs-pcol.dim{ opacity:.14 }
.bs-screen .bs-pcol .k{ letter-spacing:.2em; color:#7a6f45; margin-bottom:.55cqw;
  font-size:clamp(5.5px,1.02cqw,10px) }
.bs-screen .bs-pcol .h{ font-weight:700; line-height:1.45; margin-bottom:.65cqw;
  border-bottom:1px solid #a89c6d; padding-bottom:.55cqw;
  font-size:clamp(7.5px,1.5cqw,15px) }
.bs-screen .bs-pcol .b{ line-height:1.7; color:#3e3a22; font-size:clamp(6.5px,1.25cqw,13px) }
/* 오크 손글씨 — 붉은 세로줄. 브리델판엔 안 그려진다 */
.bs-screen .bs-pcol .mk{ color:#7a3f2a; font-weight:700; margin-top:.7cqw;
  border-left:3px solid #7a3f2a; padding-left:.7cqw; line-height:1.5;
  transform:rotate(-1.2deg); font-size:clamp(6.5px,1.25cqw,13px) }
.bs-screen .bs-pcol .w{ margin-top:auto; color:#7a3f2a; font-weight:700; padding-top:.7cqw;
  font-size:clamp(5.5px,1.08cqw,11px) }
.bs-screen .bs-pfoot{ border-top:3px double #6b6247; margin-top:.9cqw; padding-top:.7cqw;
  display:flex; justify-content:space-between; align-items:center;
  color:#6b6247; font-size:clamp(5.5px,1.08cqw,11px) }
.bs-screen .bs-pclose{ background:#6b6247; color:#e8dfb8; border:2px solid #2b2a18;
  padding:.35cqw 1.2cqw; cursor:pointer; font-family:inherit;
  font-size:clamp(6.5px,1.25cqw,13px) }
.bs-screen .bs-pclose:hover{ background:#7d7355 }

/* ── 좌판에 나왔는데 펼칠 것이 없다 ── [2026-08-25 · 기획 실측 · 소프트락 수습]
   봇짐이 빈 채로 「장터로 나선다」를 누르면 손님이 안 만들어지고(openStall 의 cur.length 가드)
   좌판 화면은 `&& nego` 라 **한 픽셀도 안 그려졌다.** 그 빈 자리에 놓는 문 하나다.
   ⚠️ 새 규격을 만들지 않는다 — .bs-plate 판 + .bs-btn 을 그대로 빌린다. 하루에 많아야 한 번 보는 판이다. */
.bs-screen .bs-empty{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:min(56%, 520px); text-align:center; z-index:6;
  padding:clamp(16px,2.4cqw,30px) clamp(18px,2.6cqw,34px) clamp(18px,2.6cqw,32px);
}
.bs-screen .bs-empty p{
  margin:clamp(10px,1.6cqw,20px) 0 clamp(16px,2.2cqw,26px);
  color:var(--c6); line-height:1.7;
}
