/* PocketCrew — 코지 픽셀아트 톤 (design/pixel-journey 목업 기준) */

/* 크롬(배경·패널·독) 팔레트.
   2026-09-05 난색(베이지·탄) → 한색(쿨 그레이-라벤더)으로 교체했다.
   방 안이 Kenney 타일의 회색·라벤더 돌바닥/벽으로 바뀌면서 따뜻한 베이지
   크롬과 계열이 어긋났기 때문이다. 책상(나무)·식물(초록) 같은 난색 소품은
   그대로 두면 한색 배경 위에서 오히려 포인트로 더 산다. */
:root {
  --bg: #d8d3e2;
  --bg-dots: rgba(58, 54, 74, 0.07);
  --panel: #faf9fc;
  --panel2: #ece8f2;
  --ink: #332f42;
  /* PM 제시값(#736d87 / #9089a3)에서 명도만 낮췄다 — 계열은 그대로.
     muted가 muted2보다 진해야 정보 계층이 유지되므로 둘 다 함께 내린다.

     2026-09-25 한 번 더 내렸다. 예전 값은 **UI 최소(3.0)**를 기준으로 잡았는데,
     3.0은 글자가 아니라 **버튼 테두리 같은 비텍스트 요소**의 기준이다. 글자는
     4.5(큰 글자 3.0)다. 안내 문구는 글자이므로 3.77로는 모자랐고, 배경보다
     어두운 지시 독(--dock) 위에서는 3.23까지 떨어졌다(35회차 대비 감사).

       muted  #494360 — bg 6.36 / dock 5.45 / panel 8.88 / panel2 7.71
       muted2 #544e69 — bg 5.37 / dock 4.60 / line 4.81 / panel 7.50 */
  --muted: #494360;
  --muted2: #544e69;
  --line: #cfc7dc;
  --shadow: #b0a7c4;
  --dark: #211d2c;
  --dark-shadow: #100d17;
  --accent: #e8965a;   /* 사용자가 고르는 포인트색 — 값 유지 */
  --good: #7fae6f;     /* 방 소품 초록과 이미 맞음 — 값 유지 */

  /* 독은 배경보다 한 톤 어둡다. 예전에는 이 값이 .instruction-dock에
     하드코딩돼 있어 팔레트를 바꿔도 혼자 남았다 — 변수로 끌어올린다. */
  --dock: #c9c3d8;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  /* 한글은 기본값이면 **글자 단위로** 줄이 바뀐다 — "진짜 / 사무실", "처 / 리해요"처럼
     낱말 한가운데가 끊겼다(디자인 개편 1차, C). 낱말 단위로 바꾸고, 한 줄보다
     긴 낱말(긴 저장소 이름 등)만 어쩔 수 없을 때 끊는다. */
  word-break: keep-all;
  overflow-wrap: break-word;
  font-family: 'Nunito', sans-serif;
  color: var(--ink);
  background: var(--bg);
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.heading { font-family: 'Fredoka', sans-serif; font-weight: 700; letter-spacing: -0.01em; }
.label { font-family: 'Fredoka', sans-serif; font-weight: 600; }

.topbar {
  height: 60px;
  flex-shrink: 0;
  background: var(--panel);
  border-bottom: 3px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  z-index: 5;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 8px;
  background: var(--accent);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 0 rgba(0,0,0,0.15);
}
.brand-name { font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: 19px; }
.topbar-right { display: flex; align-items: center; gap: 18px; font-size: 12.5px; color: var(--muted); font-weight: 600; }

/* 한/EN 전환(2026-10-10). 모든 화면 상단 오른쪽 끝에 작게 둔다 — 주행동과 겨루지
   않게 글자 버튼 정도의 무게로. 터치 대상은 32px 이상을 지킨다. */
.lang-toggle {
  min-height: 32px; padding: 4px 10px; border-radius: 8px;
  border: 1px solid rgba(0,0,0,0.14); background: transparent;
  font: inherit; font-size: 12px; font-weight: 700; color: var(--muted);
  cursor: pointer; white-space: nowrap;
}
.lang-toggle:hover { background: rgba(0,0,0,0.05); }
/* 앱으로 설치(Q3) — 브라우저가 설치 가능하다고 알려줄 때만 생긴다. 전환 버튼보다 더 가볍게. */
/* 문의용 진단 정보 복사(Q7) — 사무실 아래·연결 화면 아래 한구석에 작은 글자로. */
.diag-link {
  display: block; margin: 8px auto 0; padding: 4px 6px; border: none; background: transparent;
  font: inherit; font-size: 11.5px; color: var(--muted2); text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.diag-manual { font-size: 12px; color: var(--muted); margin: 8px 0 4px; text-align: center; }
.diag-text { width: 100%; max-width: 520px; display: block; margin: 0 auto; font: 11px/1.4 ui-monospace, monospace; }
.install-btn {
  min-height: 32px; padding: 4px 6px; border: none; background: transparent;
  font: inherit; font-size: 12px; font-weight: 700; color: var(--muted);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer; white-space: nowrap;
}

/* 사무실 화면에는 제목이 하나도 없었다 — 스크린리더로 훑을 때 "여기가 어디인지"
   짚을 자리가 아예 없고, 화면이 바뀌어도 옮길 곳이 없었다(33회차). 팀 이름을
   h1으로 올리되, 보이는 모습은 예전 <span> 그대로 둔다. */
.office-title {
  margin: 0; font-family: inherit; font-size: inherit; font-weight: inherit;
  /* 긴 팀 이름 하나가 상단 줄을 통째로 밀어내고 있었다 — 좁은 화면에서는
     70자만 돼도 "GitHub에서 보기"와 "새로고침"이 화면 밖으로 나갔고 가로
     스크롤이 생겼다(.topbar-right > * 에 white-space:nowrap이 걸려 있어서
     줄바꿈도 못 한다). 이름은 잘라 보이고 전체는 title로 남긴다(34회차 QA). */
  min-width: 0; max-width: 40vw;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.scene {
  flex: 1;
  position: relative;
  /* 장식용 .glow가 화면 밖으로 삐져나와 가로 스크롤을 만든다.
     clip은 hidden과 달리 스크롤 컨테이너를 만들지 않아서, 안쪽
     .office-floor의 세로 스크롤을 건드리지 않는다. */
  overflow-x: clip;
  background-color: var(--bg);
  background-image: radial-gradient(circle, var(--bg-dots) 1.5px, transparent 1.5px);
  background-size: 22px 22px;
}
.glow {
  position: absolute; border-radius: 50%; pointer-events: none;
}

.card {
  background: var(--panel);
  border-radius: 16px;
  box-shadow: 0 6px 0 var(--shadow);
  /* 카드 폭은 화면마다 인라인 width로 지정된다(600px 등). 좁은 화면에서
     그대로 두면 가로 스크롤이 생기므로 여기서 상한을 건다 —
     스타일시트의 max-width가 인라인 width를 이긴다. */
  max-width: 100%;
  box-sizing: border-box;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border: none; border-radius: 14px; cursor: pointer;
  font-family: 'Fredoka', sans-serif; font-weight: 600;
  transition: transform .05s ease;
}
.btn:active { transform: translateY(2px); }
.btn-primary {
  background: var(--dark); color: var(--panel);
  box-shadow: 0 5px 0 var(--dark-shadow);
  padding: 16px 32px; font-size: 15.5px;
}
.btn-primary:active { box-shadow: 0 3px 0 var(--dark-shadow); }
/* 주 버튼과 같은 크기의 두 번째 선택지. 무게는 같되 눈은 먼저 주 버튼으로 간다. */
.btn-secondary {
  background: var(--panel); color: var(--dark);
  border: 2px solid var(--dark);
  box-shadow: 0 5px 0 var(--line);
  padding: 14px 32px; font-size: 15.5px;
}
.btn-secondary:active { box-shadow: 0 3px 0 var(--line); }
.onboarding-note { text-align: center; font-size: 12.5px; line-height: 1.6; margin: 18px 0 0; }

.hero-crew { display: flex; justify-content: center; align-items: flex-end; gap: 6px; margin: 0 0 6px; }
.hero-sprite { animation: hero-frames 1.4s steps(1, end) infinite; }
@keyframes hero-frames {
  0%   { background-position: var(--f0); }
  50%  { background-position: var(--f1); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-sprite { animation: none; }
}

.btn-ghost {
  background: transparent; color: var(--muted); font-weight: 700; font-size: 13px;
  padding: 8px 4px;
}
/* 포인트색 버튼의 글자는 흰색이 아니다.
   네 가지 포인트색 어디서도 흰 글자는 대비가 2.35~3.26으로 본문 기준(4.5)에
   한참 못 미친다. 이 색 위에서는 어두운 글자가 5.05~7.00으로 훨씬 잘 읽힌다.
   하필 이 버튼들이 이 화면의 **주된 행동**이다 — "전달"과 "Claude Code에서
   이어하기"(35회차 대비 감사). */
.btn-accent {
  background: var(--accent); color: var(--dark);
  box-shadow: 0 4px 0 rgba(0,0,0,0.15);
  padding: 10px 18px; font-size: 13.5px;
}

.centerpane {
  min-height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 40px 20px;
}

.steps { display: flex; align-items: center; justify-content: center; gap: 6px; }
.steps .label { white-space: nowrap; }
.step { display: flex; align-items: center; gap: 6px; }
.step-num {
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 12px; flex-shrink: 0;
}
.step-line { width: 40px; height: 2px; background: var(--line); border-radius: 1px; }

.role-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }

.role-card {
  background: var(--panel); border-radius: 16px; padding: 16px;
  box-shadow: 0 5px 0 var(--line);
  display: flex; gap: 14px; align-items: flex-start;
  border: 2px solid transparent; cursor: pointer;
}
.role-card.selected { border-color: var(--accent); }
.avatar {
  width: 44px; height: 44px; border-radius: 50%;
  position: relative; flex-shrink: 0;
}
.avatar .hair {
  position: absolute; top: -12px; left: -3px; width: 50px; height: 22px;
  border-radius: 20px 20px 5px 5px;
}
.check-box {
  width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--line); background: var(--panel2);
}
.check-box.on { background: var(--accent); border-color: var(--accent); }

input[type="text"], input[type="password"] {
  font-family: 'Nunito', sans-serif; font-size: 14.5px; color: var(--ink);
  border: 2px solid var(--accent); border-radius: 10px; background: var(--panel2);
  padding: 12px 14px; outline: none; width: 100%;
}

/* ── 키보드 포커스 표시 ─────────────────────────────────────────
   위 입력칸 규칙이 `outline: none`으로 브라우저 기본 표시를 끄는데 **대신
   줄 것을 안 만들어뒀다.** 마우스로 쓰면 티가 안 난다 — 누른 자리가 곧
   보고 있는 자리라서. 키보드만 쓰면 지시 입력칸에 도착했는지 아닌지 알
   방법이 아예 없다(33회차 접근성 스윕).

   `:focus-visible`을 쓰므로 마우스 클릭으로 들어온 포커스에는 테두리가
   안 생긴다 — 꾸미는 화면에 상시로 링이 뜨는 일은 없다. */
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}
/* 입력칸은 위 규칙이 `outline: none`을 [type] 선택자(0,1,1)로 걸어두므로,
   같은 무게 이상으로 다시 켜야 한다 — 일반 `:focus-visible`(0,1,0)은 진다.
   여기서 이걸 놓쳐서 검사가 한 번 빨갛게 떴다(33회차). */
input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--ink);
  /* 입력칸은 이미 2px 테두리가 있어 바깥으로 더 띄우면 두 겹으로 보인다 */
  outline-offset: 1px;
}
/* 제목은 화면이 바뀔 때 포커스를 받는다(어디로 왔는지 읽어주려고).
   사용자가 스스로 간 자리가 아니므로 테두리는 그리지 않는다. */
[data-screen-title]:focus-visible { outline: none; }

/* 눈에는 안 보이고 스크린리더에만 읽히는 자리. 사무실 화면이 폴링으로
   조용히 바뀌는 것을 알리는 데 쓴다. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.room-title {
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 13px;
  color: var(--muted2); letter-spacing: 0.06em; text-transform: uppercase;
  margin-bottom: 14px;
  display: flex; align-items: center; gap: 6px;
}
/* 방 이름 옆 "지우기" (요청 13). 평소에는 눈에 안 띄게 두고, 가리키면 드러난다 —
   꾸미는 화면에서 ✕가 방마다 도드라지면 지우라고 재촉하는 것처럼 보인다.
   다만 **투명하게 숨기지는 않는다**: 터치 기기에는 hover가 없다. */
.room-remove {
  border: none; background: none; cursor: pointer;
  font-size: 12px; line-height: 1; color: var(--muted2); opacity: 0.55;
  /* 지우기는 되돌릴 수 없다. 12px짜리 ✕는 손가락으로 정확히 누를 수 없어서
     "안 눌린다"와 "잘못 눌렀다"가 둘 다 일어난다. 안쪽 여백으로 누를 수 있는
     넓이를 키우고, 같은 크기의 음수 바깥여백으로 **줄 높이는 그대로 둔다** —
     안 그러면 이름표 줄이 두꺼워져 방이 통째로 아래로 밀린다. */
  padding: 10px; margin: -10px -6px;
}
.room-remove:hover { opacity: 1; color: var(--accent); }
/* 잠긴 ✕는 `disabled`가 아니라 `aria-disabled`다 — 탭으로 닿아서 이유를
   들을 수 있어야 하기 때문이다(33회차). 보이는 모습은 예전 그대로 둔다. */
.room-remove:disabled, .room-remove[aria-disabled="true"] { cursor: not-allowed; opacity: 0.25; }
.room-remove:disabled:hover, .room-remove[aria-disabled="true"]:hover { color: var(--muted2); }

/* ── 방 타일맵 (에셋 전환 2단계) ──────────────────────────────
   방은 타일 격자다. 칸마다 절대 배치된 div 하나가 타일 한 장을 그린다.
   좌표·크기는 전부 JS의 ROOMS(타일 단위)에서 계산돼 인라인으로 온다. */
.floorplan {
  display: flex; gap: 28px; align-items: flex-start;
  flex-wrap: wrap; justify-content: center;
}
.room { flex: 0 0 auto; }
.room-grid {
  position: relative;
  border-radius: 14px;
  overflow: hidden;                    /* 둥근 모서리 밖으로 타일이 삐져나오지 않게 */
  box-shadow: 0 6px 0 var(--shadow), inset 0 0 0 3px rgba(74,56,38,0.10);
}
.room-grid .tile { position: absolute; }
/* 바닥 위 → 책상 → 소품 순으로 쌓인다. 캐릭터(3단계)는 더 위에 온다. */
.room-grid .desk { z-index: 2; }
.room-grid .prop { z-index: 3; }
/* 책상 **뒤에** 앉은(아래를 보는) 직원은 책상보다 아래에 깔린다 — 하반신이 책상 윗면에
   가려져야 앉은 것으로 읽힌다. 예전 상자 타일은 낮아서 차이가 없었지만, 높이가 있는
   책상(디자인 개편 1차 B-2)에서는 사람이 책상 위에 떠 있는 것처럼 보였다. */
.room-grid .seat.facing-down { z-index: 1; }

/* 자리에 앉은 직원 — 책상 위에 얹히고 이름표가 아래 붙는다.
   책상 한 칸 위(row-1)에서 시작해 캐릭터가 책상에 앉은 것처럼 보이게 한다. */
.room-grid .seat {
  position: absolute; z-index: 4;
  display: flex; flex-direction: column; align-items: center;
  pointer-events: none;
}
/* --flip은 characterStyle()이 인라인으로 넘긴다(왼쪽을 보면 -1).
   옆모습 스프라이트가 오른쪽만 있어서 왼쪽은 뒤집어 쓴다. */
.seat-sprite { flex-shrink: 0; transform: scaleX(var(--flip, 1)); }
.seat-labels { display: flex; flex-direction: column; align-items: center; }
/* 아래를 보는 사람은 이름표가 머리 위로 간다(마주 앉는 짝에서 발밑은 책상이다).
   흐름에서 빼내는 게 핵심이다 — 그냥 위에 끼워 넣으면 .seat 상자가 이름표부터
   시작해 **스프라이트가 이름표 높이만큼 아래로 밀리고**, 그만큼 책상을 덮는다. */
.seat.facing-down .seat-labels {
  position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  margin-bottom: 2px;
}
.seat-name {
  padding: 1px 7px;
  background: var(--panel); border-radius: 7px;
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 10.5px;
  color: var(--ink); white-space: nowrap;
  box-shadow: 0 2px 0 var(--shadow);
  /* 역할 이름은 상태.json에서 온다 — **우리가 안 쓴 값**이다(사용자의 클로드
     세션이 쓴다). 길이에 제한이 없어서 긴 역할 하나가 방을 가로지르는 글자
     띠가 됐다. 바로 아래 .seat-task에는 이 처리가 이미 있었는데 이름표에는
     안 옮겨져 있었다(34회차 QA). */
  max-width: 120px; overflow: hidden; text-overflow: ellipsis;
}
.seat-task {
  margin-top: 2px; font-size: 9.5px; color: var(--muted);
  background: var(--panel2); border-radius: 6px; padding: 1px 6px;
  white-space: nowrap; max-width: 120px; overflow: hidden; text-overflow: ellipsis;
}
/* 이름표는 배율을 따라가지 않는다 — 타일이 줄어도 글자 상자는 그대로라
   좁은 화면에서 옆자리 이름표와 겹쳐 뭉개진다. 배율 3에서는 자리 간격이
   144px라 넉넉하지만, 2에서는 96px, 1에서는 48px밖에 안 된다.
   그래서 배율에 맞춰 줄이고, 도저히 안 되는 배율 1에서는 감춘다
   (대신 방 아래 명단으로 누가 무엇을 하는지 그대로 읽을 수 있다). */
.floorplan[data-scale="2"] .seat-name { font-size: 9px; padding: 0 5px; max-width: 84px; }
.floorplan[data-scale="2"] .seat-task { font-size: 8.5px; padding: 0 4px; max-width: 84px; }
.floorplan[data-scale="1"] .seat-labels { display: none; }

/* 작업 중인 직원은 살짝 위아래로 흔들려 "일하는 느낌"을 준다.
   완벽한 워크 애니메이션이 목표가 아니다(설계 문서 5절) — 대기와 구별만 되면 된다. */
/* keyframes에도 scaleX(var(--flip))를 곱해둔다. CSS 애니메이션은 인라인
   style보다 우선하므로, 여기서 빼먹으면 **작업 중일 때만** 왼쪽을 보던
   캐릭터가 오른쪽으로 홱 뒤집힌다. */
.seat.working .seat-sprite { animation: seat-bob 1.6s ease-in-out infinite; }
@keyframes seat-bob {
  0%,100% { transform: translateY(0) scaleX(var(--flip, 1)); }
  50%     { transform: translateY(-3px) scaleX(var(--flip, 1)); }
}
@media (prefers-reduced-motion: reduce) {
  .seat.working .seat-sprite { animation: none; }
}

/* 가장 작은 배율에서 이름표 대신 쓰는 명단. 자리 순서 그대로라 사무실의
   어느 자리 이야기인지 짚어가며 읽을 수 있다. */
.seat-roster {
  /* 방보다 위에 오므로 아래쪽 여백이 필요하다 — 안 주면 첫 방 제목에 붙는다. */
  list-style: none; margin: 2px auto 18px; padding: 0;
  max-width: 320px; display: flex; flex-direction: column; gap: 4px;
}
.seat-roster li {
  display: flex; align-items: baseline; gap: 8px;
  background: var(--panel); border-radius: 9px; padding: 5px 10px;
  box-shadow: 0 2px 0 var(--shadow);
}
.seat-roster .roster-role {
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 11.5px;
  color: var(--ink); white-space: nowrap;
}
.seat-roster .roster-task {
  font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 일하는 중인 사람만 왼쪽에 강조선을 둔다 — 대기 중과 구별만 되면 된다. */
.seat-roster li.working { border-left: 3px solid var(--accent); }

/* 엘리베이터 — 층 전환. 사무실 왼쪽에 세로로 붙는다.
   타일이 아니라 일반 HTML이라 키보드·터치가 그대로 동작한다. */
.elevator {
  position: absolute; left: 14px; top: 78px; z-index: 5;
  display: flex; flex-direction: column; gap: 6px;
  /* 층이 늘면 이 기둥이 계속 자란다. 그대로 두면 **14층부터 지시 독을 덮고**
     16층부터 화면 밖으로 나간다(99층에서는 4,500px짜리 기둥이다). 층 확장에는
     제한을 두지 않기로 한 화면이라 실제로 닿는 숫자다 — 스스로 스크롤하게
     한다(35회차 QA). 빼는 값은 top(78) + 독 높이(112) + 아래 여백. */
  max-height: calc(100% - 78px - 112px - 16px);
  overflow-y: auto; overflow-x: hidden;
  /* 스크롤바가 버튼 위를 덮지 않게. 버튼은 왼쪽 기준이라 이 여백이 생겨도
     자리는 그대로다(기준 이미지 변화 없음).
     아래 4px은 버튼 그림자(0 3px 0) 자리다 — overflow를 켜면 마지막 버튼의
     그림자가 잘린다. */
  padding-right: 6px; padding-bottom: 4px;
  scrollbar-width: thin;
}
.elevator-btn {
  width: 42px; height: 38px;
  background: var(--panel); border: 2px solid var(--line); border-radius: 10px;
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 13px;
  color: var(--muted); cursor: pointer;
  box-shadow: 0 3px 0 var(--shadow);
}
.elevator-btn:hover { border-color: var(--accent); color: var(--ink); }
.elevator-btn.current {
  background: var(--dark); border-color: var(--dark); color: var(--panel);
}

/* 층 확장·공간 선택 (7-4). 사무실 아래에 한 덩어리로 둔다 —
   화면 옆에 붙이면 좁은 화면에서 사무실을 밀어낸다. */
.builder {
  margin: 18px auto 0; max-width: 760px;
  display: flex; flex-direction: column; gap: 8px; align-items: center;
}
.builder-row {
  display: flex; gap: 8px; align-items: center;
  flex-wrap: wrap; justify-content: center;
}
.builder-note { font-size: 12px; color: var(--muted); }
.space-btn {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  background: var(--panel); border: 2px solid var(--line); border-radius: 11px;
  padding: 6px 12px; cursor: pointer; box-shadow: 0 3px 0 var(--shadow);
}
.space-btn:hover { border-color: var(--accent); }
/* 잠긴 "층 지우기" — 왜 잠겼는지는 바로 아래 문구가 말한다. */
#btn-remove-floor:disabled, #btn-remove-floor[aria-disabled="true"] { cursor: not-allowed; opacity: 0.45; }
/* 잠긴 모습이 예전에는 **브라우저 기본 스타일**(button:disabled의 흐린 글자색)에
   얹혀 있었다. aria-disabled로 바꾸면 그게 안 걸려 글자가 도로 진해진다.
   UA 값을 흉내 내 베끼는 대신(브라우저마다 다르고 언제든 바뀐다) 우리 팔레트
   값을 적는다 — 잠긴 모습이 이제 어디서나 같다. 기준 이미지 7장을 이걸로
   갱신했다(버튼 글자색만, 위치·크기는 그대로). */
#btn-remove-floor[aria-disabled="true"] { color: var(--muted2); }
.space-btn .space-name {
  font-family: 'Fredoka', sans-serif; font-weight: 600; font-size: 12.5px; color: var(--ink);
  white-space: nowrap;
}
.space-btn .space-meta { font-size: 10.5px; color: var(--muted2); white-space: nowrap; }

.office-notice {
  margin-top: 18px; text-align: center; font-size: 13px; color: var(--muted);
  line-height: 1.6;
}

/* 오피스 바닥 — 예전엔 인라인 스타일이라 미디어쿼리가 닿지 않았다 */
.office-floor {
  position: absolute; inset: 70px 0 130px;
  overflow-y: auto; padding: 24px 60px 28px;
}

.instruction-dock {
  position: absolute; left: 0; right: 0; bottom: 0; height: 112px;
  background: var(--dock); border-top: 3px solid var(--shadow);
  display: flex; align-items: center; gap: 16px; padding: 0 32px;
}
.dock-field {
  /* min-width:0이 없으면 flex 항목이 콘텐츠 최소폭 아래로 줄지 않아,
     좁은 화면에서 고정폭 형제(라벨·안내문)에 밀려 입력창이 0px로 찌그러진다. */
  flex: 1; min-width: 0; max-width: 780px;
  display: flex; align-items: center; gap: 12px;
  background: var(--panel); border-radius: 16px; padding: 8px 8px 8px 20px;
  box-shadow: 0 4px 0 var(--shadow);
}
.dock-field input {
  border: none; background: transparent; box-shadow: none; padding: 6px 0;
  flex: 1; min-width: 0; width: 100%;
}

/* 배너 안 버튼은 글자가 줄바꿈되면 안 된다 — 좁은 폭에서 "내 사무실 만/들기"
   처럼 잘려 읽힌다. 배너 자체가 내용에 맞춰 늘어나므로 버튼만 고정하면 된다. */
.resume-banner .btn, .sync-error .btn { white-space: nowrap; }

/* 가운데 두기를 left:50% + translateX로 하면 **배너가 쓸 수 있는 폭이 화면의 절반으로 묶인다**
   (absolute 요소의 내용 맞춤 폭은 left부터 오른쪽 끝까지에서 정해진다). 768px에서 안내 문구가
   다섯 줄로 불어나 첫 방을 덮고 시계 아이콘이 점으로 눌렸다(2026-10-10 PM 지시). 양쪽을 0에 두고
   margin auto로 가운데 둔다 — 폭은 내용만큼, 최대 max-width까지. */
.resume-banner {
  position: absolute; left: 0; right: 0; margin: 0 auto; width: fit-content; top: 16px; z-index: 6;
  display: flex; align-items: center; gap: 14px;
  /* .sync-error에는 있는데 여기만 빠져 있었다. 없으면 배너가 .scene 폭까지
     벌어지고, 그 안에서 안내 문구가 눌려 **한 글자씩 세로로** 쪼개진다.
     한글은 어디서나 줄바꿈이 되므로 flex의 min-content가 사실상 한 글자다. */
  max-width: min(90vw, 620px);
  background: var(--panel); border: 2px solid var(--accent); border-radius: 14px;
  padding: 10px 12px 10px 18px; box-shadow: 0 5px 0 var(--shadow);
}

/* 아이콘은 줄지 않는다 — 글자에 밀려 점이 됐었다. */
.resume-banner > svg { flex-shrink: 0; }

/* 넓은 화면에서도 배너가 두 줄 이상이 되거나 두 배너가 겹쳐 뜨면 첫 방 위로 내려온다.
   겹치는 만큼만 main.js가 재어 --banner-over로 넘긴다(안 겹치면 0 — 지금 모습 그대로).
   640px 이하는 아래 미디어쿼리의 --banner-h 규칙이 이걸 덮어쓴다. */
.office-floor { padding-top: calc(24px + var(--banner-over, 0px)); }

/* 지시 전달 실패 — 입력창 옆 안내 문구 자리를 그대로 쓴다 */
.instruction-error { color: #c0503f; font-weight: 600; }
/* 데모에서 보낸 직후의 확인 한 줄 — 같은 자리, 잉크색 굵게(초록 글자는 대비가 모자란다). */
.instruction-notice { color: var(--ink); font-weight: 700; }
.instruction-notice::before { content: '✓ '; color: var(--good); }

/* 갱신 실패 배너 — resume-banner와 같은 자리·같은 톤, 색만 경고색으로.
   두 배너가 동시에 뜰 수 있어 이건 위쪽에 얹는다. */
.sync-error {
  position: absolute; left: 0; right: 0; margin: 0 auto; width: fit-content; top: 16px; z-index: 7;
  display: flex; align-items: center; gap: 14px;
  background: var(--panel); border: 2px solid #c0503f; border-radius: 14px;
  padding: 10px 12px 10px 18px; box-shadow: 0 5px 0 var(--shadow);
  font-size: 13px; color: #c0503f; max-width: min(90vw, 620px);
}
.sync-error + .resume-banner { top: 72px; }
.sync-error .btn {
  flex-shrink: 0; padding: 6px 14px; font-size: 12px;
  background: var(--panel2); border: 1.5px solid #c0503f; color: #c0503f;
}

/* 저장소가 공개일 때만 뜬다. 경고색이되 화면을 지배하지는 않는다 —
   사용자가 알고 고른 것일 수도 있어서 막지 않고 알리기만 한다. */
.repo-public-mark {
  font-size: 11.5px; font-weight: 600; color: #c0503f;
  background: #f7e3df; border: 1.5px solid #e0b3aa; border-radius: 8px;
  padding: 3px 9px; text-decoration: none; white-space: nowrap;
}

.chip {
  display: flex; align-items: center; gap: 8px; background: var(--panel2);
  border: 1.5px solid var(--line); border-radius: 12px; padding: 10px 16px;
  font-size: 13px; font-weight: 600;
  /* 좁은 화면에서는 한 줄에 못 담는다. 줄바꿈을 허용하지 않으면 안쪽 링크가
     세로로 눌려 "구매하 / 러 가기 / ↗"가 된다 — 한글은 어디서나 줄바꿈되므로
     글자가 깨지는 대신 상자가 좁아진다(30회차 QA에서 그림 보고 찾음). */
  flex-wrap: wrap;
}
/* 링크는 통째로 한 줄에 둔다. 넘치면 다음 줄로 내려가되 낱말이 쪼개지지는 않는다. */
.chip a { white-space: nowrap; }
/* 구매 링크가 브라우저 기본 파랑·밑줄로 나와 팔레트와 따로 놀았다(2026-10-24 PM 점검).
   소개 페이지의 링크와 같은 말투 — 글자는 잉크색, 밑줄은 포인트색. 포인트색 글자는 밝은 바탕에서
   대비가 모자라 글자에는 쓰지 않는다. */
.buy-link {
  color: var(--ink); font-weight: 700;
  text-decoration: underline; text-decoration-color: var(--accent);
  text-decoration-thickness: 2px; text-underline-offset: 3px;
}
.buy-link:hover { text-decoration-color: var(--ink); }
.buy-link:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

.muted { color: var(--muted); }
.muted2 { color: var(--muted2); }

.log-list { display: flex; flex-direction: column; gap: 10px; max-height: 260px; overflow-y: auto; }
.log-item { background: var(--panel); border-radius: 12px; padding: 10px 14px; box-shadow: 0 3px 0 var(--line); font-size: 13px; }

/* ─────────────────────────────────────────────────────────────
   좁은 화면 최소 대응 (2026-09-02)

   전면 반응형이 아니다. 이 앱은 GitHub 토큰 발급·붙여넣기가 필요해
   데스크톱 전제로 설계됐다(QA_REPORT ④). 다만 **데모는 토큰이 필요 없어
   모바일에서도 볼 수 있어야 하므로**, 가로 스크롤을 없애고 지시 입력창이
   쓸 수 있는 폭을 갖는 데까지만 손댄다.
   ───────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .office-floor { padding: 0 16px; }

  /* 머리글이 한 줄에 다 안 들어가면 **글자가 세로로 눌리는 대신** 줄을 바꾼다.
     360px에서 "○○의 사무실"이 폭 23px · 높이 102px로 찌그러져 있었다. */
  .topbar {
    height: auto; min-height: 60px; flex-wrap: wrap;
    padding: 8px 14px; row-gap: 6px;
    /* 줄을 안 바꾸고 버틸 때 로고와 오른쪽 글자가 맞붙지 않게(한/EN 버튼이 들어오며 빠듯해졌다). */
    column-gap: 10px;
  }
  .topbar-right { gap: 12px; flex-wrap: wrap; justify-content: flex-end; }
  .topbar-right > * { white-space: nowrap; }

  /* 데모 배너도 같은 이유로 눌린다 — 버튼을 아랫줄로 내린다. */
  .resume-banner, .sync-error {
    flex-wrap: wrap; justify-content: center; text-align: center;
    padding: 10px 14px; gap: 10px;
  }

  /* 엘리베이터를 세로로 두면 좁은 화면에서 사무실을 가린다 — 위쪽에 가로로. */
  .elevator {
    position: static; flex-direction: row; flex-wrap: wrap;
    /* 아래 4px은 버튼 그림자 자리(위 .elevator 주석) — 여기서 padding을
       다시 쓰므로 같이 적어야 한다. */
    justify-content: center; padding: 8px 12px 4px;
    /* 좁은 화면에서는 가로로 접히지만 줄이 계속 늘어난다 — 16층부터 방 위를
       덮어버렸다(99층에서는 화면 전체가 층 버튼이고 사무실이 그 위에 겹쳐
       그려졌다). 세 줄까지만 두고 나머지는 스스로 스크롤한다. */
    max-height: 144px; overflow-y: auto;
  }

  /* 역할 카드를 좁은 화면에서 두 칸으로 두면 한 칸이 150px도 안 된다.
     동그란 얼굴(44px)과 여백을 빼면 글자에 23px밖에 안 남아 **한 글자씩
     세로로** 쪼개진다 — 머리글에서 겪은 것과 같은 증상이다. 한 칸으로 편다. */
  .role-grid { grid-template-columns: 1fr; }

  /* 왼쪽 카드가 320px 고정이라 좁은 화면에서는 여백을 줄여야 들어간다. */
  .setup-pane { padding: 24px 16px !important; }
  .setup-col { width: auto !important; min-width: 0 !important; }
  /* 두 칸을 세로로 쌓는다. flex-wrap에만 맡기면 "나란히 붙었는데 안 들어가는"
     폭이 생긴다 — 390px에서 역할 칸이 106px 넘쳤다(38회차 QA). */
  .setup-row { flex-direction: column; gap: 24px !important; }

  /* 배너는 사무실 위에 떠 있다. 넓은 화면에서는 한 줄이라 위쪽 여백만 가리지만,
     좁은 화면에서는 서너 줄로 불어나 **첫 번째 방을 통째로 덮는다.**
     높이를 CSS로는 알 수 없어 main.js가 재어 --banner-h로 넘겨준다
     (배너가 없으면 0이라 아무 일도 일어나지 않는다). */
  /* 엘리베이터도 같은 문제다. 좁은 화면에서는 흐름에 놓이는데
     .office-floor는 absolute라 그 높이를 모른다 — 16층부터 층 버튼 위에
     방이 겹쳐 그려졌다(35회차 QA). 배너와 같은 방식으로 재서 받는다. */
  .office-floor { padding-top: calc(var(--banner-h, 0px) + var(--elevator-h, 0px)); }

  /* 진행 단계 표시가 320px에서 가로로 넘친다 — 줄바꿈을 허용한다 */
  /* 390px에서 "3 시작"만 아랫줄로 떨어져 두 줄이 됐다(A-1). 잇는 선과 간격을
     줄여 한 줄에 둔다. 그래도 모자란 아주 좁은 화면(320px)에서만 줄을 바꾼다. */
  /* 47회차에 한 줄로 만들었지만 글자 10.5px·선 8px로 **빽빽했다**(PM 리뷰). 세 이름을
     다 보이려니 줄일 수밖에 없었다. 좁은 화면에서는 **지금 단계 이름만** 보이고, 나머지는
     번호만 둔다 — 이름은 화면 읽기용으로 남긴다(.sr-only와 같은 방식). 그만큼 글자와
     간격을 넉넉히 되돌린다. */
  .steps { flex-wrap: wrap; row-gap: 6px; gap: 6px; }
  .step { gap: 6px; }
  .step-num { width: 24px; height: 24px; font-size: 12px; }
  .steps .label { font-size: 12px !important; }
  .step:not(.current) .label {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .step-line { width: 22px; }
  /* 두 번째 버튼이 390px에서 "GitHub / 연결하기"로 접혔다 — 좌우 여백만 줄인다 */
  .btn-secondary { padding: 14px 12px; }

  .instruction-dock { padding: 0 12px; gap: 10px; }
  /* 라벨은 줄바꿈 없이 한 줄로 좁게 */
  .instruction-dock > .label { width: auto !important; }
  /* "다음에 세션을 열 때…" 안내문은 190px를 차지한다 — 좁은 화면에서는
     입력창 자리를 뺏으므로 접는다. 오류 문구(.instruction-error)는
     읽어야 하므로 그대로 둔다. */
  .instruction-dock > .muted2 { display: none; }
  /* 오류 문구는 읽어야 하므로 보이되, **입력줄 안에 두지 않는다.** 같은 줄에 두면
     긴 문구가 한 줄 폭을 통째로 차지해(인라인 flex-shrink:0) 입력칸이 알약만 하게
     눌리고, 문구는 전달 버튼을 덮은 채 오른쪽이 잘렸다 — "줄여주세요"라는 안내를
     받았는데 줄일 글이 안 보였다(40회차 QA, 390·320px). 입력줄 바로 위에 띄운다.
     독은 position:absolute라 여기 기준으로 잡히고, 독 높이는 그대로다. */
  .instruction-dock > .muted2:has(.instruction-error),
  .instruction-dock > .muted2:has(.instruction-notice) {
    display: block; position: absolute; left: 12px; right: 12px; bottom: calc(100% + 6px);
    width: auto !important; flex-shrink: 1 !important;
    background: var(--panel); border-radius: 10px; padding: 6px 10px;
    box-shadow: 0 3px 0 var(--shadow); font-size: 12px !important; z-index: 8;
  }

  .sync-error, .resume-banner { max-width: calc(100vw - 24px); }
  }

/* 아주 좁은 화면(구형 기기)에서도 최소한 가로로 잘리지는 않게 */
@media (max-width: 380px) {
  /* 단축 padding을 쓰면 위쪽 640px 규칙이 넣어둔 padding-top(배너 높이)까지
     0으로 되돌아간다 — 실제로 그렇게 눌러버려 배너가 첫 방을 계속 덮었다.
     좌우만 건드린다. */
  .office-floor { padding-left: 10px; padding-right: 10px; }
  .instruction-dock { padding: 0 8px; }
}

/* 데모 녹화 모드(?record=1, Q4) — 영상에 안내·커서·포커스 링·툴팁이 찍히지 않게. 일반 화면에는 영향 없다. */
.record-mode, .record-mode * { cursor: none !important; }
.record-mode *:focus, .record-mode *:focus-visible { outline: none !important; box-shadow: none; }
.record-mode .resume-banner, .record-mode .sync-error, .record-mode .office-notice,
.record-mode .builder, .record-mode #btn-lang, .record-mode #btn-install,
.record-mode .topbar-right > :not(.office-title) { display: none !important; }
/* 영상(1920×1080·1080×1920)에서는 사무실이 화면에 비해 작다. 배율 3을 4/3배 해 **정확히 4배 픽셀**로
   키운다(픽셀 아트라 정수 배율을 지킨다). 녹화 모드에서만. */
.record-mode .floorplan { zoom: 1.3334; }
