/*
 * 앱 레이아웃. 토큰과 컴포넌트는 /css/tokens.css(= mockup/css.js allCss())에서 온다.
 * 여기서는 시안용 프레임 규칙만 실기기용으로 덮어쓴다 — 색은 건드리지 않는다.
 * 색을 여기서 새로 정하면 대비 게이트 바깥으로 나가므로 금지한다.
 */

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--kv-bezel);
  font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", sans-serif;
  overflow: hidden;                /* 지표 1.a — 스크롤을 만들지 않는다 */
  word-break: keep-all;
}

/*
 * 기기 프레임 (`?frame=device`) — 데스크톱 검토용. 실기기는 이 경로를 타지 않는다.
 * 앱을 1080x1920 iframe에 넣고 창에 맞춰 줄인다. 배율은 frame.js가 인라인으로 준다.
 */
.kv-frame { position: fixed; inset: 0; background: #000; overflow: hidden; }
/*
 * ⚠️ transform은 **레이아웃 크기를 바꾸지 않는다.** 줄여 그려도 이 요소는 여전히
 * 1080x1920을 차지하므로, 부모에게 가운데 정렬을 맡기면 창 밖으로 밀린다.
 * 절대 위치로 놓고 translate로 직접 가운데를 잡는다.
 */
.kv-frame-screen {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1080px;
  height: 1920px;
  border: 0;
  transform-origin: center center;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .18);
}

/* 시안은 300px 카드였다. 앱은 화면 전체를 쓴다. */
#app.kv-kiosk {
  width: 100vw;
  height: 100vh;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  position: relative;

  /*
   * 화면 칸의 안쪽 여백. **한 곳에서만 정한다.**
   *
   * 아래 `.kv-screen`의 padding과 크롬 두 줄의 음수 여백이 이 셋을 함께 쓴다. 크롬은
   * 화면 끝까지 닿아야 "바"로 읽히는데(시안의 `.kv-item .kv-topbar/.kv-bottombar`가
   * 같은 처방이다), 되끌 길이는 **화면 칸의 안쪽 여백과 정확히 같아야** 한다.
   * 시안 쪽 값(목업 14px = 앱 50.4px)을 옮겨 적을 수 없는 이유가 여기 있다: 앱의 여백은
   * 뷰포트에서 계산되는 clamp()라 1080px에서 43.2px이고 창 크기가 달라지면 함께 변한다.
   * 숫자를 두 번 적으면 바가 화면 끝에서 7px 어긋난 채 조용히 남는다
   * (2b-2 Task 2 보고서 예외 ②). 식을 하나만 두면 어긋날 수가 없다.
   */
  --kv-app-pad-x: clamp(16px, 4vw, 64px);
  --kv-app-pad-top: clamp(14px, 2.4vh, 34px);
  --kv-app-pad-bottom: clamp(14px, 2vh, 28px);
}

.kv-screen {
  border-radius: 0;
  flex: 1;
  min-height: 0;
  padding: var(--kv-app-pad-top) var(--kv-app-pad-x) var(--kv-app-pad-bottom);
  gap: 0;
}

/*
 * 크롬 두 줄을 화면 가장자리까지 끌어낸다 (시안 `.kv-item .kv-topbar`·`.kv-bottombar`와 같은 처방).
 * 상·하단바는 `.kv-screen` **안**에 있다 — 목업의 `kiosk()`가 그렇게 조립하고, 그 구조 위에
 * 상단바의 `order: -2`와 배너의 `order: -1`이 서 있다.
 *
 * 하단바의 margin-top은 **기본이 auto**다(2b-3 Task 6 · F3) — 주 CTA가 없는 화면(대기·
 * 사용 불가)에서는 이 auto 하나가 하단바를 화면 바닥에 붙이는 유일한 수단이다. 주 CTA가
 * 있는 화면(고르기·확인·전역 상태·접근성 변형)에서는 `shared/css.js`의
 * `.kv-cta-main + .kv-bottombar`가 이 값을 0으로 되돌린다 — 그 화면에서는 CTA 자신의
 * `margin-top: auto`가 남는 세로를 대신 먹고 하단바가 그 뒤에 바로 붙기 때문이다.
 * 즉 "바닥에 붙이는 auto"가 화면마다 다른 요소에 있다 — 항상 하단바 자신은 아니다.
 *
 * ⚠️ 하단바는 단축 속성을 쓰지 않는다. 첫 값을 0으로 적으면 이 규칙이(같은 특정도에서
 * 로드 순서로 이겨) 위 두 규칙이 정한 margin-top(화면에 따라 auto 또는 0)을 덮어 바가
 * 본문 바로 아래에 붙는다 — 시안 쪽에서 실제로 물린 함정이다. 2026-08-17 리뷰는 이
 * "기본이 auto"라는 전제 자체가 한 번 깨졌던 것도 잡았다 — 커밋 하나가 이 값을 화면
 * 종류와 무관하게 0으로 바꿨더니, 주 CTA가 없는 화면(대기)에서 하단바를 바닥에 붙일
 * 수단이 하나도 안 남아 바가 화면 중간으로 떠올랐다(목업 산출물, 아래 여백 368.9px).
 *
 * ⚠️ 종전에는 `.kv-overlay`(옛 음량 오버레이의 띠)도 같은 폭으로 끌어냈다. 2b-2 Task 4가
 * 그 띠를 없앴다 — `Aa` 시트는 절대 위치(`shared/css.js`의 `.kv-sheet`)라 화면 칸 안에서
 * 제 좌표로 뜨고, 되끌 것도 흐름에서 차지할 자리도 없다.
 */
.kv-topbar { margin: calc(-1 * var(--kv-app-pad-top)) calc(-1 * var(--kv-app-pad-x)) 0; }
.kv-bottombar {
  margin-left: calc(-1 * var(--kv-app-pad-x));
  margin-right: calc(-1 * var(--kv-app-pad-x));
  margin-bottom: calc(-1 * var(--kv-app-pad-bottom));
}

/*
 * **본문 타이포·배치가 여기 있었다 — 2b-3 Task 5가 지웠다.**
 *
 * `.kv-head`·`.kv-eyebrow`·`.kv-opt`·`.kv-grid`·`.kv-list`·`.kv-row`와 옛 화면 전용
 * 컴포넌트(`.kv-hero`·`.kv-voice*`·`.kv-order-*`·`.kv-total*`·`.kv-cta-card`·`.kv-ticket`·
 * `.kv-mic`·`.kv-btn`·`.kv-hint`·`.kv-card-*`) 스물 몇 줄이 이 자리에 있었다.
 *
 * 앞의 것들은 이제 `shared/css.js`가 **한 출처에서 두 축척으로** 낸다(`bothScales` + `mpx`).
 * 여기 따로 적어 두면 같은 치수가 두 곳에 있게 되고, 그것이 2b가 없애려는 것이다 —
 * 실제로 앱 헤드라인은 34px, 시안은 목업 21px(= 앱 축척 75.6px)로 **두 배 넘게 갈려 있었다.**
 * 32"/68.8ppi에서 34px은 12.5mm로 이 화면의 머리글로는 작았다.
 *
 * 뒤의 것들은 그 마크업을 그리던 화면(`ui/screens.js`의 열한 장)이 없어져 아무도 안 쓴다.
 *
 * ⚠️ **여기 남는 것은 「앱만의 사정」뿐이다**: 뷰포트에서 계산되는 여백(`--kv-app-pad-*`),
 * 크롬을 화면 끝까지 끌어내는 음수 여백, 시트가 하단바 위에서 멈추게 하는 `--kv-barh`,
 * 초점 표시, 확대 단계에서 크롬만 동결하는 규칙. 축척을 가진 값은 하나도 두지 않는다.
 */

/* 진행바 규칙 여섯이 여기 있었다 — 2b-2 Task 3이 진행바를 없애면서 함께 지웠다(설계서 §3.1).
   단계는 이제 눈썹 문구가 말한다. 옛 `.kv-pill`·`.kv-call`·`.kv-home`·`.kv-pill-ghost`(상단바)와
   `.kv-ctrlbar`·`.kv-ctrl*`(컨트롤 바) 규칙도 같은 이유로 지웠다 — 그 마크업을 그리던
   `render()`가 없어졌다. */

/* 자막 띠 규칙 셋이 여기 있었다 — 2b-3 Task 5가 지웠다. 자막은 이제 **힌트 줄**이
   겸한다(설계서 §3.1 · shared/screens/content.js의 hintLine). 띠를 없애 세로 한 줄을
   돌려주면서 지표 5.a가 요구하는 것(TTS 문장을 글로도 보여 주기)은 그대로 지킨다. */

/* 오버레이 규칙 다섯이 여기 있었다 — `.kv-overlay`(하단바 위의 띠)·`.kv-vol`·`.kv-vol-key`·
   `.kv-pad-close`. 2b-2 Task 4가 옛 음량 오버레이를 `Aa` 시트로 갈아 끼우면서 함께 지웠다:
   그 마크업을 내던 `OVERLAYS.volume`이 없어졌고, 시트의 치수는 `shared/css.js`가 두 축척으로
   낸다(`.kv-sheet`·`.kv-seg`·`.kv-mbtn`). 여기서 다시 적으면 시안과 갈린다.
   `.kv-pad`(화면 키패드)는 그 앞 Task 3이 같은 이유로 지웠다. */

/*
 * ⚠️ **시트가 열려도 크롬은 살아 있다.** (2026-08-16 Task 4 리뷰 지적 — CRITICAL)
 *
 * 무엇이 잘못됐었나. `.kv-scrim`은 `position: absolute; inset: 0`이고 좌표계는
 * `.kv-screen`(`position: relative`)이다 — 즉 **화면 칸 전체**를 덮었다(실측 1920px).
 * 두 바가 그 안에 있고 스크림이 마지막에 칠해지므로, 시트가 열린 동안 하단바의
 * `다시 듣기`·`직원 호출`·`눌러서 말하기`와 상단바의 `←`·`Aa`가 **전부 죽은 터치**가 됐다:
 * 위임 처리기는 `e.target.closest('[data-act]')`로 훅을 찾는데 스크림에는 훅이 없었다.
 * 「재청취 버튼 고정」(배리어프리 자격요건 매핑 v2 §44·46)과 「하단 직원 호출 상시」를
 * 「DOM에 있음」으로 읽은 자리이고, 같은 저장소가 이미 그 독법을 기각했다 —
 * 화면에 있으나 못 누르는 직원 호출은 「화면에 정확히 하나」를 0쪽으로 어긴 것이다
 * (shared/screens/chrome.js의 `calling` 주석, 2026-08-16 판단).
 *
 * 두 줄로 고친다.
 *  ① 상단바·배너는 스크림 **위**에 칠한다. 베일이 덮는 것은 「지금 조작 대상이 아닌 것」,
 *     즉 본문이다 — 크롬은 언제나 조작 대상이므로 베일 밖이다. 배너에도 거는 이유가 하나
 *     더 있다: `--kv-scrim`은 고대비에서 rgba(0,0,0,.72)라 소리 막힘 안내가 그 베일 아래서
 *     읽히지 않았다(지표 3.a에서 소리를 켜는 유일한 안내다).
 *  ② 스크림과 시트는 **하단바 위에서 멈춘다**(`--kv-barh`). 층을 올리는 것으로는 안 된다 —
 *     바를 시트 위에 올리면 시트 맨 아래의 「닫기」가 바 뒤로 들어가 **나가는 길이 사라진다**.
 *
 * `--kv-barh`를 CSS에 숫자로 안 적는 이유: 바 높이는 12mm 하한(tokens.js)과 크롬 여백에서
 * 나오는 **파생값**이다. 여기 실측 161.56px을 적으면 그 토큰이 움직이는 날 조용히 어긋난다.
 * `app/src/app.js`의 `render()`가 매번 재서 넘기므로 두 번 적을 일이 없다.
 * 실제로 덮이지 않는지는 선언이 아니라 **실측**이 지킨다(app/geometry.test.js의
 * 「시트가 열려도 하단바는 스크림 밖에 있다」 — 스크림·바·시트의 상자를 나란히 잰다).
 */
.kv-topbar, .kv-banner { position: relative; z-index: 1; }
.kv-scrim, .kv-sheet { margin-bottom: var(--kv-barh, 0px); }

/* 초점 표시 — 색만으로 구분하지 않는다 (4.a). 굵은 외곽선 + 배경 변화 */
[data-focused] {
  outline: 4px solid var(--kv-primary);
  outline-offset: 2px;
  background: var(--kv-accent-soft, var(--kv-muted));
}

/*
 * 확대 단계에서 **하단바만 확대를 타지 않는다** — 시안이 150·200%에서 하는 것과 같다
 * (`shared/css.js`의 `[data-scale] .kv-bottombar .kv-ctl`·`.kv-talk-label`·`.kv-talk .kv-wave`).
 *
 * 왜: 세 칸은 `white-space: nowrap`이고 `.kv-ctl`은 줄어들지 않는다(flex: 0 0 auto).
 * 200%에서 라벨을 두 배로 키우면 바가 가로로 넘쳐 라벨이 옆 버튼 위에 겹쳐 그려진다 —
 * 시안에서 실제로 물려 스크린샷으로 잡은 결함이고(74.8px 이탈), 앱은 바 안쪽 폭이 시안의
 * 3.6배라 같은 비율로 같은 일이 일어난다.
 *
 * 값을 옮겨 적지 않는 이유: 시안은 라벨을 10.5px로 얼려 두는데 그 숫자의 앱 축척 짝은
 * 37.8px이다. 여기에 37.8을 적으면 `shared/css.js`가 저작값을 바꿀 때 조용히 어긋난다.
 * `--kv-scale`을 바 안에서만 1로 되돌리면 **숫자를 한 번도 적지 않고** 같은 결과가 나온다 —
 * 이 바의 크기는 전부 `calc(<앱 축척 값> * var(--kv-scale))` 꼴이기 때문이다.
 * 확대에서 빠지는 것은 크롬뿐이고 본문은 그대로 커진다(지표 3.h는 기능 손실을 막는 것이지
 * 크롬까지 키우라는 뜻이 아니다). 하단바 글자는 얼려도 앱 축척 37.8px = 13.9mm ≈ 39pt로
 * 하한(20pt · 3.g 7.25mm)의 약 두 배다.
 */
/*
 * 배너도 같은 이유로 확대를 타지 않는다 — **스크린샷이 잡은 결함이다.**
 * 200%에서 소리 막힘 안내가 세 줄(354.33px)로 부풀어 화면 칸을 255px 넘겼고, 그만큼
 * 하단바(재청취·직원 호출)가 화면 밖으로 밀려나 있었다. 기하 게이트는 그때 「넘침 0」을
 * 찍고 있었다 — 안내는 700ms 뒤에 뜨는데 자가 그 전에 재고 끝났기 때문이다.
 * 그 사각지대는 geometry-check.js의 `OV-aa-blocked` 시나리오가 닫았다(waitMs + hasBanner).
 *
 * 배너는 본문이 아니라 크롬이다(설계서 §8 — 조작을 막지 않고 상단바 아래에 얹힌다).
 * 얼려도 앱 축척 37.8px = 13.9mm ≈ 39pt로 하한의 두 배다.
 */
/*
 * ✏️ **2026-08-28: 하단바를 이 목록에서 뺐다** (MasterKi 피드백 11번).
 *
 * 위 근거(가로가 꽉 차서 라벨이 겹친다)는 **한 줄일 때만** 참이었다. 이제 150·200%에서
 * 바가 두 줄로 접히므로(`shared/css.js`) 한 줄에 두 칸씩이라 폭이 두 배가 되고, 라벨을
 * 한 글자도 줄이지 않고 배율을 태울 수 있다.
 *
 * 두 줄을 막던 것은 세로였다 — 「200%에서 40px이 더 드는데 여유가 5.7px뿐」. 피드백
 * 4·9번이 격자·답 카드에 `flex: 1`을 주면서 그 전제가 없어졌다: 바가 커지면 카드가
 * 줄어들고, 카드는 하한의 17배라 빌려 줄 자리가 있다.
 *
 * **배너는 그대로 얼려 둔다** — 그쪽 근거(200%에서 세 줄로 부풀어 화면을 255px 넘겼다)는
 * 줄 수 문제라 두 줄 접기와 아무 상관이 없다.
 */
#app[data-scale="150"] .kv-banner,
#app[data-scale="200"] .kv-banner { --kv-scale: 1; }

/*
 * 설정 모드 (`?diag=1`) — 진단 수치와 맞추기 화면.
 *
 * ⚠️⚠️ **전체 화면이다** (2026-08-29 현장 피드백). 종전에는 오른쪽 아래 작은 상자였는데
 * **읽을 수 없었다.** 설정하는 사람은 숫자를 보며 볼륨 손잡이를 돌리고 마이크를 옮기는데,
 * 그 숫자가 구석에 작게 있으면 도구 구실을 못 한다. **설정 중에는 이용자 화면을 볼 일이
 * 없으므로** 덮어도 된다 — 그 판단이 이 결정의 근거다.
 *
 * ⚠️ **덮는 것과 미는 것은 다르다.** 여전히 `position: fixed`라 본문 배치를 **밀지 않는다** —
 * 조정하는 사람이 보는 기하와 이용자가 보는 기하가 같아야 조정이 뜻을 갖는다. 기하
 * 시나리오가 그것을 못박는다(질문 줄이 그대로 잡힌다).
 *
 * ⚠️ **글자 크기를 선언하지 않는다.** 이 파일에는 `font-size`가 하나도 없어야 하고
 * (치수의 출처는 `shared/css.js` 하나 — `app/typography.test.js`가 0개를 못박는다),
 * 앱의 모든 글자는 하한 19.6px(지표 3.g·[요청 3장])을 넘어야 한다.
 *
 * 그래서 크기는 **`--kv-scale`로** 키운다. 물려받는 글자가 전부
 * `calc(Npx * var(--kv-scale))` 꼴이므로(`shared/css.js`) 이 변수 하나면 `font-size`를
 * 한 줄도 안 적고 커진다 — 종전에 `1`로 **얼려 두던 바로 그 변수**다.
 * **`font:` 약식으로 크기를 밀어 넣지 않는다**: 그 정규식이 약식을 못 잡는 것은 검사의
 * 사각지대일 뿐이고, 그것을 이용하는 것은 게이트를 무르는 것이다.
 */
.kv-diag, .kv-calib {
  position: fixed; inset: 0; z-index: 99;
  /* 크기 손잡이는 이 하나다 — 글자 값은 shared/css.js가 갖고 여기에 이 배수가 곱해진다.
     2면 본문 40px · 보조 32px이다(1080×1920에서 여덟 줄이 화면의 1/4쯤). */
  --kv-scale: 2;
  padding: 24px 28px; overflow: auto;
  /*
   * ⚠️ **완전 불투명이다** (2026-08-29 현장 요청). 종전 `rgba(0,0,0,.94)`는 뒤의 이용자
   * 화면이 희미하게 비쳐, 설정하는 사람에게도 발주사에게도 **무엇을 보는 화면인지** 흐렸다.
   * 설정 중에는 이용자 화면을 볼 일이 없다.
   */
  background: #000; color: #fff;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  line-height: 1.6;
}
/* 맞추기가 진단 위에 겹친다 — 걸음 중에는 지시가 수치보다 앞이다. */
.kv-calib { z-index: 100; }
.kv-diag b { display: inline-block; }
.kv-diag .sub { opacity: .72; }
.kv-diag .warn { color: #ffd24d; margin-top: 8px; }
.kv-diag [data-diag-verdict="warn"] { color: #ffd24d; }
.kv-diag [data-diag-verdict="bad"] { color: #ff8a80; }
/*
 * ⚠️ **`<button>`은 글자 크기를 물려받지 않는다** — 브라우저가 폼 컨트롤에 자기 기본
 * 글꼴을 준다. 그래서 상자 글자만 커지고 버튼은 작게 남아 있었다(2026-08-29 현장 발견).
 *
 * `inherit`는 **치수가 아니다** — 「shared/css.js가 정한 것을 그대로 쓴다」는 선언이라
 * 「치수의 출처는 한 곳」이라는 규칙을 깨지 않는다. 여기에 px을 적는 것과는 다른 일이다.
 */
.kv-diag button, .kv-calib button {
  font-size: inherit; font-family: inherit;
  margin: 20px 16px 0 0; padding: 16px 28px; border-radius: 8px;
  min-height: 2em; cursor: pointer;
}

/*
 * 맞추기 화면의 안쪽 — 바깥 상자(전체 화면·크기)는 위 `.kv-diag, .kv-calib`가 함께 정한다.
 * 여기 있는 것은 그 안의 줄 간격과 색뿐이다.
 */
.kv-calib .calib-prompt { margin: 20px 0; }
.kv-calib .calib-fix { color: #ffd24d; }
.kv-calib .calib-value { margin: 12px 0; }
.kv-calib .calib-check[data-ok="false"] { color: #ff8a80; }
