/* 젠시 프레임 v13b - 화이트톤 (대표 지시 2026-09-04 02:04 「화이트톤. 애플느낌?」).
   값은 전부 :root 토큰. 화면 규칙은 변수만 참조한다.

   v13b 에서 갈린 것 - 칸을 나누는 방법이 「선」에서 「층」으로 바뀌었다.
   회색 페이지(--page) 위에 순백 카드(--bg)를 얹고 카드 테두리를 걷는다.
   그래서 --bg 는 이제 「페이지」가 아니라 「표면」이다 - 카드·입력·팝오버가 전부 이것을 쓰고
   있었으므로 이름만 바꾸면 스물몇 곳을 다 고쳐야 해서, 페이지 쪽에 --page 를 새로 세웠다.

   파랑은 주 버튼과 활성 탭에만 남긴다. 배지·게이지·막대·선택 상태의 파랑은 무채색(--sel-*)으로
   내렸다 - 파랑이 열 군데에 있으면 어느 것이 눌러야 하는 자리인지 안 갈린다.
   예외는 드래그 중 놓을 자리(drop-over)다. 정적인 「골라 둔 상태」가 아니라 지금 손이 움직이는
   동안만 뜨는 표시이고, 무채색으로 내리면 회색 위 회색이 되어 안 보인다.

   함정 셋: 테두리 회색 두 벌(--line / --divider) · 인풋 포커스는 primary 보더 + 연한 링 ·
   버튼 radius 는 --radius-btn(10px), 입력은 --radius-ctl(8px) 로 갈려 있다. */

:root {
  /* 🔴 gency.ai 무드로 맞췄다 (2026-09-23 대표 지시 「전체 디자인 무드 gency.ai보고 따라해」).
     같은 회사 제품이 한 눈에 같은 집안으로 보여야 한다. 값은 gency.ai 화면에서 실측했다 -
     주 파랑 #0A8FF5, 브랜드 그라데이션 #0A8FF5 → #B77BF8, 사이드바 #EEF0F2, 본문 #F9FAFB.
     같은 날 오전에 잠깐 주황으로 갔다가 이 지시로 되돌렸다. */
  --primary: var(--color-blue-600);          /* 주 액션 · 활성 탭 */
  --primary-hover: var(--color-blue-750);
  --primary-light: var(--color-blue-300);    /* 주 액션의 연한 배경 (gency 활성 메뉴) */
  --primary-soft: var(--color-blue-50);     /* 에디터 레일 활성 칸 */
  --brand-grad: linear-gradient(135deg, var(--color-blue-600), var(--color-purple-400));
  --accent-orange: var(--color-blue-600);    /* 「준비중」류 액센트 */
  --danger: var(--color-red-600);           /* 파괴적 동작 · 임계 95% */
  --danger-hover: var(--color-red-800);
  --warn: var(--color-orange-400);             /* 임계 80% 바 */
  --warn-text: var(--color-orange-800);        /* 경고 문구 */

  --text: var(--color-gray-900);             /* 본문 (gency 실측) */
  --text-sub: var(--color-gray-600);         /* 보조 */
  --text-hint: var(--color-gray-500);        /* 힌트 */
  --text-disabled: var(--color-gray-400);

  --page: var(--color-gray-100);             /* 페이지 바탕. 카드가 이 위에 뜬다 */
  --bg: var(--color-white);               /* 표면 - 카드 · 입력 · 팝오버 */
  --surface: var(--color-gray-200);          /* 서피스 · 호버 배경 · gency 회색 카드 */
  --sidebar-bg: var(--color-gray-200);       /* 사이드바 - gency 처럼 회색 판 위에 흰 활성 칸 */
  --line: var(--color-gray-300);             /* 입력 테두리 · 남은 구획선 */
  --divider: var(--color-gray-200);          /* 헤더 · 영역 경계 */

  --sel-bg: var(--color-gray-200);           /* 골라 둔 상태 (파랑 대신) */
  --sel-line: var(--color-gray-400);         /* 골라 둔 것의 테두리 */
  --meter: var(--color-gray-500);            /* 게이지 · 통계 막대 */

  --badge-warn-bg: var(--color-orange-100);    /* amber-100 */
  --badge-warn-text: var(--color-orange-1000);
  --badge-danger-bg: var(--color-red-100);  /* red-100 */
  --badge-danger-text: var(--color-red-900);

  --radius-card: 12px;
  --radius-ctl: 8px;
  /* 🔴 v26: 10px 에서 8px 로 내려 입력과 같은 값이 됐다. 화면 하나에 반경이 알약·16·10·8
     네 갈래였는데, **8 과 10 은 눈으로 구분이 안 되면서 종류만 늘린다.** 버튼과 입력이
     한 줄에 나란히 서는 자리가 많아서(검색 칸 옆 버튼, 폼 하단) 거기서 특히 어긋나 보였다.
     이제 셋이다 - 알약(배지·칩) · 16px(카드) · 8px(누르고 치는 것).
     「애플 느낌」은 요소가 예뻐서가 아니라 **종류가 적어서** 생긴다 (계약 §30.5). */
  --radius-btn: 8px;
  --header-h: 48px;
  --tabbar-h: 56px;
  /* 걷어낸 자리는 층(회색 위 흰색)이 대신한다. 남은 셋은 실제로 떠 있는 것에만 -
     팝오버 · 드래그 고스트 · 모달. */
  /* 그림자 색은 DS elevation 한 가지(rgba(91,105,115,.16)). 검정 그림자는 gency 화면에 없다. */
  --shadow-md: 0 1px 2px rgba(91, 105, 115, .16);
  --shadow-lg: 0 4px 8px rgba(91, 105, 115, .16);
  --shadow-xl: 0 16px 32px rgba(91, 105, 115, .16);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
body.has-tabbar { padding-bottom: calc(var(--tabbar-h) + 156px + env(safe-area-inset-bottom)); } /* v4: 보내기 바가 기간 줄 + 안내 문장까지 커졌다 */
a { color: inherit; }
img { max-width: 100%; display: block; }
h1, h2, h3 { margin: 0 0 8px; line-height: 1.35; letter-spacing: -.01em; }
h1 { font-size: 20px; font-weight: 600; }
h2 { font-size: 15px; font-weight: 600; }
h3 { font-size: 14px; font-weight: 500; }
p { margin: 0 0 8px; }
.muted { color: var(--text-hint); }
.sub-text { color: var(--text-sub); }
.small { font-size: 12px; }
.tiny { font-size: 11px; }
.accent { color: var(--danger); }
.warn-text { color: var(--warn-text); }
.hidden { display: none !important; }
/* v20: 고치는 중에는 「만들 때만 뜻이 있는 자리」를 숨긴다 (§28.2). `.hidden` 을 안 쓰는
   이유는 그 칸들이 자기 사정으로 `.hidden` 을 붙였다 뗐다 하기 때문이다 - 같은 칸을
   두 주체가 토글하면 한쪽이 다른 쪽을 되살린다. */
.edit-off { display: none !important; }
.mono { font-family: ui-monospace, Consolas, monospace; }
.num { font-variant-numeric: tabular-nums; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------------- 레이아웃 */
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 16px; }
main.wrap { padding-top: 16px; padding-bottom: 32px; }
@media (min-width: 768px) {
  .wrap { padding-left: 24px; padding-right: 24px; }
  main.wrap { padding-top: 24px; }
}

.topbar {
  position: sticky; top: 0; z-index: 20;
  height: var(--header-h);
  background: var(--bg);
  border-bottom: 1px solid var(--divider);
}
.topbar .wrap { height: 100%; display: flex; align-items: center; gap: 12px; }
.brand { display: flex; align-items: baseline; gap: 6px; white-space: nowrap; min-width: 0; overflow: hidden; }
@media (max-width: 480px) {
  .brand .org { display: none; }
  .gauge { width: 104px; }
}
.brand .name { font-size: 15px; font-weight: 700; color: var(--text); }
.brand .tag { font-size: 10px; font-weight: 500; color: var(--text-hint); letter-spacing: .06em; }
.brand .org { font-size: 12px; color: var(--text-hint); overflow: hidden; text-overflow: ellipsis; }
.topbar .spacer { flex: 1; }
.linkbtn {
  background: none; border: 0; padding: 6px 8px; min-height: 0;
  color: var(--text-hint); font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
  border-radius: var(--radius-ctl);
  position: relative;
}
/* 헤더 48px 안이라 보이는 높이는 못 키운다 - 터치 영역만 세로 45px (2026-09-03 QA r6) */
.linkbtn::after { content: ''; position: absolute; left: 0; right: 0; top: -7px; bottom: -7px; }
.linkbtn:hover { background: var(--surface); }

/* 사용량 게이지 (DESIGN 「사용량 게이지」) */
.gauge { width: 128px; flex: none; }
.gauge .g-row { display: flex; justify-content: space-between; align-items: baseline; font-size: 11px; color: var(--text-hint); }
.gauge .g-val { font-variant-numeric: tabular-nums; color: var(--text-sub); }
.gauge .g-bar { height: 4px; border-radius: 999px; background: var(--surface); margin-top: 4px; overflow: hidden; }
.gauge .g-fill { height: 100%; border-radius: 999px; background: var(--meter); transition: width .2s; }
.gauge.warn .g-fill { background: var(--warn); }
.gauge.warn .g-row, .gauge.warn .g-val { color: var(--warn-text); }
.gauge.danger .g-fill { background: var(--danger); }
.gauge.danger .g-row, .gauge.danger .g-val { color: var(--danger); }
.gauge.wide { width: 100%; }
.gauge .g-cta { font-size: 12px; margin-top: 6px; }

/* 탭 - 모바일 하단 고정, 데스크톱은 헤더 아래 상단 탭 */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 15;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--bg);
  border-top: 1px solid var(--divider);
  display: flex;
}
/* 🔴 v26: 반경을 0 으로 못 박는다. `button, .btn` 이 모든 버튼에 10px 을 주는데,
   데스크톱 탭은 활성 표시로 **아래 테두리 2px** 을 쓴다. 둥근 모서리 상자에 한 변만
   테두리를 그리면 그 선이 양끝에서 위로 휘어 올라가 **밑줄이 아니라 상자처럼 보인다.**
   대표가 보낸 그림에서 「보드」 탭 아래가 그 모양이었다. 아래 `.sec-warn` 의 왼쪽 띠도
   같은 원인이라, 이 저장소에서 같은 실수가 두 자리에 있었다. */
.tabbar button {
  flex: 1; border: 0; border-radius: 0; background: none; color: var(--text-hint);
  min-height: var(--tabbar-h); font: inherit; font-size: 10px; font-weight: 500;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  cursor: pointer; touch-action: manipulation;
}
.tabbar button .ico { font-size: 20px; line-height: 1; }
.tabbar button.active { color: var(--primary); font-weight: 600; }
/* 메뉴 아이콘은 SVG 한 벌이다(`app.html` 맨 위 sprite). 크기는 그 자리의 font-size 를
   그대로 따른다 - 폭별로 이미 정해 둔 글자 크기 규칙을 새로 쓰지 않으려는 것이다. */
.ico { display: inline-flex; align-items: center; justify-content: center; }
.ico svg, .nav-caret svg, .dash-ico svg {
  width: 1.2em; height: 1.2em; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.nav-caret svg { width: 14px; height: 14px; }
@media (min-width: 768px) {
  body.has-tabbar { padding-bottom: 0; }
  .tabbar {
    position: sticky; top: var(--header-h); bottom: auto; z-index: 15;
    height: 44px; padding-bottom: 0;
    border-top: 0; border-bottom: 1px solid var(--divider);
    justify-content: flex-start; gap: 4px;
    padding-left: max(24px, calc((100% - 1120px) / 2 + 24px));
  }
  .tabbar button {
    flex: none; flex-direction: row; gap: 6px; min-height: 0; height: 44px;
    padding: 0 14px; font-size: 13px;
    border-bottom: 2px solid transparent;
  }
  .tabbar button .ico { font-size: 15px; }
  .tabbar button.active { border-bottom-color: var(--primary); }
}

section.panel { display: none; }
section.panel.active { display: block; }

/* ---------------------------------------------------------------- 카드 */
/* v13b: 테두리를 걷고 회색 페이지 위에 순백으로 띄운다. 선이 아니라 층으로 나눈다 */
.card {
  border: 0;
  border-radius: var(--radius-card);
  padding: 16px;
  margin-bottom: 20px;
  background: var(--bg);
}
@media (min-width: 768px) { .card { padding: 24px; } }
/* soft 카드는 페이지와 같은 회색이라 층이 안 생긴다. 이것만 선으로 가른다 */
.card.soft { background: var(--surface); border: 1px solid var(--divider); }
.row { display: flex; gap: 10px; align-items: center; }
.row.between { justify-content: space-between; }
.stack > * + * { margin-top: 12px; }
.grow { flex: 1; min-width: 0; }
.divider { height: 1px; background: var(--divider); margin: 16px 0; }
.empty {
  text-align: center; color: var(--text-hint); font-size: 13px;
  padding: 48px 12px; border: 1px dashed var(--line); border-radius: var(--radius-card);
  background: var(--bg);
}

/* ---------------------------------------------------------------- 폼 */
label.field { display: block; margin-bottom: 12px; }
label.field > span.lbl { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--text-sub); margin-bottom: 4px; }
label.field .count { font-variant-numeric: tabular-nums; color: var(--text-hint); }
label.field .count.full { color: var(--danger); font-weight: 600; }
/* 저장돼 있던 글이 이 칸의 상한보다 길 때. 숫자만 빨개지면 「다 찼다」와 구분이 안 되므로
   테두리를 둘러 다른 상태인 것을 눈으로 가른다 (`web/app.js` 의 `bindCounter`). */
label.field .count.over { color: var(--danger); font-weight: 700; border: 1px solid var(--danger); border-radius: 999px; padding: 0 6px; }
/* 왜 넘쳤는지 적는 줄.
   🔴 `word-break: keep-all` 을 **여기서 주면 안 된다.** 이 문구는 세 사전을 거쳐 번역되고,
   일본어 문장에는 공백이 하나도 없다. 일본어에서 `keep-all` 은 글자 사이를 전부 막으므로
   문장 하나가 **통째로 한 줄**이 되어 카드 밖으로 튀어나가고 가로 스크롤이 생긴다.
   한국어는 아래 `html[lang=ko] .hint` 가 같은 일을 이미 하고 있고(줄 뒤에 있어 이긴다),
   그 규칙이 `overflow-wrap: anywhere` 를 짝으로 달고 있어 긴 낱말도 갇히지 않는다.
   ⚠ 가를 축은 「무슨 칸인가」가 아니라 **「그 칸에 어느 말이 들어오는가」**다. */
p.hint.count-over { color: var(--danger); }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=tel], input[type=time], input[type=date], select, textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-ctl);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
input::placeholder, textarea::placeholder { color: var(--text-hint); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--color-blue-100);
}
input:disabled, select:disabled { background: var(--surface); color: var(--text-hint); }
@media (max-width: 767px) {
  input, textarea, select { font-size: 16px !important; }  /* iOS 자동 확대 방지 */
}
.hint { font-size: 12px; color: var(--text-hint); margin-top: 4px; }
/* .hint 가 .warn-text 보다 뒤에 있어 같은 특이도에서 이겼다. 경고를 힌트로 쓴 자리
   (날씨 시트의 「이 매장에 아직 지역이 없습니다」)가 회색으로 나오고 있었다 - v13b 그림 QA. */
.hint.warn-text { color: var(--warn-text); }

/* ---------------------------------------------------------------- 버튼 */
button, .btn {
  padding: 8px 16px;
  border-radius: var(--radius-btn);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text-sub);
  font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
button:hover { background: var(--surface); }
/* 다른 페이지로 넘기는 것은 `<a>` 여야 한다 - 가운데 버튼으로 새 탭에 열거나 주소를
   복사하는 길이 `<button>` 에는 없다. 다만 `.btn` 의 모양 규칙은 hover 와 밑줄을
   `button` 에만 걸어 두어서, 링크로 쓰면 그 둘이 빠진 채 그려진다. */
a.btn { text-decoration: none; }
a.btn:hover { background: var(--surface); }
button.primary { background: var(--primary); border-color: var(--primary); color: var(--color-white); font-weight: 600; }
button.primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
button.danger { background: var(--danger); border-color: var(--danger); color: var(--color-white); }
button.danger:hover { background: var(--danger-hover); border-color: var(--danger-hover); }
button.ghost { border-color: transparent; color: var(--text-hint); }
button.ghost:hover { background: var(--surface); }
button.block { width: 100%; padding-top: 11px; padding-bottom: 11px; }
button.sm { padding: 6px 12px; font-size: 12px; }
button:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }
button .sub { font-weight: 400; font-size: 11px; opacity: .8; }

/* ---------------------------------------------------------------- 배지 */
.badge {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 500; white-space: nowrap;
}
/* v13b: 배지의 파랑을 무채색으로 내렸다. 배지는 상태를 알리는 것이지 누르는 자리가 아니다 */
.badge.brand { background: var(--sel-bg); color: var(--text-sub); }
.badge.neutral { background: var(--surface); border: 1px solid var(--divider); color: var(--text-hint); }
.badge.warn { background: var(--badge-warn-bg); color: var(--badge-warn-text); }
.badge.danger { background: var(--badge-danger-bg); color: var(--badge-danger-text); }
.badge.pill { background: var(--sel-bg); color: var(--text-sub); }
/* 🔴 **새 색을 만들지 않았다** (계약 §30.5 - 「애플 느낌」은 요소가 예뻐서가 아니라 종류가
   적어서 생긴다). 「지금 벽에 걸려 있다」는 경고가 아니라 좋은 상태라 amber·red 가 안 맞고,
   v13b 가 배지의 파랑을 무채색으로 내려 둔 자리라 파랑도 안 맞다. 그래서 **무채색 안에서
   대비만 올린다** - 글자를 본색으로 올리고 테두리를 준다. 걸려 있는 것과 안 걸려 있는 것이
   눈으로 갈리는 것이 이 배지의 일이고, 색 하나를 더 만드는 것은 그 일에 필요하지 않다.
   11px 은 그대로 둔다 - 이 배지는 화면 안에서 다가와 읽는 글이고, 벽에서 읽는 글이 아니다. */
.badge.pill.ok { background: var(--bg); border: 1px solid var(--sel-line); color: var(--text); }

/* 걸려 있을 때 뜨는 「다른 기기에도 보내기」가 360px 에서 「다른 기기에도 보 / 내기」로
   낱말 중간이 쪼개졌다(교정 전 증거 `docs/qa/round-ff6fdecb/before-keepall-buttons-onwall-360.png`).
   직전 회차가 라이브러리 CTA 에서 같은 결함을 `word-break: keep-all` 로 고쳤고(`.lib-new`)
   같은 방식을 쓴다 - 한국어는 낱말 사이에서 접혀야 읽힌다. */
#btn-go-board { word-break: keep-all; }

/* ---------------------------------------------------------------- 보드 */
/* 🔴 **기기 현황이 먼저다** (대표님 지시 2026-09-13, 계약 §71). 칸 순서가 `200px 1fr`
   에서 `1fr 200px` 로 바뀐 것은 **넓은 화면에서 자리를 지키기 위해서다** - 좁은 화면의
   순서를 고치려고 DOM 에서 기기 카드를 앞으로 옮겼는데, 칸 폭을 그대로 두면 넓은 화면에서
   기기 카드가 200px 짜리 좁은 칸에 들어간다. **한쪽을 고치면 다른 쪽이 깨지는 자리라
   둘을 같이 옮긴다.** 화면 목록은 끌어다 놓는 자리라 계속 보여야 하므로 없애지 않고
   오른쪽으로 보낸다. */
.board { display: block; }
@media (min-width: 768px) {
  .board { display: grid; grid-template-columns: 1fr 200px; gap: 24px; align-items: start; }
}

.library { min-width: 0; }
.library .lib-title { font-size: 12px; color: var(--text-hint); margin-bottom: 8px; }
.lib-grid { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 8px; -webkit-overflow-scrolling: touch; }
.lib-grid::-webkit-scrollbar { height: 4px; }
@media (min-width: 768px) {
  .library {
    position: sticky; top: calc(var(--header-h) + 44px + 16px);
    background: var(--sidebar-bg);
    border: 0; border-radius: var(--radius-card);
    padding: 12px;
    max-height: calc(100vh - var(--header-h) - 44px - 32px);
    overflow-y: auto;
  }
  .lib-grid { display: grid; grid-template-columns: 1fr; gap: 12px; overflow-x: visible; padding-bottom: 0; }
}
.lib-item { flex: none; width: 104px; cursor: pointer; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
@media (min-width: 768px) { .lib-item { width: auto; } }
.lib-item .lib-thumb {
  width: 100%; aspect-ratio: 5 / 3; object-fit: contain;
  background: var(--surface);
  border: 1px solid var(--divider); border-radius: var(--radius-ctl);
  /* v26: 축소 표시에서는 auto. `pixelated` 는 최근접 이웃이라 800×480 을
     100~200px 로 줄일 때 **가는 획을 통째로 버린다** - 메뉴판 미리보기의 한글이
     뭉개져 안 읽히던 원인이다. 원본 폭에 가깝게 키워 보여주는 자리에서만 픽셀을 살린다. */
  image-rendering: auto;
}
.lib-item .lib-name { font-size: 11px; color: var(--text-sub); margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* v13b: 골라 둔 표시를 파랑에서 진한 테두리로. 파랑은 누르는 자리에만 남긴다 */
.lib-item.selected .lib-thumb { border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.lib-item.selected .lib-name { color: var(--text); font-weight: 600; }
.lib-new {
  flex: none; width: 104px; min-height: 62px;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line); border-radius: var(--radius-ctl);
  background: none; color: var(--text-hint); font-size: 12px; font-weight: 500;
  cursor: pointer; padding: 8px;
  aspect-ratio: 5 / 3;
}
.lib-new:hover { background: var(--surface); color: var(--text); }
@media (min-width: 768px) { .lib-new { width: auto; aspect-ratio: auto; padding: 14px 8px; } }

/* ---------------------------------------------------------------- 첫 걸음 (계약 §71.4)
   🔴 **한 장도 없는 계정에서는 이 카드가 목록이 아니다.** 목록의 규칙(왼쪽부터 채우고
   가로로 민다)을 빈 상태에 그대로 쓰면, 단추 하나가 왼쪽 끝에 붙고 오른쪽 90% 가 빈
   채로 카드 높이만 차지한다. 2026-09-20 에 대표님이 「지금걸린화면도 이상해
   디자인깨진거같아」로 짚으신 자리가 정확히 그 모양이었다.
   **빈 상태는 덜 채워진 목록이 아니라 다른 화면이다** - 여기서 할 일이 하나뿐이므로
   그 하나를 가운데 놓고, 무엇인지 알려 주는 문장을 바로 붙여 한 덩어리로 읽히게 한다.
   ⚠ 안내 문장은 이 그리드의 형제(`#lib-hint`)라서 인접 선택자로 같이 잡는다. 문장을
   그리드 안으로 옮기지 않은 이유는 그 자리가 목록일 때도 쓰이기 때문이다 - 한쪽
   상태를 고치려고 양쪽이 쓰는 자리를 옮기면 반대쪽이 조용히 어긋난다. */
.lib-grid.lib-grid-first {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 28px 12px 4px;
}
.lib-grid.lib-grid-first .lib-new {
  width: 176px;
  aspect-ratio: auto;
  min-height: 92px;
  border-color: var(--brand);
  color: var(--brand);
  font-size: 13px;
}
.lib-grid.lib-grid-first .lib-new:hover { background: var(--brand-weak, var(--surface)); }
.lib-grid.lib-grid-first + .hint {
  text-align: center;
  padding: 0 16px 24px;
  margin: 0;
}
@media (min-width: 768px) {
  /* 768 이상에서 `.lib-grid` 가 1열 그리드로 바뀌므로 여기서 다시 세로 배치로 돌린다.
     안 적으면 이 상태만 위 규칙에 덮여 단추가 카드 폭 전체로 늘어난다. */
  .lib-grid.lib-grid-first { display: flex; }
  .lib-grid.lib-grid-first .lib-new { width: 176px; padding: 14px 8px; }
}

.store-sec { margin-bottom: 40px; }
/* v13b §22.10: 보드 전체 상태 띠. 회색 페이지 위 순백 층이라 카드와 같은 문법이고,
   칸을 나누는 선은 쓰지 않는다. 칩은 누르는 자리이지만 파랑을 안 쓴다 - §22.6 이
   파랑을 주 버튼과 활성 탭에만 남겼고, 여기서 파래지면 무엇이 주 동작인지 다시 흐려진다.
   고른 상태는 짙은 무채색으로 뒤집어 표시한다. */
.status-strip {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  background: var(--bg); border-radius: var(--radius-card);
  padding: 12px 16px; margin-bottom: 16px;
}
/* v26: 거를 것이 없을 때. 카드를 걷고 한 줄로 낮춘다 - 담긴 것이 짧은 글 둘뿐인데
   흰 카드 한 장을 쓰면 화면이 비어 보인다. 조건은 `renderStatusStrip` 의 `thin` 에 있다. */
.status-strip.thin { background: none; padding: 2px 0 8px; margin-bottom: 8px; }
.status-strip .ss-total { font-weight: 600; font-size: 15px; margin-right: 4px; }
.status-strip .ss-ok { font-size: 13px; color: var(--text-hint); }
.status-strip .spacer { flex: 1; }
.ss-chip {
  min-height: 32px; padding: 5px 12px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--text);
  font-size: 13px; font-weight: 500; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.ss-chip:hover { border-color: var(--sel-line); }
.ss-chip.bad { background: var(--badge-danger-bg); border-color: transparent; color: var(--badge-danger-text); }
.ss-chip.warn { background: var(--badge-warn-bg); border-color: transparent; color: var(--badge-warn-text); }
.ss-chip.on { background: var(--text); border-color: var(--text); color: var(--color-white); }
@media (max-width: 480px) {
  .status-strip { padding: 10px 12px; gap: 6px; }
  .status-strip .ss-total { width: 100%; margin-right: 0; }
}

/* v14 §24.7: 보안 경고 띠. 상태 띠 바로 위이고 같은 순백 층 문법을 쓰되, 왼쪽에 경고색
   세로 줄 하나만 세운다. 칩처럼 배경을 통째로 물들이지 않는 이유는 - 이 줄은 세는 자리가
   아니라 읽는 자리라서, 넓은 색면을 깔면 아래 상태 띠의 「응답 없음 4」와 무게가 같아진다. */
/* 🔴 v26: 왼쪽 색 띠(`border-left: 3px`)를 걷었다. 반경 16px 짜리 카드에 왼쪽 테두리만
   그리니 그 선이 위아래 모서리를 따라 휘어 **괄호 「(」 가 카드 밖에 떠 있는 것처럼** 보였다.
   위 `.tabbar button` 의 밑줄과 같은 원인이다.
   띠가 없어도 뜻은 안 죽는다 - 「보안 점검」 배지가 이미 경고색이고 그것이 첫 글자다.
   **뒤집을 조건** - 배너 종류가 셋을 넘어 배지만으로 급함이 안 갈리면, 테두리가 아니라
   배경색으로 등급을 나눈다. 모서리를 따라 휘지 않는 것은 배경뿐이다. */
.sec-warn {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  background: var(--surface); border-radius: var(--radius-card);
  padding: 12px 16px; margin-bottom: 12px;
}
.sec-warn .sec-badge {
  font-size: 12px; font-weight: 600; white-space: nowrap;
  color: var(--badge-warn-text); background: var(--badge-warn-bg);
  border-radius: 999px; padding: 3px 10px;
}
.sec-warn .sec-text { font-size: 14px; line-height: 1.5; flex: 1 1 240px; }
@media (max-width: 480px) {
  .sec-warn { padding: 10px 12px; gap: 8px; }
}

.store-head {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; margin: 0 -10px 10px;
  border-radius: var(--radius-ctl);
  border: 1px dashed transparent;
}
.store-head h2 { margin: 0; }
.store-head .cnt { font-size: 12px; color: var(--text-hint); }
.store-head .spacer { flex: 1; }
body.dragging .store-head[data-drop] { border-color: var(--line); background: var(--sidebar-bg); }
.store-head.drop-over { border-color: var(--primary) !important; background: var(--primary-light) !important; }

.dev-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
@media (min-width: 768px) { .dev-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; } }
.dev-card {
  position: relative;
  border: 0; border-radius: var(--radius-card);
  background: var(--bg);
  padding: 10px;
  transition: box-shadow .12s, transform .12s;
}
.dev-card.clickable { cursor: pointer; }
.dev-card.clickable:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.dev-card .dev-thumb {
  width: 100%; aspect-ratio: 5 / 3; object-fit: contain;
  background: var(--surface);
  border: 1px solid var(--divider); border-radius: var(--radius-ctl);
  /* v26: 축소 표시에서는 auto. `pixelated` 는 최근접 이웃이라 800×480 을
     100~200px 로 줄일 때 **가는 획을 통째로 버린다** - 메뉴판 미리보기의 한글이
     뭉개져 안 읽히던 원인이다. 원본 폭에 가깝게 키워 보여주는 자리에서만 픽셀을 살린다. */
  image-rendering: auto;
}
.dev-card .dev-thumb.empty {
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--text-hint);
}
.dev-card .dev-name { font-size: 14px; font-weight: 500; margin-top: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dev-card .dev-pop { font-size: 11px; color: var(--text-hint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-height: 1.5em; }
.dev-card .dev-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
/* 배지 한 장이 카드보다 넓으면 카드 밖으로 삐져나가 **문서 전체가 가로로 넘친다.**
   390px 에서 기기 격자는 2열이라(이 파일 아래쪽 max-width 규칙) 카드 한 칸이 165px 인데,
   일본어 「中継オフ・プライスタグ1個が待っています」가 201px 한 줄로 버텨 화면을 23px
   밀어냈다 - 실측 `docs/qa/relayseen-3f7c91a4/validation.json` 의 before-390-ja.
   `.badge` 의 nowrap 은 「온라인」 같은 짧은 상태값을 위한 것이다. 중계 배지는 점주가
   읽고 프레임을 켜러 가야 하는 **문장**이라 말줄임으로 자르면 할 일이 사라지므로,
   자르지 않고 **카드 안에서 접는다.** 한국어는 낱말 사이에서 접혀야 읽히므로 keep-all 을
   주고(`#btn-go-board` 와 같은 이유), 그러면 안 접히는 일본어와 긴 기기 이름은
   overflow-wrap 이 마지막에만 받아 준다. */
.dev-card .dev-badges .badge {
  white-space: normal; word-break: keep-all; overflow-wrap: anywhere; max-width: 100%;
}
body.dragging .dev-card[data-drop] { border-style: dashed; }
.dev-card.drop-over { border-color: var(--primary) !important; border-style: solid !important; box-shadow: 0 0 0 2px rgba(10, 143, 245, .25); background: var(--primary-light); }
.dev-card .pickmark {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 24px; height: 24px; border-radius: 999px;
  border: 1.5px solid var(--line); background: rgba(255, 255, 255, .9);
  color: transparent; font-size: 14px; line-height: 21px; text-align: center;
  cursor: pointer;
}
.dev-card.picked { box-shadow: 0 0 0 2px var(--text); }
.dev-card.picked .pickmark { background: var(--text); border-color: var(--text); color: var(--color-white); }

/* 드래그 고스트 */
#drag-ghost {
  position: fixed; z-index: 100; pointer-events: none;
  width: 132px; aspect-ratio: 5 / 3; object-fit: contain;
  background: var(--bg);
  border: 1px solid var(--primary); border-radius: var(--radius-ctl);
  box-shadow: var(--shadow-lg);
  transform: translate(-50%, -60%);
  opacity: .92;
  /* v26: 축소 표시에서는 auto. `pixelated` 는 최근접 이웃이라 800×480 을
     100~200px 로 줄일 때 **가는 획을 통째로 버린다** - 메뉴판 미리보기의 한글이
     뭉개져 안 읽히던 원인이다. 원본 폭에 가깝게 키워 보여주는 자리에서만 픽셀을 살린다. */
  image-rendering: auto;
}
body.dragging { -webkit-user-select: none; user-select: none; }

/* 보내기 모드 하단 바 - v4 에서 두 줄(대상 + 기간)이 됐다 */
.sendbar {
  position: fixed; left: 0; right: 0; z-index: 18;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--divider);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, .06);
  padding: 10px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.sendbar .sb-main { display: flex; align-items: center; gap: 12px; }
.sendbar .sb-thumb {
  width: 56px; aspect-ratio: 5 / 3; object-fit: contain; flex: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  /* v26: 축소 표시에서는 auto. `pixelated` 는 최근접 이웃이라 800×480 을
     100~200px 로 줄일 때 **가는 획을 통째로 버린다** - 메뉴판 미리보기의 한글이
     뭉개져 안 읽히던 원인이다. 원본 폭에 가깝게 키워 보여주는 자리에서만 픽셀을 살린다. */
  image-rendering: auto;
}
.sendbar .sb-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sendbar .sb-hint { font-size: 11px; color: var(--text-hint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 768px) {
  .sendbar {
    left: 50%; right: auto; bottom: 24px; transform: translateX(-50%);
    width: auto; max-width: 640px; min-width: 420px;
    border: 1px solid var(--line); border-radius: var(--radius-card);
    box-shadow: var(--shadow-lg);
  }
}

/* ---------------------------------------------------------------- 만들기 */
.choice-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.choice {
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); color: var(--text-sub);
  padding: 14px 8px; font-size: 13px; font-weight: 500;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  cursor: pointer;
}
.choice .ico { font-size: 20px; line-height: 1; }
.choice:hover { background: var(--surface); }
.choice.selected { border-color: var(--sel-line); background: var(--sel-bg); color: var(--text); font-weight: 600; }

/* ---- v27 (§31): 고르는 자리에 그 앱이 실제로 뽑는 그림을 건다.
   조판은 앱 열둘과 템플릿 칩이 함께 쓰고, 상품 POP 쓰임새 여덟도 나중에 같은 자리에 얹는다
   (PLAN-v27 §7 - 그쪽은 상품 사진이 있어야 해서 이번 판에서 뺐다).

   🔴 **파랑을 쓰지 않는다.** 고른 상태는 무채색(--sel-*)이다 - 이 격자에 카드가 열둘이라
   파랑을 칠하면 한 화면에 주 동작이 열둘이 되어 「만들기」 버튼이 안 보인다 (계약 §30.5 ②).
   🔴 **반경은 --radius-ctl 하나만 쓴다.** 8/10/12 를 섞으면 종류만 늘고 눈으로는 안 갈린다.
   🔴 **image-rendering 을 건드리지 않는다.** 800x480 을 200px 로 줄여 보여주는 자리라
   pixelated 를 걸면 가는 획이 통째로 버려져 한글이 뭉개진다 (v26 결함). */
.shot-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 560px) { .shot-grid { grid-template-columns: repeat(2, 1fr); } }
.shot-card {
  display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 6px;
  padding: 8px; text-align: left;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); color: var(--text-sub);
  cursor: pointer;
}
.shot-card:hover { background: var(--surface); }
.shot-card.selected { border-color: var(--sel-line); background: var(--sel-bg); color: var(--text); }
.shot-thumb {
  display: block; width: 100%; aspect-ratio: 5 / 3; object-fit: contain;
  background: var(--surface); border-radius: var(--radius-ctl);
}
.shot-name { font-size: 13px; font-weight: 600; color: var(--text); }
.shot-badges { display: flex; flex-wrap: wrap; gap: 4px; }

/* 템플릿 칩 - 이름이 「테두리형 명패」인데 그림이 한 장도 없던 자리 (PLAN-v27 §2) */
.shot-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.shot-chip {
  display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  width: 150px; padding: 8px; text-align: left;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); color: var(--text-sub);
  font-size: 12px; cursor: pointer;
}
.shot-chip:hover { background: var(--surface); }
.shot-chip.selected { border-color: var(--sel-line); background: var(--sel-bg); color: var(--text); font-weight: 600; }

.filepick {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 160px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-card);
  color: var(--text-hint); font-size: 13px;
  cursor: pointer; text-align: center; padding: 16px;
}
.filepick:hover { background: var(--surface); }
.filepick input { display: none; }
.filepick.has-photo { border-style: solid; padding: 0; min-height: 0; overflow: hidden; }
.filepick.has-photo img { width: 100%; max-height: 280px; object-fit: contain; background: var(--surface); }

/* 자료 탭 - 그림·영상 올리기 (`#panel-assets`).
   고르는 상자는 `.filepick` 을 그대로 물려받고 설명 두 줄만 얹는다. 같은 일을 하는
   상자를 새로 만들지 않는다 (§35.5 D7 - 길이 둘이 되면 다음 판이 어느 쪽을 고칠지
   모른다). §79 는 젠시라이트 부품을 닮게 하라는 다른 조항이라 여기 근거가 아니다. */
.assetpick { gap: 6px; }
.assetpick-main { font-size: 14px; font-weight: 600; color: var(--text); }
/* ⚠ `max-width` 를 34em 으로 뒀더니 1280px 화면에서 한국어가 세 줄로 접히며 「올라갑니다」
   한 낱말만 셋째 줄에 남았다. 그림을 눈으로 보고 잡은 자리다 - 검사는 넘침만 재므로
   전부 초록이었다. 일본어·영어는 34em 에서도 한 줄이라 안 걸렸다. */
.assetpick-sub { font-size: 12px; color: var(--text-hint); max-width: 48em; }
#asset-progress { margin-top: 14px; }
#asset-progress .g-row { gap: 12px; }
#asset-progress .g-cta { display: block; margin-left: auto; }
/* 여러 장을 놓았을 때 걸린 파일이 여럿이면 사유를 줄로 나눠 적는다. `pre-line` 이 없으면
   두세 줄이 한 줄로 붙어 **어디서 한 파일의 이야기가 끝나는지 안 갈린다.** */
#asset-error, #asset-note { margin: 12px 0 0; white-space: pre-line; }

/* 끌어다 놓는 자리 (frame-0033). 파일을 창 위로 끌고 올 때만 뜨는 덮개다.
   🔴 `pointer-events: none` 을 주면 **덮개 위에서 `drop` 이 안 잡힌다.** 받는 자리가
      보이는데 안 받는 것이 가장 나쁜 꼴이라, 덮개는 이벤트를 그대로 받는다.
   ⚠ `position: fixed` 다. 목록이 길어 스크롤이 내려가 있으면 `absolute` 덮개는 화면
     밖에 그려져 **아무것도 안 보인 채 받는 상태**가 된다. */
.asset-drop {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: rgba(17, 17, 17, .45);
}
.asset-drop.hidden { display: none; }
/* ⚠ **폰 폭에서 넘쳤다** (2026-09-19 실측 - 390px 화면에서 카드가 420px). 상한 안내 줄을
   넣으면서 늘어난 것인데, 넘치면 받는 자리가 화면 밖으로 밀려 **놓을 곳이 안 보인다.**
   좌우 여백을 폭에 따라 줄이고 카드 폭에 상한을 건다. */
.asset-drop-card {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  box-sizing: border-box;
  max-width: min(560px, calc(100vw - 32px));
  padding: 32px clamp(18px, 6vw, 56px); text-align: center;
  background: var(--bg); color: var(--text);
  border: 2px dashed var(--primary); border-radius: var(--radius-card);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .22);
}
.asset-drop-card strong { font-size: 18px; }
.asset-drop-mark {
  width: 44px; height: 44px; line-height: 44px; font-size: 22px;
  border-radius: 999px; background: var(--primary-light); color: var(--primary);
}

.asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 14px; }
.asset-card {
  border: 1px solid var(--divider); border-radius: var(--radius-card);
  padding: 10px; background: var(--bg); min-width: 0;
}
/* 방금 올라간 것을 한 번 짚어 준다. 목록이 스무 개를 넘으면 「올렸습니다」 한 문장으로는
   어느 것이 방금 올린 것인지 못 찾는다. */
.asset-card.is-new { border-color: var(--primary); }
.asset-thumb {
  display: block; width: 100%; height: 108px; object-fit: contain;
  background: var(--surface); border-radius: 10px;
}
.asset-film { display: flex; align-items: center; justify-content: center; }
.asset-play { font-size: 26px; color: var(--text-hint); line-height: 1; }
.asset-name { margin: 8px 0 2px; font-size: 13px; font-weight: 600; }
.asset-meta, .asset-when { margin: 0; }
.asset-when { margin-top: 2px; }
/* 🔴 줄바꿈 규칙은 **한국어에만** 준다. 공통 규칙으로 `keep-all` 을 주면 일본어가 접을
   자리를 잃어 좁은 폭에서 넘친다 - 이 저장소가 이미 여섯 자리에서 겪은 함정이다. */
html[lang=ko] .assetpick-sub,
html[lang=ko] #asset-error,
html[lang=ko] #asset-note,
html[lang=ko] #asset-todo { word-break: keep-all; overflow-wrap: anywhere; }

/* 재생목록 탭 (`#panel-playlists`, 계약 §82).
   왼쪽에 목록, 오른쪽에 고치는 자리다. 세로로만 쌓으면 스크롤이 길어져 담당자가 「순서」와
   「기기에 걸기」 사이를 오갈 때 길을 잃는다. 좁은 폭에서는 한 줄로 접는다. */
.pl-layout { display: grid; grid-template-columns: 260px 1fr; gap: 22px; align-items: start; }
.pl-side { min-width: 0; }
.pl-main { min-width: 0; }
.pl-h2 { margin: 0; font-size: 15px; font-weight: 700; }
.pl-h3 { margin: 0 0 10px; font-size: 14px; font-weight: 700; }

.pl-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  width: 100%; text-align: left; padding: 11px 12px; margin-bottom: 8px;
  border: 1px solid var(--divider); border-radius: var(--radius-card);
  background: var(--bg); cursor: pointer; min-width: 0;
}
.pl-card:hover { background: var(--surface); }
.pl-card.selected { border-color: var(--sel-line); background: var(--sel-bg); }
.pl-card-name { font-size: 14px; font-weight: 600; color: var(--text); }
.pl-card-sub { font-size: 12px; color: var(--text-hint); }

.pl-name-wrap { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.pl-name { width: 100%; max-width: 420px; }
.pl-url { flex: 1; min-width: 0; }

.pl-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-bottom: 6px;
  border: 1px solid var(--divider); border-radius: var(--radius-card); background: var(--bg);
}
/* 사라진 항목은 지우지 않고 회색으로 남긴다. 지우면 담당자가 무엇을 다시 넣어야 할지 모른다. */
.pl-item.missing { opacity: .62; border-style: dashed; }
.pl-item.pl-moving { border-color: var(--sel-line); background: var(--sel-bg); }
/* 🔴 `touch-action: none` 이 없으면 태블릿에서 손잡이를 끌 때 화면이 같이 스크롤되어
   순서가 안 바뀐다. 공간 카드 손잡이(§26)가 같은 이유로 이 한 줄을 갖고 있다. */
.pl-grip { touch-action: none; cursor: grab; padding: 4px 8px; line-height: 1; }
.pl-grip.moving { cursor: grabbing; }
.pl-ord { min-width: 18px; font-size: 12px; color: var(--text-hint); text-align: right; }
.pl-thumb {
  width: 76px; height: 46px; object-fit: contain; border-radius: 8px;
  background: var(--surface); flex: none;
}
.pl-thumb.none { display: flex; align-items: center; justify-content: center;
  color: var(--text-hint); font-size: 18px; }
.pl-item-mid { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.pl-item-title { font-size: 13px; font-weight: 600; color: var(--text); }
/* ⚠ 「초까지」가 두 줄로 접혀 「초까 / 지」가 됐다. 그림을 눈으로 보고 잡은 자리다 -
   검사는 가로 넘침만 재므로 전부 초록이었다. */
.pl-dur-wrap { display: flex; align-items: center; gap: 5px; flex: none; }
.pl-dur-wrap span { white-space: nowrap; }
.pl-dur { width: 68px; text-align: right; }
.pl-del { flex: none; }
/* 지우기·빼기는 **글자 단추**다. 전역 `button.danger` 는 빨간 채움이라, 줄마다 붙으면
   목록에서 가장 눈에 띄는 것이 「빼기」가 된다. 파괴적 동작이라 색만 물려받는다. */
.pl-danger { color: var(--danger); }
.pl-danger:hover { background: var(--badge-danger-bg); }

.pl-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px; margin-top: 12px; }
.pl-pick {
  display: flex; flex-direction: column; gap: 6px; padding: 8px; min-width: 0;
  border: 1px solid var(--divider); border-radius: var(--radius-card);
  background: var(--bg); cursor: pointer; text-align: left;
}
.pl-pick:hover { border-color: var(--sel-line); background: var(--sel-bg); }
.pl-pick-thumb { width: 100%; height: 74px; object-fit: contain;
  background: var(--surface); border-radius: 8px; }
.pl-pick-name { font-size: 12px; color: var(--text-sub); }

.pl-dev {
  display: flex; align-items: center; gap: 10px; padding: 9px 11px; margin-bottom: 6px;
  border: 1px solid var(--divider); border-radius: var(--radius-card);
  background: var(--bg); cursor: pointer; flex-wrap: wrap;
}
.pl-dev-mid { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.pl-dev-name { font-size: 13px; font-weight: 600; color: var(--text); }
#pl-error, #pl-deploy-note, #pl-budget { margin: 12px 0 0; }

/* 좁은 폭에서는 한 줄로 접는다. 목록이 위, 고치는 자리가 아래다 - 순서가 반대면
   폰에서 목록을 고르려고 매번 아래까지 스크롤해야 한다. */
@media (max-width: 860px) {
  .pl-layout { grid-template-columns: 1fr; gap: 14px; }
  .pl-item { flex-wrap: wrap; }
  .pl-item-mid { flex-basis: 100%; order: 5; }
}
html[lang=ko] #panel-playlists .hint,
html[lang=ko] .pl-card-sub,
html[lang=ko] #pl-deploy-note { word-break: keep-all; overflow-wrap: anywhere; }

.result-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.result-heading { align-items: flex-start; }
#result-status { white-space: normal; text-align: right; }
/* 🔴 **`keep-all` 을 한국어에만 준다.** 이 배지가 네 갈래로 갈리면서 문장이 길어졌고,
   360px 에서 한국어가 「보내지 않았습니 / 다」로 낱말 중간에 쪼개졌다(교정 전 증거는
   `docs/qa/round-ff6fdecb/verify-badge-wrap.json` 의 `badWords`).
   ⚠ 처음에 `#result-status` 전체에 줬더니 **일본어 배지가 360px 에서 두 줄에서 세 줄로
   늘었다**(높이 40 -> 57, `fix2-badge-wrap.json`). 일본어는 낱말 사이에 공백이 없어서
   `keep-all` 이 접을 자리를 다 막고, 그러면 `overflow-wrap: anywhere` 가 대신 아무 데서나
   접으면서 줄 배분이 나빠진다. **일본어는 글자 단위로 접히는 것이 원래 옳은 조판이다.**
   `i18n.js` 가 `document.documentElement.lang` 을 갱신하므로 이 셀렉터가 실제로 듣는다. */
html[lang=ko] #result-status { word-break: keep-all; overflow-wrap: anywhere; }
/* 같은 결함이 **안내 문구에도 그대로 있었다.** 이 판이 결과 화면에 폴백 사유(`#result-note`)를
   세우고 360px 을 눈으로 보다가 잡았다 - 「기본 방식으 / 로」, 바로 위 `create.resultHint` 도
   「이 그림은 기 / 기가」로 쪼개진다. 증거는 `docs/qa/result-note-4b1f8c2a/card-fallback-360.png`
   의 교정 전 판이다. 위 배지와 원인도 해법도 같으므로 같은 규칙을 안내 문구에 준다.
   ⚠ **한국어에만 준다** - 일본어는 낱말 사이에 공백이 없어 `keep-all` 이 접을 자리를 다 막고
   줄 배분이 나빠진다(위 주석의 실측). 영어는 애초에 공백에서 접히므로 줄 것이 없다. */
html[lang=ko] .hint { word-break: keep-all; overflow-wrap: anywhere; }
/* 🔴 **세 번째다.** 이 판이 기기 등록 칸을 360px 로 눈으로 보다가 또 잡았다 - 입력칸 이름표가
   「MAC 주 / 소」로 쪼개진다(`docs/qa/round-d6ca63d2/after-form-360.png` 의 교정 전 판).
   `.lbl` 안에 이름표와 보조 설명이 나란히 들어가는 구조라 좁은 폭에서 자리가 모자란다.
   1440 에서는 안 보이고 360 에서만 나온다. 위 둘과 원인도 해법도 같으므로 같은 규칙을 준다.
   ⚠ 한국어에만 준다 (일본어는 접을 자리를 다 막는다 - 위 주석의 실측). */
html[lang=ko] .field .lbl { word-break: keep-all; overflow-wrap: anywhere; }
/* §45 **네 번째다.** 이름표 옆 보조 설명을 늘렸더니 이번에는 이름표 자체가 눌렸다 -
   일본어 360px 에서 「MAC / アド / レス」 세 줄이 됐다(2줄 → 3줄 실측). 위 셋과 자리는
   같은데 **원인이 반대다** - 접을 자리가 모자란 것이 아니라 옆칸이 넓어져 이름표가 좁아졌다.
   그래서 해법도 다르다. 접기를 허용하는 대신 **이름표만 안 접히게** 한다.
   ⚠ 세 언어 다 준다. 이름표는 「MAC 주소」·「MACアドレス」·「MAC address」로 짧아
   nowrap 이 칸을 넘길 수 없다(360px 에서 넘침 0 실측). */
.field .lbl .lbl-name { white-space: nowrap; }
/* §61 **다섯 번째다.** 이 판이 `stale` 카드를 390px 로 눈으로 보다가 또 잡았다 -
   가격표 카드에 서는 안내 줄이 「가격표는 시간대·날씨로 안 바뀝니 / 다」로, 마지막 한 글자만
   홀로 다음 줄에 떨어진다(교정 전 증거는 `docs/qa/staleact-9d4b12f7/card-390-ko.png`).
   이 줄은 `.hint` 가 아니라 `.tiny.muted` 라서 위 `html[lang=ko] .hint` 규칙이 안 닿았다.
   원인과 해법은 앞의 넷과 같으므로 같은 규칙을 이 줄에만 준다.
   ⚠ **한국어에만 준다** - 일본어는 낱말 사이에 공백이 없어 `keep-all` 이 접을 자리를 다
   막고 줄 배분이 나빠진다(위 `#result-status` 주석의 실측). 영어는 공백에서 이미 접힌다.
   ⚠ 선택자를 `.tiny` 로 넓히지 않는다. 그 클래스는 로그 주소처럼 **낱말이 아닌 값**에도
   붙어 있어, 거기까지 `keep-all` 이 들면 접을 자리가 없어져 칸을 넘긴다. */
html[lang=ko] [data-when="off"] { word-break: keep-all; overflow-wrap: anywhere; }
/* §45 기기에 넣을 서버 주소.
   🔴 **눈으로 보다가 잡았다.** `<code>` 가 인라인이라 이름표 바로 뒤에 붙어
   「기기에 넣을 서버 주소 http://localhost:2300」 한 줄로 섰다(1440·360 둘 다).
   그러면 **무엇을 옮겨 적는 값인지가 안 드러난다** - 대표님이 기기 설정 화면에 손으로
   넣으실 바로 그 글자다. 줄을 갈라 크게 세우고, 한 번 눌러 통째로 집히게 한다.
   ⚠ `word-break: break-all` 은 여기 **주소에만** 준다. 주소는 낱말이 아니라서 어디서
   접혀도 뜻이 안 상하고, 360px 에서 칸을 넘지 않아야 한다. 같은 칸의 안내 문장은
   위 `html[lang=ko] .hint` 규칙이 이미 낱말 단위로 지킨다. */
#device-server-addr-value {
  display: block; margin: 6px 0 6px;
  font-size: 17px; font-weight: 600;
  word-break: break-all;
  user-select: all;
}
/* 값이 경고 갈래일 때도 색이 실제로 바뀌어야 한다 - `.hint` 가 `.warn-text` 를 이기던
   자리와 같은 종류라(위 238행 주석) 같은 특이도에서 지지 않게 id 로 못 박는다. */
#device-server-addr-value.warn-text { color: var(--warn-text); }
/* §48: 위 값은 「이 주소는 안 붙습니다」 쪽이라 주황이고, **아래 이 값이 실제로 넣을
   값**이다. 크기는 위와 같게 두되 색은 평상색으로 둔다 - 🔴 **주황이 둘이면 어느 것이
   경고인지 안 갈린다.** §47 이 반대 방향에서 같은 결함에 걸렸다(모달 전체가 주황인데
   가운데 한 줄만 검정이라 못 쓰는 값이 유일하게 쓸 수 있는 값처럼 읽혔다).
   ⚠ `word-break: break-all` 은 여기서도 **주소에만** 준다. 같은 칸의 안내 문장은
   `html[lang=ko] .hint` 가 이미 낱말 단위로 지키고, ja·en 은 기본값 normal 로 남는다. */
#device-server-lan { margin-top: 12px; }
#device-server-lan-value {
  display: block; margin: 6px 0 6px;
  font-size: 17px; font-weight: 600;
  word-break: break-all;
  user-select: all;
}
@media (max-width: 640px) {
  .result-heading { flex-direction: column; align-items: stretch; }
  #result-status { align-self: flex-start; text-align: left; }
}
.result-main img {
  width: 100%; aspect-ratio: 5 / 3; object-fit: contain;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--surface); image-rendering: pixelated;
}
.result-side { display: flex; gap: 10px; align-items: flex-start; }
.result-side img { width: 120px; aspect-ratio: 4 / 3; object-fit: contain; border: 1px solid var(--line); border-radius: var(--radius-ctl); }
@media (min-width: 600px) {
  .result-grid { grid-template-columns: 2fr 1fr; }
  .result-side { flex-direction: column; }
  .result-side img { width: 100%; }
}
.price-preview { font-size: 12px; color: var(--text-hint); margin-top: 4px; min-height: 1.5em; font-variant-numeric: tabular-nums; }
/* 할인이 걸려 있으면 이 줄은 「친 값을 다시 보여 주는 것」이 아니라 **벽에 걸릴 값을
   미리 말해 주는 것**이라 무게가 다르다. 흐린 회색 12px 로 두면 점주가 안 읽고 지나가고,
   그 줄을 읽지 않는 순간 이 개선은 없는 것과 같다. */
.price-preview.with-sale { font-size: 14px; font-weight: 700; color: var(--text); }
/* 🔴 390px 에서 「(15% 할인)」이 **「할」과 「인」 사이에서 끊겼다**(브라우저 실측
   `docs/qa/liquorpop-4e2a8c19/readout-ko-390.png`). 검사는 전부 초록이었다 - 글자는
   다 있었기 때문이다. 한국어는 낱말 사이에서 접혀야 읽힌다.
   ⚠ **한국어에만 준다.** 일본어 문장에는 공백이 없어 `keep-all` 이 접을 자리를 다 막고,
      그러면 `overflow-wrap` 이 대신 아무 데서나 끊는다(이 파일 583행이 같은 판정을
      이미 했다). */
html[lang=ko] .price-preview { word-break: keep-all; overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- 매장 · 기기 관리 */
.mgr-dev { display: grid; grid-template-columns: 108px 1fr; gap: 12px; }
.mgr-dev .dev-thumb { width: 108px; aspect-ratio: 5 / 3; }
/* 🔴 360px 에서 「안내 화 면」으로 낱말 중간이 쪼개졌다 (§44 회차가 그림을 보다가 찾았다).
   이 저장소가 같은 결함에 걸린 것이 **네 번째**다 - `.lib-new` · `#result-status` ·
   `.field .lbl` 에 이어서다. 해법도 그때와 같다.
   ⚠ **한국어에만 준다** - 일본어는 낱말 사이에 공백이 없어 `keep-all` 이 접을 자리를 다
   막고, 그러면 `overflow-wrap: anywhere` 가 대신 아무 데서나 끊어 더 나빠진다(§36.6 실측). */
html[lang=ko] .mgr-dev .dev-thumb.empty { word-break: keep-all; }
.mgr-dev .mac { font-family: ui-monospace, Consolas, monospace; font-size: 13px; color: var(--text-sub); }
.mgr-dev .stats { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 11px; color: var(--text-hint); margin-top: 4px; }
.mgr-dev .controls { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
/* MAC + 배지 줄이 좁은 화면에서 안 꺾여 가로 스크롤을 만들었다 (360px 실측 +68px, 2026-09-03 QA r6) */
.mgr-dev .row.between { flex-wrap: wrap; }
@media (max-width: 480px) { .mgr-dev .controls { grid-template-columns: 1fr; } }
/* v13b: 카드 안 목록은 흰 덩어리 하나로 두고 안쪽만 얇은 선으로 가른다 (§22.6).
   행마다 테두리를 두르면 흰 카드 안에 흰 카드가 겹쳐 층이 세 겹이 되고, 테두리만 걷으면
   행 경계가 통째로 사라진다 - 실제로 v13b 첫 그림에서 매장 목록과 앱 목록 열넷이
   경계 없이 붙어 한 덩어리 글자로 읽혔다.
   기기 목록은 각 행이 `.card` 라 자기 margin-bottom 으로 간격을 갖는다. 그래서 gap 이 없어도 된다. */
.list { display: flex; flex-direction: column; gap: 0; }
.list > .store-row + .store-row,
.list > .app-row + .app-row { border-top: 1px solid var(--divider); }

/* ---------------------------------------------------------------- 토스트 */
#toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--tabbar-h) + 156px + env(safe-area-inset-bottom));  /* v4: 커진 보내기 바 위로 */
  background: var(--text); color: var(--color-white);
  padding: 11px 18px; border-radius: 999px; font-size: 13px;
  max-width: calc(100% - 32px);
  display: flex; align-items: center; gap: 12px;
  opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 60;
  box-shadow: var(--shadow-lg);
}
body:not(.has-tabbar) #toast { bottom: 24px; }
@media (min-width: 768px) { #toast { bottom: 88px; } }
#toast.show { opacity: 1; pointer-events: auto; }
#toast.error { background: var(--danger); }
#toast button {
  background: none; border: 0; padding: 0; margin: 0; min-height: 0;
  color: var(--color-blue-500); font-size: 13px; font-weight: 600; cursor: pointer;
  white-space: nowrap;
  position: relative;
}
/* 「되돌리기」는 실측 21px - 알약 모양은 그대로 두고 터치 영역만 44px (2026-09-03 QA r6) */
#toast button::after { content: ''; position: absolute; left: -6px; right: -6px; top: -12px; bottom: -12px; }
#toast button:hover { background: none; text-decoration: underline; }
#toast.error button { color: var(--color-white); text-decoration: underline; }

/* ---------------------------------------------------------------- 로그인 */
.login { max-width: 360px; margin: 12vh auto 0; }
.login .brand { justify-content: center; margin-bottom: 20px; }
.login .brand .name { font-size: 22px; }
.login .brand .tag { font-size: 12px; }
.login .foot { text-align: center; font-size: 12px; color: var(--text-hint); margin-top: 16px; }

/* 480px 이하: 헤더의 Beta 태그를 숨겨 로고 잘림을 막는다 */
@media (max-width: 480px) {
  .topbar .brand .tag { display: none; }
}

/* ================================================================ v3 - 개통과 관리 (§12.6) */

/* 언어 토글 KO/JA. i18n.js 가 [data-lang-set] 클릭을 위임으로 받는다 */
.langtog {
  display: inline-flex; flex: none;
  border: 1px solid var(--line); border-radius: 999px;
}
.langtog button {
  border: 0; border-radius: 0; background: transparent;
  padding: 3px 10px; min-height: 0;
  font-size: 11px; font-weight: 600; color: var(--text-hint);
  position: relative;
}
/* 보이는 높이 24px 를 바꾸지 않고 터치 영역만 세로 44px 로 (2026-09-03 QA).
   가로는 옆 버튼과 겹치므로 늘리지 않는다. -10px 는 실측 43.6px 로 반걸음 모자랐다 (QA r6). */
.langtog button::after {
  content: ''; position: absolute; left: 0; right: 0; top: -11px; bottom: -11px;
}
.langtog button:first-child { border-radius: 999px 0 0 999px; }
.langtog button:last-child { border-radius: 0 999px 999px 0; }
.langtog button:hover { background: var(--surface); }
.langtog button.active { background: var(--sel-bg); color: var(--text); }
.langtog button.active:hover { background: var(--sel-bg); }
/* 360px 헤더에서 게이지 · 토글 · 로그아웃이 다 들어가게 (일본어는 더 길다).
   로고가 「젠시」로 잘리던 것(2026-09-03 QA): 게이지 88px · 로고 14px · 넘치면 말줄임. */
@media (max-width: 420px) {
  .langtog button { padding: 3px 7px; }
  .topbar .linkbtn { padding: 6px 4px; }
  .topbar .wrap { gap: 8px; }
  .gauge { width: 88px; }
  .brand .name { font-size: 14px; overflow: hidden; text-overflow: ellipsis; }
}

/* 모달 (DESIGN 「모달」 - 오버레이 .5, 패널 --surface, radius 16, shadow-2xl) */
.modal-overlay {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(0, 0, 0, .5);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.modal {
  width: 100%; max-width: 420px;
  background: var(--bg);
  border-radius: var(--radius-card);
  padding: 24px;
  box-shadow: var(--shadow-xl);
  max-height: 85vh; overflow-y: auto;
}
/* Expand within the card row, leaving the board accessible. */
.create-dialog { grid-column: 1 / -1; min-width: 0; width: 100%; padding: 0 20px 20px; margin: 4px 0 20px; border: 1px solid var(--divider); border-radius: var(--radius-card); background: var(--bg); color: var(--text); scroll-margin-top: 270px; }
.create-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--divider); margin-bottom: 16px; }
.create-dialog-head h2 { margin: 0; }
.create-dialog #panel-create { display: block; }
.create-dialog #edit-banner { padding: 12px 0; margin-bottom: 12px; }
.create-dialog #panel-create > .card { box-shadow: none; }
.editor-source { outline: 2px solid var(--accent, var(--color-green-900)); outline-offset: 3px; }
.editing-content .board { display: block; }
.editing-content .library { position: static; max-height: none; overflow: visible; margin-bottom: 24px; }
.editing-content .lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); overflow: visible; gap: 12px; }
.lib-send { width: 100%; margin-top: 6px; font-size: 11px; }
.lib-edit { width: 100%; margin-top: 10px; font-size: 12px; }
.lib-reuse { width: 100%; margin-top: 6px; white-space: normal; font-size: 12px; min-height: 36px; }
#reuse-banner { border-color: var(--sel-line); background: var(--color-gray-150); }
.result-grid.result-no-photo { grid-template-columns: 1fr; }
.result-no-photo .result-main { max-width: 680px; width: 100%; margin-inline: auto; }
@media (max-width: 600px) { .create-dialog { padding: 0 12px 12px; scroll-margin-top: 230px; } .editing-content .lib-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* 디자인 편집기 덮개 (계약 §71.1). 🔴 **여백을 거의 안 준다** - 편집기는 가로 1024px
   미만에서 캔버스가 사실상 사라지므로(`MIN_EDITOR_WIDTH`), 여백으로 깎은 폭이 그대로
   「이 창에서는 못 엽니다」로 바뀐다. 1280px 창에서 양쪽 16px 짜리 기본 여백을 그대로
   두면 iframe 이 1248px 이 되어 아직 되지만, 1040px 창에서는 1008px 이 되어 넘어간다. */
.editor-overlay { padding: 0; background: rgba(0, 0, 0, .62); }
.editor-shell {
  width: 100vw; height: 100vh;
  background: var(--bg);
  overflow: hidden;
}
.editor-shell iframe { display: block; width: 100%; height: 100%; border: 0; }
@media (min-width: 1240px) {
  /* 넓은 화면에서는 덮개처럼 보이게 조금 띄운다. 그래도 1024px 은 반드시 남긴다. */
  .editor-overlay { padding: 12px; }
  .editor-shell {
    width: 100%; height: 100%;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-xl);
  }
}

.modal h2 { margin-bottom: 4px; }
.modal .m-desc { font-size: 13px; color: var(--text-sub); margin-bottom: 16px; }
/* v13b: 「언제 무엇을」이 시간대 넷 + 날씨 셋으로 길어지면서 저장 버튼이 스크롤 밖으로 나갔다.
   시트가 길어도 저장과 취소는 늘 보이게 바닥에 붙인다. 음수 여백은 모달 padding(24px)을
   되돌려 줄이 전폭으로 서게 하는 것이다. */
.modal .m-actions {
  position: sticky; bottom: -24px; z-index: 1;
  display: flex; justify-content: flex-end; gap: 8px;
  margin: 16px -24px -24px; padding: 12px 24px;
  background: var(--bg);
  border-top: 1px solid var(--divider);
}

/* 개통 코드 입력 - 크고 또렷하게 */
input.code-input {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 22px !important;
  font-weight: 600;
  letter-spacing: .35em;
  text-align: center;
  text-transform: uppercase;
}

/* 요약 스트립 (매장 화면: 기기 N · 온라인 M · 배터리 주의 K) */
.sumstrip { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
.sumstrip .sum {
  border: 0; border-radius: var(--radius-card);
  background: var(--bg);
  padding: 12px 6px; text-align: center; min-width: 0;
}
.sumstrip .sum-n { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.3; }
.sumstrip .sum-l { font-size: 11px; color: var(--text-hint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sumstrip .sum.ok .sum-n { color: var(--text); }
.sumstrip .sum.alert .sum-n { color: var(--danger); }

/* 오프라인 카드의 「해결 안내」 접이식 */
.fixguide {
  margin-top: 8px;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--surface);
  font-size: 12px;
}
.fixguide summary {
  cursor: pointer; padding: 7px 10px;
  color: var(--warn-text); font-weight: 600;
  list-style: none;
  display: flex; align-items: center; gap: 6px;
  min-height: 44px;   /* 다른 접이식 summary 와 같은 터치 타깃 (2026-09-03 QA r6) */
}
.fixguide summary::-webkit-details-marker { display: none; }
.fixguide summary::after { content: '▾'; margin-left: auto; color: var(--text-hint); transition: transform .15s; }
.fixguide[open] summary::after { transform: rotate(180deg); }
.fixguide ol { margin: 0; padding: 0 12px 10px 26px; color: var(--text-sub); }
.fixguide li { margin: 4px 0; }

/* 기기 카드의 이름표 인라인 수정 (매장 화면) */
.dev-name-row { display: flex; align-items: center; gap: 2px; margin-top: 8px; min-height: 28px; }
.dev-name-row .dev-name { margin-top: 0; flex: 1; min-width: 0; }
.name-edit {
  border: 0; background: none; flex: none;
  padding: 2px 6px; min-height: 0;
  color: var(--text-hint); font-size: 12px; cursor: pointer;
  border-radius: 6px;
  position: relative;
}
/* 보이는 크기는 이름 줄에 맞추고 터치 영역만 44px 로 (2026-09-03 QA r6) */
.name-edit::before { content: ''; position: absolute; inset: -11px; }
.name-edit:hover { background: var(--surface); color: var(--text); }
.dev-name-row input { padding: 4px 8px; font-size: 13px !important; }
.dev-meta { font-size: 11px; color: var(--text-hint); margin-top: 4px; }
/* §65: 중계가 안 켜진 카드에 「어디서 어떻게 켜나」를 한 줄로 세운다.
   전에는 이 문장이 배지의 `title` 에만 있었고, `title` 은 터치 화면에 안 뜬다 -
   곧 휴대폰으로 보는 점주에게는 처방이 0건이었다(계약 §64.5-4).
   🔴 줄바꿈 규칙은 §64.6 이 배지에서 쓴 것을 그대로 쓴다. 390px 에서 기기 격자가
   2열이라 카드 한 칸이 165px 인데 이 문장은 그보다 길다. `keep-all` 하나로는
   일본어가 안 접히고, 그것 없이는 한국어가 낱말 중간에서 쪼개진다. */
.dev-hint {
  font-size: 11px; line-height: 1.5; margin-top: 4px;
  color: var(--badge-warn-text); background: var(--badge-warn-bg);
  border-radius: 6px; padding: 5px 7px;
  white-space: normal; word-break: keep-all; overflow-wrap: anywhere; max-width: 100%;
}

/* 기기 로그 모달 본문 */
.loglines {
  background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  padding: 10px; margin: 0;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 11px; line-height: 1.5;
  max-height: 50vh; overflow: auto;
  white-space: pre-wrap; word-break: break-all;
}
/* §46 - 로그가 이제 기계 낱말이 아니라 우리말 문장을 담는다. `break-all` 은 긴 파일 이름을
   접으려고 붙은 것인데, 그 규칙이 한국어에서는 낱말 가운데를 쪼갠다(이 저장소에서 네 번째다 -
   `ff6fdecb` 배지 · `4b1f8c2a` 안내 문구 · `d6ca63d2` 입력칸 이름표).
   🔴 **일본어에는 주지 않는다** - `keep-all` 이 일본어에서는 접을 자리를 통째로 막아
   같은 칸의 높이를 40px 에서 57px 로 늘린 전례가 있다. 그래서 `html[lang=ko]` 로만 좁힌다.
   `overflow-wrap: anywhere` 를 같이 주어 접을 자리가 없는 긴 토큰은 여전히 접힌다.

   🔴 **그런데 이 모달 안에는 축이 둘이다.** 위 규칙이 맡는 것은 **번역되는 글**
   (`.logboot` · `.logwhen` · `.logempty`)이고, 기기가 보낸 문장(`.logmsg`)은
   **UI 언어와 상관없이 늘 한국어**다 - `gflog(...)` 의 서식 문자열이 펌웨어에 한국어로
   박혀 있고 서버도 웹도 그것을 번역하지 않는다. 그래서 UI 언어로만 가르면 일본어·영어로
   보시는 분께는 규칙이 안 걸린다. 기술 리뷰가 실화면에서 쟀다 - 360px 일본어·영어에서
   한국어 낱말이 **3건**(「유지」 「폴링」 「이전」) 쪼개졌다.
   ⚠ 그렇다고 스코프를 통째로 떼면 안 된다. 그러면 번역된 안내문에까지 `keep-all` 이
   걸려 일본어 빈 상태가 3줄에서 4줄로 늘어난다(같은 실측). **내용에 맞춰 건다.** */
html[lang=ko] .loglines { word-break: keep-all; overflow-wrap: anywhere; }
.logmsg { word-break: keep-all; overflow-wrap: anywhere; }

/* 로그 한 묶음 = 부팅 한 번. 머리 줄이 언제·왜 켜졌는지를 말한다. */
.logboot { margin: 8px 0 2px; font-weight: 600; }
.logboot:first-of-type { margin-top: 2px; }
.logrow { display: flex; gap: 8px; align-items: baseline; }
/* 경과 시각 칸은 폭을 고정한다 - 안 그러면 줄마다 본문 시작점이 달라져 훑어 내려가기 어렵다. */
.logup { flex: 0 0 auto; min-width: 52px; text-align: right; color: var(--text-hint); }
.logmsg { flex: 1 1 auto; min-width: 0; }
/* 빈 목록은 한 마디가 아니라 「무엇을 하시면 되는지」까지 말한다 - 여러 줄이라 본문 글꼴로. */
.logempty, .logwhen {
  font-family: Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-size: 12px; line-height: 1.55;
}
.logwhen { color: var(--text-hint); margin-bottom: 6px; }

/* §47 - 「한 번도 닿지 않았습니다」 바로 밑에 서는 서버 주소. 대표님이 기기 포털의
   「서버 주소」 칸과 **한 글자씩 대조하실 값**이다.

   🔴 등록 카드의 `#device-server-addr-value` 규칙(17px/600)을 그대로 가져오지 않는다.
   기술 담당이 360px 에서 쟀다 - 이 모달 본문의 실제 폭이
   `360 - 32(overlay) - 48(modal) - 2(border) - 20(loglines) = 258px` 인데
   `http://192.168.45.36:2300` 25자를 17px 로 그리면 약 255px 라 **여유가 3px 뿐**이다.
   도메인이나 다른 포트가 붙는 순간 접히고, **주소가 줄 가운데서 쪼개지면 한 글자씩
   대조를 못 하신다.** 13px 이면 약 195px 로 63px 이 남는다.

   🔴 **줄바꿈 규칙은 여기서 갈라야 한다. §46.5 의 축이 한 칸 모자랐다.** §46 은
   「한국어에만 `keep-all`」로 갈랐는데, 남은 `break-all` 이 **영어 산문을 그대로 쪼갠다** -
   영어는 낱말 경계가 띄어쓰기라 `break-all` 이면 아무 글자에서나 잘린다. 이 회차가
   브라우저로 쟀다: 360px 영어에서 **다섯 낱말**(`Check` · `wo/rks` · `Ope/n` · `sho/wn` ·
   `the`), **1440px 에서도 셋**(`se/tup` · `ab/ove` · `ad/dress`)이다. 폭 문제가 아니다.

   🔴 **`keep-all` 로 고치면 안 된다.** §36 · §46.5 가 실측으로 막아 둔 자리다 - 일본어에
   `keep-all` 을 주면 접을 자리가 통째로 막혀 빈 상태의 줄 수가 늘어난다. 영어에 필요한
   것은 `keep-all` 이 아니라 **`normal`**(기본 줄바꿈)이고, 일본어에서도 `normal` 이 옳다.
   `overflow-wrap: anywhere` 를 같이 주어 접을 자리가 없는 긴 토큰은 여전히 접힌다.

   ⚠ **주소만은 반대다.** 주소는 낱말이 아니라서 어디서 접혀도 뜻이 안 상하고, 안 접으면
   360px 에서 칸을 넘는다. 그래서 산문과 주소를 갈라서 준다. */
.logempty, .logwhen, .logaddr { word-break: normal; overflow-wrap: anywhere; }
html[lang=ko] .logempty,
html[lang=ko] .logwhen,
html[lang=ko] .logaddr { word-break: keep-all; }
.logaddr {
  font-family: Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-size: 12px; line-height: 1.55;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
}
.logaddr-label { color: var(--text-hint); }
/* `user-select: all` 은 §45 가 등록 카드에 준 것과 같다 - 한 번 누르면 통째로 집힌다.
   대표님이 기기 포털 칸에 옮기실 값이라 부분 선택이 오히려 사고를 만든다.
   `.warn-text` 는 `.hint` 가 같은 특이도에서 이기던 자리와 같은 종류라(§45 가 id 로 못
   박은 그 자리) 클래스를 두 번 겹쳐 이기게 한다. */
.logaddr-value {
  display: block; margin-top: 4px; font-size: 13px; font-weight: 600;
  word-break: break-all;
  user-select: all;
}
.logaddr-value.warn-text { color: var(--warn-text); }

/* §49: 위 값은 「이 주소는 안 붙습니다」 쪽이라 주황이고, **이 값이 실제로 넣을 값**이다.
   🔴 **경고색을 주지 않는다** - 주황이 둘이면 어느 것이 경고인지 안 갈린다(§48.5). 크기는
   위와 같게 두어, 옮겨 적을 값이라는 것이 같은 무게로 읽히게 한다.
   `user-select: all` 도 위와 같다 - 한 번 누르면 통째로 집힌다. 대표님이 기기 포털 칸에
   손으로 옮기실 값이라 부분 선택이 오히려 사고를 만든다. */
.loglan-label { display: block; margin-top: 8px; }
.loglan-value {
  display: block; margin-top: 4px; font-size: 13px; font-weight: 600;
  word-break: break-all;
  user-select: all;
}
/* ⚠ 산문 둘은 **번역된 문장**이라 주소와 같은 규칙을 받으면 안 된다. 가를 축은 언어가
   아니라 「그 칸에 어느 말이 들어오는가」다(§46.7) - 주소는 낱말이 아니라서 어디서 접혀도
   뜻이 안 상하지만, 이 둘은 낱말 중간에서 쪼개지면 읽히지 않는다. 위 `.logempty` 계열이
   세운 규칙과 같은 것을 준다. */
.loglan-how, .logredo { word-break: normal; overflow-wrap: anywhere; }
html[lang=ko] .loglan-how,
html[lang=ko] .logredo { word-break: keep-all; }
.logredo { margin-top: 8px; }

/* 기기 카드 동작 버튼 줄 (개통 카드 · 로그 · 시간대 교대) */
.devact { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }

/* ================================================================ v4 - 측정과 시간 (§13.6) */

/* 보내기 바의 기간 선택 줄 - 좁은 화면에서는 가로 스크롤 */
.sb-period {
  display: flex; align-items: center; gap: 6px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.sb-period::-webkit-scrollbar { height: 3px; }
.sb-period .sb-plabel { font-size: 11px; color: var(--text-hint); flex: none; }
/* 칩은 한 손 조작 대상이라 44px 를 지킨다 (대표 지시 2026-09-03) */
.chip {
  flex: none; min-height: 44px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); color: var(--text-sub);
  padding: 0 14px; font-size: 12px; font-weight: 500;
}
.chip:hover { background: var(--surface); }
.chip.selected { border-color: var(--sel-line); background: var(--sel-bg); color: var(--text); font-weight: 600; }
/* input.sb-date - 요소 선택자를 붙여야 위쪽 input[type=date] 규칙(특이도 0,1,1)을 이긴다.
   클래스만으로는 (0,1,0) 이라 파일 뒤쪽에 있어도 지고, width:100% 를 물려받아 보내기 바의
   기간 칩이 가로 스크롤 밖으로 밀렸다 (QA v11 결함 6). */
input.sb-date {
  flex: none; width: auto; min-height: 44px;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); color: var(--text);
  font: inherit; font-size: 14px; padding: 0 10px;
}
.sb-date:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 1px rgba(10, 143, 245, .25); }
@media (max-width: 767px) { .sb-date { font-size: 16px; } }  /* iOS 자동 확대 방지 */
/* 고른 기간이 무슨 뜻인지 말해 주는 한 문장 */
.sb-expl { font-size: 12px; color: var(--text-sub); }

/* 라이브러리 썸네일 오버레이 (QR 배지 · 스캔 배지 · POP 메뉴) */
.lib-thumbwrap { position: relative; }
.lib-menu {
  position: absolute; top: 4px; right: 4px; z-index: 2;
  width: 28px; height: 28px; min-height: 0; padding: 0;
  border-radius: 999px; border: 1px solid var(--line);
  background: rgba(255, 255, 255, .92); color: var(--text-sub);
  font-size: 15px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.lib-menu::before { content: ''; position: absolute; inset: -8px; }   /* 실제 터치 영역 44px */
.lib-menu:hover { background: var(--bg); color: var(--text); }
.qr-badge {
  position: absolute; top: 4px; left: 4px; z-index: 2;
  font-size: 9px; font-weight: 700; letter-spacing: .04em;
  padding: 1px 5px; border-radius: 999px;
  background: rgba(255, 255, 255, .92); border: 1px solid var(--line); color: var(--text-sub);
}
/* 편집기에서 저장한 화면임을 카드에서 바로 알린다 (§51.10). 이 카드만 누르면 다른 화면
   (편집기)으로 넘어가므로, 표시가 없으면 점주는 같은 목록에서 왜 하나만 다르게 움직이는지
   모른다. 🔴 자리는 `.qr-badge`(좌상) · `.scan-badge`(우하) · `.lib-menu`(우상) 셋을 피해
   좌하로 잡았다. */
.editor-badge {
  position: absolute; bottom: 4px; left: 4px; z-index: 2;
  font-size: 9px; font-weight: 700; letter-spacing: .04em;
  padding: 1px 5px; border-radius: 999px;
  background: rgba(255, 255, 255, .92); border: 1px solid var(--line); color: var(--text-sub);
}
.scan-badge {
  position: absolute; bottom: 4px; right: 4px; z-index: 2;
  font-size: 9px; font-weight: 600;
  padding: 1px 6px; border-radius: 999px;
  background: var(--sel-bg); color: var(--text-sub);
}

/* 접이식 카드 - 선택 기능은 기본 동선을 막지 않게 접어 둔다 (완성 화면의 QR 페이지) */
details.card.fold { padding: 0; overflow: hidden; }
details.card.fold summary {
  cursor: pointer; list-style: none;
  min-height: 44px; padding: 12px 16px;
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 500; color: var(--text-sub);
  -webkit-user-select: none; user-select: none;
}
@media (min-width: 768px) { details.card.fold summary { padding: 12px 24px; } }
details.card.fold summary::-webkit-details-marker { display: none; }
details.card.fold summary::after { content: '▾'; margin-left: auto; color: var(--text-hint); transition: transform .15s; }
details.card.fold[open] summary::after { transform: rotate(180deg); }
details.card.fold summary:hover { background: var(--surface); }
details.card.fold .fold-body { padding: 0 16px 16px; }
@media (min-width: 768px) { details.card.fold .fold-body { padding: 0 24px 20px; } }

/* 기간 토글 (통계 7일/30일) - langtog 와 같은 문법의 범용판 */
.segtog {
  display: inline-flex; flex: none;
  border: 1px solid var(--line); border-radius: 999px;
  overflow: hidden;
}
.segtog button {
  border: 0; border-radius: 0; background: transparent;
  padding: 0 16px; min-height: 44px;
  font-size: 12px; font-weight: 600; color: var(--text-hint);
}
.segtog button:hover { background: var(--surface); }
.segtog button.active { background: var(--sel-bg); color: var(--text); }
.segtog button.active:hover { background: var(--sel-bg); }

/* 통계 탭 */
.stat-row { padding: 12px 16px; margin-bottom: 12px; }
@media (min-width: 768px) { .card.stat-row { padding: 12px 16px; } }
.stat-head { display: flex; align-items: center; gap: 12px; cursor: pointer; -webkit-user-select: none; user-select: none; }
.stat-thumb {
  width: 64px; aspect-ratio: 5 / 3; object-fit: contain; flex: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  /* v26: 축소 표시에서는 auto. `pixelated` 는 최근접 이웃이라 800×480 을
     100~200px 로 줄일 때 **가는 획을 통째로 버린다** - 메뉴판 미리보기의 한글이
     뭉개져 안 읽히던 원인이다. 원본 폭에 가깝게 키워 보여주는 자리에서만 픽셀을 살린다. */
  image-rendering: auto;
}
div.stat-thumb.empty { padding: 0; border-style: dashed; }
.stat-name { font-size: 14px; font-weight: 500; }
.stat-count { font-size: 15px; font-weight: 700; flex: none; }
.stat-caret { color: var(--text-hint); font-size: 12px; flex: none; transition: transform .15s; }
.stat-row.open .stat-caret { transform: rotate(180deg); }
.stat-detail { margin-top: 12px; border-top: 1px solid var(--divider); padding-top: 4px; }
.stat-sec { font-size: 11px; color: var(--text-hint); margin: 8px 0 6px; }
.stat-bars { display: flex; align-items: flex-end; gap: 2px; height: 48px; }
.stat-barcol { flex: 1; height: 100%; display: flex; align-items: flex-end; min-width: 0; }
.stat-bar { width: 100%; background: var(--meter); border-radius: 2px 2px 0 0; }
.stat-axis { display: flex; justify-content: space-between; margin-top: 2px; }
.stat-store { display: flex; align-items: center; gap: 8px; margin: 4px 0; font-size: 12px; color: var(--text-sub); }
.stat-store-name { flex: none; width: 96px; }
.stat-store-bar { flex: 1; height: 4px; border-radius: 999px; background: var(--surface); overflow: hidden; }
.stat-store-fill { height: 100%; background: var(--meter); border-radius: 999px; }

/* ================================================================ v5 - 소리와 상황 (§14.6·14.7) */

/* 첫 사용 체크리스트 (보드 상단 카드 - 셋 다 완료면 렌더 안 됨) */
.onboard h2 { margin-bottom: 4px; }
.onboard .ob-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
.onboard .ob-row + .ob-row { border-top: 1px solid var(--divider); }
.ob-check {
  width: 28px; height: 28px; border-radius: 999px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line);
  color: var(--text-hint); font-size: 13px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ob-row.done .ob-check { background: var(--primary); border-color: var(--primary); color: var(--color-white); }
.ob-row.done .ob-name { color: var(--text-hint); }
.ob-name { font-size: 14px; font-weight: 500; }
.ob-row button { flex: none; }

/* v16 §27.3: 「어디에 거시나요」 - 한 번만 묻는다.
   회색 페이지 위 순백 카드, 파랑은 고른 자리에만 (v13b 의 화이트톤 규약). */
.ob-choices { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 12px 0 10px; }
@media (max-width: 640px) { .ob-choices { grid-template-columns: 1fr; } }
.ob-choice {
  display: block; width: 100%; text-align: left;
  padding: 14px; border: 1px solid var(--divider); border-radius: 12px;
  background: var(--color-white); cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.ob-choice:hover { border-color: var(--primary); background: var(--primary-weak, var(--color-gray-150)); }
.ob-choice:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.ob-choice-name { font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.ob-ask .hint { margin-bottom: 0; }
.ob-ask > button.ghost { margin-top: 2px; }

/* 모달 안 접이식 (POP 메뉴의 소리 문안) - 카드 접이식과 같은 문법, 테두리만 컨트롤급 */
details.fold-inline {
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); margin: 12px 0;
}
/* §44: 기기 카드의 「연결 정보 · 시간 설정」 접기가 **한 규칙도 안 걸려 있었다.**
   그 요소는 `details.device-details.fold` 인데, 이 파일의 접기 문법은 `details.card.fold`
   와 `details.fold-inline` 두 선택자로만 걸려 있어서 **`card` 도 `fold-inline` 도 아닌
   그 하나만 브라우저 기본값으로 남았다.** 실측: `cursor: auto` · `padding: 0px` ·
   `::after` 가 `none` · 마커가 `disclosure-closed`. 즉 **여는 손잡이가 손잡이로 안 보인다.**
   안에 MAC·배터리·전파세기·펌웨어·로그 단추가 들어 있는데 대표가 그것을 여는 방법을 모른다.
   🔑 **새 디자인을 만들지 않는다.** 값 하나 안 바꾸고 선택자만 더한다.
   ⚠ 바깥 테두리(`details.fold-inline` 규칙)는 **일부러 안 준다** - 그것은 모달 안에서
   컨트롤처럼 서라고 만든 것이고, 카드 안에 주면 카드 안에 카드가 생긴다. */
details.fold-inline summary,
details.device-details.fold summary {
  cursor: pointer; list-style: none;
  min-height: 44px; padding: 10px 12px;
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 500; color: var(--text-sub);
  -webkit-user-select: none; user-select: none;
}
details.fold-inline summary::-webkit-details-marker,
details.device-details.fold summary::-webkit-details-marker { display: none; }
details.fold-inline summary::after,
details.device-details.fold summary::after { content: '▾'; margin-left: auto; color: var(--text-hint); transition: transform .15s; }
details.fold-inline[open] summary::after,
details.device-details.fold[open] summary::after { transform: rotate(180deg); }
details.fold-inline summary:hover,
details.device-details.fold summary:hover { background: var(--surface); }
/* 카드 안이라 좌우 여백은 카드가 이미 준다. 위아래 손가락 자리만 남긴다. */
details.device-details.fold summary { padding-left: 0; padding-right: 0; }
details.fold-inline .fold-body { padding: 0 12px 12px; }

/* 소리 설정 시트 - 반복 간격 칩 줄 (.chip 은 v4 의 44px 칩 재사용) */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }

/* 음량 슬라이더 - 트랙은 가운데 그려지고 세로 44px 전체가 터치 영역 (2026-09-03 QA r6) */
input[type=range] {
  width: 100%; height: 44px; padding: 0; margin: 0;
  accent-color: var(--primary);
  touch-action: manipulation;
}

/* 매장 목록 행 (이름 + 지역 선택). v13b: 회색 페이지 위 흰 덩어리 - 테두리 대신 층으로 */
.store-row {
  display: flex; align-items: center; gap: 12px;
  border: 0; border-radius: var(--radius-ctl);
  background: var(--bg);
  padding: 12px;
}
.store-row select { width: auto; max-width: 190px; flex: none; }

/* 편성표의 줄 (frame-0035). 🔴 클래스만 붙이고 규칙을 안 쓰면 화면에는 글자가 뜨는데
   레이아웃이 통째로 없어서, 단추가 줄 아래로 흘러 폭이 0 이 되는 자리가 생긴다.
   매장 화면 스타일과 같은 문법을 그대로 쓴다 - 새 모양을 만들 이유가 없다. */
.sched-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 0; border-radius: var(--radius-ctl);
  background: var(--bg);
  padding: 12px;
}
.list > .sched-row + .sched-row { border-top: 1px solid var(--divider); }

/* ================================================================ v5 QA r6 - 모바일 터치 타깃 44px (2026-09-03)
   360px 전수 실측: 기본 버튼 38.8 · button.sm 33.2 · select 43 이 전부 44 미만이었다.
   자기 min-height 를 가진 것(.linkbtn · .langtog button · .lib-menu · .name-edit · #toast button)은
   클래스 특이도가 이겨서 그대로 두고, 각자 가짜요소로 터치 영역을 늘린다. */
@media (max-width: 767px) {
  button, .btn { min-height: 44px; }
  input[type=text], input[type=email], input[type=password], input[type=number],
  input[type=tel], input[type=time], input[type=date], select, textarea { min-height: 44px; }
}

/* ================================================================ v6 - 넘버링과 식별 (§15.4) */

/* 매장 안 번호 배지 - 카드 좌상단에 크게 (윈도우 모니터 번호 문법).
   ①②③ 글리프 대신 CSS 원 - 20을 넘어도 그려진다 */
.no-badge {
  position: absolute; top: 8px; left: 8px; z-index: 2;
  min-width: 30px; height: 30px; padding: 0 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .94);
  border: 1.5px solid var(--sel-line);
  color: var(--text); font-size: 16px; font-weight: 600; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.mgr-thumbwrap { position: relative; }
.mgr-thumbwrap .no-badge { top: 4px; left: 4px; min-width: 26px; height: 26px; font-size: 14px; padding: 0 6px; }

/* 매장 헤더가 「번호 표시」 버튼을 얻어 360px 에서 꺾일 수 있게 */
.store-head { flex-wrap: wrap; }

/* 기기 ⋯ 메뉴 (매장 · 기기 탭). 보이는 크기 30px, 터치 영역은 가짜요소로 44px (QA r6 문법) */
.devmenu-wrap { position: relative; display: inline-flex; }
.dev-menu {
  width: 30px; height: 30px; min-height: 0; padding: 0;
  border-radius: 999px; font-size: 15px; line-height: 1;
  position: relative;
}
.dev-menu::after { content: ''; position: absolute; inset: -7px; }
.devmenu {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 30;
  min-width: 168px; padding: 4px;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius-ctl); box-shadow: var(--shadow-lg);
}
.devmenu button {
  display: flex; width: 100%; justify-content: flex-start;
  border: 0; background: none; border-radius: 6px;
  padding: 10px 12px; min-height: 44px; font-size: 13px; color: var(--text);
  white-space: nowrap;
}
.devmenu button:hover { background: var(--surface); }

/* 식별 중 - 예상 시각 안내 한 줄 + 해제 버튼 */
.idf-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.idf-row .grow { min-width: 0; }

/* ================================================================ v7 - 보관과 정리 (§16.4) */

/* 모달 액션 줄 - POP 메뉴가 버튼 넷이 될 수 있어 360px 에서 꺾이게 */
.modal .m-actions { flex-wrap: wrap; }

/* POP 메뉴의 「보관」 행 - 저장/취소와 다른 결의 동작이라 경계선으로 가른다 */
.arch-action {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--divider);
}
.arch-action .tiny { min-width: 0; }

/* 공용 확인 시트 - 무엇이 바뀌는지 목록 (dry run 결과를 사람 말로) */
.confirm-lines {
  list-style: none; margin: 0 0 12px; padding: 0;
  font-size: 13px; color: var(--text);
}
.confirm-lines li { position: relative; padding: 7px 0 7px 16px; }
.confirm-lines li::before { content: '·'; position: absolute; left: 2px; color: var(--text-hint); font-weight: 700; }
.confirm-lines li + li { border-top: 1px solid var(--divider); }

/* 매장 목록 행이 「매장 보관」 버튼을 얻어 360px 에서 꺾일 수 있게 (store-head 와 같은 문법) */
.store-row { flex-wrap: wrap; }
/* 🔴 v13b 그림 QA - 390px 에서 매장 이름이 세로로 한 글자씩 쪼개져 있었다.
   이름 칸이 `flex: 1`(= basis 0) 이라 버튼 셋(번호 표시 · 지역 고르기 · 매장 보관)이 자리를
   먼저 가져가면 0 까지 눌리고, wrap 은 이미 자리를 잡은 그 칸을 다음 줄로 내려 주지 않는다.
   기기가 있는 매장에서만 「번호 표시」가 붙어서, 목록 첫 행만 깨지고 둘째 행은 멀쩡했다.
   v13b 가 만든 것은 아니다 - 테두리를 걷어 좌우 여유는 2px 늘었고, 선이 사라지며 드러났을 뿐이다. */
@media (max-width: 480px) {
  .store-row > .grow { flex-basis: 100%; }
}

/* 보관함 (매장기기 탭 하단 접이식) */
.arch-sec { font-size: 11px; color: var(--text-hint); margin: 12px 0 2px; }
.arch-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; }
.arch-row + .arch-row { border-top: 1px solid var(--divider); }
.arch-thumb {
  width: 56px; aspect-ratio: 5 / 3; object-fit: contain; flex: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  /* v26: 축소 표시에서는 auto. `pixelated` 는 최근접 이웃이라 800×480 을
     100~200px 로 줄일 때 **가는 획을 통째로 버린다** - 메뉴판 미리보기의 한글이
     뭉개져 안 읽히던 원인이다. 원본 폭에 가깝게 키워 보여주는 자리에서만 픽셀을 살린다. */
  image-rendering: auto;
}

/* 통계 행 이름 옆 「보관됨」 배지 - 이름이 길면 이름 쪽이 말줄임 */
.stat-name { display: flex; align-items: center; gap: 6px; min-width: 0; }
.stat-name .ellipsis { min-width: 0; }

/* ================================================================ v8 - 앱 갤러리 · 명패 · NFC (§17.8) */

/* 만들기 갈래 - 두 칸 선택 (상품 POP / 앱 화면) */
.choice-grid.two { grid-template-columns: repeat(2, 1fr); }

/* 앱 갤러리 행 (store-row 문법 - 이름 + 배지 + 켜기/끄기, 360px 에서 꺾인다) */
.app-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 0; border-radius: var(--radius-ctl);
  background: var(--bg);
  padding: 12px;
}
.app-row .app-name { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 14px; font-weight: 500; }
.app-row .app-badges { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.app-row button { flex: none; }

/* ---------------------------------------------------------------- 등록 대기 (계약 §4, 2026-09-12)
   🔴 줄 하나가 세로로 자라므로 `align-items: center` 가 아니라 `flex-start` 다. 가운데로 맞추면
   MAC 뒷 네 자리(큰 글자)와 단추가 서로 다른 높이에 떠서 어느 단추가 어느 줄 것인지 흐려진다.
   ⚠ 390px 에서 단추 둘이 왼쪽 덩어리와 한 줄에 못 들어간다. `flex-wrap` 으로 아래로 내리고
   단추 묶음이 폭을 다 쓰게 둔다 - 잘려 나가면 「내 기기 아님」을 못 누른다. */
.pending-row {
  display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  border: 0; border-radius: var(--radius-ctl);
  background: var(--bg);
  padding: 12px;
}
.list > .pending-row + .pending-row { border-top: 1px solid var(--divider); }
.pending-row .pending-tail { font-size: 20px; font-weight: 700; line-height: 1.2; }
.pending-row .pending-acts { flex: none; margin-left: auto; }
.pending-row button { flex: none; }
@media (max-width: 767px) {
  .pending-row .pending-acts { margin-left: 0; flex-basis: 100%; }
}

/* v9: 앱 폼 내부 칸 간격 (카드 + 접이식 + 버튼이 형제로 서는 영업시간 폼) */
.app-form > * + * { margin-top: 12px; }

/* v9: 메뉴판 품절 체크 줄 - 한 손 조작 대상이라 44px (칩과 같은 기준) */
.mn-item { display: flex; align-items: center; gap: 10px; min-height: 44px; font-size: 13px; cursor: pointer; }
.mn-item input[type="checkbox"] { flex: none; width: 18px; height: 18px; margin: 0; accent-color: var(--primary); }
.mn-item .mn-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* NFC 패널의 URL - 좁은 화면에서 줄바꿈 (가로 스크롤 0) */
.nfc-url {
  word-break: break-all;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-ctl);
  padding: 8px 10px; color: var(--text-sub);
}

/* datetime-local 도 다른 입력과 같은 모양 (기본 목록에 없던 타입) · 모바일 44px · iOS 확대 방지 */
input[type=datetime-local] {
  width: 100%; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); color: var(--text); font: inherit; font-size: 14px;
}
input[type=datetime-local]:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 1px rgba(10, 143, 245, .25);
}
@media (max-width: 767px) {
  input[type=datetime-local] { min-height: 44px; font-size: 16px !important; }
}

/* ================================================================ v10 - 기기 이상 알림 (§19.3) */

/* 헤더의 알림 벨. 보이는 32px, 터치 영역은 가짜요소로 44px (QA r6 문법 - 헤더 48px 안이라 세로는 못 키운다) */
.bellbtn {
  position: relative; flex: none;
  width: 32px; height: 32px; min-height: 0; padding: 0;
  border: 0; border-radius: 999px; background: none;
  font-size: 15px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.bellbtn::after { content: ''; position: absolute; left: -6px; right: -6px; top: -8px; bottom: -8px; }
.bellbtn:hover { background: var(--surface); }
.bell-dot {
  position: absolute; top: -2px; right: -5px; z-index: 1;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px;
  background: var(--danger); color: var(--color-white);
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}

/* 알림 목록 행 - 종류 배지 · 기기 · 매장 · 언제부터. 좁은 화면에서는 꺾인다 (가로 스크롤 0) */
.alert-row { display: flex; align-items: center; gap: 8px; padding: 10px 0; min-height: 44px; flex-wrap: wrap; }
.alert-row + .alert-row { border-top: 1px solid var(--divider); }
.alert-row .badge { flex: none; }
.alert-row .a-dev { font-size: 13px; font-weight: 500; }
.alert-row .a-store { font-size: 11px; color: var(--text-hint); }
.alert-row .a-time { font-size: 11px; color: var(--text-hint); flex: none; margin-left: auto; }
.alert-row.closed .a-dev { color: var(--text-hint); font-weight: 400; }
.alert-sec { font-size: 11px; color: var(--text-hint); margin: 12px 0 2px; }   /* arch-sec 문법 */

/* ================================================================ v12 - 기기 번호 배지 (§21.6) */

/* 켬/끔 한 글자 라벨이라 segtog 기본 패딩(0 16px)만으로는 폭 42px 가 나온다.
   높이는 segtog 가 44px 를 지키지만 가로도 44px 를 넘기도록 이 토글만 하한을 준다. */
#badge-tog button { min-width: 56px; }

/* ================================================================ v15 - 공간 묶음 (§26.4) */

/* 기기 목록을 묶음 단위로 접는다. 흰 카드 안에 카드를 겹치지 않는다는 v13b 규약(§22.6)을
   그대로 지켜, 묶음 머리는 회색 페이지 위에 얇은 띠 하나로만 선다. */
.grp-store {
  font-size: 11px; color: var(--text-hint);
  margin: 14px 0 6px; padding-left: 2px;
}
.grp-store:first-child { margin-top: 0; }
.grp { margin-bottom: 10px; }
.space-drag-handle { touch-action: none; cursor: grab; }
.space-drag-handle.moving { cursor: grabbing; }
body.moving-space #toast { pointer-events: none; }
.grp.space-drop-over { outline: 2px solid var(--primary); background: var(--primary-light); border-radius: 8px; }
.grp-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  min-height: 44px; padding: 0 12px;                  /* 손가락으로 눌리는 하한 44px */
  background: var(--surface); border: 1px solid var(--divider); border-radius: 10px;
  text-align: left; cursor: pointer;
}
.grp-head.open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.grp-caret { font-size: 11px; color: var(--text-hint); flex: none; width: 12px; }
.grp-name { font-size: 14px; font-weight: 500; flex: 1; min-width: 0; }
.grp-head .badge { flex: none; }
/* 펼친 안쪽은 머리와 이어 붙는다 - 떨어져 있으면 어느 묶음에 속한 기기인지 안 갈린다 */
.grp-head.open + .card { border-top-left-radius: 0; border-top-right-radius: 0; }
.grp .empty { padding: 12px; font-size: 12px; }
/* 묶음이 붙으면 기기 카드 안 조작 줄이 셋이 된다 (이름 · 매장 · 묶음) */
.mgr-dev .controls:has(> :nth-child(3)) { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 640px) { .mgr-dev .controls:has(> :nth-child(3)) { grid-template-columns: 1fr; } }

/* Product workspace: stable board, readable controls and an in-place editor. */
:root {
  /* 위 :root 를 덮는 두 번째 블록이다. 여기 값이 실제로 먹는다 - 위와 같게 둔다. */
  --primary: var(--color-blue-600);
  --primary-hover: var(--color-blue-750);
  --primary-light: var(--color-blue-300);
  --text: var(--color-gray-900);
  --text-sub: var(--color-gray-600);
  --text-hint: var(--color-gray-500);
  --page: var(--color-gray-100);
  --surface: var(--color-gray-200);
  --line: var(--color-gray-300);
  --divider: var(--color-gray-200);
  --header-h: 64px;
  --tabbar-h: 68px;
}
body { line-height: 1.55; }
h1 { font-size: 26px; font-weight: 700; letter-spacing: -.035em; }
h2 { font-size: 17px; font-weight: 650; }
h3 { font-size: 15px; font-weight: 600; }
.wrap { max-width: 1440px; }
main.wrap { padding-top: 28px; }
button, .btn { min-height: 44px; font-size: 14px; }
button.sm { min-height: 40px; font-size: 13px; }
button:focus-visible, [role=button]:focus-visible, summary:focus-visible, a:focus-visible {
  outline: 3px solid var(--primary); outline-offset: 3px;
}
input:focus, select:focus, textarea:focus { box-shadow: 0 0 0 3px var(--primary-light); }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=tel], input[type=time], input[type=date], input[type=datetime-local], select { min-height: 44px; }
label.field { margin-bottom: 18px; }
label.field > span.lbl { font-size: 13px; margin-bottom: 7px; font-weight: 550; }
.hint { line-height: 1.6; }
.card { border: 1px solid var(--divider); box-shadow: var(--shadow-md); }
.topbar .wrap { max-width: none; padding: 0 28px; gap: 20px; }
.brand .name { font-size: 18px; letter-spacing: -.025em; }
.brand .tag { font-size: 11px; }
.brand .org { margin-left: 10px; padding-left: 14px; border-left: 1px solid var(--line); }
.topbar .linkbtn { min-height: 44px; padding: 8px 12px; }
.linkbtn::after, .langtog button::after, .bellbtn::after { display: none; }
.bellbtn { width: 44px; height: 44px; }
.langtog button { min-width: 40px; min-height: 40px; padding: 6px 9px; }
.page-heading { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 24px; }
.page-heading h1 { margin-bottom: 6px; }
.page-heading p { color: var(--text-sub); margin: 0; }
/* 제목 줄과 그 옆 물음표 (frame-0069, 2026-09-20). 설명 한 줄이 여기 뒤로 들어가면서
   제목과 검색창 사이가 탭마다 84~304px 로 갈려 있던 것이 한 값으로 모인다. */
.page-title-row { display: flex; align-items: center; gap: 8px; }
.page-title-row h1 { margin-bottom: 0; }
.page-help-btn {
  width: 22px; height: 22px; flex: none; padding: 0;
  border: 1px solid var(--line); border-radius: 50%; background: var(--bg);
  font: inherit; font-size: 12px; line-height: 1; color: var(--text-hint); cursor: pointer;
}
.page-help-btn:hover { color: var(--text); border-color: var(--text-hint); }
.page-help-btn.open { background: var(--surface); color: var(--text); }
.page-help { margin-top: 8px; display: grid; gap: 4px; }
.page-heading > button { flex: none; }
/* 🔴 버튼을 묶음 안에 넣으면 위 규칙이 안 걸린다 - 직계 자식이 `button` 이 아니라 `div` 가
   되기 때문이다. `.page-heading` 은 768px 이상에서 줄바꿈을 안 하므로, 안 적어 두면 창을
   800~1000px 로 좁혔을 때 묶음이 눌려 단추 라벨이 두 줄로 접힌다. */
.page-heading > .row { flex: none; }
.board, .editing-content .board { display: block; }
.library, .editing-content .library {
  position: static; max-height: none; overflow: visible;
  padding: 22px; margin-bottom: 30px;
  background: var(--bg); border: 1px solid var(--divider); border-radius: var(--radius-card);
}
.library .lib-title { font-size: 17px; font-weight: 650; color: var(--text); margin: 0 0 16px; }
.library-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.library-toolbar input { flex: 1 1 220px; min-width: 0; }
.library-toolbar select { width: auto; flex: 0 1 180px; }
.lib-grid, .editing-content .lib-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  align-items: start; gap: 16px; overflow: visible; padding-bottom: 0;
}
.lib-item { width: auto; min-width: 0; position: relative; padding: 10px; border: 1px solid var(--divider); border-radius: 12px; background: var(--bg); }
.lib-item:hover { border-color: var(--sel-line); background: var(--color-gray-100); }
.lib-item .lib-name { font-size: 13px; font-weight: 550; margin-top: 9px; }
.lib-item .lib-thumb { border: 0; border-radius: 6px; }
.lib-new { width: 100%; min-height: 148px; aspect-ratio: auto; font-size: 14px; background: var(--surface); border-color: var(--color-gray-400); word-break: keep-all; }
.lib-new:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-light); }
.lib-edit, .lib-send { font-size: 12px; min-height: 36px; }
.lib-edit { margin-top: 10px; }
.lib-send { margin-top: 6px; background: var(--bg); }
#lib-hint { margin: 16px 0 0; }
.board-section-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 0 0 18px; }
.board-section-head .lib-title { margin-bottom: 4px; }
.lib-device-count { display: inline-flex; margin-top: 8px; }
.store-sec { margin-bottom: 28px; }
.store-head { margin-bottom: 14px; gap: 10px; }
.dev-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 18px; }
.dev-card { border: 1px solid var(--divider); padding: 14px; min-width: 0; }
.dev-card.clickable:hover { transform: none; border-color: var(--sel-line); box-shadow: 0 4px 18px rgba(30,45,65,.06); }
.dev-card .dev-name { font-weight: 600; }
.dev-card .dev-pop { font-size: 12px; margin-top: 4px; }
.dev-meta { line-height: 1.6; font-size: 12px; }
.status-strip { border: 1px solid var(--divider); margin-bottom: 20px; }
.status-strip.thin { border: 0; }
.create-dialog { padding: 0 24px 24px; margin: 8px 0 12px; border-color: var(--color-gray-400); background: var(--color-gray-100); scroll-margin-top: 84px; }
.create-dialog-head { padding: 18px 0; margin-bottom: 20px; align-items: center; }
.create-dialog-head h2 { font-size: 20px; }
.editor-source { outline: 2px solid var(--primary); outline-offset: 3px; }
.create-dialog #panel-create > .card { background: transparent; padding: 0 0 20px; border: 0; border-bottom: 1px solid var(--divider); border-radius: 0; }
.create-dialog #edit-banner { padding: 12px 16px; border: 1px solid var(--line); border-radius: 8px; background: var(--primary-light); }
.editor-fields, .editor-preview, .editor-workspace { min-width: 0; }
#panel-settings > .card:has(> #store-label-box.hidden) { display: none; }
#create-form:has(> .editor-fields), .editor-workspace { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(280px, .85fr); gap: 24px; align-items: start; }
#create-form.stack > .editor-preview { margin-top: 0; }
.editor-fields > .card { padding: 20px; margin-bottom: 16px; }
.editor-preview { position: sticky; top: 88px; padding: 20px; border: 1px solid var(--divider); border-radius: 12px; background: var(--bg); }
.editor-preview img { width: 100%; object-fit: contain; border-radius: 8px; }
.editor-preview > button { width: 100%; margin-top: 12px; }
.editor-preview-empty { display: flex; align-items: center; justify-content: center; flex-direction: column; min-height: 210px; aspect-ratio: 5 / 3; padding: 24px; border: 1px dashed var(--line); border-radius: 8px; text-align: center; color: var(--text-hint); background: var(--surface); }
.editor-preview-status { font-size: 13px; color: var(--text-sub); line-height: 1.6; margin-top: 12px; }
.choice-grid { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; }
.choice { padding: 12px 10px; min-height: 48px; }
.choice.selected, .shot-card.selected, .shot-chip.selected { border-color: var(--color-gray-500); box-shadow: inset 0 0 0 1px var(--color-gray-500); }
#app-pick.shot-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
#create-app .app-form { max-width: 880px; margin-left: auto; margin-right: auto; }
.product-design-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.product-design-heading h2 { margin-bottom: 0; }
#product-design-title { scroll-margin-top: calc(var(--header-h) + 16px); }
.product-example-label { font-size: 12px; color: var(--text-sub); background: var(--surface); padding: 4px 8px; border-radius: 4px; white-space: nowrap; }
#product-layouts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin: 16px 0; }
#product-layouts .product-design-card { display: flex; flex-direction: column; overflow: hidden; min-width: 0; padding: 0; text-align: left; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); }
#product-layouts .product-design-card.selected { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
#product-layouts .product-design-card:focus-visible { outline: 3px solid var(--primary); outline-offset: 4px; }
#product-layouts img { display: block; width: 100%; height: auto; aspect-ratio: 5 / 3; object-fit: contain; border-bottom: 1px solid var(--divider); background: white; }
.product-design-info { display: flex; flex-direction: column; gap: 8px; padding: 14px; width: 100%; }
.product-design-title { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px; font-size: 15px; }
.product-design-selected { font-size: 12px; font-weight: 500; color: var(--text-sub); }
.selected .product-design-selected { color: var(--primary); font-weight: 700; }
.product-design-description { font-size: 13px; font-weight: 400; line-height: 1.6; color: var(--text-sub); }
.product-design-photo { font-size: 12px; font-weight: 400; color: var(--text-sub); }
.product-candidate { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.product-candidate .product-design-card { width: 100%; flex: 1; }
.product-candidate-empty { width: 100%; aspect-ratio: 5 / 3; display: grid; place-content: center; padding: 20px; text-align: center; font-size: 14px; line-height: 1.6; color: var(--text-sub); background: var(--surface); }
#product-compare-status:empty { display: none; }
@media (max-width: 600px) { #product-layouts { grid-template-columns: minmax(0, 1fr); } }
.result-main img { image-rendering: auto; }
#panel-manage > .card, #panel-settings > .card { margin-bottom: 24px; }
.mgr-dev { grid-template-columns: 132px minmax(0,1fr); gap: 20px; }
.mgr-dev .dev-thumb { width: 132px; border-radius: 8px; }
.grp-head { min-height: 56px; padding: 10px 16px; background: var(--color-gray-200); }
.grp-name { font-weight: 600; }
.store-row, .app-row { padding: 18px 8px; gap: 16px; }
.empty { line-height: 1.7; padding: 36px 20px; }
@media (min-width: 1000px) {
  body.has-tabbar { padding-left: 176px; padding-bottom: 0; }
  body.has-tabbar .topbar { margin-left: -176px; }
  .tabbar { position: fixed; top: var(--header-h); bottom: 0; left: 0; right: auto; width: 176px; height: auto; padding: 22px 12px; border: 0; border-right: 1px solid var(--divider); flex-direction: column; gap: 6px; justify-content: flex-start; }
  .tabbar button { width: 100%; height: 46px; min-height: 46px; padding: 0 15px; border: 0; border-radius: 8px; flex: none; justify-content: flex-start; flex-direction: row; gap: 12px; font-size: 14px; }
  .tabbar button .ico { width: 20px; font-size: 19px; }
  .tabbar button.active { background: var(--primary-light); color: var(--primary); }
  .tabbar button[data-panel=create] { margin-bottom: 18px; }
  main.wrap { padding: 30px 36px 72px; }
  .sendbar { left: calc(50% + 88px); }
}
@media (min-width: 768px) and (max-width: 999px) {
  .tabbar { padding-left: 16px; }
  main.wrap { padding-bottom: 96px; }
}
@media (max-width: 767px) {
  :root { --header-h: 112px; }
  body.has-tabbar { padding-bottom: calc(var(--tabbar-h) + 24px + env(safe-area-inset-bottom)); }
  body.has-tabbar:has(.sendbar:not(.hidden)) { padding-bottom: calc(var(--tabbar-h) + 180px + env(safe-area-inset-bottom)); }
  .topbar { height: auto; min-height: var(--header-h); }
  .topbar .wrap { display: flex; flex-wrap: wrap; gap: 4px 10px; padding: 10px 16px; }
  .topbar .brand { flex: 1 1 calc(100% - 160px); }
  .topbar .brand .name { font-size: 16px; }
  .topbar .spacer { display: none; }
  .topbar .gauge { width: 104px; }
  .topbar .langtog { margin-left: auto; }
  .topbar .linkbtn { font-size: 12px; }
  .topbar .brand .org { display: none; }
  .tabbar { padding-left: 4px; padding-right: 4px; box-shadow: 0 -2px 12px rgba(30,45,65,.04); }
  .tabbar button { min-width: 0; padding: 7px 2px; font-size: 11px; gap: 5px; }
  .tabbar button .ico { font-size: 21px; }
  .tabbar button.active { background: var(--primary-light); }
  main.wrap { padding-top: 22px; }
  h1 { font-size: 23px; }
  .page-heading { align-items: flex-start; flex-wrap: wrap; gap: 14px; margin-bottom: 20px; }
  .library, .editing-content .library { padding: 16px; }
  .lib-grid, .editing-content .lib-grid { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 12px; }
  .lib-item { padding: 8px; }
  .lib-new { min-height: 136px; }
  .library-toolbar { gap: 8px; }
  .library-toolbar input { flex-basis: 100%; }
  .library-toolbar select { flex: 1 1 100%; width: 100%; }
  .dev-grid { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 12px; }
  .dev-card { padding: 10px; }
  .dev-card .dev-name { font-size: 13px; }
  .create-dialog { padding: 0 14px 16px; scroll-margin-top: 132px; }
  .create-dialog-head h2 { font-size: 18px; }
  #create-form:has(> .editor-fields), .editor-workspace { grid-template-columns: minmax(0,1fr); gap: 16px; }
  .editor-fields > .card { padding: 16px; }
  .editor-preview { position: static; padding: 16px; }
  .choice-grid { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .choice-grid.two { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .choice { min-height: 48px; }
  #app-pick.shot-grid { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .mgr-dev { grid-template-columns: 80px minmax(0,1fr); gap: 12px; }
  .mgr-dev .dev-thumb { width: 80px; }
  .mgr-dev .controls, .mgr-dev .controls:has(> :nth-child(3)) { grid-template-columns: minmax(0,1fr); }
  .mgr-dev .mac { font-size: 11px; overflow-wrap: anywhere; }
  #toast { bottom: calc(var(--tabbar-h) + 20px + env(safe-area-inset-bottom)); border-radius: 12px; }
  body:has(.sendbar:not(.hidden)) #toast { bottom: calc(var(--tabbar-h) + 180px + env(safe-area-inset-bottom)); }
}
@media (max-width: 380px) {
  .brand .tag { display: none; }
  .lib-grid, .editing-content .lib-grid { gap: 8px; }
  .lib-name, .lib-item .lib-name { font-size: 12px; }
  .dev-grid { grid-template-columns: minmax(0,1fr); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
/* Search is a native search input, with the same control geometry as filters. */
input[type=search] {
  width: 100%; min-height: 44px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); color: var(--text); font: inherit; font-size: 14px;
  -webkit-appearance: none; appearance: none;
}
input[type=search]:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light); }
input[type=search]::placeholder { color: var(--text-hint); }
@media (max-width: 767px) { input[type=search] { font-size: 16px; } }
.editor-preview-empty { width: 100%; min-width: 0; aspect-ratio: auto; overflow-wrap: anywhere; }
@media (min-width: 768px) and (max-width: 1199px) {
  #create-form:has(> .editor-fields), .editor-workspace { grid-template-columns: minmax(0,1fr); }
  .editor-preview { position: static; }
}
@media (min-width: 768px) and (max-width: 999px) {
  .create-dialog { scroll-margin-top: 128px; }
}
/* Native time controls need room for localized AM/PM and the clock button. */
@media (max-width: 480px) {
  .app-form[data-app="timetable"] .row { flex-direction: column; }
  .app-form[data-app="timetable"] .row > .field { width: 100%; }
}
/* Full-width product proof, with an optional scrollable 800px original. */
#product-preview-dialog { width:min(960px, calc(100vw - 24px)); max-width:calc(100vw - 24px); max-height:calc(100dvh - 24px); padding:16px; border:1px solid var(--line, var(--color-gray-300)); border-radius:16px; box-sizing:border-box; }
#product-preview-dialog::backdrop { background:rgba(15,23,42,.65); }
.product-preview-toolbar { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:12px; }
.product-preview-toolbar h2 { margin:0; }
#product-preview-scroll { overflow:auto; max-height:calc(100dvh - 210px); margin-top:12px; border:1px solid var(--color-gray-300); background:var(--color-white); }
#product-preview-large { display:block; width:auto; max-width:100%; height:auto; margin:auto; object-fit:contain; }
#product-preview-scroll.original-size #product-preview-large { width:800px; max-width:none; margin:0; }

/* ================================================================ 랜딩 (index.html)
   값은 전부 :root 토큰이고 새 색을 만들지 않는다.

   🔴 이 파일은 브라우저가 그대로 받아 간다. 회차의 판단 근거와 경쟁 조사는 여기가
      아니라 `docs/qa/landing2-2b7f9c04/README.md` 와 `docs/ROADMAP.md` 에 적는다.
      아래 주석은 이 CSS 를 고칠 사람이 알아야 하는 것만 남긴다.

   구조 - 헤더 / 히어로 / 신뢰 띠 / 비교 표 / 갤러리 / 세 단계 / 사양 표 / FAQ /
   문의 / 로그인 / 푸터. 문의가 주 버튼이고 로그인은 맨 아래 자기 칸이다.

   줄바꿈은 맨 아래 `html[lang=ko]` 블록에만 둔다. 일본어 문장에는 공백이 없어서
   keep-all 이 접을 자리를 전부 막는다 (첫 판이 일본어 360px 에서 25px 넘긴 자리). */

.lp-body { background: var(--page); }

/* ---- 헤더. 48px 로 앱 화면(--header-h)과 같은 높이를 쓴다 */
.lp-top {
  position: sticky; top: 0; z-index: 20;
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--divider);
}
.lp-top-in {
  max-width: 1120px; margin: 0 auto; padding: 0 24px;
  height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.lp-top .brand .name { font-size: 16px; }
.lp-top-right { display: flex; align-items: center; gap: 8px; }
.lp-toplink {
  position: relative;
  display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px;
  font-size: 13px; font-weight: 500; color: var(--text-sub); text-decoration: none;
  border-radius: var(--radius-btn);
}
/* 보이는 높이는 32px 로 두고 손가락이 닿는 자리만 44px 로 넓힌다. 헤더가 48px 이라
   버튼 자체를 44px 로 키우면 머리가 꽉 차고, 기억칸에 쓴 것과 같은 처방이다.
   위아래 6px 씩이라 확장분이 헤더 밖으로 나가지 않는다 - 아래 글을 가로채지 않는다. */
.lp-toplink::after, .lp-topcta::after {
  content: ''; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px;
}
.lp-toplink:hover { background: var(--surface); color: var(--text); }
.lp-topcta {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 32px; padding: 0 14px;
  border-radius: var(--radius-btn); background: var(--primary); color: var(--color-white);
  font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.lp-topcta:hover { background: var(--primary-hover); }

.lp-main { max-width: 1120px; margin: 0 auto; padding: 0 24px 24px; }

/* ---- 히어로 */
.lp-hero {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 56px; align-items: center;
  padding: 60px 0 52px;
}
.lp-eyebrow {
  margin: 0 0 14px; font-size: 12px; font-weight: 600; color: var(--text-hint);
}
.lp-h1 {
  margin: 0 0 20px;
  font-size: 46px; line-height: 1.16; font-weight: 700; letter-spacing: -.035em;
  color: var(--text);
}
.lp-lede {
  margin: 0 0 26px; font-size: 17px; line-height: 1.62; color: var(--text-sub);
  max-width: 32em;
}

/* 숫자 띠. 「위에 올릴 숫자가 하나도 없다」는 반박이 이 칸을 만들었다 */
.lp-specstrip {
  list-style: none; margin: 0 0 26px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 8px;
}
.lp-specstrip li {
  display: flex; align-items: baseline; gap: 5px;
  padding: 7px 12px; border-radius: 999px;
  background: var(--bg); border: 1px solid var(--line);
  font-size: 12px; color: var(--text-hint); white-space: nowrap;
}
.lp-specstrip strong { font-size: 14px; font-weight: 700; color: var(--text); }

.lp-herobtns { display: flex; flex-wrap: wrap; gap: 10px; }
.lp-ctabtn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 22px;
  border-radius: var(--radius-btn); background: var(--primary); color: var(--color-white);
  font-size: 14px; font-weight: 600; text-decoration: none;
}
.lp-ctabtn:hover { background: var(--primary-hover); }
.lp-ctabtn-lg { min-height: 50px; padding: 0 28px; font-size: 15px; }
.lp-ghostbtn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 18px;
  border-radius: var(--radius-btn); background: transparent;
  border: 1px solid var(--line); color: var(--text-sub);
  font-size: 14px; font-weight: 500; text-decoration: none;
}
.lp-ghostbtn:hover { background: var(--surface); color: var(--text); }

/* 기기 틀. 실제 기기는 흰 베젤이라 그 모양으로 감싼다 */
.lp-device {
  margin: 0; padding: 14px; border-radius: 18px;
  background: var(--color-white); border: 1px solid var(--line);
  box-shadow: 0 18px 40px rgba(17, 17, 17, .10), 0 2px 6px rgba(17, 17, 17, .05);
}
.lp-device img {
  display: block; width: 100%; height: auto;
  border-radius: 4px; border: 1px solid var(--divider);
}
.lp-device-cap {
  margin: 12px 2px 0; font-size: 12px; line-height: 1.6; color: var(--text-hint);
}

/* 히어로 바로 아래 얇은 띠. 처음 온 사람이 「실재하는 회사인가」를 먼저 재는 자리다.
   여기에는 이 제품에 대해 그대로 사실인 것만 적는다. 근거는 QA README 에 있다. */
.lp-trust {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  padding: 13px 18px; margin-bottom: 8px;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card);
  font-size: 13.5px; line-height: 1.6; font-weight: 500; color: var(--text);
}
.lp-trust span { display: inline-flex; align-items: center; gap: 7px; }
.lp-trust span::before {
  content: ''; flex: none; width: 5px; height: 5px; border-radius: 999px;
  background: var(--primary);
}

/* ---- 섹션 뼈대 */
.lp-sec { padding: 52px 0; }
.lp-sec-tint {
  background: var(--bg); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  padding: 44px 32px; margin: 8px 0;
}
.lp-h2 {
  margin: 0 0 8px;
  font-size: 28px; line-height: 1.28; font-weight: 700; letter-spacing: -.028em;
  color: var(--text);
}
.lp-sub { margin: 0 0 28px; font-size: 14px; line-height: 1.6; color: var(--text-hint); }
.lp-card {
  background: var(--bg); border-radius: var(--radius-card);
  padding: 24px; box-shadow: var(--shadow-md);
}
.lp-card-h { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
/* 화면에는 필요 없고 스크린 리더에만 읽히는 표 머리 */
.lp-vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---- 표 둘. 좁은 화면에서는 표만 가로로 스크롤한다 (페이지는 안 넘친다) */
.lp-tablewrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  background: var(--bg); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
}
.lp-cmp, .lp-spec { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.lp-cmp th, .lp-cmp td, .lp-spec th, .lp-spec td {
  padding: 14px 16px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--divider); line-height: 1.55;
}
.lp-cmp thead th {
  font-size: 12px; font-weight: 600; color: var(--text-hint);
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.lp-cmp tbody th, .lp-spec th {
  font-weight: 600; color: var(--text); white-space: nowrap; width: 1%;
}
.lp-cmp td { color: var(--text-sub); }
.lp-cmp tr:last-child th, .lp-cmp tr:last-child td,
.lp-spec tr:last-child th, .lp-spec tr:last-child td { border-bottom: 0; }
/* 우리 칸만 얕게 띄운다. 파랑은 주 버튼에만 쓰므로 여기서는 배경만 깐다 */
.lp-cmp .lp-ours { background: var(--primary-light); color: var(--text); font-weight: 500; }
.lp-cmp thead .lp-ours { color: var(--primary); font-weight: 700; }
/* 「붙었는지 확인이 안 된다」가 종이의 진짜 약점이라 그 줄만 세운다 */
.lp-cmp-key th, .lp-cmp-key td { background: var(--surface); }
.lp-cmp-key .lp-ours { background: var(--primary-light); }
.lp-cmp-key th { font-weight: 700; }
/* 칸 안의 열 이름. 넓은 화면에서는 머리글이 그 일을 하므로 숨는다 */
.lp-cmp-who { display: none; }
.lp-punch {
  margin: 24px 0 0; padding-left: 16px; border-left: 3px solid var(--primary);
  font-size: 16px; line-height: 1.6; font-weight: 600; color: var(--text);
}
.lp-spec-warn th { color: var(--text-sub); font-weight: 600; }
.lp-spec-warn td { color: var(--text); }

/* ---- 화면 갤러리 */
.lp-gal { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.lp-gal-item {
  margin: 0; padding: 10px; border-radius: var(--radius-card);
  background: var(--bg); box-shadow: var(--shadow-md);
}
.lp-gal-item img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius-ctl); border: 1px solid var(--divider);
}
.lp-gal-item figcaption {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 4px 2px; font-size: 12px; color: var(--text-sub);
}
.lp-gal-item figcaption b {
  padding: 2px 8px; border-radius: 999px;
  background: var(--sel-bg); color: var(--text-sub);
  font-size: 11px; font-weight: 600;
}

/* ---- 세 단계 */
.lp-steps {
  list-style: none; margin: 28px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px;
}
.lp-steps li { display: flex; flex-direction: column; gap: 8px; }
.lp-step-no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 999px;
  background: var(--primary-light); color: var(--primary);
  font-size: 13px; font-weight: 700;
}
.lp-steps h3 { margin: 0; font-size: 16px; font-weight: 600; letter-spacing: -.015em; color: var(--text); }
.lp-steps p { margin: 0; font-size: 13.5px; line-height: 1.65; color: var(--text-sub); }

/* ---- 자주 묻는 것. 전자종이가 낯선 기술이라 이 칸이 실제로 필요하다 */
.lp-faq { display: grid; gap: 10px; }
.lp-faq details {
  background: var(--bg); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  padding: 4px 20px;
}
.lp-faq summary {
  padding: 15px 0; cursor: pointer; list-style: none;
  font-size: 14.5px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.lp-faq summary::-webkit-details-marker { display: none; }
.lp-faq summary::after {
  content: ''; flex: none; width: 8px; height: 8px;
  border-right: 2px solid var(--text-hint); border-bottom: 2px solid var(--text-hint);
  transform: rotate(45deg) translate(-2px, -2px);
}
.lp-faq details[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.lp-faq p { margin: 0; padding: 0 0 16px; font-size: 13.5px; line-height: 1.7; color: var(--text-sub); }

/* ---- 문의 */
.lp-contact {
  text-align: center; padding: 52px 32px 56px; margin: 8px 0;
  background: var(--bg); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
}
.lp-contact .lp-sub { margin-left: auto; margin-right: auto; max-width: 42em; }
.lp-contact-tel { margin: 14px 0 0; font-size: 13px; color: var(--text-hint); }

/* ---- 로그인. 랜딩 맨 아래가 자기 자리다 */
.lp-login { padding: 52px 0 24px; display: flex; justify-content: center; }
.lp-loginbox {
  width: 100%; max-width: 380px;
  display: flex; flex-direction: column; gap: 14px;
}
.lp-login-note { margin: -6px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--text-hint); }
.lp-remember {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-sub); cursor: pointer;
  position: relative; min-height: 24px;
}
.lp-remember input { width: 16px; height: 16px; margin: 0; accent-color: var(--primary); flex: none; }
/* 보이는 높이는 그대로 두고 터치 영역만 44px (2026-09-03 QA 와 같은 처방) */
.lp-remember::after { content: ''; position: absolute; left: 0; right: 0; top: -10px; bottom: -10px; }

/* 헤더가 sticky 라 앵커로 뛰면 머리가 그 아래로 들어간다 */
#login, #compare, #contact { scroll-margin-top: calc(var(--header-h) + 16px); }

/* ---- 푸터. B2B 에서 회사 정보가 없으면 실재하는 회사인지 의심받는다 */
.lp-bottom { border-top: 1px solid var(--divider); background: var(--bg); }
.lp-bottom-in {
  max-width: 1120px; margin: 0 auto; padding: 24px;
  font-size: 12px; line-height: 1.8; color: var(--text-hint);
}
.lp-bottom-in p { margin: 0; }
.lp-bottom-brand { font-size: 13px; font-weight: 600; color: var(--text-sub); }
.lp-bottom-sep { padding: 0 6px; color: var(--text-disabled); }
/* 🔴 **이 링크가 랜딩의 유일한 연락 경로가 됐다** (2026-09-20). 해지된 대표전화를
   걷어내면서 맨 아래 줄에 남은 것이 메일 하나인데, 휴대폰에서 재어 보니 100x14px 라
   손가락으로 겨냥하기 어려웠다. **연락 경로를 하나로 줄이는 변경은 남은 그 하나가
   실제로 눌리는지까지가 한 묶음이다.**
   글자 크기는 그대로 두고 위아래로 눌리는 자리만 넓힌다 - 맨 아래 줄은 회색 잔글씨로
   조용히 있는 것이 맞고, 키우면 사업자등록번호 옆에서 혼자 튄다. */
.lp-bottom-in a {
  color: var(--text-hint);
  display: inline-block;
  padding: 12px 4px;
  margin: -12px 0;
}
.lp-bottom-in a:hover { color: var(--text); }

/* ---- 좁은 화면 */
@media (max-width: 979px) {
  .lp-hero { grid-template-columns: minmax(0, 1fr); gap: 32px; padding: 32px 0 28px; }
  .lp-h1 { font-size: 32px; }
  .lp-lede { font-size: 15.5px; }
  .lp-gal, .lp-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lp-steps { gap: 24px; }
  .lp-sec { padding: 36px 0; }
  .lp-sec-tint { padding: 32px 20px; }
  .lp-contact { padding: 40px 20px 44px; }
  .lp-h2 { font-size: 23px; }
  .lp-login { padding: 36px 0 16px; }
}
@media (max-width: 599px) {
  .lp-gal, .lp-steps { grid-template-columns: minmax(0, 1fr); }
  .lp-h1 { font-size: 27px; }
  .lp-spec { font-size: 13px; }
  .lp-spec th, .lp-spec td { padding: 12px 13px; }
  .lp-punch { font-size: 15px; }

  /* 🔴 비교 표를 행마다 카드로 접는다. 360px 에 네 열이면 열당 90px 이라 가로
     스크롤이 되는데, **미는 줄 모르는 사람에게는 우리 칸이 아예 없는 표가 된다.**
     이 페이지에서 제일 중요한 표이고 링크는 보통 폰으로 먼저 열린다.
     사양 표는 두 열이라 이 폭에서도 그대로 읽히므로 손대지 않는다. */
  .lp-tablewrap { overflow-x: visible; background: transparent; box-shadow: none; }
  .lp-cmp, .lp-cmp tbody, .lp-cmp tr, .lp-cmp th, .lp-cmp td { display: block; width: auto; }
  .lp-cmp thead { display: none; }
  .lp-cmp tbody tr {
    background: var(--bg); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
    margin-bottom: 10px; padding: 4px 16px 10px;
  }
  .lp-cmp tbody th, .lp-cmp tbody td { padding: 10px 0; border-bottom: 0; }
  .lp-cmp tbody th {
    font-size: 15px; padding-top: 14px;
    border-bottom: 1px solid var(--divider); margin-bottom: 4px;
  }
  .lp-cmp tbody td { font-size: 13.5px; }
  /* 카드 안에서는 우리 칸을 배경이 아니라 왼쪽 선으로 세운다. 칸이 가로로 꽉 차서
     배경을 깔면 카드 한 장이 통째로 파래 보인다 */
  .lp-cmp tbody .lp-ours {
    background: transparent; padding-left: 12px;
    border-left: 3px solid var(--primary); font-weight: 500;
  }
  .lp-cmp-key th, .lp-cmp-key td { background: transparent; }
  /* 넓은 화면에서 이 줄만 배경으로 세운 것과 같은 일을 한다. 카드에서는 배경을
     깔면 카드 한 장이 통째로 갈리므로 테두리로 바꾼다 */
  .lp-cmp-key { box-shadow: 0 0 0 1.5px var(--primary) inset, var(--shadow-md); }
  .lp-cmp-who {
    display: block; margin-bottom: 3px;
    font-size: 11.5px; font-weight: 600; color: var(--text-hint);
  }
  .lp-cmp .lp-ours .lp-cmp-who { color: var(--primary); }
}
@media (max-width: 480px) {
  .lp-top-in, .lp-main, .lp-bottom-in { padding-left: 16px; padding-right: 16px; }
  .lp-card, .lp-device { padding: 14px; }
  /* 헤더에 로고 · 언어 · 로그인 · 문의가 다 들어가야 한다. 언어 토글을 먼저 접는다 */
  .lp-top .langtog { display: none; }
  .lp-toplink { padding: 0 8px; }
}

/* 🔴 줄바꿈은 한국어에만 낱말 단위로 묶는다. 일본어 문장에는 공백이 하나도 없어서
   keep-all 이 접을 자리를 전부 막고 문장 하나가 통째로 한 줄이 된다 - 첫 판이
   일본어 360px 에서 가로를 25px 넘긴 자리다. 영어는 기본값 normal 이 맞다. */
html[lang=ko] .lp-h1,
html[lang=ko] .lp-lede,
html[lang=ko] .lp-h2,
html[lang=ko] .lp-sub,
html[lang=ko] .lp-punch,
html[lang=ko] .lp-steps p,
html[lang=ko] .lp-device-cap,
html[lang=ko] .lp-login-note,
html[lang=ko] .lp-trust,
html[lang=ko] .lp-faq p,
html[lang=ko] .lp-cmp td,
html[lang=ko] .lp-spec td { word-break: keep-all; overflow-wrap: anywhere; }

/* ── 랜딩 2차: 신뢰 띠 · 시범 설치 · 설치와 사후 관리 · 마지막 CTA ── */

.lp-proof {
  max-width: 1080px;
  margin: 0 auto;
  padding: 22px 24px 26px;
}
.lp-proof-lede {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-hint);
  text-align: center;
}
.lp-proof-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.lp-proof-list li {
  padding: 14px 14px 13px;
  background: var(--bg);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-md);
  text-align: center;
}
.lp-proof-list strong {
  display: block;
  margin-bottom: 4px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.lp-proof-list span {
  display: block;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-hint);
}

.lp-pilot {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
}
.lp-pilot li {
  padding: 16px;
  background: var(--bg);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-md);
  /* 🔴 위쪽 한 변만 그리면 둥근 모서리에서 선이 끊겨 밑줄처럼 보인다.
     나머지 세 변을 옅게 둘러야 상자로 읽힌다 (`test_v26_ui.py` 가 재는 자리). */
  border: 1px solid var(--line);
  border-top: 3px solid var(--primary);
}
.lp-pilot strong {
  display: block;
  margin-bottom: 5px;
  font-size: 15px;
  font-weight: 600;
  color: var(--primary);
}
.lp-pilot span {
  display: block;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-sub);
}
.lp-pilot-note {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-hint);
  text-align: center;
}
.lp-herobtns-c {
  justify-content: center;
}

.lp-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.lp-cards .lp-card {
  padding: 18px;
}
.lp-cards .lp-card p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--text-sub);
}

.lp-last {
  max-width: 1080px;
  margin: 0 auto;
  padding: 34px 24px 6px;
  text-align: center;
}
.lp-last-h {
  margin: 0 0 8px;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.lp-last-p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--text-sub);
}

#pilot {
  scroll-margin-top: calc(var(--header-h) + 16px);
}

@media (max-width: 979px) {
  .lp-pilot { grid-template-columns: repeat(2, 1fr); }
  .lp-cards { grid-template-columns: 1fr; }
  .lp-last-h { font-size: 21px; }
}

@media (max-width: 599px) {
  .lp-proof { padding: 18px 16px 20px; }
  .lp-proof-list { grid-template-columns: 1fr; }
  .lp-proof-list li { text-align: left; }
  .lp-pilot { grid-template-columns: 1fr; }
  .lp-last { padding: 26px 16px 4px; }
  .lp-last-h { font-size: 19px; }
}

html[lang=ko] .lp-proof-lede,
html[lang=ko] .lp-proof-list span,
html[lang=ko] .lp-pilot span,
html[lang=ko] .lp-pilot-note,
html[lang=ko] .lp-cards .lp-card p,
html[lang=ko] .lp-last-h,
html[lang=ko] .lp-last-p {
  word-break: keep-all;
  overflow-wrap: anywhere;
}

/* ================================================================
   Yodeck 구조 맞추기 - 좌측 메뉴와 목록 한 틀 (frame-0054, 2026-09-18)

   🔴 이 블록은 파일 맨 뒤에 있다. 위쪽 `.tabbar` 규칙(147행 · 1748행)을 지우지 않고
      덮어쓰는 방식이라, 되돌릴 때 이 블록만 걷어내면 예전 화면으로 돌아온다.

   🔴 **폰의 하단 탭바는 그대로 둔다.** 고객역할 검토(2026-09-18)가 짚었다 - 데스크톱은
      이미 1000px 이상에서 176px 좌측 레일이었고, 이번에 바뀌는 것은 갈래와 순서이지
      「세로로 세우는 것」이 아니다. 폰에서 하단 바를 서랍으로 바꾸면 매장 담당자의 왕복이
      탭 한 번에서 두 번으로 늘고, `--tabbar-h` 를 기준으로 잡은 자리 넷(본문 여백 ·
      보내기 바 · 토스트)이 같이 어긋난다.

   🔴 **주황과 보라는 실측 근거가 있는 곳에만 쓴다.** `docs/YODECK-PARITY-2026-09-18.md`
      가 기록한 것은 목록 화면 아래 만들기 단추 둘의 색(주황 · 보라)뿐이다. Yodeck 레일의
      바탕색은 아무도 재지 않았으므로 지어내지 않고 우리 흰 레일을 그대로 둔다. */

:root {
  /* 이름은 Yodeck 실측 때 붙인 것이다. 값은 2026-09-23 gency.ai 무드로 파랑이 됐다 -
     이름을 바꾸면 쓰는 자리 스무 곳을 같이 고쳐야 해서 값만 바꿨다. */
  --yd-orange: var(--color-blue-600);
  --yd-orange-dark: var(--color-blue-750);
  --yd-purple: var(--color-purple-600);        /* 실측: Create with AI */
  --rail-w: 211px;        /* 실측: Yodeck 좌측 메뉴 (reference-measurements.md) */
}

/* ---------------------------------------------------------- 좌측 메뉴 */
.tabbar .nav-scroll { display: contents; }
.tabbar .nav-grp { display: contents; }
.tabbar .nav-div, .tabbar .nav-foot, .tabbar .nav-caret { display: none; }
.tabbar .nav-sub { display: none; }
.nav-soon {
  font-size: 10px; color: var(--text-hint); border: 1px solid var(--line);
  border-radius: 999px; padding: 0 6px; margin-left: auto; font-weight: 500;
  line-height: 1.6; white-space: nowrap;
}

/* 폰 - 하단 바에는 자주 쓰는 다섯과 「더보기」만 세운다 */
@media (max-width: 767px) {
  .tabbar > .nav-scroll > button:not([data-m]),
  .tabbar .nav-grp > button:not([data-m]) { display: none; }
  .tabbar button[data-panel=board] { order: 1; }
  .tabbar button[data-panel=create] { order: 2; }
  .tabbar .nav-grp > button[data-panel=assets] { order: 3; }
  .tabbar button[data-panel=playlists] { order: 4; }
  .tabbar button[data-panel=devices] { order: 5; }
  .tabbar .nav-more {
    order: 6; flex: 1; border: 0; border-radius: 0; background: none; color: var(--text-hint);
    min-height: var(--tabbar-h); font: inherit; font-size: 10px; font-weight: 500;
    display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; cursor: pointer; touch-action: manipulation;
  }
  .tabbar .nav-more .ico { font-size: 20px; line-height: 1; }

  /* 「더보기」를 누르면 바가 시트로 펴진다. 닫으면 그대로 하단 바로 돌아온다 */
  .tabbar.open {
    height: auto; max-height: 78vh; overflow-y: auto; flex-direction: column;
    align-items: stretch; padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
    border-radius: 16px 16px 0 0; box-shadow: var(--shadow-xl);
  }
  .tabbar.open > .nav-scroll > button,
  .tabbar.open .nav-grp > button { display: flex; }
  .tabbar.open .nav-sub { display: block; }
  .tabbar.open .nav-scroll > button,
  .tabbar.open .nav-grp > button,
  .tabbar.open .nav-more {
    order: 0; flex: none; flex-direction: row; justify-content: flex-start; gap: 12px;
    min-height: 46px; height: 46px; padding: 0 14px; font-size: 14px; border-radius: 8px;
  }
  .tabbar.open .nav-sub button {
    flex: none; flex-direction: row; justify-content: flex-start; gap: 10px;
    min-height: 42px; height: 42px; padding: 0 14px 0 46px; font-size: 13px;
    width: 100%; border-radius: 8px; border: 0; background: none; font: inherit;
    color: var(--text-hint); display: flex; align-items: center; cursor: pointer;
  }
  .tabbar.open .nav-sub button.active { background: var(--sel-bg); color: var(--text); font-weight: 600; }
  .tabbar.open .nav-div { display: block; height: 1px; background: var(--divider); margin: 8px 6px; }
  .tabbar.open .nav-foot { display: block; border-top: 1px solid var(--divider); margin-top: 8px; padding-top: 8px; }
  .tabbar.open .nav-help {
    display: flex; align-items: center; gap: 12px; height: 46px; padding: 0 14px;
    border-radius: 8px; text-decoration: none; color: var(--text-hint); font-size: 14px;
  }
  .tabbar.open .nav-help .ico { width: 20px; text-align: center; }
  .tabbar.open .nav-cta { background: var(--yd-orange); color: var(--color-white); font-weight: 600; }
  .tabbar.open .nav-more { order: 99; color: var(--text-hint); }
}

/* 데스크톱과 태블릿 - Yodeck 과 같은 세로 레일. 768px 부터 선다
   (예전에는 768~999px 이 상단 가로 탭이었다. Yodeck 은 그 폭에서도 레일이다) */
@media (min-width: 768px) {
  body.has-tabbar { padding-left: var(--rail-w); padding-bottom: 0; }
  body.has-tabbar .topbar { margin-left: calc(var(--rail-w) * -1); }
  .tabbar {
    position: fixed; top: var(--header-h); bottom: 0; left: 0; right: auto;
    width: var(--rail-w); height: auto; padding: 14px 10px 0;
    border: 0; border-right: 1px solid var(--divider); border-top: 0;
    flex-direction: column; gap: 0; justify-content: flex-start; overflow: hidden;
  }
  .tabbar .nav-more { display: none; }
  .tabbar .nav-scroll {
    display: block; flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain;
    padding-bottom: 8px;
  }
  .tabbar .nav-grp { display: block; }
  .tabbar .nav-scroll > button,
  .tabbar .nav-grp > button {
    width: 100%; height: 42px; min-height: 42px; padding: 0 12px;
    border: 0; border-radius: 8px; flex: none;
    justify-content: flex-start; flex-direction: row; gap: 11px;
    font-size: 14px; font-weight: 500; color: var(--text-sub);
  }
  .tabbar .nav-scroll > button:hover,
  .tabbar .nav-grp > button:hover { background: var(--surface); }
  .tabbar .nav-scroll > button .ico,
  .tabbar .nav-grp > button .ico { width: 20px; font-size: 17px; text-align: center; }
  .tabbar .nav-scroll > button.active,
  .tabbar .nav-grp > button.active {
    background: var(--primary-light); color: var(--primary); font-weight: 600;
    border-bottom: 0;
  }

  /* 만들기 - 메뉴 항목이 아니라 동작이라 맨 위에 따로 세운다. `switchPanel('create')` 는
     패널을 안 바꾸고 덮개를 연다. Yodeck 목록 아래 주황 만들기 단추와 같은 값이다 */
  .tabbar .nav-cta {
    background: var(--yd-orange); color: var(--color-white); font-weight: 600; margin-bottom: 12px;
  }
  .tabbar .nav-cta:hover { background: var(--yd-orange-dark); }
  .tabbar .nav-cta.active { background: var(--yd-orange-dark); color: var(--color-white); }

  .tabbar .nav-caret {
    display: inline-block; margin-left: auto; font-size: 11px; color: var(--text-hint);
    transition: transform .15s ease;
  }
  .tabbar .nav-grp > button[aria-expanded=true] .nav-caret { transform: rotate(180deg); }
  .tabbar .nav-grp > button[aria-expanded=true] + .nav-sub { display: block; }
  .tabbar .nav-sub { padding: 2px 0 6px; }
  .tabbar .nav-sub button {
    width: 100%; height: 34px; min-height: 34px; padding: 0 12px 0 43px;
    border: 0; border-radius: 8px; flex: none; background: none;
    display: flex; align-items: center; justify-content: flex-start; gap: 8px;
    font: inherit; font-size: 13px; color: var(--text-hint); cursor: pointer;
  }
  .tabbar .nav-sub button:hover { background: var(--surface); }
  .tabbar .nav-sub button.active { background: var(--sel-bg); color: var(--text); font-weight: 600; }

  .tabbar .nav-div { display: block; height: 1px; background: var(--divider); margin: 10px 6px; }
  .tabbar .nav-foot {
    display: block; flex: none; border-top: 1px solid var(--divider);
    padding: 8px 0 calc(8px + env(safe-area-inset-bottom));
  }
  .tabbar .nav-help {
    display: flex; align-items: center; gap: 11px; height: 40px; padding: 0 12px;
    border-radius: 8px; text-decoration: none; color: var(--text-hint); font-size: 13px;
  }
  .tabbar .nav-help:hover { background: var(--surface); }
  .tabbar .nav-help .ico { width: 20px; text-align: center; font-size: 15px; }

  main.wrap { padding: 26px 32px 72px; }
  .sendbar { left: calc(50% + (var(--rail-w) / 2)); }
}

/* ------------------------------------------------- 목록 화면 한 틀 (.lf)
   Yodeck 은 Layouts · Media · Playlists · Screens 가 **같은 틀**을 쓴다. 우리는 탭마다
   모양이 달랐다. 위에서부터 - 검색창 → 도구 줄 → 본문(격자 또는 표) → 쪽 넘김 →
   만들기 단추. 실측 출처는 `docs/YODECK-PARITY-2026-09-18.md` 와 frame-0054 항목이다. */
.lf { margin-top: 4px; }
.lf-search { position: relative; margin-bottom: 12px; }
.lf-search input {
  width: 100%; height: 40px; padding: 0 12px 0 36px;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); font: inherit; font-size: 14px; color: var(--text);
}
.lf-search input:focus { outline: 2px solid var(--primary); outline-offset: -1px; border-color: var(--primary); }
.lf-search .lf-mag {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-hint); font-size: 14px; pointer-events: none;
}
.lf-tools {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 0 10px; border-bottom: 1px solid var(--divider); margin-bottom: 12px;
}
.lf-all { font-size: 13px; font-weight: 600; color: var(--text); }
/* 항목 수와 쪽당 개수가 2026-09-20 에 쪽 넘김 줄에서 여기로 올라왔다 (frame-0069).
   「전체 항목」보다 약하게 보여야 그 라벨이 계속 줄의 머리로 읽힌다. */
.lf-count { font-size: 12px; color: var(--text-hint); }
.lf-count:empty { display: none; }
.lf-tools .lf-per { font-size: 12px; color: var(--text-hint); margin-left: 4px; }
.lf-spacer { flex: 1 1 auto; }
/* 그림 하나만 든 도구 단추. 글자 단추와 높이를 맞추고 가로만 좁힌다. */
.lf-tools .lf-btn.lf-ico {
  width: 32px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
}
.lf-tools .lf-btn {
  height: 32px; padding: 0 11px; border: 1px solid var(--line); border-radius: var(--radius-ctl);
  background: var(--bg); font: inherit; font-size: 12px; color: var(--text-sub); cursor: pointer;
}
.lf-tools .lf-btn:hover:not([disabled]) { background: var(--surface); }
.lf-tools .lf-btn[disabled] { opacity: .45; cursor: not-allowed; }
.lf-view { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-ctl); overflow: hidden; }
.lf-view button {
  width: 34px; height: 32px; border: 0; border-radius: 0; background: var(--bg);
  color: var(--text-hint); font-size: 14px; cursor: pointer; padding: 0;
}
.lf-view button + button { border-left: 1px solid var(--line); }
.lf-view button.active { background: var(--sel-bg); color: var(--text); }

/* 목록 틀의 탭 줄 - 한 화면 안에 목록이 둘 설 때 쓴다. Yodeck 은 Apps 를 이 줄로 갈라
   `My apps`(내가 만든 앱 인스턴스)와 `Discover apps`(고를 수 있는 카탈로그) 둘을 세운다
   (2026-09-20 실측, `docs/qa/yodeck-parity/apps/앱탭-대조표-2026-09-20.md`).
   ⚠ 좌측 메뉴의 탭(`nav.*`)과는 다른 것이다. 이것은 한 메뉴 **안**에서 갈리는 줄이다. */
.lf-tabs {
  display: inline-flex; gap: 4px; padding: 4px; margin-bottom: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-ctl);
}
.lf-tab {
  border: 0; background: transparent; color: var(--text-hint);
  font-size: 13px; font-weight: 600; padding: 7px 16px;
  border-radius: calc(var(--radius-ctl) - 3px); cursor: pointer;
}
.lf-tab:hover:not(.active) { color: var(--text); }
.lf-tab.active { background: var(--bg); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.08); }

/* 기기 축 고르개 (2026-09-21 대표님 지시 - 「템플릿도 기기별로 볼수있게 해놔야할듯」).
   ⚠ 위 `.lf-tabs` 와 **다른 축이다.** 저쪽은 「만들기 전 / 만든 뒤」로 가르고 이쪽은
   그 안에서 다시 기기로 가른다. 두 줄이 세로로 붙으므로 모양을 일부러 다르게 둔다 -
   같은 알약 모양이 두 줄 서면 어느 것이 상위인지 안 보인다. */
.dev-axis { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 16px; }
/* 🔴 `hidden` 속성이 위 `display: flex` 에 덮여 칸이 하나뿐인 축도 보였다 (2026-09-23) */
.dev-axis[hidden] { display: none; }
.ind-axis-n { margin-left: 6px; font-size: 12px; color: var(--text-hint); font-variant-numeric: tabular-nums; }
.dev-axis-btn.active .ind-axis-n { color: inherit; opacity: .75; }
.dev-axis-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text-hint);
  font-size: 13px; font-weight: 600; padding: 8px 14px;
  border-radius: var(--radius-ctl); cursor: pointer;
  transition: border-color .12s, color .12s;
}
.dev-axis-btn:hover:not(.active) { color: var(--text); border-color: var(--text-hint); }
.dev-axis-btn.active {
  border-color: var(--primary); color: var(--primary); background: var(--bg);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.dev-axis-name { white-space: nowrap; }
/* 「보유」 표시. 열다섯 장 중 어느 것이 내 매장에서 쓸 것인지가 고르기 전에 보여야 한다. */
.badge.sm { font-size: 10px; padding: 1px 5px; }

/* 목록이 아직 하나도 없을 때 서는 자리 (`gfEmpty`, 2026-09-20).

   Yodeck 은 탭마다 같은 틀에 문구만 갈아 끼운다 - 큰 제목(`Add your first schedule`) ·
   일러스트 · 설명 한 줄 · 단추 · 투어 링크 다섯이다. 두 탭을 재서 확인했고 근거는
   `docs/qa/yodeck-parity/schedules/Yodeck-Schedules-구조-2026-09-20.md` 에 있다.

   🔑 **설명 한 줄이 「그것이 무엇인가」를 정의한다.** 「눌러서 만드세요」가 아니라
   「스케줄이란 무엇을 언제 틀지 정하는 달력이다」라고 말한다. 처음 온 사람이 그 탭이 무슨
   탭인지 모르는 상태를 전제로 쓴 문구다.

   ⚠ 이것은 `.lf-empty` 와 다른 물건이다. 저쪽은 **검색 결과가 0** 일 때이고 이쪽은
   **아직 하나도 안 만든** 때다. 둘을 합치면 「검색어를 지우세요」와 「첫 줄을 만드세요」가
   같은 자리에서 번갈아 나온다. */
.gf-blank {
  text-align: center; padding: 56px 16px;
  border: 1px dashed var(--line); border-radius: var(--radius-card); background: var(--bg);
}
.gf-blank h2 { font-size: 20px; margin: 0 0 18px; color: var(--text); }
.gf-blank .gf-blank-art {
  display: inline-block; padding: 14px; margin-bottom: 18px;
  border-radius: var(--radius-card); background: var(--surface);
}
.gf-blank .gf-blank-desc {
  font-size: 13px; color: var(--text-sub); margin: 0 auto 20px; max-width: 460px; line-height: 1.6;
}
/* 🔴 단추 색을 여기서 정하지 않는다. `.primary` 가 이미 주계열을 들고 있고, 그 계열이
   파랑인지 주황인지는 `frame-0085` 가 정할 자리다. 여기에 색값을 박으면 그 항목이
   시작하기도 전에 결론이 박힌다. */
.gf-blank .gf-blank-tour {
  display: block; margin-top: 16px; font-size: 13px; color: var(--text-hint);
  background: none; border: 0; cursor: pointer; text-decoration: underline;
}
.gf-blank .gf-blank-tour:hover { color: var(--text); }
html[lang=ko] .gf-blank .gf-blank-desc { word-break: keep-all; overflow-wrap: anywhere; }

.lf-empty { padding: 34px 16px; text-align: center; color: var(--text-hint); line-height: 1.7; }
.lf-empty strong { display: block; color: var(--text); font-size: 14px; margin-bottom: 6px; }

/* 표 보기 - 체크박스 자리는 고른 것으로 할 일이 실제로 있는 목록에만 그린다.
   자료에는 지우기 라우트가 서버에 0개라(`asset.archived_at` 을 쓰는 라우트가 없다)
   체크박스를 주면 「여러 개 골라 지우기」를 약속하게 된다 - 그래서 아직 안 준다. */
.lf-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.lf-table th {
  text-align: left; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  color: var(--text-hint); padding: 0 10px 8px;
  border-bottom: 1px solid var(--divider); white-space: nowrap;
}
.lf-table td { padding: 10px; border-bottom: 1px solid var(--divider); vertical-align: middle; }
.lf-table tbody tr:hover { background: var(--surface); }
.lf-table .lf-c-when { color: var(--text-hint); white-space: nowrap; width: 150px; }
.lf-table .lf-c-act { width: 1%; white-space: nowrap; text-align: right; }
.lf-name-cell { display: flex; align-items: center; gap: 10px; min-width: 0; }
.lf-mini {
  width: 44px; height: 30px; flex: none; border-radius: 5px; background: var(--surface);
  object-fit: cover; display: flex; align-items: center; justify-content: center;
  color: var(--text-hint); font-size: 14px; overflow: hidden;
}
.lf-name-btn {
  border: 0; background: none; padding: 0; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--text); cursor: pointer; text-align: left; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lf-name-btn:hover { color: var(--primary); text-decoration: underline; }
.lf-sub { font-size: 11px; color: var(--text-hint); font-weight: 400; }

/* 격자 보기 */
.lf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 14px; }
.lf-tile {
  border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--bg);
  overflow: hidden; text-align: left; padding: 0; cursor: pointer; font: inherit;
  display: flex; flex-direction: column;
}
.lf-tile:hover { border-color: var(--sel-line); box-shadow: var(--shadow-md); }
.lf-tile.selected { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.lf-shot {
  aspect-ratio: 16 / 9; width: 100%; background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-hint); font-size: 22px; overflow: hidden;
}
.lf-shot img { width: 100%; height: 100%; object-fit: cover; }
.lf-shot { position: relative; }
.lf-shot > .kind-tag { position: absolute; top: 6px; left: 6px; }
.lf-tile-body { padding: 9px 11px 11px; min-width: 0; }
.lf-tile-name {
  font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lf-tile-meta { font-size: 11px; color: var(--text-hint); margin-top: 2px; }
.lf-tile-when { font-size: 11px; color: var(--text-hint); margin-top: 1px; }

/* 쪽 넘김 */
.lf-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 2px 0; margin-top: 12px; border-top: 1px solid var(--divider);
  font-size: 12px; color: var(--text-hint);
}
.lf-per { display: inline-flex; align-items: center; gap: 6px; }
.lf-per select {
  height: 28px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg);
  font: inherit; font-size: 12px; color: var(--text); padding: 0 4px;
}
.lf-pager { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; }
.lf-pager button {
  height: 28px; min-width: 28px; padding: 0 8px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--bg); font: inherit; font-size: 12px;
  color: var(--text-sub); cursor: pointer;
}
.lf-pager button[disabled] { opacity: .4; cursor: not-allowed; }
.lf-pager button.active { background: var(--primary); border-color: var(--primary); color: var(--color-white); font-weight: 600; }

/* 목록 아래 만들기 단추 - Yodeck 과 같은 자리, 같은 두 색 */
.lf-create { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.lf-make {
  height: 40px; padding: 0 18px; border: 0; border-radius: var(--radius-btn);
  background: var(--yd-orange); color: var(--color-white); font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; display: inline-flex; align-items: center; gap: 7px;
}
.lf-make:hover:not([disabled]) { background: var(--yd-orange-dark); }
.lf-make.ai { background: var(--yd-purple); }
.lf-make.ai:hover:not([disabled]) { background: var(--color-purple-900); }
.lf-make[disabled] { opacity: .5; cursor: not-allowed; }

/* 기기 목록은 기존 카드를 그대로 두고 틀만 씌운다 - 매일 확인하는 것이 「살아 있는가」라
   이름과 날짜만 남는 표로 바꾸면 썸네일과 상태 배지가 사라진다(고객역할 검토 2026-09-18).
   그래서 이 목록은 격자 보기가 기본이고 표 보기를 주지 않는다. */
.lf-wrap-hide { display: none !important; }
.grp-collapsed > .mgr-dev, .grp-collapsed > .empty { display: none; }
#device-list.lf-wrap-searching .grp > .mgr-dev:not(.lf-wrap-hide) { display: flex; }
#device-list.lf-wrap-searching .grp-head,
#device-list.lf-wrap-searching .grp-store { display: none; }
#device-list.lf-wrap-searching .grp { margin-bottom: 0; }

.lf-mini img { width: 100%; height: 100%; object-fit: cover; }

/* 재생목록도 같은 틀을 쓰면서 두 칸 배치를 위아래로 편다. Yodeck 은 Playlists 목록이
   Media · Layouts 와 같은 전폭 목록이고, 고른 뒤에 편집 화면이 따라온다. */
.pl-layout { grid-template-columns: 1fr; gap: 26px; }

/* 기기 목록의 「목록 보기」 - 카드를 갈아치우지 않고 빽빽하게만 만든다 */
#device-list.lf-wrap-compact .dev-thumb { display: none; }
#device-list.lf-wrap-compact > * { padding-top: 8px; padding-bottom: 8px; }

/* 좁은 화면에서 목록 틀 */
@media (max-width: 599px) {
  .lf-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
  .lf-table .lf-c-when { display: none; }
  .lf-table th.lf-c-when { display: none; }
  .lf-foot { gap: 8px; }
  .lf-pager { margin-left: 0; }
}

/* --- 회차 안에서 화면을 눈으로 보고 고친 자리 (frame-0054, 2026-09-18) --- */

/* 「쪽당」이 두 줄로 접혀 「쪽 / 당」으로 읽혔다 */
.lf-per span { white-space: nowrap; }
.lf-foot > span:first-child { white-space: nowrap; }

/* 지금 쪽 표시가 파랑이고 바로 아래 만들기 단추가 주황이라, 한 화면에 강조색이 둘이었다.
   이 틀 안의 강조는 Yodeck 에서 실측한 주황 하나로 모은다 */
.lf-pager button.active { background: var(--yd-orange); border-color: var(--yd-orange); }

/* 표 줄이 느슨해서 한 화면에 네 줄밖에 안 들어갔다. Yodeck 목록은 이보다 촘촘하다 */
.lf-table td { padding: 7px 10px; }
.lf-name-cell { line-height: 1.35; }
.lf-sub { line-height: 1.4; }

/* 재생목록 머리의 「새 재생목록」이 파랑이라 목록 아래 주황 만들기 단추와 갈렸다.
   같은 일을 하는 단추는 같은 색이어야 한 벌로 읽힌다 */
#pl-new.primary { background: var(--yd-orange); border-color: var(--yd-orange); }
#pl-new.primary:hover { background: var(--yd-orange-dark); border-color: var(--yd-orange-dark); }

/* --- 「기기에 보내기」 - 오른쪽 위 상시 단추 (계약 §84, frame-0056) ---------------
   Yodeck 은 `Push to Screens` 를 파란 알약으로 두고 바꿀 것이 없으면 회색 `Changes
   pushed` 로 죽인다. 우리도 같은 두 상태인데 **강조색은 주황을 안 쓴다** - 이 틀에서
   주황은 「만들기」 하나이고(frame-0054 가 그렇게 모았다), 같은 화면에 강조색이 둘이면
   먼저 눌러야 하는 것이 안 갈린다. 만들기는 왼쪽 레일, 보내기는 오른쪽 머리글이라
   자리로는 이미 갈려 있고 색까지 같으면 두 주황이 서로를 죽인다. */
.pushbtn {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 38px; padding: 7px 14px; flex: none;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); color: var(--text-sub);
  font: inherit; font-size: 13px; font-weight: 550; white-space: nowrap;
  cursor: pointer;
}
.pushbtn .push-ico { font-size: 11px; opacity: .8; }
.pushbtn:hover { background: var(--surface); }
/* 안 나간 것이 있을 때만 살아난다. 0건에서 파랗게 두면 늘 눌러야 할 것처럼 보이고,
   매일 보는 사람은 이틀이면 그 색을 안 읽는다 */
.pushbtn.has-pending {
  background: var(--primary); border-color: var(--primary); color: var(--color-white);
}
.pushbtn.has-pending:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.pushbtn .push-num {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 999px; background: rgba(255, 255, 255, .24);
  font-size: 12px; font-weight: 700; line-height: 1;
}
@media (max-width: 720px) {
  /* 폰에서는 글자를 접고 아이콘과 숫자만 남긴다 - 머리글에 네 칸이 이미 들어 있다 */
  .pushbtn .push-text { display: none; }
  .pushbtn { padding: 7px 10px; }
}

/* 덮개 안 - 무엇이 나가는지, 누가 고쳤는지, 어느 기기가 받아 갔는지 */
#push-body h3 { margin: 18px 0 8px; font-size: 14px; }
#push-body h3:first-child { margin-top: 0; }
#push-body .push-h-soft { color: var(--text-hint); }
.push-list, .push-devs { list-style: none; margin: 0; padding: 0; }
.push-list.soft { opacity: .72; }
.push-row {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 8px 0; border-bottom: 1px solid var(--divider); font-size: 13px;
}
.push-row .push-kind { color: var(--text-hint); flex: none; }
.push-row .push-title { font-weight: 550; color: var(--text); word-break: keep-all; }
.push-row .push-at, .push-row .push-who { color: var(--text-hint); font-size: 12px; }
.push-row .push-who { margin-left: auto; }
.push-dev {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 0; border-bottom: 1px solid var(--divider); font-size: 13px;
}
.push-dev .push-dot { color: var(--text-hint); font-size: 10px; }
.push-dev.got .push-dot { color: var(--color-green-700); }
.push-dev .push-dev-name { flex: 1; min-width: 0; }
.push-dev .push-dev-state { color: var(--text-hint); font-size: 12px; }
.push-dev.got .push-dev-state { color: var(--color-green-700); }

/* ===================================================================
   Yodeck 실측값 맞추기 - 목록 한 틀의 치수와 기기 탭 상태 띠 (frame-0057, 2026-09-18)

   출처는 `docs/qa/yodeck-parity/reference-measurements.md` 이고, 2026-09-18 20:10 에
   로그인된 Chrome 의 실제 DOM 에서 잰 값이다(viewport 1700×1171).

   🔴 **frame-0054 가 실측과 어긋나게 좁혀 둔 자리를 여기서 되돌린다.** 그 회차는
      「표 줄이 느슨해서 한 화면에 네 줄밖에 안 들어갔다」는 눈대중으로 `td` 의 padding 을
      7px 로 줄였는데, **같은 날 한 시간 앞서 잰 실측은 데이터 행이 72px 였다.** 눈대중이
      실측을 이긴 자리라 실측으로 되돌린다. 촘촘하게 보고 싶은 사람에게는 이미 목록 보기와
      쪽당 25·50 이 있다.

   🔴 **글꼴 이름은 안 베낀다.** Yodeck 본문은 Inter 인데 우리 본문은 Pretendard 로 서 있고,
      한국어 매장 화면에서 Inter 는 한글 글리프가 없어 시스템 글꼴로 떨어진다. 베끼면
      **한글이 Yodeck 보다 나빠진다.** 맞추는 것은 크기(14px)와 본문 색이고 글꼴 가족은
      우리 것을 지킨다. */

/* 검색창 - 실측 width=329 · height=40 · font=16px · border=#c9cacf */
/* 🔴 `min-height` 를 같이 적어야 한다. 1817행의 `input[type=search]` 가 `min-height: 44px`
      를 들고 있어서 `height: 40px` 만으로는 **44px 로 선다** - 오류가 안 나고 화면만 4px
      크다. 실측으로 재기 전까지 아무도 몰랐다.
   ⚠ 폰에서는 44px 를 지킨다. 그 값은 Yodeck 을 베낀 것이 아니라 손가락 표적이다. */
.lf-search input {
  max-width: 329px; height: 40px; min-height: 40px; font-size: 16px; border-color: var(--color-gray-400);
}
@media (max-width: 767px) { .lf-search input { height: 44px; min-height: 44px; } }

/* 표 머리 - 실측 height=42 · 배경 #e7ecf2 */
.lf-table th {
  height: 42px; padding: 0 12px; background: var(--color-gray-200);
  color: var(--text); font-size: 12px; letter-spacing: 0;
}
.lf-table th:first-child { border-top-left-radius: 6px; border-bottom-left-radius: 6px; }
.lf-table th:last-child { border-top-right-radius: 6px; border-bottom-right-radius: 6px; }

/* 데이터 행 - 실측 height=72 · 아래 border=#c9cacf */
.lf-table td { height: 72px; padding: 0 12px; border-bottom-color: var(--color-gray-400); }

/* 기기 탭 상태 띠 - 검색창보다 위에 선다. 기기 탭에 들어온 사람이 먼저 답해야 하는
   물음이 「어느 기기가 죽었나」라 그 답이 쪽 넘김 아래로 내려가면 안 된다 */
#device-status:not(:empty) { margin: 4px 0 14px; }
/* Media selection and preview, following the shared Yodeck list pattern. */
.lf-selectable{position:relative;min-width:0}.lf-selectable .lf-tile{width:100%;height:100%}
.lf-selectable>input{position:absolute;top:12px;left:12px;width:18px;height:18px;accent-color:var(--color-blue-600);cursor:pointer}
.lf-selectable.is-selected{outline:2px solid var(--color-blue-600);border-radius:8px}
.lf-selection{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0}
.lf-selection label{display:flex;align-items:center;gap:8px}.lf-selection input,.lf-check input{width:18px;height:18px;accent-color:var(--color-blue-600)}
.lf-table .lf-check{width:40px;padding:12px}.lf-c-act{white-space:nowrap}
.asset-preview-dialog{width:min(1000px,94vw);max-height:90dvh;border:1px solid var(--color-gray-400);border-radius:8px;padding:24px;color:var(--color-gray-900);background:white}
.asset-preview-dialog::backdrop{background:#1e1c24b3}.asset-preview-dialog header,.asset-preview-dialog footer{display:flex;align-items:center;gap:16px}
.asset-preview-dialog header{justify-content:space-between;margin-bottom:16px}.asset-preview-dialog strong{overflow-wrap:anywhere}
.asset-preview-dialog footer{margin-top:16px;flex-wrap:wrap}.asset-preview-dialog footer span{margin-right:auto;color:var(--color-gray-600)}
.asset-preview-media{display:flex;align-items:center;justify-content:center;background:var(--color-gray-150);min-height:160px}
.asset-preview-media img,.asset-preview-media video{max-width:100%;max-height:65dvh;object-fit:contain}
.lf-sort{border:0;background:transparent;color:inherit;font:inherit;padding:8px 0;cursor:pointer;white-space:nowrap}
.lf-table .lf-c-type{width:120px;white-space:nowrap}
.asset-row-menu{position:relative;display:inline-block;text-align:left}
.asset-row-menu>summary{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:4px;cursor:pointer;list-style:none;font-size:24px}
.asset-row-menu>summary::-webkit-details-marker{display:none}
.asset-row-menu>summary:hover,.asset-row-menu[open]>summary{background:var(--color-gray-200)}
.asset-row-options{position:absolute;right:0;top:100%;z-index:50;min-width:180px;padding:6px;background:white;border:1px solid var(--color-gray-400);border-radius:6px;box-shadow:0 4px 16px #1e1c2426}
.asset-row-options>.sm{display:block;width:100%;text-align:left;margin:0;padding:10px 12px;border:0;background:white;box-sizing:border-box;text-decoration:none}
.asset-row-options>.sm:hover{background:var(--color-gray-150)}
.asset-row-options>button.danger { color:var(--danger); }
.asset-confirm-dialog{width:min(480px,92vw);max-height:90dvh;box-sizing:border-box;padding:24px;border:1px solid var(--color-gray-400);border-radius:8px;background:white;color:var(--color-gray-900)}
.asset-confirm-dialog::backdrop{background:#1e1c2480}
.asset-confirm-dialog h2{margin:0 0 16px;font-size:20px}
.asset-confirm-dialog p{line-height:1.6;white-space:pre-line}
.asset-confirm-dialog footer{display:flex;justify-content:flex-end;gap:12px;margin-top:24px}
.asset-availability-form>label{display:flex;flex-direction:column;gap:6px;margin:14px 0}
.asset-availability-form>label:has(input[type=checkbox]){flex-direction:row;align-items:center;gap:8px}
.asset-availability-form input[type=checkbox]{margin:0;width:auto}
.lf-tools select.lf-btn{width:auto;max-width:100%;margin:0}
.asset-weekly-dialog{width:min(580px,96vw);margin:30px auto auto;padding:0}
.asset-weekly-dialog h2{font-size:18px;font-weight:500;padding:20px;margin:0;border-bottom:1px solid var(--color-gray-300)}
.asset-weekly-dialog form>p{margin:18px 20px}
.asset-weekly-dialog table{width:calc(100% - 30px);border-collapse:collapse;margin:20px 15px 0;font-size:13px}
.asset-weekly-dialog th,.asset-weekly-dialog td{padding:10px 6px;border:1px solid var(--color-gray-300);text-align:left}
.asset-weekly-dialog th{font-weight:500;background:var(--color-gray-150)}
.asset-weekly-dialog input[type=time]{width:108px;min-width:0;padding:5px 0;margin:0;border:0;box-shadow:none;font-size:12px}
.asset-weekdays{white-space:nowrap}
.asset-weekdays label{position:relative;display:inline-block;margin:2px}
.asset-weekdays input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.asset-weekdays span{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:30px;border:1px solid var(--color-gray-500);border-radius:6px}
.asset-weekdays input:checked+span{background:var(--color-gray-500);color:white}
.asset-weekdays input:focus-visible+span{outline:2px solid var(--color-blue-600);outline-offset:2px}
.asset-weekly-dialog .asset-weekly-add{width:calc(100% - 30px);margin:0 15px 20px;border-radius:0 0 6px 6px}
.asset-weekly-dialog footer{background:var(--color-gray-150);margin-top:24px;padding:16px;gap:16px}
.asset-weekly-dialog footer button{min-width:84px;height:40px}
.asset-weekly-dialog footer .primary{background:var(--color-blue-600);border-color:var(--color-blue-600)}
.asset-weekly-close{position:absolute;right:16px;top:12px;border:0;background:none;color:var(--color-gray-500);font-size:22px;padding:3px 5px}
.media-edit-back{border:0;background:none;padding:0;margin:0 0 16px;color:var(--color-gray-800);min-height:0;height:20px;line-height:20px}
.media-edit-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:28px;gap:20px}
.media-edit-heading h1{font-size:20px;font-weight:500;margin:0}
.media-edit-buttons{display:flex;gap:16px}
.media-edit-buttons button{min-width:86px;min-height:40px;height:40px}
.media-edit-buttons .primary{background:var(--color-blue-600);border-color:var(--color-blue-600)}
.media-edit-delete{color:var(--color-blue-800);background:none;border:1px solid var(--color-gray-400)}
.media-edit-columns{display:grid;grid-template-columns:1fr 2.05fr;gap:24px;align-items:start}
.media-edit-details,.media-edit-settings{margin:0;padding:20px;background:var(--color-white);border:0;border-radius:8px;min-width:0;box-shadow:0 3px 12px #29283309}
.media-edit-columns h2{font-size:13px;font-weight:500;margin:0 0 30px;padding:0 0 8px;border-bottom:1px solid var(--color-gray-300);text-transform:uppercase}
.media-edit-preview{border:1px solid var(--color-gray-300);aspect-ratio:1.6;display:flex;align-items:center;justify-content:center;margin:32px 0}
.media-edit-preview img,.media-edit-preview video,.media-edit-preview iframe{width:100%;height:100%;object-fit:contain;border:0}
.media-edit-details dl{display:grid;grid-template-columns:100px 1fr;gap:12px;margin:24px 0 0;padding:24px;background:var(--color-gray-150);border-radius:8px;font-size:12px}
.media-edit-details dt{text-align:right;color:var(--color-gray-600)}.media-edit-details dd{margin:0;overflow-wrap:anywhere}
.media-edit-row{display:grid;grid-template-columns:170px minmax(0,450px);gap:20px;align-items:center;margin:24px 0}
.media-edit-row>label{text-align:right;font-size:14px}.media-edit-row input,.media-edit-row textarea{margin:0}
.media-edit-row input[type=number]{width:104px}.media-edit-row input[type=checkbox]{appearance:none;width:40px;height:24px;border:0;border-radius:20px;background:var(--color-gray-200);position:relative;cursor:pointer}
.media-edit-row input[type=checkbox]::before{content:'';display:block;width:22px;height:22px;position:absolute;left:1px;top:1px;background:white;border-radius:50%;box-shadow:0 1px 5px #0003}
.media-edit-row input[type=checkbox]:checked{background:var(--color-blue-600)}.media-edit-row input[type=checkbox]:checked::before{transform:translateX(16px)}
.media-edit-row textarea{min-height:90px;width:100%}
.media-description-add,.media-weekly-link{border:0;background:none;padding:0;text-align:left;min-height:32px}
.media-description-add[hidden],.media-edit-row textarea[hidden]{display:none!important}
.media-weekly-link{color:var(--color-blue-600);margin-top:16px;font-size:13px}
.media-edit-tag-chips{display:contents}.media-edit-tag-chips button{border:0;background:none;padding:0 3px;min-height:0}
.media-edit-tags{position:relative;width:fit-content;min-width:192px;max-width:450px}
.media-tag-control{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:5px;min-height:44px;border:1px solid var(--color-gray-400);border-radius:3px;padding:5px 12px;background:white}
.media-tag-control:focus-within{border-color:var(--color-blue-600)}.media-tag-icon{color:var(--color-gray-500);font-size:18px}.media-tag-control input{border:0!important;box-shadow:none!important;outline:none;flex:1 1 100px;width:100px!important;min-width:75px;max-width:100%;padding:4px!important;min-height:30px}
.media-tag-control .asset-tag{background:var(--color-gray-200);border:1px solid var(--color-gray-300);color:var(--color-gray-700);border-radius:3px;padding:2px 5px;font-size:13px;max-width:100%;overflow-wrap:anywhere}
.media-tag-suggestions{position:absolute;top:100%;left:-1px;right:-1px;z-index:10;max-height:220px;overflow:auto;background:white;border:1px solid var(--color-gray-400);border-radius:0 0 3px 3px;box-shadow:0 4px 7px #0002}
.media-tag-suggestions[hidden]{display:none!important}.media-tag-suggestions [role=option]{padding:9px 14px;cursor:pointer;overflow-wrap:anywhere}.media-tag-suggestions [role=option]:hover,.media-tag-suggestions [aria-selected=true]{background:var(--color-gray-150)}
.media-manage-tags{display:block;text-align:left;margin-top:8px;color:var(--color-blue-600);text-decoration:none;font-size:14px}
.media-tag-search{margin:32px 0 0}.media-tag-search input{width:330px;max-width:100%;height:40px;border-radius:3px}
.media-tag-tools{height:112px;position:relative;display:flex;align-items:flex-end;padding-bottom:22px}.media-tag-tools>button{position:absolute;right:0;top:22px;width:40px;height:40px;padding:0;background:white;border-radius:4px}
.media-tag-sort{border:0;background:none;padding:0;min-height:0;text-transform:uppercase;font-size:12px}.media-tag-sort:hover{background:none}
#panel-media-tags>h1{font-size:24px;font-weight:400;margin:0}#panel-media-tags>.media-edit-back[hidden]{display:none!important}
@media(min-width:1024px){#panel-media-tags{margin:0 -28px}}
.media-tag-table{width:100%;border-collapse:collapse;background:transparent}.media-tag-table th,.media-tag-table td{padding:14px 20px;border-bottom:1px solid var(--color-gray-300);text-align:left}.media-tag-table th{background:var(--color-gray-200);color:var(--color-gray-700);font-weight:400;font-size:12px;line-height:18px;padding:12px 20px;height:42px}.media-tag-table th:last-child{width:150px}.media-tag-table tbody::before{content:'';display:table-row;height:22px}.media-tag-table td{background:white;height:70px}
.media-tag-name{background:none;border:0;padding:0;color:inherit;text-align:left}.media-tag-footer{margin-top:48px}.media-tag-form>.media-edit-buttons{justify-content:flex-end;margin-bottom:28px}.media-tag-form>label{display:flex;gap:60px;align-items:center;background:white;padding:32px}.media-tag-form input{width:360px;max-width:70%}
#panel-media-tags .primary{background:var(--color-blue-600);border-color:var(--color-blue-600)}#panel-media-tags .primary:hover{background:var(--color-blue-600);border-color:var(--color-blue-600)}
.media-edit-settings .media-availability-heading{margin-top:64px;margin-bottom:24px}
.media-period-dates{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:0 0 36px 190px;max-width:450px}
.media-period-dates label{display:block;font-size:13px}.media-period-dates input[type=datetime-local]{margin-top:6px;width:100%;min-width:0;font-size:12px;padding:10px 8px}
.media-period-dates .media-nonexpiring{display:flex;align-items:center;gap:6px;margin-top:16px}.media-nonexpiring input{width:auto;margin:0}
@media(min-width:1024px){body.editing-media .topbar{position:fixed;top:0;left:0;margin-left:0;width:var(--rail-w);height:76px;z-index:35}body.editing-media .topbar .wrap{padding:20px}body.editing-media .topbar .wrap>:not(.brand),body.editing-media .topbar .tag,body.editing-media .topbar .org{display:none}body.editing-media .tabbar{top:76px}body.editing-media main{max-width:none;padding:24px 28px 72px}}
@media(max-width:1100px){.media-edit-columns{grid-template-columns:1fr}.media-edit-preview{max-height:320px}.media-edit-row{grid-template-columns:140px 1fr}.media-period-dates{margin-left:160px}}
@media(max-width:600px){.media-edit-row{grid-template-columns:1fr;gap:6px}.media-edit-row>label{text-align:left}.media-period-dates{margin-left:0;grid-template-columns:1fr}.media-edit-buttons{gap:6px}.media-edit-buttons button{min-width:54px}.media-edit-details dl{padding:12px;grid-template-columns:80px 1fr}}
@media(max-width:620px){.asset-weekdays{white-space:normal}.asset-weekly-dialog th,.asset-weekly-dialog td{padding:5px 3px}}
.asset-upload-dialog{width:min(800px,94vw);max-height:90dvh;box-sizing:border-box;padding:24px;border:1px solid var(--color-gray-400);border-radius:8px;background:white;color:var(--color-gray-900)}
.asset-upload-dialog::backdrop{background:#1e1c2480}
.asset-upload-dialog header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:24px}
.asset-upload-dialog h2{margin:0;font-size:20px}
#asset-add{margin-top:20px;background:var(--primary);border-color:var(--primary);color:white}
#asset-lf .lf-selection{justify-content:flex-end}
#asset-lf .lf-bottom-actions { justify-content:flex-start; gap:12px; margin-top:18px; padding:0; }
#asset-lf .lf-bottom-actions #asset-add { margin-top:0; }
.asset-bulk-menu { position:relative; }
.asset-bulk-menu > summary { cursor:pointer; list-style:none; padding:11px 18px; border:1px solid var(--color-gray-300); border-radius:6px; background:white; font-weight:600; }
.asset-bulk-menu > summary::after { content:' ▾'; }
.asset-bulk-menu > summary::-webkit-details-marker { display:none; }
.asset-bulk-menu .asset-row-options { left:0; right:auto; bottom:calc(100% + 5px); top:auto; min-width:180px; z-index:20; }
.asset-preview-media iframe{width:100%;height:65dvh;border:0;background:white}
.asset-upload-dialog .segtog{margin-bottom:20px}
.lf-search > .lf-btn { flex:none; width:auto; margin:0 8px; }
.lf-tag-status:empty { display:none; }
.lf-tag-status { display:flex; align-items:center; gap:12px; margin:8px 0; }
.lf-tag { display:inline-block; padding:2px 8px; margin:2px; border-radius:4px; background:var(--color-gray-200); color:var(--color-gray-700); font-size:12px; overflow-wrap:anywhere; }
.lf-tags { max-width:240px; }
.asset-tag-field { margin:16px 0; }
.asset-tag-field label { display:flex; align-items:center; gap:8px; margin-bottom:8px; }
.asset-tag-field input[type=checkbox] { width:auto; }
.asset-playlist-choices { max-height:320px; overflow:auto; margin-top:12px; }
.asset-playlist-choices label { display:flex; align-items:center; gap:10px; padding:10px 4px; }
.asset-playlist-choices input { width:18px; height:18px; flex:none; }
.asset-folder-path,.asset-folder-children { display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin:12px 0; }
.asset-folder-children:empty { display:none; }
.asset-folder-children button { min-width:140px; text-align:left; padding:14px; }
.asset-folder-card { display:flex; gap:2px; }
.asset-folder-card button:last-child { min-width:40px; padding:10px; text-align:center; }
.media-usage-link{display:block;margin:24px auto 0;border:0;background:none;text-decoration:underline;font-size:14px;font-weight:400}
.media-usage-dialog{width:min(580px,94vw);padding:0;margin:30px auto auto;border:0;border-radius:8px;overflow:hidden;box-shadow:0 3px 12px #0003}
.media-usage-dialog header{display:flex;align-items:center;justify-content:space-between;padding:16px 22px;border-bottom:1px solid var(--color-gray-400);height:56px;box-sizing:border-box}
.media-usage-dialog header h2{margin:0;font-size:18px;font-weight:500}
.media-usage-dialog header button{padding:0;border:0;background:none;font-size:22px;color:var(--color-gray-500);min-height:0;line-height:1}
.media-usage-body{padding:20px;min-height:180px;max-height:60vh;overflow:auto;box-sizing:border-box;font-size:14px}
.media-usage-body summary{cursor:pointer;list-style:none;padding:8px 0 18px;border-bottom:1px solid var(--color-gray-400)}
.media-usage-body summary::after{content:'⌄';float:right}
.media-usage-body details:not([open]) summary::after{content:'›'}
.media-usage-body ul{padding-left:40px;margin:20px 0 30px;color:var(--color-gray-600)}
.media-usage-body a{color:var(--color-blue-600);text-decoration:none;overflow-wrap:anywhere}
.media-usage-body a:hover{text-decoration:underline}
.media-usage-dialog footer{display:flex;justify-content:flex-end;padding:16px;background:var(--color-gray-150);margin:0}
.media-usage-dialog footer button{min-width:86px;min-height:40px;background:var(--color-blue-600);border-color:var(--color-blue-600);color:var(--color-white)}
.media-save-group{display:flex;position:relative}
.media-edit-buttons .media-save-group>button:first-child{border-radius:7px 0 0 7px;min-width:72px}
.media-edit-buttons .media-save-toggle{min-width:34px;width:34px;padding:0;border-radius:0 7px 7px 0;border-left:1px solid #ffffff50}
.media-save-menu{position:absolute;top:calc(100% + 5px);right:0;z-index:30;min-width:200px;padding:6px 0;background:white;border:1px solid var(--color-gray-200);border-radius:6px;box-shadow:0 5px 14px #0002}
.media-save-menu[hidden]{display:none}
.media-edit-buttons .media-save-action{width:100%;height:auto;min-height:28px;border:0;border-radius:0;background:white;color:var(--color-gray-800);font-size:14px;font-weight:400;text-align:left;white-space:nowrap;padding:6px 12px}
.media-save-action:hover,.media-save-action:focus-visible{background:var(--color-gray-150)}
#panel-media-edit .media-save-toggle[aria-expanded=true],#panel-media-edit .media-save-toggle:hover{background:var(--color-blue-600);border-color:var(--color-blue-600);color:white}
.media-screens-dialog{width:min(600px,94vw);padding:0;margin:30px auto auto;border:0;border-radius:8px;overflow:hidden;box-shadow:0 3px 12px #0003}
.media-screens-dialog header{height:56px;padding:16px 22px;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-gray-400)}
.media-screens-dialog header h2{font-size:18px;font-weight:500;margin:0}
.media-screens-dialog header button{border:0;padding:0;background:none;font-size:22px;min-height:0;color:var(--color-gray-500)}
.media-screens-body{padding:32px 20px;min-height:350px;box-sizing:border-box;max-height:65vh;overflow:auto}
.media-screen-row{display:grid;grid-template-columns:104px 1fr;gap:14px;margin:10px 0 26px;align-items:start;font-size:14px}
.media-screen-row>label,.media-screen-row>span:first-child{text-align:right;color:var(--color-gray-600)}
.media-screen-choices{max-height:160px;overflow:auto;border:1px solid var(--color-gray-200);border-top:0;padding:4px 10px}
.media-screen-choices label{display:flex;align-items:center;gap:8px;padding:8px 0;font-size:14px}
.media-screen-choices input{width:16px;height:16px;flex:none}
.media-screen-chips{display:flex;flex-wrap:wrap;gap:4px}
.media-screen-chips button{padding:4px 8px;border:0;font-size:12px;min-height:0;margin-bottom:6px;background:var(--color-gray-200)}
.media-screens-dialog footer{margin:0;padding:16px;display:flex;justify-content:flex-end;gap:16px;background:var(--color-gray-150)}
.media-screens-dialog footer button{min-height:40px}
.media-screens-dialog footer .primary{background:var(--color-blue-600);border-color:var(--color-blue-600);color:white}
.media-screens-dialog [hidden]{display:none!important}
.media-screen-types{display:flex;flex-wrap:wrap;gap:18px}
.media-screen-types label{display:flex;align-items:center;gap:6px;font-size:14px}
.media-screen-types input{width:18px;height:18px;margin:0}
@media(max-width:600px){.media-screen-row{grid-template-columns:1fr;gap:6px}.media-screen-row>label,.media-screen-row>span:first-child{text-align:left}}

/* 지금 화면 (frame-0061, 계약 §87). 기기가 올린 그림 한 장을 모달에 띄운다.
   🔴 `.stale` 은 장식이 아니다 - 낡은 그림을 지금 것으로 읽는 것이 이 기능의 유일한
   치명적 실패 방식이라, 글로만 적으면 크고 선명한 그림이 작은 글을 이긴다. */
.shot-frame{display:flex;align-items:center;justify-content:center;background:var(--color-gray-1000);
  border-radius:6px;min-height:200px;margin:10px 0;overflow:hidden}
.shot-img{max-width:100%;max-height:60vh;display:block}
.shot-img.stale{filter:grayscale(.7) brightness(.62)}
.shot-empty{color:var(--color-gray-500);font-size:14px;padding:40px 16px;text-align:center}

/* ============================================================ 대시보드 (frame-0063)
   Yodeck Dashboard 실측 2026-09-19 을 그대로 옮긴 값이다. 기준은
   `docs/qa/yodeck-parity/reference-measurements.md` 의 Dashboard 절.
   제목 24px/400 · 본문 x=243 · 첫 행 y=170 · 열 341/341/703 · 간격 20 ·
   카드 흰 배경 radius 5 padding 14/18/20 그림자 0 4px 21px rgba(0,0,0,.05).

   🔴 **숫자를 반올림하지 않았다.** 5px 을 6px 으로, 20px 을 24px 로 바꾸면 우리 기존
   토큰과는 맞아도 나란히 놓았을 때 눈에 보이는 차이가 남는다. 대표님 지시가 「배치뿐
   아니라 간격도 대상」이라 실측값을 그대로 쓴다. */
/* (2026-09-23 이후 두 「주황」 토큰 모두 gency 파랑 값이다. 아래는 그 전 사정이다.)
   🔴 **`--yd-orange` 를 덮어쓰지 않는다.** 그 토큰은 이미 `#F58220`(Yodeck 의 Create New
   Layout 단추 실측)을 담고 있고, 여기서 다시 선언하면 뒤에 오는 이 줄이 이겨 **만들기
   단추 색이 조용히 바뀐다.** 대시보드 환영 카드의 주황은 실측이 `#F26F26` 으로 다른
   값이라 이름을 따로 둔다. 같은 「주황」이라는 말에 값이 둘인 것이 원인이다. */
:root { --yd-hello-orange: var(--color-blue-600); --yd-card-shadow: 0 4px 21px rgba(0, 0, 0, .05); }

/* 대시보드만 본문 폭을 다 쓴다. Yodeck 은 `max-width` 없이 좌우 32px 여백만 둔다.
   ✅ 3열이 실측 703 으로 선다. 한동안 698 이었고 남는 5px 는 이 화면이 아니라 **좌측 메뉴
   폭**에서 왔다 - `frame-0054` 가 216 으로 두었는데 Yodeck 실측은 211 이다. `frame-0065`
   에서 211 로 내리며 이 칸이 같이 맞았다.
   🔑 **한 화면에서 어긋난 값의 원인이 그 화면 밖에 있을 수 있다.** 여기서 5px 를 더해
   맞췄으면 숫자는 맞고 나머지 화면 전부가 그만큼 틀어졌을 것이다. */
body.on-dashboard main.wrap { max-width: none; padding-left: 32px; padding-right: 32px; }

.dash-head { margin: 0 0 28px; }
/* Yodeck 제목은 굵지 않다. 24px 에 weight 400 이고, 굵게 하면 그것만 튄다. */
.dash-title { font-size: 24px; font-weight: 400; line-height: 29px; margin: 0; color: var(--ink); }

/* 열 셋. 앞 둘은 341 고정이고 셋째만 늘어난다 - Yodeck 지도 칸이 703 으로 혼자 넓다.
   ⚠ 1700px 미만에서는 셋이 안 들어간다. 우리 화면은 1440 을 자주 쓰므로 접는다. */
/* 🔴 **열 폭을 341 에서 258 로 줄여 3열이 1440 에서 살아난다** (2026-09-20, 대표님 지시
   「대시보드와 에디터 최대한 yodeck과 동일하게해」).
   341+341+703 은 간격을 더하면 **1,425px** 를 요구하는데 이 화면의 본문은 1,086px 다.
   그래서 아래 미디어 쿼리가 늘 걸려 **1440 에서도 2열로 접혔고**, 접힌 열이 아래로
   쌓이면서 페이지가 2,146px 이 됐다. Yodeck 은 그보다 좁은 1147 폭에서도 3열을 지키고
   대시보드가 한 화면에서 끝난다.
   **저쪽 실측 비율은 24.6 : 24.8 : 50.6 이다**(본문 959 = 229 + 231 + 471 + 간격 14 둘).
   우리 본문 1,086 에 같은 비율을 씌우면 257 + 260 + 529 이고, 앞 둘을 258 로 맞췄다.
   ⚠ **줄이는 쪽이라 카드 안이 넘칠 수 있다.** 이 저장소 주석이 「341 은 카드 안 내용이
   맞춰져 있어 늘리면 글자만 흩어진다」고 경고해 둔 자리이고, 줄이는 것은 반대 방향의
   같은 위험이다. 그래서 바꾼 뒤 카드 안에서 `scrollWidth > clientWidth` 인 요소를 전수로
   재어 넘치는 것이 없음을 확인했다. 폭을 다시 건드리면 그 측정을 다시 한다. */
.dash-grid { display: grid; grid-template-columns: 258px 258px minmax(0, 1fr);
  gap: 20px; align-items: start; }
.dash-col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

.dash-card { background: var(--color-white); border-radius: 5px; padding: 14px 18px 20px;
  box-shadow: var(--yd-card-shadow); min-width: 0; }
/* Yodeck 카드 제목은 16px / weight 400 이다. 우리 h2 기본값이 훨씬 굵어 따로 적는다. */
.dash-card-title { font-size: 16px; font-weight: 400; line-height: 28px; margin: 0 0 6px;
  color: var(--ink); }
/* 실측 높이. 안이 비어도 카드가 쪼그라들지 않는다 - Yodeck 은 기기 0대일 때도 420 을
   그대로 두고 그 안에서 「아직 없습니다」라고 말한다. */
.dash-card-tall { min-height: 420px; }
/* 🔴 **640 은 Yodeck 의 지도 칸 높이다. 우리는 아직 지도가 없다.**
   그쪽 오른쪽 열은 `Screen Locations` 지도가 575~640 을 꽉 채우고, 그 덩어리가 화면
   전체를 붙잡아 주기 때문에 옆 카드 아래가 남아도 허전해 보이지 않는다. 우리는 그
   자리에 안내문 카드(`#dash-start`)를 넣고 높이만 가져왔고, 실측하니 640 중 **417 이
   빈 흰색**이었다(2026-09-20. 내용은 223 뿐이다). 대표님이 「대시보드 화면 전체
   개선필요함」으로 짚으신 자리에서 가장 큰 덩어리가 이것이었다.
   **높이를 베끼면서 그 높이를 채우는 것을 안 베끼면, 같은 숫자가 반대 뜻이 된다.**
   ⚠ 되돌릴 조건 - 기기 지도(frame-0064)가 이 칸에 들어오면 그때 640 을 되살린다.
   그때는 이 숫자가 채워지는 높이라서 원래 뜻대로 맞는다. */
.dash-card-tallest { min-height: 0; }

.dash-hello { background: var(--yd-hello-orange); color: var(--color-white); min-height: 200px;
  padding: 40px 18px 20px; display: flex; flex-direction: column; gap: 14px; }
.dash-hello-text { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.4; color: var(--color-white); }
.dash-hello-sub { margin: 0; font-size: 14px; line-height: 1.55; color: var(--color-white); opacity: .92; }
.dash-hello-btn { align-self: flex-start; margin-top: auto; border: 0; cursor: pointer;
  background: var(--color-white); color: var(--yd-hello-orange); font-weight: 600; font-size: 14px;
  border-radius: 8px; padding: 10px 16px; }
.dash-hello-btn:hover { background: var(--color-blue-100); }

/* 카드 안의 빈 상태. Yodeck 은 「You have not added any screens yet!」 을 16px/500 으로
   적고 그 아래 설명 두 줄을 회색으로 둔다. */
.dash-empty-title { font-size: 16px; font-weight: 500; margin: 14px 0 6px; color: var(--ink); }
.dash-empty-body { font-size: 13px; line-height: 1.6; color: var(--muted); margin: 0; }

.dash-line { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0;
  font-size: 13px; border-bottom: 1px solid var(--line); }
.dash-line:last-child { border-bottom: 0; }
.dash-line .dash-line-k { color: var(--muted); }
.dash-line .dash-line-v { font-weight: 600; color: var(--ink); }

/* 매장 공지 (2026-09-23). 걸린 것은 브랜드 색 띠로 두어 「지금 매장에 나가는 중」이
   입력 칸과 섞이지 않게 한다. 258px 칸이라 입력 요소는 전부 한 줄씩 쌓는다. */
.dash-notice-live { border-left: 3px solid var(--primary); background: var(--color-blue-50);
  padding: 8px 10px; margin: 0 0 10px; }
.dash-notice-text { margin: 0; font-size: 13px; font-weight: 600; color: var(--ink);
  line-height: 1.45; overflow-wrap: anywhere; }
.dash-notice-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 4px; font-size: 12px; color: var(--muted); }
.dash-notice-meta .sm { padding: 2px 8px; }
.dash-notice-form { display: flex; flex-direction: column; gap: 8px; }
.dash-notice-form input, .dash-notice-form select { width: 100%; box-sizing: border-box; }
.dash-notice-spans { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }
.dash-notice-spans .chip { padding: 4px 0; font-size: 12px; justify-content: center; text-align: center; }
.dash-notice-hint { font-size: 12px; }

/* 업종 템플릿 입구. 넓은 3열에서 네 장이 한 줄이고, 좁아지면 둘씩 접힌다. */
.dash-tpl-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.dash-tpl { display: flex; flex-direction: column; gap: 6px; text-decoration: none; color: var(--ink);
  font-size: 12px; min-width: 0; }
.dash-tpl img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 4px;
  border: 1px solid var(--line); background: var(--surface); transition: box-shadow .15s; }
.dash-tpl:hover img { box-shadow: 0 0 0 2px var(--primary); }
.dash-tpl span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 900px) { .dash-tpl-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* 최근 활동은 Yodeck 처럼 시각을 회색 작은 글씨로 위에, 내용을 아래에 둔다. */
.dash-act { padding: 8px 0; border-bottom: 1px solid var(--line); }
.dash-act:last-child { border-bottom: 0; }
.dash-act-when { display: block; font-size: 12px; color: var(--muted); }
.dash-act-what { font-size: 13px; line-height: 1.5; color: var(--ink); }
.dash-act-what em { font-style: normal; color: var(--yd-hello-orange); }
.dash-scroll { max-height: 128px; overflow-y: auto; }

/* 셋이 안 들어가면 넓은 칸을 아래로 내린다.
   🔴 **임계를 1699 에서 1241 로 내렸다** (2026-09-20). 1699 는 열 폭이 341 이던 때의
   값인데, 그 조합은 1,425px 를 요구해서 **1440 짜리 화면에서도 늘 이 규칙이 걸렸다** -
   3열로 적어 놓고 한 번도 3열로 서지 못한 셈이다. 258 로 줄인 지금은 본문 960 이면
   3열이 서고, 그 960 은 Yodeck 이 실제로 3열을 유지하는 폭(959)과 같다.
   1241 = 본문 960 + 왼쪽 메뉴 210 + 좌우 여백 72 다. */
@media (max-width: 1241px) {
  .dash-grid { grid-template-columns: 258px minmax(0, 1fr); }
  .dash-col-wide { grid-column: 1 / -1; }
}
@media (max-width: 899px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr); }
  .dash-col-wide { grid-column: auto; }
  .dash-card-tall, .dash-card-tallest { min-height: 0; }
}

/* 🔴 **넓은 칸도 화면 한 장 안에서 끝난다.** Yodeck 3열은 860px 로 못 박혀 있고 안이
   넘치면 그 안에서 스크롤한다. 우리 첫 판은 이것을 안 두어 기기 12대짜리 계정에서
   페이지가 4,407px 가 됐다 - 대시보드인데 스크롤을 다섯 번 해야 아래 카드가 나온다.
   **한눈에 본다는 것이 이 화면의 전부이고, 길어지는 순간 그 뜻이 사라진다.** */
/* 🔴 **세 열이 전부 860 에서 끝난다.** Yodeck 실측이 그렇다 - 1열 200+420+200,
   2열 640+200, 3열 860 이고 간격 20 을 더하면 셋 다 860 이다. 그래서 대시보드가
   화면 한 장에 들어간다. 우리 3열에는 카드가 둘이므로 420 씩 나눠 같은 합을 만든다.
   ⚠ 420 안에서 매장 카드를 다 보기는 좁다. **그것이 맞다** - 여기는 한눈에 보는
   자리이고 자세히 보는 자리는 「기기」 탭이다. 둘을 한 화면에서 겸하려다 4,407px 가 됐다. */
/* ⚠ 420 에서 560 으로 올렸다(2026-09-20). 원래 값의 근거는 「Yodeck 3열이 860 에서
   끝나므로 우리도 한 화면 안에서 끝낸다」인데, **그 전제가 이 페이지에서는 이미
   깨져 있었다** - 대시보드 전체가 2,146px 이라 어차피 굴려야 한다. 그 상태에서 이
   카드만 420 으로 가두면 한 화면에 담기는 것이 아니라 **잘린 것이 어디에도 안 보이게
   될 뿐이다.** 실측으로 매장 셋 중 하나가 통째로 스크롤 밖에 있었고, 그 안에 이
   계정의 유일한 실기기가 들어 있었다.
   🔴 그래도 상한을 없애지는 않는다. 기기 12대 계정에서 페이지가 4,407px 이 된 사고가
   이 값을 만든 이유이고 그 위험은 그대로다. **전체 구조(3열 · 지도)를 Yodeck 과 맞추는
   판에서 이 카드의 자리 자체를 다시 정하고, 그때 이 숫자도 같이 다시 잰다.** */
.dash-col-wide .dash-card { display: flex; flex-direction: column; max-height: 560px; }
/* 🔴 **가로축을 반드시 같이 적는다.** `overflow-y: auto` 만 주면 가로축의 `visible` 이
   CSS 규칙에 따라 `auto` 로 승격된다 - 한 축이 `visible` 이 아니면 다른 축의 `visible` 은
   계산값이 `auto` 가 된다. 그래서 세로 막대가 생기는 순간 그것이 먹은 폭만큼 안쪽이
   넘쳐 **가로 막대까지 같이 뜬다.** 2026-09-20 에 대표님이 「기기현황쪽 스크롤이
   이상하게 뜨고」로 짚으신 자리이고, 실측값이 그대로였다(세로 455 넘침 · 가로 10 넘침,
   그 10 이 막대 폭이다). 막대 둘이 직각으로 붙은 상자는 내용이 아니라 고장으로 읽힌다.
   `scrollbar-gutter: stable` 은 막대 자리를 미리 비워 두어, 내용이 늘어 막대가 생기는
   순간 안쪽 글이 옆으로 밀리는 것도 같이 막는다. */
.dash-col-wide .dash-card > #board-stores,
.dash-col-wide .dash-card > .lib-grid {
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-gutter: stable;
  min-height: 0;
}

/* 🔴 **기기가 없는 매장이 있는 매장과 같은 자리를 먹고 있었다.** 실측(2026-09-20,
   매장 둘 + 미배정 하나) - 빈 매장 둘이 190px 씩 가져가고, 정작 기기가 실제로 들어
   있는 섹션 374px 는 통째로 잘려 스크롤 밖에 있었다. 대시보드가 위에서는 「빈 자리
   1대」라고 알리면서 그 한 대를 보려면 카드 안을 굴려야 했다.
   **비어 있다는 사실은 한 줄이면 전해지고, 자리를 먹어야 하는 쪽은 실물이다.**
   ⚠ `.empty` 는 이 저장소에서 여덟 곳 넘게 쓰는 공용 칸이라 값을 여기서 바꾸지 않고
   `#board-stores` 안쪽으로만 좁혀 적는다. 자료 목록과 공간 탭의 빈 상태는 화면 하나를
   통째로 채우는 자리라 지금 크기가 맞다. */
#board-stores .empty {
  padding: 14px 16px;
  text-align: left;
  font-size: 12px;
  border-radius: var(--radius-ctl);
  /* `.dev-grid` 는 기기 카드를 여러 칸으로 까는 격자다. 빈 상태는 카드가 아니라
     그 줄 전체가 하는 말이므로 한 칸에 갇히면 왼쪽 1/3 만 쓰고 오른쪽이 빈다.
     줄 전체를 쓰게 해야 글과 상자의 폭이 같은 뜻을 갖는다. */
  grid-column: 1 / -1;
}
/* 매장 사이 간격도 같이 좁힌다. 28px 은 한 매장이 카드 여러 장을 가질 때의 값이고,
   한 줄짜리 빈 매장이 이어질 때는 그 간격이 내용보다 커진다. */
#board-stores .store-sec { margin-bottom: 18px; }
#board-stores .store-sec:last-child { margin-bottom: 0; }

/* 🔴 **가로로 10px 넘치던 진짜 원인이 여기였다.** `.store-head` 는 `margin: 0 -10px`
   으로 좌우 10px 씩 바깥으로 나가 있다 - 매장 제목 줄이 카드 안쪽 여백보다 넓게
   보여야 끌어다 놓는 자리로 읽히기 때문이고, 그 자체는 맞는 설계다.
   **그런데 이 영역이 스크롤 상자가 되면서 그 20px 가 「넘친 내용」이 됐다.** 스크롤
   상자는 자기 밖으로 나간 것을 넘침으로 세므로, 부모의 여백을 빌려 쓰던 음수 마진이
   갈 곳을 잃는다. 위에서 `overflow-x: hidden` 으로 막대는 없앴지만 그것은 가린 것이지
   고친 것이 아니었다 - 실제로 오른쪽 10px 가 잘리고 있었다.
   **그래서 스크롤 상자 안에서만 음수 마진을 거둔다.** 매장 탭의 같은 줄은 스크롤
   상자가 아니므로 원래대로 둔다. 거기서는 지금 모양이 맞다. */
#board-stores .store-head { margin-left: 0; margin-right: 0; }
/* 접힌 화면에서는 높이를 풀어 준다. 좁은 화면에서 860 을 유지하면 카드 안에 스크롤이
   둘 생겨 손가락이 어느 쪽을 미는지 알 수 없다. */
@media (max-width: 899px) {
  .dash-col-wide .dash-card { max-height: none; }
  .dash-col-wide .dash-card > #board-stores,
  .dash-col-wide .dash-card > .lib-grid { overflow-y: visible; }
}

/* ---------------------------------------------------------------- 재생 기록 (계약 §93.2)
   `.lf-table` 의 Yodeck 머리 모양을 그대로 물려받고 줄 높이만 낮춘다. 그쪽은 72px 짜리
   썸네일이 들어가는 자료 목록이고 여기는 글자뿐이라, 같은 높이를 두면 한 화면에 넉 줄밖에
   안 들어간다. 증빙을 훑는 화면에서 그것은 스크롤을 늘리는 것 말고 하는 일이 없다. */
.play-table td { height: 44px; }
.play-table th.num, .play-table td.num { text-align: right; }
.play-table td .ellipsis { display: block; max-width: 420px; }

/* ---------------------------------------------------------------- QR 화면 만들기 (계약 §17.9)
   🔴 **왼쪽 미리보기 · 오른쪽 입력.** Yodeck 의 같은 앱 배치이고(2026-09-20 실측,
   `docs/qa/yodeck-parity/qr/대조표.md`), 이 화면에서는 그 배치가 특히 값이 있다 - 색을
   고르는 일은 결과를 보면서 해야 한다. 안 보이면 저장하고 확인하고 다시 고치기를 되풀이한다. */
.qr-app-split { display: grid; grid-template-columns: minmax(240px, 320px) 1fr; gap: 24px; align-items: start; }
.qr-app-preview { position: sticky; top: 12px; }
/* 16:10 은 800x480 정본에 가장 가까운 흔한 비율이다. 정확히 5:3 으로 두면 기기 셋 중
   하나에만 맞고, 어느 쪽이든 **조판은 기기 크기에 다시 맞춰지므로** 여기는 느낌만 준다. */
.qr-app-stage { aspect-ratio: 5 / 3; border: 1px solid var(--line, var(--color-gray-300)); border-radius: 12px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 16px; overflow: hidden; }
.qr-app-title { font-weight: 700; font-size: 20px; line-height: 1.2; text-align: center;
  max-width: 100%; overflow-wrap: anywhere; }
.qr-app-sub { font-size: 13px; line-height: 1.2; text-align: center;
  max-width: 100%; overflow-wrap: anywhere; }
/* ⚠ QR 은 **비율을 절대 안 바꾼다.** 늘어난 QR 은 오류를 안 내고 그냥 안 찍힌다. */
.qr-app-img { flex: 0 1 auto; min-height: 0; aspect-ratio: 1; object-fit: contain;
  image-rendering: pixelated; background: var(--color-white); border-radius: 4px; }
/* 주소를 아직 안 넣은 상태. **빈 자리로 두지 않는다** - 아무것도 없으면 고장으로 읽힌다. */
.qr-app-slot { flex: 0 1 auto; min-height: 0; aspect-ratio: 1; width: 45%;
  border: 2px dashed currentColor; border-radius: 6px; opacity: .45;
  display: flex; align-items: center; justify-content: center;
  padding: 8px; font-size: 11px; line-height: 1.25; text-align: center; }
/* 제목 위 아이콘. 서버가 그린 PNG 를 받으므로 색은 `img` 교체로 바뀐다 - CSS 로
   칠하지 않는다(필터로 칠하면 기기에 뜨는 색과 어긋난다). */
.qr-app-icon { flex: 0 0 auto; width: 15%; max-width: 48px; aspect-ratio: 1;
  object-fit: contain; }
/* 아이콘 고르기. 여덟에 「없음」까지 아홉이라 한 줄에 다 안 들어간다 - 접히게 둔다. */
.qr-icon-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.qr-icon { width: 44px; height: 44px; padding: 7px; cursor: pointer;
  border: 1px solid var(--line, var(--color-gray-300)); border-radius: 10px; background: var(--color-white);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1.1; color: var(--ink-2, var(--color-gray-600)); }
.qr-icon img { width: 100%; height: 100%; object-fit: contain; }
.qr-icon:hover { border-color: var(--ink-2, var(--color-gray-500)); }
/* 고른 것은 테두리 두께가 아니라 색과 그림자로 알린다 - 두께를 바꾸면 칸이 1px 씩
   움직여 목록 전체가 흔들린다. */
.qr-icon.selected { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(10,143,245,.18); }
.qr-app-fields .row.gap { display: flex; gap: 12px; }
.qr-app-fields .row.gap > .field { flex: 1; }
.qr-app-fields input[type="color"] { width: 100%; height: 40px; padding: 2px;
  border: 1px solid var(--line, var(--color-gray-300)); border-radius: 8px; background: var(--color-white); cursor: pointer; }
/* 좁은 화면에서는 미리보기가 위로 올라온다. 옆에 붙이면 둘 다 못 읽을 만큼 좁아진다. */
@media (max-width: 719px) {
  .qr-app-split { grid-template-columns: 1fr; }
  .qr-app-preview { position: static; }
}


/* ===================================================== 첫 화면 셋 (2026-09-23)
   대표님 - 「대시보드는 특히 지금 너무 복잡해」. 위에서부터 만들기 · 우리 매장 화면 ·
   공지와 템플릿이고, 예전 격자는 「자세히 보기」 안에 접혀 있다. 글자를 한 단계씩 키웠다 -
   매장 계산대 옆에서 휴대폰이나 작은 노트북으로 여는 화면이다. */
#panel-board .dash-head { display: none; }
.home { display: flex; flex-direction: column; gap: 20px; max-width: 1180px; }
.home-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 28px;
  background: radial-gradient(120% 140% at 0% 0%, var(--color-purple-100) 0%, rgba(239,230,254,0) 55%),
    radial-gradient(90% 120% at 100% 100%, var(--color-blue-300) 0%, rgba(221,239,254,0) 60%), var(--color-white);
  border-radius: 16px; padding: 32px 36px; border: 1px solid var(--divider); }
.home-hello { margin: 0 0 6px; font-size: 15px; color: var(--text-sub); }
.home-lead { margin: 0 0 10px; font-size: 28px; line-height: 1.3; font-weight: 700;
  letter-spacing: -0.02em; color: var(--text); word-break: keep-all; }
.home-sub { margin: 0 0 22px; font-size: 15px; line-height: 1.6; color: var(--text-sub); word-break: keep-all; }
.home-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.home-btn-main { display: inline-flex; align-items: center; gap: 8px; border: 0; cursor: pointer;
  background: var(--primary); color: var(--color-white); font: inherit; font-size: 16px; font-weight: 700;
  padding: 14px 22px; border-radius: 8px; }
.home-btn-main:hover { filter: brightness(.94); }
.home-btn-ico { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }
.home-btn-sub { border: 1px solid var(--line); background: var(--color-white); color: var(--text); cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 600; padding: 13px 18px; border-radius: 8px; }
.home-btn-sub:hover { background: var(--surface); }

.home-latest { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.home-latest-title { margin: 0 0 10px; font-size: 13px; color: var(--text-sub); }
.home-latest-empty { margin: 0; padding: 28px; border: 2px dashed var(--color-blue-400); border-radius: 12px;
  text-align: center; color: var(--text-sub); font-size: 14px; line-height: 1.6; word-break: keep-all; }
.home-versions { display: flex; gap: 12px; align-items: flex-end; }
.home-version { margin: 0; flex: 1 1 0; min-width: 0; }
.home-version img { display: block; width: 100%; border-radius: 8px; background: var(--color-white);
  box-shadow: 0 2px 10px rgba(24, 27, 30, .10); }
.home-version-tv { flex-grow: 1.5; }
.home-version-tv img { border: 6px solid var(--color-gray-900); border-radius: 10px; }
.home-version-eink img { border: 8px solid var(--color-gray-300); }
.home-version-tag { flex-grow: .7; }
.home-version-tag img { border: 4px solid var(--color-gray-300); border-radius: 6px; }
.home-version.broken img { visibility: hidden; }
.home-version figcaption { margin-top: 8px; font-size: 12px; font-weight: 600; color: var(--text-sub);
  text-align: center; }

.home-card { background: var(--color-white); border-radius: 12px; padding: 20px 24px 24px; border: 1px solid var(--divider); }
.home-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.home-card-title { margin: 0; font-size: 18px; font-weight: 700; color: var(--text); }
.home-card-meta { font-size: 13px; color: var(--color-green-800); font-weight: 600; }
.home-card-meta.warn { color: var(--danger); }
.home-card-head .sm { margin-left: auto; }
.home-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }
.home-tile { display: flex; flex-direction: column; gap: 10px; text-align: left; cursor: pointer;
  border: 1px solid var(--line); background: var(--color-white); border-radius: 10px; padding: 10px; font: inherit;
  color: var(--text); min-width: 0; }
.home-tile:hover { border-color: var(--primary); }
.home-tile.off { border-color: var(--color-red-200); background: var(--color-gray-100); }
.home-tile-thumb { width: 100%; aspect-ratio: 5 / 3; border-radius: 8px; background: var(--surface);
  display: flex; align-items: center; justify-content: center; overflow: hidden; }
.home-tile-tv .home-tile-thumb { aspect-ratio: 16 / 9; background: var(--color-gray-900); }
.home-tile-tag .home-tile-thumb { aspect-ratio: 296 / 128; }
.home-tile-thumb img { width: 100%; height: 100%; object-fit: contain; }
.home-tile-none { font-size: 12px; color: var(--text-hint); white-space: nowrap; }
/* 기기 종류 태그 (2026-09-23 - 「fhd와 e-eing구분쉽도록 아이콘이나 태그」). 섬네일 왼쪽 위에
   얹는다. TV(FHD) 파랑 · 전자종이 초록 · 가격표 회색. `kindTag()` 가 그린다. */
.kind-tag { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 7px;
  border-radius: 6px; font-size: 11px; font-weight: 700; line-height: 1; white-space: nowrap;
  background: var(--color-white); color: var(--color-gray-700); box-shadow: 0 1px 2px rgba(91,105,115,.16); }
.kind-tag svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.kind-tag-tv { background: var(--color-blue-600); color: var(--color-white); }
.kind-tag-eink { background: var(--color-green-100); color: var(--color-green-800); }
.kind-tag-tag { background: var(--color-gray-150); color: var(--color-gray-700); }
.home-tile-thumb { position: relative; }
.home-tile-thumb > .kind-tag { position: absolute; top: 6px; left: 6px; }
/* 그림 위 아래쪽 띠 - 찍은 시각이나 재생목록 이름 (2026-09-23) */
.home-tile-age { position: absolute; left: 0; right: 0; bottom: 0; padding: 4px 8px;
  font-size: 11px; font-weight: 600; color: #fff; background: linear-gradient(transparent, rgba(0,0,0,.62));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.home-tile-pl { display: inline-flex; align-items: center; gap: 6px; max-width: 86%; padding: 0 8px;
  font-size: 12px; font-weight: 600; color: var(--color-white); }
.home-tile-pl > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.home-tile-pl svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.home-tile-tv .home-tile-none { color: var(--color-gray-400); }
.home-tile-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.home-tile-name { font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.home-tile-state { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-sub); }
.home-tile-state .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.home-tile-state .dot.ok { background: var(--color-green-700); }
.home-tile-state .dot.bad { background: var(--danger); }
.home-tile-more { align-items: center; justify-content: center; font-weight: 600; color: var(--text-sub);
  background: var(--surface); }
.home-tiles-empty { grid-column: 1 / -1; padding: 12px 4px; }
.home-tiles-empty .sm { margin-top: 10px; }

.home-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: 20px; align-items: start; }
.home-row > [hidden] { display: none; }
.home-row .dash-card { border-radius: 12px; padding: 20px 24px 24px; }
.home-row .dash-card-title { font-size: 18px; font-weight: 700; }

.home-more { background: transparent; }
.home-more > summary { cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 12px;
  padding: 12px 4px; font-size: 15px; font-weight: 700; color: var(--text-sub); }
.home-more > summary::-webkit-details-marker { display: none; }
.home-more > summary::before { content: ''; width: 8px; height: 8px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor; transform: rotate(-45deg); margin-right: 2px; transition: transform .15s; }
.home-more[open] > summary::before { transform: rotate(45deg); }
.home-more-hint { font-size: 13px; font-weight: 400; color: var(--text-hint); }
.home-more[open] > .dash-grid { margin-top: 8px; }

@media (max-width: 900px) {
  .home-hero { grid-template-columns: 1fr; padding: 24px 20px; }
  .home-lead { font-size: 23px; }
  .home-row { grid-template-columns: 1fr; }
  .home-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } .home-tile { padding: 8px; } .home-tile-name { font-size: 13px; }
}

/* 메뉴 접기 (2026-09-23). data-adv 단추는 「더 보기」 뒤로 접힌다. 이 매장에 필요한 것
   (.nav-keep)과 지금 열려 있는 칸(.active)은 접혀 있어도 보인다 - 길을 잃지 않게. */


/* ===================================================== gency.ai 무드 (2026-09-23)
   대표님 - 「전체 디자인 무드 gency.ai보고 따라해」. 실측한 gency.ai 관리 화면 값이다.
   - 좌측 메뉴는 회색 판(#EEF0F2) 위에 흰 알약이 활성 칸이다. 활성 글자는 파랑.
   - 「새로 만들기」는 파랑 단추(반경 8) 하나. 주황을 걷었다 - 주 색은 하나다.
   - 칩: 켜진 것은 흰 바탕 + 파랑 테두리 + 파랑 글자, 꺼진 것은 회색 바탕.
   - 제목은 굵게(700), 카드는 흰 바탕에 옅은 테두리.
   - 브랜드 그라데이션(#0A8FF5 → #B77BF8)은 강조 한 곳에만 쓴다 - 로고 점과 AI 표시. */
.topbar { background: var(--color-white); border-bottom: 1px solid var(--divider); }
.topbar .brand .name { font-weight: 800; letter-spacing: -0.02em; }
.topbar .brand::before { content: ''; width: 18px; height: 18px; border-radius: 5px;
  background: var(--brand-grad); flex: none; margin-right: 8px; display: inline-block; vertical-align: -3px; }
@media (min-width: 768px) {
  .tabbar { background: var(--sidebar-bg); border-right: 0; }
  .tabbar .nav-scroll > button,
  .tabbar .nav-grp > button { color: var(--text); font-weight: 500; }
  .tabbar .nav-scroll > button:hover,
  .tabbar .nav-grp > button:hover { background: rgba(255,255,255,.6); }
  .tabbar .nav-scroll > button.active,
  .tabbar .nav-grp > button.active { background: var(--color-white); color: var(--primary); font-weight: 700; }
  .tabbar .nav-cta { background: var(--primary); color: var(--color-white); font-weight: 600; }
  .tabbar .nav-cta:hover, .tabbar .nav-cta.active { background: var(--primary-hover); color: var(--color-white); }
  .tabbar .nav-sub button:hover { background: rgba(255,255,255,.6); }
  .tabbar .nav-sub button.active { background: var(--color-white); color: var(--primary); }
  .tabbar .nav-div, .tabbar .nav-foot { border-color: var(--color-gray-300); }
  .tabbar .nav-div { background: var(--color-gray-300); }
}
.tabbar.open .nav-cta { background: var(--primary); }
.tabbar > button.active, .tabbar .nav-scroll > button.active { color: var(--primary); }
button.primary, .btn.primary { background: var(--primary); border-color: var(--primary); }
.chip, .seg button { border-radius: 8px; }
.chip.on, .chip.active, .chip[aria-pressed="true"] {
  background: var(--color-white); border-color: var(--primary); color: var(--primary); }
.card, .dash-card { border-radius: 12px; }
h1, h2, .dash-card-title, .home-card-title { font-weight: 700; letter-spacing: -0.01em; }

/* ===================================================== 관리 화면 - gency.ai 대조 (2026-09-23)
   대표님 - 「대시보드의 물음표나 만들기버튼, 추가장수등 여전히 gency.ai랑 분위기 다른것들 있으니
   체크하고」. gency.ai 워크스페이스에서 잰 값(computed style)으로 맞췄다.
   - 좌측 메뉴 칸: 높이 34, 반경 8, 14/600, 꺼진 칸 gray-600, 켜진 칸 흰 바탕 + blue-600. 아이콘 18.
   - 「새로 만들기」: 높이 38, 반경 8, 흰 글자 14/600. 예전엔 .nav-scroll > button 규칙에
     밀려 파란 바탕에 검은 글자였다(선택자 점수 0,2,0 < 0,2,1).
   - 머리글 단추(보내기·알림·로그아웃)는 알약(999)이 아니라 반경 8 사각. 이모지·글자 기호 대신
     메뉴와 같은 선 아이콘.
   - 언어 전환은 DS ToggleButtonGroup - 회색 판 안에 흰 칸이 켜진 것.
   - 「준비 중」은 테두리 알약이 아니라 DS StatusLabel(반경 4, 회색 바탕).
   - 사용량 게이지: 라벨 12/600 gray-700, 값 12/700 gray-900, 채움은 주 색. */
.topbar .pushbtn {
  min-height: 36px; height: 36px; padding: 0 14px; gap: 6px;
  border-radius: 8px; border-color: var(--color-gray-300);
  background: var(--color-white); color: var(--color-gray-700);
  font-size: 14px; font-weight: 600;
}
.topbar .pushbtn:hover { background: var(--color-gray-100); }
.topbar .pushbtn.has-pending { background: var(--primary); border-color: var(--primary); color: var(--color-white); }
.topbar .pushbtn.has-pending:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.pushbtn .push-ico { display: inline-flex; opacity: 1; }
.pushbtn .push-ico svg, .bellbtn .bell-ico svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.topbar .bellbtn {
  width: 36px; height: 36px; border-radius: 8px; color: var(--color-gray-600);
}
.topbar .bellbtn:hover { background: var(--color-gray-150); color: var(--color-gray-900); }
.bellbtn .bell-ico { display: inline-flex; }

.topbar .langtog {
  border: 0; border-radius: 10px; padding: 3px; gap: 2px; background: var(--color-gray-200);
}
.topbar .langtog button {
  min-width: 36px; min-height: 30px; height: 30px; padding: 0 8px;
  border-radius: 8px; font-size: 12px; font-weight: 600; color: var(--color-gray-600);
}
.topbar .langtog button:first-child, .topbar .langtog button:last-child { border-radius: 8px; }
.topbar .langtog button:hover { background: rgba(255,255,255,.6); color: var(--color-gray-900); }
.topbar .langtog button.active, .topbar .langtog button.active:hover {
  background: var(--color-white); color: var(--color-gray-900);
  box-shadow: 0 2px 4px var(--elevation-color);
}

.topbar #btn-logout {
  min-height: 36px; padding: 0 12px; border-radius: 8px;
  font-size: 14px; font-weight: 600; color: var(--color-gray-600);
}
.topbar #btn-logout:hover { background: var(--color-gray-150); color: var(--color-gray-900); }

.topbar .gauge .g-row { font-size: 12px; font-weight: 600; color: var(--color-gray-700); }
.topbar .gauge .g-val { font-weight: 700; color: var(--color-gray-900); }
.topbar .gauge .g-bar { height: 6px; background: var(--color-gray-200); margin-top: 5px; }
.topbar .gauge .g-fill { background: var(--primary); }
.topbar .gauge.warn .g-fill { background: var(--warn); }
.topbar .gauge.danger .g-fill { background: var(--danger); }

.nav-soon {
  border: 0; border-radius: 4px; padding: 0 6px; line-height: 18px; height: 18px;
  background: var(--color-gray-100); color: var(--color-gray-500);
  font-size: 11px; font-weight: 600;
}

@media (min-width: 768px) {
  .tabbar .nav-scroll > button,
  .tabbar .nav-grp > button {
    height: 34px; min-height: 34px; padding: 0 8px; gap: 8px; margin-bottom: 2px;
    font-size: 14px; font-weight: 600; color: var(--color-gray-600);
  }
  .tabbar .nav-scroll > button .ico,
  .tabbar .nav-grp > button .ico { width: 18px; font-size: 18px; }
  .tabbar .nav-scroll > button .ico svg,
  .tabbar .nav-grp > button .ico svg { width: 18px; height: 18px; }
  .tabbar .nav-scroll > button:hover,
  .tabbar .nav-grp > button:hover { background: rgba(255,255,255,.6); color: var(--color-gray-900); }
  .tabbar .nav-scroll > button.active,
  .tabbar .nav-grp > button.active,
  .tabbar .nav-scroll > button.active:hover,
  .tabbar .nav-grp > button.active:hover {
    background: var(--color-white); color: var(--primary); font-weight: 600;
  }
  .tabbar .nav-scroll > .nav-cta,
  .tabbar .nav-scroll > .nav-cta:hover,
  .tabbar .nav-scroll > .nav-cta.active {
    height: 38px; min-height: 38px; margin-bottom: 14px; justify-content: center;
    background: var(--primary); color: var(--color-white); font-weight: 600;
  }
  .tabbar .nav-scroll > .nav-cta:hover,
  .tabbar .nav-scroll > .nav-cta.active { background: var(--primary-hover); }
  .tabbar .nav-sub button {
    height: 32px; min-height: 32px; padding: 0 8px 0 34px;
    font-size: 13px; font-weight: 500; color: var(--color-gray-600);
  }
  .tabbar .nav-sub button:hover { background: rgba(255,255,255,.6); color: var(--color-gray-900); }
  .tabbar .nav-sub button.active { background: var(--color-white); color: var(--primary); font-weight: 600; }
  .tabbar .nav-sub .nav-soon { background: var(--color-white); }
  .tabbar .nav-sub button.active .nav-soon { background: var(--color-gray-100); }
  .tabbar .nav-foot { padding-left: 0; padding-right: 0; }
  .tabbar .nav-help {
    height: 34px; padding: 0 8px; gap: 8px;
    font-size: 14px; font-weight: 600; color: var(--color-gray-600);
  }
  .tabbar .nav-help:hover { background: rgba(255,255,255,.6); color: var(--color-gray-900); }
  .tabbar .nav-help .ico { width: 18px; font-size: 18px; }
  .tabbar .nav-help .ico svg { width: 18px; height: 18px; }
}
/* 폰 머리글은 두 줄 안에 들어가야 한다 - 언어 칸과 로그아웃만 좁힌다 */
@media (max-width: 767px) {
  .topbar .pushbtn { padding: 0 10px; }
  .topbar .langtog button { min-width: 30px; padding: 0 6px; }
  .topbar #btn-logout { padding: 0 6px; font-size: 13px; }
}
.tabbar.open .nav-cta, .tabbar.open .nav-cta * { color: var(--color-white); }
.dash-card-title, .home-row .dash-card-title { font-size: 18px; font-weight: 700; color: var(--color-gray-900); }

/* ===================================================== 랜딩 - gency.ai 무드 (2026-09-23)
   gency.ai 첫 화면에서 잰 것을 옮겼다.
   - 첫 화면: 가운데 정렬, 굵은(800) 두 줄 제목, 둘째 줄은 파랑→보라 그라데이션 글자.
     바탕은 왼쪽 위 연보라와 오른쪽 아래 연하늘이 번지는 파스텔.
   - 주 단추: 파랑→보라 그라데이션(270deg) + 반짝임 아이콘, 반경 8.
   - 기능 카드: 연하늘(#EAF5FE) 큰 판, 반경 24, 그 안에 결과물 한 장. 아래 굵은 제목.
   - 섹션 제목은 가운데 정렬, 작은 파랑 머리말이 위에 붙는다.
   - 맨 아래: 옅은 회색 바탕에 회사 정보, 그 밑에 아주 큰 회색 워드마크. */
.lp-body { background: var(--color-white); font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.lp-top { background: rgba(255,255,255,.9); border-bottom: 1px solid var(--color-gray-200); }
.lp-top-in { max-width: 1200px; height: 60px; }
.lp-top .brand { align-items: center; }
.lp-top .brand::before { content: ''; width: 20px; height: 20px; border-radius: 6px; background: var(--brand-grad); margin-right: 8px; flex: none; }
.lp-top .brand .name { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; }
.lp-nav { display: flex; gap: 4px; margin-right: auto; margin-left: 28px; }
.lp-nav a { padding: 8px 14px; border-radius: 8px; font-size: 15px; font-weight: 700; color: var(--color-gray-900); text-decoration: none; }
.lp-nav a:hover { background: var(--color-blue-300); color: var(--color-blue-600); }
.lp-topcta { background: var(--brand-grad); border-radius: 8px; min-height: 36px; padding: 0 16px; font-size: 14px; }
.lp-topcta:hover { background: var(--brand-grad); filter: brightness(.95); }

.lp-main { max-width: 1200px; }
.lp-hero {
  display: block; text-align: center; position: relative;
  margin: 0 calc(50% - 50vw); padding: 88px 24px 72px;
  background:
    radial-gradient(60% 70% at 8% 0%, var(--color-purple-100) 0%, rgba(237,227,253,0) 70%),
    radial-gradient(55% 60% at 100% 85%, var(--color-blue-300) 0%, rgba(217,236,253,0) 70%),
    var(--color-white);
}
.lp-hero-copy { max-width: 760px; margin: 0 auto; }
.lp-eyebrow { font-size: 14px; font-weight: 700; color: var(--color-blue-600); margin-bottom: 16px; }
.lp-h1 { font-size: 52px; line-height: 1.32; font-weight: 800; letter-spacing: -0.03em; color: var(--color-gray-900); margin-bottom: 20px; }
.lp-grad { background: var(--brand-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.lp-lede { margin: 0 auto 30px; font-size: 18px; color: var(--color-gray-600); }
.lp-herobtns-c { justify-content: center; }
.lp-ctabtn { border-radius: 8px; background: var(--color-blue-600); font-weight: 700; }
.lp-ctabtn:hover { background: var(--color-blue-750); }
.lp-ctabtn-grad, .lp-ctabtn-grad:hover { background: linear-gradient(270deg, var(--color-purple-400) 0%, var(--color-blue-600) 100%); gap: 8px; min-height: 48px; padding: 0 24px; font-size: 16px; }
.lp-ctabtn-grad:hover { filter: brightness(.95); }
.lp-spark { width: 16px; height: 16px; fill: var(--color-white); }
.lp-ghostbtn { border-radius: 8px; min-height: 48px; background: var(--color-white); border-color: var(--color-gray-300); color: var(--color-gray-900); font-weight: 600; font-size: 15px; }
.lp-specstrip { justify-content: center; margin: 26px 0 0; }
.lp-specstrip li { background: rgba(255,255,255,.8); border-color: var(--color-gray-200); }

.lp-hero-shot { max-width: 1000px; margin: 56px auto 0; }
.lp-stage { position: relative; padding: 0 0 40px; }
.lp-device { border-radius: 16px; border: 1px solid var(--color-gray-200); padding: 10px;
  box-shadow: 0 24px 60px rgba(24, 27, 30, .12); }
.lp-device img { border: 0; border-radius: 8px; }
.lp-device-tv { width: 78%; background: var(--color-gray-900); border-color: var(--color-gray-900); }
.lp-device-eink { position: absolute; right: 0; bottom: 0; width: 40%; background: var(--color-white); }
.lp-pill { position: absolute; padding: 10px 18px; border-radius: 999px; background: var(--color-white);
  font-size: 15px; font-weight: 700; color: var(--color-gray-900); box-shadow: 0 8px 24px rgba(24,27,30,.12); }
.lp-pill-a { left: -12px; top: 18%; }
.lp-pill-b { right: 6%; bottom: -8px; color: var(--color-blue-600); }
.lp-device-cap { text-align: center; }

.lp-kicker { margin: 0 0 10px; text-align: center; font-size: 14px; font-weight: 700; color: var(--color-blue-600); }
.lp-center { text-align: center; }
.lp-h2 { font-size: 36px; font-weight: 800; letter-spacing: -0.03em; }
.lp-sub { font-size: 16px; color: var(--color-gray-600); }
.lp-sub.lp-center { max-width: 40em; margin-left: auto; margin-right: auto; margin-bottom: 36px; }
.lp-sec { padding: 88px 0; }
.lp-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.lp-feat h3 { margin: 20px 4px 6px; font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.lp-feat p { margin: 0 4px; font-size: 15px; line-height: 1.6; color: var(--color-gray-600); }
.lp-feat-shot { background: var(--color-blue-100); border-radius: 24px; padding: 48px 40px; aspect-ratio: 4 / 3;
  display: flex; align-items: center; justify-content: center; }
.lp-feat-shot img { display: block; width: 100%; height: auto; border-radius: 10px;
  box-shadow: 0 16px 40px rgba(10, 143, 245, .14); background: var(--color-white); }
.lp-feat-dark { background: linear-gradient(135deg, var(--color-blue-100), var(--color-purple-100)); }

.lp-proof { background: var(--color-gray-100); border-radius: 24px; padding: 36px 32px; text-align: center; }
.lp-sec-tint { background: var(--color-gray-100); box-shadow: none; border-radius: 24px; padding: 64px 40px; }
.lp-sec-tint .lp-h2, .lp-sec-tint > .lp-sub { text-align: center; }
.lp-sec-tint > .lp-sub { max-width: 40em; margin-left: auto; margin-right: auto; }
.lp-card, .lp-gal-item, .lp-faq details, .lp-tablewrap { box-shadow: none; border: 1px solid var(--color-gray-200); border-radius: 16px; }
.lp-gal-item { padding: 12px; background: var(--color-white); }
.lp-gal-item figcaption b { background: var(--color-blue-300); color: var(--color-blue-600); }
.lp-step-no { background: var(--brand-grad); color: var(--color-white); width: 32px; height: 32px; }
.lp-steps h3 { font-size: 18px; font-weight: 800; }
.lp-steps p, .lp-faq p { font-size: 15px; }
.lp-faq summary { font-size: 16px; }
.lp-cmp .lp-ours { background: var(--color-blue-50); }
.lp-cmp thead .lp-ours { color: var(--color-blue-600); }
.lp-punch { border-left-color: var(--color-blue-600); }

.lp-contact { background: linear-gradient(135deg, var(--color-blue-600), var(--color-purple-400)); color: var(--color-white); border-radius: 24px;
  box-shadow: none; padding: 72px 32px; }
.lp-contact .lp-last-h { color: var(--color-white); font-size: 36px; font-weight: 800; letter-spacing: -0.03em; margin: 0 0 12px; }
.lp-contact .lp-sub, .lp-contact .lp-contact-tel { color: rgba(255,255,255,.88); }
.lp-contact .lp-ctabtn { background: var(--color-white); color: var(--color-blue-600); }
.lp-contact .lp-ctabtn:hover { background: var(--color-blue-50); }

.lp-bottom { background: var(--color-gray-100); border-top: 0; margin-top: 40px; overflow: hidden; }
.lp-bottom-in { max-width: 1200px; padding: 48px 24px 0; font-size: 13px; }
.lp-bottom-brand { font-size: 15px; font-weight: 800; color: var(--color-gray-900); margin-bottom: 6px !important; }
.lp-wordmark { margin: 36px 0 -0.18em !important; font-size: clamp(48px, 11.5vw, 150px); font-weight: 800;
  letter-spacing: -0.04em; line-height: 1; color: var(--color-gray-300); white-space: nowrap; user-select: none; }

@media (max-width: 979px) {
  .lp-nav { display: none; }
  .lp-hero { padding: 56px 16px 48px; }
  .lp-h1 { font-size: 34px; }
  .lp-lede { font-size: 16px; }
  .lp-h2, .lp-contact .lp-last-h { font-size: 26px; }
  .lp-sec { padding: 56px 0; }
  .lp-duo { grid-template-columns: 1fr; }
  .lp-feat-shot { padding: 28px 20px; }
  .lp-sec-tint { padding: 40px 20px; }
}
@media (max-width: 599px) {
  .lp-h1 { font-size: 29px; }
  .lp-pill { display: none; }
  .lp-device-tv { width: 100%; }
  .lp-device-eink { position: relative; width: 70%; margin: -40px 0 0 auto; }
  .lp-stage { padding: 0; }
}
/* ---- FHD 판 (2026-09-23 대표 지시 「랜딩페이지의 메인은 fhd이고 서브로 e-ink」)
   첫 화면의 주인공은 매장 TV 한 대다. 화면 안 네 장은 16초에 한 바퀴 도는 재생목록이고,
   옆 카드가 지금 몇 번째가 나오는지를 같은 박자로 짚는다. 박자는 음수 지연으로 맞춘다 -
   양수 지연이면 시작 전 구간에 첫 키프레임이 채워져 네 장이 한꺼번에 떠 버린다. */
.lp-tvstage { position: relative; padding: 0 0 4px; }
.lp-tv { position: relative; width: 84%; margin: 0 auto; padding: 12px; border-radius: 18px;
  background: var(--color-gray-1000); box-shadow: 0 30px 70px rgba(24, 27, 30, .22); }
.lp-tv-screen { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 6px; background: var(--color-gray-900); }
.lp-tv-slide { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; animation: lp-tvslide 16s infinite; }
.lp-tv-slide:nth-child(2), .lp-pl li:nth-child(2) { animation-delay: -12s; }
.lp-tv-slide:nth-child(3), .lp-pl li:nth-child(3) { animation-delay: -8s; }
.lp-tv-slide:nth-child(4), .lp-pl li:nth-child(4) { animation-delay: -4s; }
@keyframes lp-tvslide { 0%, 25% { opacity: 1; } 28%, 97% { opacity: 0; } 100% { opacity: 1; } }
.lp-tv-res { position: absolute; right: 24px; bottom: 24px; padding: 4px 10px; border-radius: 999px;
  background: rgba(18, 20, 22, .72); color: var(--color-white); font-size: 12px; font-weight: 700; letter-spacing: .02em; }
.lp-tv-stand { width: 70%; height: 22px; margin: 4px auto 0;
  background: radial-gradient(closest-side, rgba(24, 27, 30, .18), rgba(24, 27, 30, 0)); }

.lp-plcard { position: absolute; left: 0; bottom: 40px; width: 232px; padding: 14px; text-align: left;
  border-radius: 16px; border: 1px solid var(--color-gray-200); background: var(--color-white);
  box-shadow: 0 16px 40px rgba(24, 27, 30, .14); }
.lp-plcard-h { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; font-size: 13px; font-weight: 800; color: var(--color-gray-900); }
.lp-plcard-h svg, .lp-pill-stick svg { width: 16px; height: 16px; flex: none; fill: none; stroke: var(--color-blue-600);
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lp-pl { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.lp-pl li { display: flex; align-items: center; gap: 10px; padding: 5px; border-radius: 10px;
  font-size: 13px; font-weight: 600; color: var(--color-gray-600); animation: lp-plon 16s infinite; }
.lp-pl img { display: block; width: 52px; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 4px; flex: none; }
@keyframes lp-plon {
  0%, 25% { background-color: var(--color-blue-100); color: var(--color-blue-600); }
  26%, 100% { background-color: rgba(255, 255, 255, 0); color: var(--color-gray-600); } }
.lp-pill-stick { right: 3%; top: 10%; display: inline-flex; align-items: center; gap: 8px; }

/* 기능 - 결과물 두 장 + 아이콘 카드 여섯 */
.lp-feat-tv img, .lp-fan img { border: 6px solid var(--color-gray-1000); border-radius: 10px; }
.lp-fan { position: relative; overflow: hidden; }
.lp-fan img { position: absolute; left: 50%; top: 50%; width: 62%; }
.lp-fan img:nth-child(1) { transform: translate(-80%, -70%) rotate(-6deg); }
.lp-fan img:nth-child(2) { transform: translate(-20%, -30%) rotate(5deg); }
.lp-fan img:nth-child(3) { transform: translate(-50%, -45%); z-index: 2; box-shadow: 0 20px 44px rgba(24, 27, 30, .24); }
.lp-tvfeat { list-style: none; margin: 48px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.lp-tvfeat li { padding: 24px; border: 1px solid var(--color-gray-200); border-radius: 16px; background: var(--color-white); }
.lp-tvfeat-ic { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  margin-bottom: 14px; border-radius: 12px; background: var(--color-blue-100); }
.lp-tvfeat-ic svg { width: 24px; height: 24px; fill: none; stroke: var(--color-blue-600); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.lp-tvfeat h3 { margin: 0 0 6px; font-size: 17px; font-weight: 800; letter-spacing: -0.02em; color: var(--color-gray-900); }
.lp-tvfeat p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--color-gray-600); }
.lp-sec-tint .lp-kicker { margin-bottom: 10px; }
.lp-gal-tv .lp-gal-item img { border: 4px solid var(--color-gray-1000); }

/* 전자종이 - 보조 섹션. TV 판과 전자종이 판을 화살표 하나로 잇고 사양은 접어 둔다 */
.lp-einkpair { display: grid; grid-template-columns: minmax(0, 1.35fr) auto minmax(0, 1fr); gap: 24px; align-items: center;
  max-width: 980px; margin: 0 auto; }
.lp-einkpair figure { margin: 0; }
.lp-einkpair img { display: block; width: 100%; height: auto; border-radius: 8px; }
.lp-einkpair-tv img { border: 8px solid var(--color-gray-1000); border-radius: 12px; box-shadow: 0 16px 40px rgba(24, 27, 30, .14); }
.lp-einkframe { padding: 10px; border: 1px solid var(--color-gray-200); border-radius: 14px; background: var(--color-white);
  box-shadow: 0 16px 40px rgba(24, 27, 30, .10); }
.lp-einkframe img { border-radius: 4px; }
.lp-einkpair figcaption { margin-top: 14px; font-size: 14px; line-height: 1.55; color: var(--color-gray-600); }
.lp-einkpair figcaption b { display: block; margin-bottom: 2px; font-size: 16px; font-weight: 800; color: var(--color-gray-900); }
.lp-einkpair-arrow { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: 999px; background: var(--color-blue-100); }
.lp-einkpair-arrow svg { width: 22px; height: 22px; fill: none; stroke: var(--color-blue-600); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lp-einkpts { list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 36px 0 0; padding: 0; }
.lp-einkpts li { padding: 8px 14px; border-radius: 999px; border: 1px solid var(--color-gray-200); background: var(--color-gray-100);
  font-size: 14px; font-weight: 600; color: var(--color-gray-700); }
.lp-einkmore { max-width: 820px; margin: 20px auto 0; }
.lp-einkmore summary { padding: 8px; cursor: pointer; list-style: none; text-align: center;
  font-size: 14px; font-weight: 700; color: var(--color-blue-600); }
.lp-einkmore summary::-webkit-details-marker { display: none; }
.lp-einkmore summary::after { content: ''; display: inline-block; width: 7px; height: 7px; margin-left: 8px; vertical-align: 3px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); }
.lp-einkmore[open] summary { margin-bottom: 12px; }
.lp-einkmore[open] summary::after { transform: rotate(-135deg); vertical-align: -1px; }

@media (max-width: 979px) {
  .lp-tv { width: 100%; }
  .lp-plcard { width: 196px; bottom: 28px; left: -8px; }
  .lp-tvfeat { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 599px) {
  .lp-tv { padding: 6px; border-radius: 12px; }
  .lp-tv-screen { border-radius: 4px; }
  .lp-tv-res { right: 12px; bottom: 12px; font-size: 10px; padding: 3px 8px; }
  .lp-pill-stick { display: none; }
  .lp-plcard { position: static; width: auto; margin: 4px 0 0; padding: 12px; }
  .lp-pl { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .lp-pl li { flex-direction: column; align-items: stretch; gap: 4px; padding: 4px; font-size: 11px; line-height: 1.3;
    text-align: center; overflow-wrap: anywhere; }
  .lp-pl img { width: 100%; }
  .lp-tvfeat { grid-template-columns: minmax(0, 1fr); margin-top: 32px; }
  .lp-tvfeat li { padding: 20px; }
  .lp-einkpair { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .lp-einkpair-arrow { justify-self: center; transform: rotate(90deg); }
  .lp-einkpts { justify-content: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
  .lp-tv-slide, .lp-pl li { animation: none; }
  .lp-tv-slide:first-child { opacity: 1; }
  .lp-pl li:first-child { background-color: var(--color-blue-100); color: var(--color-blue-600); }
}
.lp-body { overflow-x: clip; }

/* 랜딩 - 맞는 곳 / 안 되는 것 두 열 (2026-09-23) */
.lp-fit-kicker{text-align:center;margin:0 0 6px;font-size:14px;font-weight:600;color:var(--gc-accent,#6b4dff)}
.lp-fit{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:28px}
.lp-fit-col{background:#fff;border-radius:16px;padding:24px 26px;box-shadow:0 4px 21px rgba(0,0,0,.05)}
.lp-fit-col h3{margin:0 0 14px;font-size:18px}
.lp-fit-col ul{margin:0;padding:0;list-style:none;display:grid;gap:10px}
.lp-fit-col li{position:relative;padding-left:26px;word-break:keep-all;line-height:1.6;font-size:15px}
.lp-fit-col li::before{position:absolute;left:0;top:0;font-weight:700}
.lp-fit-good li::before{content:"\2713";color:#1a9d5a}
.lp-fit-not li::before{content:"\00d7";color:#c0392b;font-size:18px;line-height:1.4}
@media (max-width:760px){.lp-fit{grid-template-columns:1fr}}
