/* 젠시팝 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) 로 갈려 있다. */

#nav-ordercalls[hidden], #store-ordercalls[hidden], .asset-confirm-dialog button[hidden] { display: none !important; }
.media-kind-picker { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; }
.media-kind-picker button { min-height: 44px; padding: 8px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); color: var(--text); font: inherit; cursor: pointer; }
.media-kind-picker button[aria-pressed=true] { border-color: var(--primary); background: var(--primary-light); color: var(--primary); font-weight: 600; }
.nav-section { margin: 14px 14px 4px; color: var(--text-hint); font-size: 11px; font-weight: 600; letter-spacing: .04em; }
.mobile-menu-section { grid-column: 1 / -1; margin: 10px 0 0; font-size: 12px; font-weight: 600; color: var(--text-hint); }
:root {
  /* 🔴 gency.ai 무드로 맞췄다 (2026-09-23 대표 지시 「전체 디자인 무드 gency.ai보고 따라해」).
     같은 회사 제품이 한 눈에 같은 집안으로 보여야 한다. 값은 gency.ai 화면에서 실측했다 -
     주 파랑 #0A8FF5, 브랜드 그라데이션 #0A8FF5 → #B77BF8, 사이드바 #EEF0F2, 본문 #F9FAFB.
     같은 날 오전에 잠깐 주황으로 갔다가 이 지시로 되돌렸다. */
  /* 글꼴은 두 벌뿐이다 (2026-10-02) - 글자는 Pretendard, 기기 주소 · 개통 코드 · 기록 같은 고정폭 숫자만 mono. */
  --font-sans: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono: ui-monospace, Consolas, monospace;
  --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;
  letter-spacing: .25px; /* DESIGN.md v3.2 - gency 는 11~36px 글자 전부가 +0.25px 다 */
  background: var(--page);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 22px;
  -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: .25px; }
h1 { font-size: 20px; font-weight: 600; }
h2 { font-size: 14px; 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; line-height: 20px; }
.tiny { font-size: 11px; line-height: 16px; }
.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: var(--font-mono); }
.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: 8px; white-space: nowrap; min-width: 0; overflow: hidden; }
@media (max-width: 480px) {
  .brand .org { display: none; }
  .gauge { width: 104px; }
}
.brand .name { font-size: 14px; line-height: 22px; font-weight: 700; color: var(--text); }
.brand .tag { font-size: 11px; line-height: 16px; font-weight: 500; color: var(--text-hint); letter-spacing: .25px; }
.brand .org { font-size: 12px; line-height: 20px; color: var(--text-hint); overflow: hidden; text-overflow: ellipsis; }
.topbar .spacer { flex: 1; }
.linkbtn {
  background: none; border: 0; padding: 8px 8px; min-height: 0;
  color: var(--text-hint); font: inherit; font-size: 12px; line-height: 20px; 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; line-height: 16px; 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; line-height: 20px; 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: 11px; line-height: 16px; 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: 8px; min-height: 0; height: 44px;
    padding: 0 16px; font-size: 14px; line-height: 22px;
    border-bottom: 2px solid transparent;
  }
  .tabbar button .ico { font-size: 14px; }
  .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: 12px;
  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; line-height: 20px; 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 8px; }
/* 왜 넘쳤는지 적는 줄.
   🔴 `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; line-height: 22px;
}
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; line-height: 24px; }  /* 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: var(--bg);
  color: var(--text);
  font: inherit; font-size: 12px; line-height: 20px; font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
button:hover { background: var(--color-gray-100); }
/* 다른 페이지로 넘기는 것은 `<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 { background: transparent; border-color: transparent; color: var(--text-sub); }
button.ghost:hover { background: var(--color-gray-150); color: var(--text); }
button.block { width: 100%; padding-top: 11px; padding-bottom: 11px; }
button.sm { padding: 8px 12px; font-size: 12px; line-height: 20px; }
button:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }
button .sub { font-weight: 400; font-size: 11px; line-height: 16px; opacity: .8; }

/* ---------------------------------------------------------------- 배지 */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; line-height: 16px; 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; line-height: 20px; 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; line-height: 16px; 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; line-height: 20px; 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: 16px 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: 16px;
  padding: 24px 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: 14px; line-height: 22px;
}
.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: 16px 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: 14px; line-height: 22px; margin-right: 4px; }
.status-strip .ss-ok { font-size: 12px; line-height: 20px; color: var(--text-hint); }
.status-strip .spacer { flex: 1; }
.ss-chip {
  min-height: 32px; padding: 4px 12px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--text);
  font-size: 14px; line-height: 22px; 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: 8px; }
  .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; line-height: 16px; font-weight: 600; white-space: nowrap;
  color: var(--badge-warn-text); background: var(--badge-warn-bg);
  border-radius: 999px; padding: 4px 10px;
}
.sec-warn .sec-text { font-size: 14px; line-height: 22px; 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; line-height: 20px; 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; line-height: 16px; color: var(--text-hint);
}
.dev-card .dev-name { font-size: 14px; line-height: 22px; font-weight: 500; margin-top: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dev-card .dev-pop { font-size: 11px; line-height: 16px; 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: 14px; line-height: 22px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sendbar .sb-hint { font-size: 11px; line-height: 16px; 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: 16px 8px; font-size: 12px; line-height: 20px; 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: 8px;
  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: 14px; 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: 8px;
  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; line-height: 16px; 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: 12px; line-height: 20px;
  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: 8px; }
.assetpick-main { font-size: 14px; line-height: 22px; font-weight: 600; color: var(--text); }
/* ⚠ `max-width` 를 34em 으로 뒀더니 1280px 화면에서 한국어가 세 줄로 접히며 「올라갑니다」
   한 낱말만 셋째 줄에 남았다. 그림을 눈으로 보고 잡은 자리다 - 검사는 넘침만 재므로
   전부 초록이었다. 일본어·영어는 34em 에서도 한 줄이라 안 걸렸다. */
.assetpick-sub { font-size: 12px; line-height: 20px; 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(20px, 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; line-height: 28px; }
.asset-drop-mark {
  width: 44px; height: 44px; line-height: 44px; font-size: 20px;
  border-radius: 999px; background: var(--primary-light); color: var(--primary);
}

.asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 16px; }
.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: 24px; color: var(--text-hint); line-height: 1; }
.asset-name { margin: 8px 0 2px; font-size: 14px; line-height: 22px; 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: 14px; line-height: 22px; font-weight: 700; }
.pl-h3 { margin: 0 0 10px; font-size: 14px; line-height: 22px; 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; line-height: 22px; font-weight: 600; color: var(--text); }
.pl-card-sub { font-size: 12px; line-height: 20px; 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; line-height: 20px; 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; line-height: 28px; }
.pl-item-mid { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.pl-item-title { font-size: 14px; line-height: 22px; font-weight: 600; color: var(--text); }
/* ⚠ 「초까지」가 두 줄로 접혀 「초까 / 지」가 됐다. 그림을 눈으로 보고 잡은 자리다 -
   검사는 가로 넘침만 재므로 전부 초록이었다. */
.pl-dur-wrap { display: flex; align-items: center; gap: 4px; 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: 8px; 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; line-height: 20px; 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: 14px; line-height: 22px; 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: 16px; }
  .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: 16px; line-height: 24px; 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: 16px; line-height: 24px; 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; line-height: 20px; color: var(--text-hint); margin-top: 4px; min-height: 1.5em; font-variant-numeric: tabular-nums; }
/* 할인이 걸려 있으면 이 줄은 「친 값을 다시 보여 주는 것」이 아니라 **벽에 걸릴 값을
   미리 말해 주는 것**이라 무게가 다르다. 흐린 회색 12px 로 두면 점주가 안 읽고 지나가고,
   그 줄을 읽지 않는 순간 이 개선은 없는 것과 같다. */
.price-preview.with-sale { font-size: 14px; line-height: 22px; 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: var(--font-mono); font-size: 12px; line-height: 20px; color: var(--text-sub); }
.mgr-dev .stats { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 11px; line-height: 16px; 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 20px; border-radius: 999px; font-size: 14px; line-height: 22px;
  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: 14px; line-height: 22px; 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: 20px; line-height: 30px; }
.login .brand .tag { font-size: 12px; line-height: 20px; }
.login .foot { text-align: center; font-size: 12px; line-height: 20px; color: var(--text-hint); margin-top: 16px; }

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

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

/* 언어 고르는 칸 (2026-10-01 대표 지시 「드롭다운으로 바꾸자」). 모든 화면이 이 한 칸을 쓴다.
   i18n.js 가 select[data-lang-select] 의 바뀜을 받는다. 처음 값은 지역으로 정한다(`regionLang`). */
.langsel {
  flex: none; width: auto; min-width: 0;
  min-height: 40px; padding: 6px 28px 6px 12px;
  border: 1px solid var(--line); border-radius: 999px; background-color: var(--bg);
  font-size: 14px; line-height: 22px; font-weight: 600; color: var(--text);
}

/* 언어 토글 KO/JA (옛 판, 2026-10-01 부터 쓰는 화면 없음). 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: 4px 10px; min-height: 0;
  font-size: 11px; line-height: 16px; 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: 4px 8px; }
  .topbar .linkbtn { padding: 8px 4px; }
  .topbar .wrap { gap: 8px; }
  .gauge { width: 88px; }
  .brand .name { font-size: 14px; line-height: 22px; 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; line-height: 16px; }
.lib-edit { width: 100%; margin-top: 10px; font-size: 12px; line-height: 20px; }
.lib-reuse { width: 100%; margin-top: 6px; white-space: normal; font-size: 12px; line-height: 20px; 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: 12px; line-height: 20px; 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: var(--font-mono);
  font-size: 20px !important; line-height: 30px;
  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 8px; text-align: center; min-width: 0;
}
.sumstrip .sum-n { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 30px; }
.sumstrip .sum-l { font-size: 11px; line-height: 16px; 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; line-height: 20px;
}
.fixguide summary {
  cursor: pointer; padding: 8px 10px;
  color: var(--warn-text); font-weight: 600;
  list-style: none;
  display: flex; align-items: center; gap: 8px;
  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 24px; 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 8px; min-height: 0;
  color: var(--text-hint); font-size: 12px; line-height: 20px; 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: 14px !important; line-height: 22px; }
.dev-meta { font-size: 11px; line-height: 16px; 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: 16px; margin-top: 4px;
  color: var(--badge-warn-text); background: var(--badge-warn-bg);
  border-radius: 6px; padding: 4px 8px;
  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: var(--font-mono);
  font-size: 11px; line-height: 16px;
  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: var(--font-sans);
  font-size: 12px; line-height: 20px;
}
.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: var(--font-sans);
  font-size: 12px; line-height: 20px;
  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: 14px; line-height: 22px; 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: 14px; line-height: 22px; 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: 8px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.sb-period::-webkit-scrollbar { height: 3px; }
.sb-period .sb-plabel { font-size: 11px; line-height: 16px; 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 16px; font-size: 12px; line-height: 20px; 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; line-height: 22px; 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; line-height: 24px; } }  /* iOS 자동 확대 방지 */
/* 고른 기간이 무슨 뜻인지 말해 주는 한 문장 */
.sb-expl { font-size: 12px; line-height: 20px; 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: 14px; 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: 11px; line-height: 16px; font-weight: 700; letter-spacing: .25px;
  padding: 1px 4px; 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: 11px; line-height: 16px; font-weight: 700; letter-spacing: .25px;
  padding: 1px 4px; 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: 11px; line-height: 16px; font-weight: 600;
  padding: 1px 8px; 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: 12px; line-height: 20px; 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일) 등 `.segtog` 의 모양은 맨 끝 「탭 한 양식」 블록에 있다 (2026-10-02). */

/* 통계 탭 */
.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; line-height: 22px; font-weight: 500; }
.stat-count { font-size: 14px; line-height: 22px; font-weight: 700; flex: none; }
.stat-caret { color: var(--text-hint); font-size: 12px; line-height: 20px; 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; line-height: 16px; 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; line-height: 20px; 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: 12px; line-height: 20px; 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; line-height: 22px; 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: 16px; 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: 14px; line-height: 22px; 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: 12px; line-height: 20px; 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 8px; }

/* 매장 헤더가 「번호 표시」 버튼을 얻어 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: 14px; 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: 14px; line-height: 22px; 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: 14px; line-height: 22px; color: var(--text);
}
.confirm-lines li { position: relative; padding: 8px 0 8px 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; line-height: 16px; 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: 8px; 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: 8px; flex-wrap: wrap; font-size: 14px; line-height: 22px; 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: 14px; line-height: 22px; 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; line-height: 22px;
}
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; line-height: 24px; }
}

/* ================================================================ 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: 14px; 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: 11px; 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: 14px; line-height: 22px; font-weight: 500; }
.alert-row .a-store { font-size: 11px; line-height: 16px; color: var(--text-hint); }
.alert-row .a-time { font-size: 11px; line-height: 16px; 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; line-height: 16px; 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; line-height: 16px; 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; line-height: 16px; color: var(--text-hint); flex: none; width: 12px; }
.grp-name { font-size: 14px; line-height: 22px; 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; line-height: 20px; }
/* 묶음이 붙으면 기기 카드 안 조작 줄이 셋이 된다 (이름 · 매장 · 묶음) */
.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: 22px; }
h1 { font-size: 24px; line-height: 36px; font-weight: 700; letter-spacing: .25px; }
h2 { font-size: 16px; line-height: 24px; font-weight: 650; }
h3 { font-size: 14px; line-height: 22px; font-weight: 600; }
.wrap { max-width: 1440px; }
main.wrap { padding-top: 24px; }
button, .btn { min-height: 44px; font-size: 14px; line-height: 22px; }
button.sm { min-height: 40px; font-size: 14px; line-height: 22px; }
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: 14px; line-height: 22px; margin-bottom: 7px; font-weight: 500; }
.hint { line-height: 20px; }
.card { border: 1px solid var(--divider); box-shadow: var(--shadow-md); }
.topbar .wrap { max-width: none; padding: 0 24px; gap: 20px; }
.brand .name { font-size: 18px; line-height: 28px; letter-spacing: .25px; }
.brand .tag { font-size: 11px; line-height: 16px; }
.brand .org { margin-left: 10px; padding-left: 16px; 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: 8px 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: 16px; line-height: 24px; 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: 14px; line-height: 22px; font-weight: 500; 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; line-height: 22px; 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; line-height: 20px; 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: 20px; }
.dev-card { border: 1px solid var(--divider); padding: 16px; 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; line-height: 20px; margin-top: 4px; }
.dev-meta { line-height: 20px; 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: 20px 0; margin-bottom: 20px; align-items: center; }
.create-dialog-head h2 { font-size: 20px; line-height: 30px; }
.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: 12px; color: var(--text-sub); line-height: 20px; 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; line-height: 20px; 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: 16px; 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: 16px; width: 100%; }
.product-design-title { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; font-size: 14px; line-height: 22px; }
.product-design-selected { font-size: 12px; line-height: 20px; font-weight: 500; color: var(--text-sub); }
.selected .product-design-selected { color: var(--primary); font-weight: 700; }
.product-design-description { font-size: 12px; font-weight: 400; line-height: 20px; color: var(--text-sub); }
.product-design-photo { font-size: 12px; line-height: 20px; 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: 22px; 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: 20px 8px; gap: 16px; }
.empty { line-height: 20px; 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: 8px; 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; line-height: 22px; }
  .tabbar button .ico { width: 20px; font-size: 20px; }
  .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; line-height: 24px; }
  .topbar .spacer { display: none; }
  .topbar .gauge { width: 104px; }
  .topbar .langtog { margin-left: auto; }
  .topbar .linkbtn { font-size: 12px; line-height: 20px; }
  .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: 8px 2px; font-size: 11px; line-height: 16px; gap: 4px; }
  .tabbar button .ico { font-size: 20px; }
  .tabbar button.active { background: var(--primary-light); }
  main.wrap { padding-top: 22px; }
  h1 { font-size: 24px; }
  .page-heading { align-items: flex-start; flex-wrap: wrap; gap: 16px; 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: 14px; line-height: 22px; }
  .create-dialog { padding: 0 16px 16px; scroll-margin-top: 132px; }
  .create-dialog-head h2 { font-size: 18px; line-height: 28px; }
  #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; line-height: 16px; 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; line-height: 20px; }
  .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; line-height: 22px;
  -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; line-height: 24px; } }
.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; line-height: 24px; }
.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: 12px; line-height: 20px; 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 16px;
  border-radius: var(--radius-btn); background: var(--primary); color: var(--color-white);
  font-size: 14px; line-height: 22px; 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; line-height: 20px; font-weight: 600; color: var(--text-hint);
}
.lp-h1 {
  margin: 0 0 20px;
  font-size: 50px; line-height: 1.16; font-weight: 700; letter-spacing: 0;
  color: var(--text);
}
.lp-lede {
  margin: 0 0 26px; font-size: 18px; line-height: 28px; 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: 4px;
  padding: 8px 12px; border-radius: 999px;
  background: var(--bg); border: 1px solid var(--line);
  font-size: 12px; line-height: 20px; color: var(--text-hint); white-space: nowrap;
}
.lp-specstrip strong { font-size: 14px; line-height: 22px; 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; line-height: 22px; font-weight: 600; text-decoration: none;
}
.lp-ctabtn:hover { background: var(--primary-hover); }
.lp-ctabtn-lg { min-height: 50px; padding: 0 24px; font-size: 16px; line-height: 24px; }
.lp-ghostbtn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 20px;
  border-radius: var(--radius-btn); background: transparent;
  border: 1px solid var(--line); color: var(--text-sub);
  font-size: 14px; line-height: 22px; font-weight: 500; text-decoration: none;
}
.lp-ghostbtn:hover { background: var(--surface); color: var(--text); }

/* 기기 틀. 실제 기기는 흰 베젤이라 그 모양으로 감싼다 */
.lp-device {
  margin: 0; padding: 16px; 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: 20px; color: var(--text-hint);
}

/* 히어로 바로 아래 얇은 띠. 처음 온 사람이 「실재하는 회사인가」를 먼저 재는 자리다.
   여기에는 이 제품에 대해 그대로 사실인 것만 적는다. 근거는 QA README 에 있다. */
.lp-trust {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  padding: 13px 20px; margin-bottom: 8px;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card);
  font-size: 14px; line-height: 22px; font-weight: 500; color: var(--text);
}
.lp-trust span { display: inline-flex; align-items: center; gap: 8px; }
.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: 24px; line-height: 36px; font-weight: 700; letter-spacing: .25px;
  color: var(--text);
}
.lp-sub { margin: 0 0 28px; font-size: 14px; line-height: 22px; 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; line-height: 28px; font-weight: 700; letter-spacing: .25px; }
/* 화면에는 필요 없고 스크린 리더에만 읽히는 표 머리 */
.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: 14px; line-height: 22px; }
.lp-cmp th, .lp-cmp td, .lp-spec th, .lp-spec td {
  padding: 16px 16px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--divider); line-height: 22px;
}
.lp-cmp thead th {
  font-size: 12px; line-height: 20px; 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: 24px; 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: 8px;
  padding: 10px 4px 2px; font-size: 12px; line-height: 20px; 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; line-height: 16px; 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: 24px;
}
.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: 14px; line-height: 22px; font-weight: 700;
}
.lp-steps h3 { margin: 0; font-size: 16px; line-height: 24px; font-weight: 600; letter-spacing: .25px; color: var(--text); }
.lp-steps p { margin: 0; font-size: 12px; line-height: 20px; 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: 16px; line-height: 24px; 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: 12px; line-height: 20px; 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: 12px; line-height: 20px; 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: 16px;
}
.lp-login-note { margin: -6px 0 0; font-size: 12px; line-height: 20px; color: var(--text-hint); }
.lp-remember {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; line-height: 20px; 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: 20px; color: var(--text-hint);
}
.lp-bottom-in p { margin: 0; }
.lp-bottom-brand { font-size: 12px; line-height: 20px; font-weight: 600; color: var(--text-sub); }
.lp-bottom-sep { padding: 0 8px; 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 24px; }
  .lp-h1 { font-size: 36px; }
  .lp-lede { font-size: 16px; line-height: 24px; }
  .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: 24px; line-height: 36px; }
  .lp-login { padding: 36px 0 16px; }
}
@media (max-width: 599px) {
  .lp-gal, .lp-steps { grid-template-columns: minmax(0, 1fr); }
  .lp-h1 { font-size: 24px; }
  .lp-spec { font-size: 14px; line-height: 22px; }
  .lp-spec th, .lp-spec td { padding: 12px 13px; }
  .lp-punch { font-size: 16px; }

  /* 🔴 비교 표를 행마다 카드로 접는다. 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: 16px; line-height: 24px; padding-top: 16px;
    border-bottom: 1px solid var(--divider); margin-bottom: 4px;
  }
  .lp-cmp tbody td { font-size: 14px; line-height: 22px; }
  /* 카드 안에서는 우리 칸을 배경이 아니라 왼쪽 선으로 세운다. 칸이 가로로 꽉 차서
     배경을 깔면 카드 한 장이 통째로 파래 보인다 */
  .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: 12px; line-height: 20px; 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: 16px; }
  /* 헤더에 로고 · 언어 · 로그인 · 문의가 다 들어가야 한다. 언어 토글을 먼저 접는다 */
  .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 24px;
}
.lp-proof-lede {
  margin: 0 0 14px;
  font-size: 12px;
  line-height: 20px;
  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: 16px 16px 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; line-height: 22px;
  font-weight: 600;
  color: var(--text);
}
.lp-proof-list span {
  display: block;
  font-size: 12px;
  line-height: 20px;
  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: 16px; line-height: 24px;
  font-weight: 600;
  color: var(--primary);
}
.lp-pilot span {
  display: block;
  font-size: 12px;
  line-height: 20px;
  color: var(--text-sub);
}
.lp-pilot-note {
  margin: 0 0 18px;
  font-size: 12px;
  line-height: 20px;
  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: 20px;
}
.lp-cards .lp-card p {
  margin: 0;
  font-size: 12px;
  line-height: 20px;
  color: var(--text-sub);
}

.lp-last {
  max-width: 1080px;
  margin: 0 auto;
  padding: 34px 24px 8px;
  text-align: center;
}
.lp-last-h {
  margin: 0 0 8px;
  font-size: 24px; line-height: 36px;
  font-weight: 600;
  letter-spacing: .25px;
  color: var(--text);
}
.lp-last-p {
  margin: 0;
  font-size: 16px;
  line-height: 24px;
  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: 20px; line-height: 30px; }
}

@media (max-width: 599px) {
  .lp-proof { padding: 20px 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: 24px 16px 4px; }
  .lp-last-h { font-size: 20px; line-height: 30px; }
}

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: 11px; color: var(--text-hint); border: 1px solid var(--line);
  border-radius: 999px; padding: 0 8px; margin-left: auto; font-weight: 500;
  line-height: 16px; 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: 11px; line-height: 16px; 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 16px; font-size: 14px; line-height: 22px; 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 16px 0 46px; font-size: 12px; line-height: 20px;
    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 16px;
    border-radius: 8px; text-decoration: none; color: var(--text-hint); font-size: 14px; line-height: 22px;
  }
  .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: 16px 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; line-height: 22px; 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: 16px; 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; line-height: 16px; 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 8px; }
  .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: 12px; line-height: 20px; 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: 12px; line-height: 20px;
  }
  .tabbar .nav-help:hover { background: var(--surface); }
  .tabbar .nav-help .ico { width: 20px; text-align: center; font-size: 14px; }

  main.wrap { padding: 24px 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; line-height: 22px; 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; line-height: 22px; 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: 14px; line-height: 22px; font-weight: 600; color: var(--text); }
/* 항목 수와 쪽당 개수가 2026-09-20 에 쪽 넘김 줄에서 여기로 올라왔다 (frame-0069).
   「전체 항목」보다 약하게 보여야 그 라벨이 계속 줄의 머리로 읽힌다. */
.lf-count { font-size: 12px; line-height: 20px; color: var(--text-hint); }
.lf-count:empty { display: none; }
.lf-tools .lf-per { font-size: 12px; line-height: 20px; 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; line-height: 20px; 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; line-height: 22px; 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.*`)과는 다른 것이다. 이것은 한 메뉴 **안**에서 갈리는 줄이다.
   모양은 맨 끝 「탭 한 양식」 블록의 1차 탭이다 (2026-10-02). */

/* 기기 축 고르개 (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; line-height: 20px; 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: 8px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text-hint);
  font-size: 12px; line-height: 20px; font-weight: 600; padding: 8px 16px;
  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: 11px; line-height: 16px; padding: 1px 4px; }

/* 목록이 아직 하나도 없을 때 서는 자리 (`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; line-height: 30px; margin: 0 0 18px; color: var(--text); }
.gf-blank .gf-blank-art {
  display: inline-block; padding: 16px; margin-bottom: 18px;
  border-radius: var(--radius-card); background: var(--surface);
}
.gf-blank .gf-blank-desc {
  font-size: 12px; color: var(--text-sub); margin: 0 auto 20px; max-width: 460px; line-height: 20px;
}
/* 🔴 단추 색을 여기서 정하지 않는다. `.primary` 가 이미 주계열을 들고 있고, 그 계열이
   파랑인지 주황인지는 `frame-0085` 가 정할 자리다. 여기에 색값을 박으면 그 항목이
   시작하기도 전에 결론이 박힌다. */
.gf-blank .gf-blank-tour {
  display: block; margin-top: 16px; font-size: 12px; line-height: 20px; 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: 22px; }
/* 고른 기기에 맞는 템플릿이 없을 때 (2026-09-24). 그 기기에서 되는 길을 단추로 둔다. */
#layout-open-empty { margin-bottom: 16px; }
#layout-open-empty p { margin: 0 0 8px; }
#layout-open-empty .row { justify-content: center; flex-wrap: wrap; margin-top: 14px; }
.lf-empty strong { display: block; color: var(--text); font-size: 14px; line-height: 22px; margin-bottom: 6px; }

/* 표 보기 - 체크박스 자리는 고른 것으로 할 일이 실제로 있는 목록에만 그린다.
   자료에는 지우기 라우트가 서버에 0개라(`asset.archived_at` 을 쓰는 라우트가 없다)
   체크박스를 주면 「여러 개 골라 지우기」를 약속하게 된다 - 그래서 아직 안 준다. */
.lf-table { width: 100%; border-collapse: collapse; font-size: 14px; line-height: 22px; }
.lf-table th {
  text-align: left; font-size: 11px; line-height: 16px; font-weight: 600; letter-spacing: .25px;
  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; line-height: 22px; overflow: hidden;
}
.lf-name-btn {
  border: 0; background: none; padding: 0; font: inherit; font-size: 14px; line-height: 22px; 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: 16px; }
.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;
  /* 🔴 위에서부터 쌓는다 (2026-10-02 대표 「앱에서 섬네일 상단 흰여백」). 이 카드는 `<button>` 이라
     공통 `button, .btn { justify-content: center }` 를 물려받는다. 같은 줄 옆 카드의 설명이
     길어 카드가 늘어나면 내용 전체가 세로 가운데로 내려가서 썸네일 위에 흰 띠가 생겼다.
     썸네일 SVG(640x360 꽉 찬 그림)는 원인이 아니었다. 「내 앱」 격자 보기도 같은 카드다. */
  justify-content: flex-start;
}
.lf-tile > .lf-shot { flex: none; }
.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: 20px; 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: 14px; line-height: 22px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lf-tile-meta { font-size: 11px; line-height: 16px; color: var(--text-hint); margin-top: 2px; }
.lf-tile-when { font-size: 11px; line-height: 16px; color: var(--text-hint); margin-top: 1px; }

/* 쪽 넘김 */
.lf-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 16px 2px 0; margin-top: 12px; border-top: 1px solid var(--divider);
  font-size: 12px; line-height: 20px; color: var(--text-hint);
}
.lf-per { display: inline-flex; align-items: center; gap: 8px; }
.lf-per select {
  height: 28px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg);
  font: inherit; font-size: 12px; line-height: 20px; 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; line-height: 20px;
  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 20px; border: 0; border-radius: var(--radius-btn);
  background: var(--yd-orange); color: var(--color-white); font: inherit; font-size: 14px; line-height: 22px; font-weight: 600;
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
}
.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: 24px; }

/* 기기 목록의 「목록 보기」 - 카드를 갈아치우지 않고 빽빽하게만 만든다 */
#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: 8px 10px; }
.lf-name-cell { line-height: 22px; }
.lf-sub { line-height: 16px; }

/* 재생목록 머리의 「새 재생목록」이 파랑이라 목록 아래 주황 만들기 단추와 갈렸다.
   같은 일을 하는 단추는 같은 색이어야 한 벌로 읽힌다 */
#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: 8px;
  min-height: 38px; padding: 8px 16px; flex: none;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); color: var(--text-sub);
  font: inherit; font-size: 12px; line-height: 20px; font-weight: 500; 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 8px;
  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: 8px 10px; }
}

/* 덮개 안 - 무엇이 나가는지, 누가 고쳤는지, 어느 기기가 받아 갔는지 */
#push-body h3 { margin: 18px 0 8px; font-size: 14px; line-height: 22px; }
#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: 14px; line-height: 22px;
}
.push-row .push-kind { color: var(--text-hint); flex: none; }
.push-row .push-title { font-weight: 500; color: var(--text); word-break: keep-all; }
.push-row .push-at, .push-row .push-who { color: var(--text-hint); font-size: 12px; line-height: 20px; }
.push-row .push-who { margin-left: auto; }
.push-dev {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 0; border-bottom: 1px solid var(--divider); font-size: 14px; line-height: 22px;
}
.push-dev .push-dot { color: var(--text-hint); font-size: 11px; }
.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; line-height: 20px; }
.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; line-height: 24px; 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; line-height: 20px; letter-spacing: .25px;
}
.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; line-height: 36px;}
.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:8px;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; line-height: 30px;}
.asset-confirm-dialog p{line-height:22px;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:8px;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; line-height: 28px;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: 14px; line-height: 22px;}
.asset-weekly-dialog th,.asset-weekly-dialog td{padding:10px 8px;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:4px 0;margin:0;border:0;box-shadow:none;font-size: 12px; line-height: 20px;}
.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: 20px;padding:4px 4px}
.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; line-height: 30px;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: 14px; line-height: 22px;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; line-height: 20px;}
.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; line-height: 22px;}.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: 14px; line-height: 22px;}
.media-edit-tag-chips{display:contents}.media-edit-tag-chips button{border:0;background:none;padding:0 4px;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:4px;min-height:44px;border:1px solid var(--color-gray-400);border-radius:3px;padding:4px 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 4px;font-size: 14px; line-height: 22px;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 16px;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; line-height: 22px;}
.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; line-height: 20px;}.media-tag-sort:hover{background:none}
#panel-media-tags>h1{font-size: 24px; line-height: 36px;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:16px 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: 14px; line-height: 22px;}.media-period-dates input[type=datetime-local]{margin-top:6px;width:100%;min-width:0;font-size: 12px; line-height: 20px;padding:10px 8px}
.media-period-dates .media-nonexpiring{display:flex;align-items:center;gap:8px;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 24px 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:8px}.media-edit-row>label{text-align:left}.media-period-dates{margin-left:0;grid-template-columns:1fr}.media-edit-buttons{gap:8px}.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:4px 4px}}
.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; line-height: 30px;}
#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 20px; 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; line-height: 20px; 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:16px; }
.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; line-height: 22px;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; line-height: 28px;font-weight:500}
.media-usage-dialog header button{padding:0;border:0;background:none;font-size: 20px;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; line-height: 22px;}
.media-usage-body summary{cursor:pointer;list-style:none;padding:8px 0 20px;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:8px 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; line-height: 22px;font-weight:400;text-align:left;white-space:nowrap;padding:8px 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; line-height: 28px;font-weight:500;margin:0}
.media-screens-dialog header button{border:0;padding:0;background:none;font-size: 20px;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:16px;margin:10px 0 26px;align-items:start;font-size: 14px; line-height: 22px;}
.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; line-height: 22px;}
.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; line-height: 20px;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:20px}
.media-screen-types label{display:flex;align-items:center;gap:8px;font-size: 14px; line-height: 22px;}
.media-screen-types input{width:18px;height:18px;margin:0}
@media(max-width:600px){.media-screen-row{grid-template-columns:1fr;gap:8px}.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: 16px 20px 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 20px 20px; display: flex; flex-direction: column; gap: 16px; }
.dash-hello-text { margin: 0; font-size: 18px; font-weight: 600; line-height: 28px; color: var(--color-white); }
.dash-hello-sub { margin: 0; font-size: 14px; line-height: 22px; 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; line-height: 22px;
  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; line-height: 24px; font-weight: 500; margin: 14px 0 6px; color: var(--ink); }
.dash-empty-body { font-size: 12px; line-height: 20px; color: var(--muted); margin: 0; }

.dash-line { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0;
  font-size: 14px; line-height: 22px; 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: 14px; font-weight: 600; color: var(--ink);
  line-height: 22px; overflow-wrap: anywhere; }
.dash-notice-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 4px; font-size: 12px; line-height: 20px; 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; line-height: 20px; justify-content: center; text-align: center; }
.dash-notice-hint { font-size: 12px; line-height: 20px; }

/* 업종 템플릿 입구. 넓은 3열에서 네 장이 한 줄이고, 좁아지면 둘씩 접힌다. */
.dash-tpl-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.dash-tpl { display: flex; flex-direction: column; gap: 8px; text-decoration: none; color: var(--ink);
  font-size: 12px; line-height: 20px; 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; line-height: 20px; color: var(--muted); }
.dash-act-what { font-size: 14px; line-height: 22px; 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: 16px 16px;
  text-align: left;
  font-size: 12px; line-height: 20px;
  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: 14px; 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: 8px; 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: 24px;
  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: 14px; line-height: 22px; color: var(--text-sub); }
.home-lead { margin: 0 0 10px; font-size: 24px; line-height: 36px; font-weight: 700;
  letter-spacing: .25px; color: var(--text); word-break: keep-all; }
.home-sub { margin: 0 0 22px; font-size: 14px; line-height: 22px; 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; line-height: 24px; font-weight: 700;
  padding: 16px 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: 14px; line-height: 22px; font-weight: 600; padding: 13px 20px; 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: 12px; line-height: 20px; color: var(--text-sub); }
.home-latest-empty { margin: 0; padding: 24px; border: 2px dashed var(--color-blue-400); border-radius: 12px;
  text-align: center; color: var(--text-sub); font-size: 14px; line-height: 22px; 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; line-height: 20px; 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; line-height: 28px; font-weight: 700; color: var(--text); }
.home-card-meta { font-size: 14px; line-height: 22px; 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: 16px; }
.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;
  /* 위에서부터 쌓는다 - button 공통 justify-content:center 를 받으면 2열 격자에서 TV(16:9) 옆
     가격표(긴 비율) 칸의 그림이 가운데로 내려가 줄이 안 맞는다 (2026-10-02). */
  justify-content: flex-start; }
.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; line-height: 20px; 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 8px;
  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; line-height: 16px; 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: 8px; max-width: 86%; padding: 0 8px;
  font-size: 12px; line-height: 20px; 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: 4px; min-width: 0; }
.home-tile-name { font-size: 14px; line-height: 22px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.home-tile-state { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; line-height: 20px; 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-tile-more { gap: 2px; text-align: center; }
.home-tile-more-title { font-size: 14px; line-height: 22px; font-weight: 700; color: var(--primary); }
.home-tile-more-sub { font-size: 12px; line-height: 20px; font-weight: 500; color: var(--text-sub); }
.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; line-height: 28px; 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: 14px; line-height: 22px; 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: 12px; line-height: 20px; 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: 24px; }
  .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: 14px; line-height: 22px; }
}

/* 메뉴 접기 (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: .25px; }
.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; }
/* GENCY POP 로고 (2026-10-02). 로고 자체에 심볼이 있으므로 그라데이션 점은 접는다.
   정본은 docs/brand/gencypop, 웹 사본은 web/brand. */
.topbar .brand:has(.brand-logo) { align-items: center; }
.topbar .brand:has(.brand-logo)::before { display: none; }
.brand .brand-logo { display: block; height: 24px; width: auto; flex: none; }
@media (max-width: 767px) { .brand .brand-logo { height: 22px; } }
@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: .25px; }

/* ===================================================== 관리 화면 - 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 16px; gap: 8px;
  border-radius: 8px; border-color: var(--color-gray-300);
  background: var(--color-white); color: var(--color-gray-700);
  font-size: 14px; line-height: 22px; 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: 4px; 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; line-height: 20px; 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; line-height: 22px; 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; line-height: 20px; 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 8px; line-height: 16px; height: 16px;
  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; line-height: 22px; 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: 12px; line-height: 20px; 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; line-height: 22px; 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 8px; }
  .topbar #btn-logout { padding: 0 8px; font-size: 14px; line-height: 22px; }
}
.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: var(--font-sans); }
.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; line-height: 28px; font-weight: 800; letter-spacing: .25px; }
.lp-nav { display: flex; gap: 4px; margin-right: auto; margin-left: 28px; }
.lp-nav a { padding: 8px 16px; border-radius: 8px; font-size: 16px; line-height: 24px; 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; line-height: 22px; }
.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; line-height: 22px; font-weight: 700; color: var(--color-blue-600); margin-bottom: 16px; }
.lp-h1 { font-size: 50px; line-height: 70px; font-weight: 800; letter-spacing: 0; 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; line-height: 28px; 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; line-height: 24px; }
.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: 16px; line-height: 24px; }
.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 20px; border-radius: 999px; background: var(--color-white);
  font-size: 16px; line-height: 24px; 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; line-height: 22px; font-weight: 700; color: var(--color-blue-600); }
.lp-center { text-align: center; }
.lp-h2 { font-size: 36px; line-height: 45px; font-weight: 800; letter-spacing: .25px; }
.lp-sub { font-size: 16px; line-height: 24px; color: var(--color-gray-600); }
.lp-sub.lp-center { max-width: 40em; margin-left: auto; margin-right: auto; margin-bottom: 36px; }
.lp-sec { padding: 140px 0; } /* DESIGN.md v3.2 - gency 랜딩 섹션 위아래 140 */
.lp-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.lp-feat h3 { margin: 20px 4px 6px; font-size: 24px; line-height: 36px; font-weight: 800; letter-spacing: .25px; }
.lp-feat p { margin: 0 4px; font-size: 16px; line-height: 24px; 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: 100px 40px; } /* 짧은 띠 100 */
.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; line-height: 28px; font-weight: 800; }
.lp-steps p, .lp-faq p { font-size: 16px; line-height: 24px; }
.lp-faq summary { font-size: 16px; line-height: 24px; }
.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; line-height: 54px; font-weight: 800; letter-spacing: .25px; 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: 14px; line-height: 22px; }
.lp-bottom-brand { font-size: 16px; line-height: 24px; 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.03em; 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: 36px; }
  .lp-lede { font-size: 16px; line-height: 24px; }
  .lp-h2, .lp-contact .lp-last-h { font-size: 24px; line-height: 36px; }
  .lp-sec { padding: 56px 0; }
  .lp-duo { grid-template-columns: 1fr; }
  .lp-feat-shot { padding: 24px 20px; }
  .lp-sec-tint { padding: 40px 20px; }
}
@media (max-width: 599px) {
  .lp-h1 { font-size: 24px; }
  .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; line-height: 20px; font-weight: 700; letter-spacing: .25px; }
.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: 16px; 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: 8px; margin: 0 0 10px; font-size: 14px; line-height: 22px; 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: 4px; border-radius: 10px;
  font-size: 12px; line-height: 16px; 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: 18px; line-height: 28px; font-weight: 800; letter-spacing: .25px; color: var(--color-gray-900); }
.lp-tvfeat p { margin: 0; font-size: 16px; line-height: 24px; 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: 22px; color: var(--color-gray-600); }
.lp-einkpair figcaption b { display: block; margin-bottom: 2px; font-size: 16px; line-height: 24px; 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 16px; border-radius: 999px; border: 1px solid var(--color-gray-200); background: var(--color-gray-100);
  font-size: 14px; line-height: 22px; 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; line-height: 22px; 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: 8px; border-radius: 12px; }
  .lp-tv-screen { border-radius: 4px; }
  .lp-tv-res { right: 12px; bottom: 12px; font-size: 11px; line-height: 16px; padding: 4px 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: 8px; }
  .lp-pl li { flex-direction: column; align-items: stretch; gap: 4px; padding: 4px; font-size: 11px; line-height: 16px;
    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; line-height: 22px;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 24px;box-shadow:0 4px 21px rgba(0,0,0,.05)}
.lp-fit-col h3{margin:0 0 14px;font-size: 18px; line-height: 28px;}
.lp-fit-col ul{margin:0;padding:0;list-style:none;display:grid;gap:10px}
.lp-fit-col li{position:relative;padding-left:24px;word-break:keep-all;line-height: 24px;font-size: 16px}
.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: 28px}
@media (max-width:760px){.lp-fit{grid-template-columns:1fr}}

/* ---------------------------------------------------------------- 메뉴 아이콘 한 벌 (frame-0084, 2026-09-23)
   🔴 **크기를 한 값으로 묶는다.** 고치기 전에는 중단점마다 다른 규칙이 덮여 데스크톱 18px,
   아래쪽 탭 25.19px(글자 크기 19px 의 1.2em), 「더보기」만 24px 이었다 - 한 줄 안에서 하나만
   작았다. 이제 메뉴의 모든 칸이 `--nav-ico` 하나를 쓴다. 선 굵기는 판(24칸)의 1.8 이라
   20px 에서 1.5px, 22px 에서 1.65px 로 같은 화면 안에서는 전부 같다.
   색은 칸의 글자색(currentColor)을 따른다 - 고른 칸 파랑, 안 고른 칸 회색이 그대로 온다. */
.tabbar { --nav-ico: 20px; }
@media (max-width: 767px) { .tabbar { --nav-ico: 22px; } }
.tabbar :is(.nav-scroll, .nav-grp, .nav-foot) :is(button, a) .ico,
.tabbar .nav-more .ico { width: var(--nav-ico); height: var(--nav-ico); font-size: var(--nav-ico); flex: none; }
.tabbar :is(.nav-scroll, .nav-grp, .nav-foot) :is(button, a) .ico svg,
.tabbar .nav-more .ico svg { width: var(--nav-ico); height: var(--nav-ico); stroke-width: 1.8; }

/* ================================================================ 스케줄 화면 (2026-09-24 개편)
   대표님 지시 「스케줄 메뉴는 UI 깨진 것도 있고, 사람들이 세팅하기 편하게 UI/UX 다시 짜고」.
   🔴 전부 `#panel-schedules` 와 스케줄 덮개(`.sch-*`) 안에 가둔다. 다른 탭의 모양을 안 건드린다.
   색은 GENCY DS v3.0 토큰만 쓴다(docs/DESIGN.md 규칙 1). 근거는 docs/스케줄-UIUX-외부사례-2026-09-24.md. */

/* 물음표가 세로로 늘어난 타원이었다(22×44). 버튼 공통 최소 높이가 이긴 탓이다. */
#panel-schedules .page-help-btn { min-height: 22px; height: 22px; }
.sch-alert { margin: 0 0 12px; }

/* ---------------- 목록 보기 */
/* 2026-10-02 390 폭에서 새로고침 단추가 혼자 한 줄에 놓였다(칸 320 + 단추 40 + 간격 > 358). 칸이 줄고 한 줄에 남는다 */
.sch-filter { display: flex; align-items: flex-end; gap: 8px; margin-bottom: 12px; flex-wrap: nowrap; }
.sch-filter-field { display: grid; gap: 4px; flex: 1 1 0; max-width: 320px; min-width: 0; }
.sch-filter-field select { width: 100%; }
.sch-icon-btn { width: 40px; min-width: 40px; height: 40px; padding: 0; font-size: 16px; flex: none; }
.sch-now-line { background: var(--bg); border-radius: var(--radius-card); padding: 12px 16px; margin-bottom: 12px; display: grid; gap: 2px; }
/* 「걸린 화면」 칸의 긴 이름이 줄을 안 바꿔서 휴대폰 폭 문서가 옆으로 넘쳤다(실측 628px). */
#sched-lf .lf-c-type { white-space: normal; overflow-wrap: anywhere; max-width: 260px; }
#sched-lf .lf-name-btn { white-space: normal; overflow-wrap: anywhere; text-align: left; }
/* 스케줄에는 폴더도 거르개도 보기 전환도 없다. 눌러도 아무 일 없는 칸은 걷는다. */
#sched-lf .lf-tools .lf-btn, #sched-lf .lf-tools .lf-view { display: none; }
@media (max-width: 767px) {
  #sched-lf .lf-c-type, #sched-lf .lf-c-when { display: none; }
}

/* ---------------- 상세 머리 */
.sch-top { display: grid; gap: 10px; margin-bottom: 14px; }
.sch-back { justify-self: start; border-color: transparent; padding-left: 4px; color: var(--text-sub); }
.sch-name-row { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.sch-name-field { display: grid; gap: 4px; flex: 1 1 260px; min-width: 0; }
.sch-name-field input { font-size: 18px; line-height: 28px; font-weight: 700; }
.sch-del { color: var(--danger); }
.sch-del:hover { background: var(--color-red-100); }

/* 세 걸음 */
.sch-steps { list-style: none; margin: 0 0 14px; padding: 12px 16px; display: flex; gap: 8px 20px; flex-wrap: wrap;
  background: var(--color-blue-50); border: 1px solid var(--color-blue-200); border-radius: var(--radius-card); }
.sch-steps li { display: flex; align-items: center; gap: 8px; font-size: 14px; line-height: 22px; color: var(--text-sub); }
.sch-steps li.done { color: var(--text-hint); text-decoration: line-through; }
.sch-step-no { width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg); border: 1px solid var(--color-blue-400); font-size: 12px; line-height: 20px; font-weight: 700; color: var(--primary); flex: none; }
.sch-steps li.done .sch-step-no { background: var(--primary); color: var(--color-white); border-color: var(--primary); }

/* 지금 매장 화면 */
.sch-live { background: var(--bg); border-radius: var(--radius-card); padding: 16px 16px; margin-bottom: 14px; box-shadow: var(--shadow-md); }
.sch-live-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 14px; line-height: 22px; }
.sch-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-red-600); box-shadow: 0 0 0 3px var(--color-red-100); }
.sch-live-list { display: grid; gap: 8px; }
.sch-live-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1.4fr); gap: 4px 12px; align-items: baseline;
  font-size: 14px; line-height: 22px; padding: 8px 0; border-top: 1px solid var(--divider); }
.sch-live-row:first-child { border-top: 0; }
.sch-live-dev { color: var(--text-sub); overflow-wrap: anywhere; }
.sch-live-pl { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.sch-live-why { color: var(--text-hint); font-size: 12px; line-height: 20px; }
.sch-live-row.src-takeover .sch-live-why, .sch-live-row.src-pop .sch-live-why { color: var(--warn-text); }
.sch-live-row.src-none .sch-live-pl { color: var(--text-hint); }
@media (max-width: 640px) { .sch-live-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .sch-live-why { grid-column: 1 / -1; } }

/* ---------------- 두 칸: 달력 | 옆 칸 */
.sch-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
@media (min-width: 1100px) { .sch-layout { grid-template-columns: minmax(0, 1fr) 320px; } }
.sch-side { display: grid; gap: 16px; min-width: 0; }
@media (min-width: 768px) and (max-width: 1099px) { .sch-side { grid-template-columns: repeat(2, minmax(0, 1fr)); } .sch-side > :last-child { grid-column: 1 / -1; } }
.sch-side-card, .sch-cal-card { margin: 0; min-width: 0; }
.sch-side-card h2, .sch-cal-card h2 { font-size: 16px; line-height: 24px; margin: 0; }
.sch-side-head { gap: 8px; margin-bottom: 8px; }
.sch-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0; }
.sch-chips .chip, .sch-chips .badge { min-height: 0; height: auto; padding: 4px 10px; align-items: center; }
.sch-wrap { white-space: normal; overflow-wrap: anywhere; max-width: 100%; }
.sch-filler-row { overflow-wrap: anywhere; }

.sch-cal-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.sch-cal-top > div { min-width: 0; flex: 1 1 220px; }

/* 빠른 시작 */
.sch-start { border: 1px dashed var(--color-blue-400); background: var(--color-blue-50); border-radius: var(--radius-card); padding: 16px; margin-bottom: 12px; }
.sch-start-head { display: grid; gap: 2px; margin-bottom: 10px; }
.sch-start-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px; }
.sch-tpl { display: grid; gap: 4px; justify-items: start; text-align: left; background: var(--bg); border-color: var(--color-blue-200);
  padding: 12px 16px; white-space: normal; height: auto; }
.sch-tpl:hover { border-color: var(--primary); background: var(--bg); }
.sch-tpl-name { font-weight: 700; color: var(--text); font-size: 14px; line-height: 22px; }
.sch-tpl-sub { font-size: 12px; color: var(--text-hint); line-height: 16px; }
.sch-tpl-row { border: 1px solid var(--divider); border-radius: var(--radius-ctl); padding: 10px 12px; }
.sch-tpl-row-head { margin-bottom: 6px; font-size: 14px; line-height: 22px; }
.sch-tpl-row-body { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
.sch-tpl-row-body .field { margin: 0; min-width: 0; }
@media (max-width: 520px) { .sch-tpl-row-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .sch-tpl-row-body .field:first-child { grid-column: 1 / -1; } }

/* 주간 달력. 요일 칸 일곱 + 시각 칸. 휴대폰 폭에서는 하루씩 본다 - 일곱 칸을 390px 에
   넣으면 블록이 44px 폭의 가는 조각이 되어 이름이 안 읽힌다(Google Calendar 사용자 불만과 같다). */
.sch-daytabs { display: none; gap: 4px; margin-bottom: 8px; }
.sch-daytab { flex: 1 1 0; min-width: 0; padding: 8px 0; font-size: 14px; line-height: 22px; }
.sch-daytab.on { background: var(--primary); border-color: var(--primary); color: var(--color-white); font-weight: 700; }
.sch-daytab.today:not(.on) { border-color: var(--primary); color: var(--primary); }
.sch-cal { border: 1px solid var(--divider); border-radius: var(--radius-ctl); overflow: hidden; background: var(--bg); }
.sch-cal-head, .sch-cal-body { display: grid; grid-template-columns: 48px repeat(7, minmax(0, 1fr)); }
.sch-cal-head { border-bottom: 1px solid var(--divider); background: var(--color-gray-100); }
.sch-dh { text-align: center; font-size: 12px; line-height: 20px; font-weight: 600; color: var(--text-sub); padding: 8px 0; border-left: 1px solid var(--divider); }
.sch-dh.today { color: var(--primary); }
.sch-cal-scroll { max-height: 560px; overflow-y: auto; overscroll-behavior: contain; }
.sch-cal-body { position: relative; }
.sch-gut { position: relative; }
.sch-hr { position: absolute; right: 6px; transform: translateY(-50%); font-size: 11px; line-height: 16px; color: var(--text-hint); font-variant-numeric: tabular-nums; }
.sch-col { position: relative; border-left: 1px solid var(--divider); cursor: crosshair; touch-action: pan-y;
  background-image: linear-gradient(var(--divider) 1px, transparent 1px); background-size: 100% 40px; user-select: none; }
.sch-block { position: absolute; display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 0;
  padding: 4px 8px 4px 8px; border: 0; border-left: 3px solid; border-radius: 6px; overflow: hidden; text-align: left;
  font-size: 12px; line-height: 16px; min-height: 0; cursor: pointer; box-shadow: -1px 0 0 var(--bg), 0 1px 3px rgba(91, 105, 115, .16); }
.sch-block:hover { filter: brightness(.97); }
.sch-block:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.sch-b-name { font-weight: 700; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 16px; }
.sch-b-time { font-size: 11px; line-height: 16px; opacity: .85; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.sch-b-rank { position: absolute; top: 3px; right: 4px; min-width: 14px; height: 14px; border-radius: 7px; font-size: 11px; line-height: 16px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .8); }
.sch-block.tiny { flex-direction: row; align-items: center; gap: 4px; padding-top: 0; padding-bottom: 0; }
.sch-block.tiny .sch-b-time { display: none; }
.sch-block.tiny .sch-b-rank { top: 50%; transform: translateY(-50%); }
.sch-block.off { opacity: .55; border-left-style: dashed; filter: grayscale(.7); }
.sch-block.live { box-shadow: 0 0 0 2px var(--color-red-600); }
.sch-b-live { position: absolute; left: 8px; bottom: 3px; font-size: 11px; line-height: 16px; font-weight: 700; color: var(--color-white);
  background: var(--color-red-600); border-radius: 4px; padding: 0 4px; white-space: nowrap; }
.sch-block.tiny .sch-b-live { display: none; }
/* 가려지는 시간 - 빗금. 순서가 위인 일정이 덮고 있어 이 시간에는 안 나온다. */
.sch-shadow { position: absolute; left: 0; right: 0; pointer-events: none;
  background: repeating-linear-gradient(135deg, rgba(24, 27, 30, .16) 0 4px, transparent 4px 8px); }
.sch-nowline { position: absolute; left: 0; right: 0; height: 2px; background: var(--color-red-600); z-index: 60; pointer-events: none; }
.sch-nowline::before { content: ''; position: absolute; left: -5px; top: -4px; width: 10px; height: 10px; border-radius: 50%; background: var(--color-red-600); }
.sch-ghost { position: absolute; left: 2px; right: 2px; border-radius: 6px; background: var(--color-blue-200); border: 2px dashed var(--primary);
  font-size: 11px; line-height: 16px; font-weight: 700; color: var(--color-blue-900); padding: 2px 8px; z-index: 61; pointer-events: none; }
.sch-c0, .sch-c0:hover { background-color: var(--color-blue-100); border-color: var(--color-blue-600); color: var(--color-blue-1000); }
.sch-c1, .sch-c1:hover { background-color: var(--color-purple-100); border-color: var(--color-purple-600); color: var(--color-purple-1000); }
.sch-c2, .sch-c2:hover { background-color: var(--color-green-100); border-color: var(--color-green-600); color: var(--color-green-1000); }
.sch-c3, .sch-c3:hover { background-color: var(--color-orange-100); border-color: var(--color-orange-600); color: var(--color-orange-1000); }
.sch-c4, .sch-c4:hover { background-color: var(--color-red-100); border-color: var(--color-red-600); color: var(--color-red-1000); }
.sch-c5, .sch-c5:hover { background-color: var(--color-gray-200); border-color: var(--color-gray-600); color: var(--color-gray-900); }
.sch-dot { width: 10px; height: 10px; border-radius: 3px; border: 2px solid; flex: none; }
@media (max-width: 640px) {
  .sch-daytabs { display: flex; }
  .sch-cal-head, .sch-cal-body { grid-template-columns: 48px minmax(0, 1fr); }
  .sch-cal-head .sch-dh:not(.on), .sch-cal-body .sch-col:not(.on) { display: none; }
  .sch-cal-scroll { max-height: 460px; }
}
.sch-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 10px; font-size: 12px; line-height: 20px; color: var(--text-hint); }
.sch-lg { display: inline-flex; align-items: center; gap: 8px; }
.sch-lg i { width: 18px; height: 12px; border-radius: 3px; display: inline-block; flex: none; }
.sch-lg-shadow { background: repeating-linear-gradient(135deg, rgba(24, 27, 30, .3) 0 3px, var(--color-blue-100) 3px 6px); }
.sch-lg-off { border: 1px dashed var(--color-gray-500); background: var(--color-gray-150); }
.sch-lg i.sch-lg-now { height: 2px; background: var(--color-red-600); }
.sch-lg-empty { border: 1px solid var(--divider); background: var(--bg); }

/* 일정 순서 목록 */
.sch-rank { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.sch-rank-row { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; grid-template-areas: 'no main move' '. tags tags';
  align-items: center; gap: 2px 8px; padding: 8px 0; border-top: 1px solid var(--divider); }
.sch-rank-row:first-child { border-top: 0; }
.sch-rank-row.off .sch-rank-main { opacity: .6; }
.sch-rank-no { grid-area: no; font-size: 12px; line-height: 20px; font-weight: 700; color: var(--text-hint); text-align: center; }
.sch-rank-main { grid-area: main; display: flex; align-items: center; gap: 8px; border: 0; padding: 4px; justify-content: flex-start;
  text-align: left; min-width: 0; min-height: 0; background: none; }
.sch-rank-main:hover { background: var(--color-gray-150); }
.sch-rank-text { display: grid; min-width: 0; }
.sch-rank-name { font-weight: 600; color: var(--text); font-size: 14px; line-height: 22px; overflow-wrap: anywhere; }
.sch-rank-sub { font-size: 12px; line-height: 20px; color: var(--text-hint); overflow-wrap: anywhere; }
.sch-rank-tags { grid-area: tags; display: flex; gap: 4px; flex-wrap: wrap; }
.sch-rank-move { grid-area: move; display: flex; gap: 2px; }
.sch-rank-move .sch-icon-btn { width: 32px; min-width: 32px; height: 32px; min-height: 32px; font-size: 14px; }
.sch-live-badge { background: var(--color-red-100); color: var(--color-red-900); }

/* ---------------- 덮개 */
.sch-modal { max-width: 560px; }
.sch-editor { max-width: 520px; }
.sch-daypick { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.sch-day { position: relative; display: flex; }
.sch-day input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.sch-day span { flex: 1; text-align: center; padding: 8px 0; border: 1px solid var(--line); border-radius: var(--radius-ctl);
  font-size: 12px; line-height: 20px; color: var(--text-sub); background: var(--bg); }
.sch-day input:checked + span { background: var(--primary); border-color: var(--primary); color: var(--color-white); font-weight: 700; }
.sch-day input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 2px; }
.sch-presets { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.sch-presets .chip { padding: 4px 10px; font-size: 12px; line-height: 20px; min-height: 0; }
.sch-times { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
.sch-times .field { margin: 0; min-width: 0; }
.sch-summary { margin: 0; padding: 10px 12px; border-radius: var(--radius-ctl); background: var(--color-blue-50); color: var(--text); font-size: 14px; line-height: 22px; }
.sch-summary:empty { display: none; }
.sch-editor-actions { align-items: center; }
.sch-spacer { flex: 1; }
.sch-pick-list { display: grid; gap: 8px; max-height: 50vh; overflow-y: auto; }
/* 「다른 스케줄: … - 옮겨집니다」 배지가 한 줄로 고정돼 긴 이름에서 덮개 밖으로 나갔다. */
.sch-pick .badge { white-space: normal; overflow-wrap: anywhere; max-width: 46%; text-align: right; }
.sch-pick .pl-dev-name { overflow-wrap: anywhere; }
@media (max-width: 767px) {
  .sch-day span { padding: 10px 0; }
  .sch-presets .chip { min-height: 36px; }
  .sch-rank-move .sch-icon-btn { width: 40px; min-width: 40px; height: 40px; min-height: 40px; }
}

/* ============================================================ 묶음 A · B · D (2026-09-24)
   만들기 창 덮개 · 대시보드 「TV 에 화면 걸기」 · TV 에 걸기 · 기기 추가 · 상태 칩.
   🔴 만들기 창은 어디서 불러도 이 덮개 한 자리다. 예전에는 부른 카드 뒤에 붙어 1440 에서
      폭 558px · 2569px 아래에 섰다. 덮개 z-index 는 모달(50) 아래 - 덮개 안에서 여는
      확인 창과 「TV 에 걸기」 가 그 위에 떠야 한다. */
.create-overlay { position: fixed; inset: 0; z-index: 40; background: rgba(0, 0, 0, .45);
  overflow-y: auto; overscroll-behavior: contain; padding: 32px 24px 48px; }
.create-overlay.hidden { display: none; }
.create-overlay > .create-dialog { max-width: 1120px; margin: 0 auto; box-shadow: var(--shadow-xl);
  grid-column: auto; scroll-margin-top: 0; }
.create-overlay .create-dialog-head { position: sticky; top: -32px; z-index: 2; background: inherit; }
.create-overlay .editor-preview { top: 76px; }
body.editing-content { overflow: hidden; }
@media (max-width: 600px) {
  .create-overlay { padding: 0; background: var(--page); }
  .create-overlay > .create-dialog { min-height: 100%; margin: 0; border-radius: 0; border: 0; box-shadow: none; }
  .create-overlay .create-dialog-head { top: 0; }
}

/* 대시보드 「TV 에 화면 걸기」 세 걸음 */
.home-tv { margin-bottom: 16px; }
.home-tv[hidden] { display: none; }
.home-tv-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.home-tv-step { display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; align-items: center; gap: 16px;
  padding: 16px 16px; border: 1px solid var(--divider); border-radius: var(--radius-ctl); background: var(--bg); }
.home-tv-step.next { border-color: var(--primary); background: var(--primary-soft); }
.home-tv-num { width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px; line-height: 22px; background: var(--surface); color: var(--text-sub); }
.home-tv-step.next .home-tv-num { background: var(--primary); color: var(--color-white); }
.home-tv-step.done .home-tv-num { background: var(--color-green-100); color: var(--color-green-1000); }
.home-tv-name { margin: 0; font-weight: 700; font-size: 14px; line-height: 22px; color: var(--text); }
.home-tv-desc { margin: 2px 0 0; font-size: 12px; line-height: 20px; color: var(--text-sub); }
.home-tv-step.done .home-tv-name { color: var(--text-sub); }
.home-tv-acts { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 600px) {
  .home-tv-step { grid-template-columns: 28px minmax(0, 1fr); padding: 12px; gap: 10px; }
  .home-tv-num { width: 28px; height: 28px; font-size: 14px; line-height: 22px; }
  .home-tv-acts { grid-column: 1 / -1; justify-content: stretch; }
  .home-tv-acts button { flex: 1 1 0; min-height: 44px; }
}
#home-screens-meta[role="button"] { cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

/* TV 에 걸기 창 */
.hang-modal { max-width: 560px; }
.hang-sec { margin: 14px 0; }
.hang-sec > .lbl { margin: 0 0 8px; font-size: 12px; line-height: 20px; font-weight: 700; color: var(--text-sub); }
.hang-pops { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px; max-height: 260px; overflow-y: auto; }
.hang-pop { display: flex; flex-direction: column; gap: 8px; padding: 8px; min-width: 0; text-align: left;
  border: 2px solid var(--divider); border-radius: var(--radius-ctl); background: var(--bg); cursor: pointer; }
.hang-pop.on { border-color: var(--primary); background: var(--primary-soft); }
.hang-pop-thumb { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: contain; background: var(--surface); border-radius: 4px; }
.hang-pop-name { font-size: 12px; line-height: 20px; color: var(--text); }
.hang-devs { display: grid; gap: 8px; }
.hang-dev { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; align-items: center;
  padding: 10px 12px; border: 1px solid var(--divider); border-radius: var(--radius-ctl); cursor: pointer; }
.hang-dev input { width: 18px; height: 18px; margin: 0; grid-row: 1 / span 2; }
.hang-dev-name { font-weight: 600; font-size: 14px; line-height: 22px; overflow-wrap: anywhere; }
.hang-dev-now { font-size: 12px; line-height: 20px; color: var(--text-hint); overflow-wrap: anywhere; }
.hang-mode { display: flex; gap: 8px; align-items: flex-start; font-size: 14px; line-height: 22px; margin: 8px 0; cursor: pointer; }
.hang-mode[hidden] { display: none; }
.hang-result { min-height: 1.4em; margin: 8px 0 0; font-size: 12px; line-height: 20px; color: var(--text-sub); }
.hang-result.ok { color: var(--color-green-1000); font-weight: 600; }
.hang-result.bad { color: var(--danger); }
.hang-return { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 45;
  display: flex; align-items: center; gap: 10px; max-width: calc(100vw - 32px);
  padding: 10px 10px 10px 16px; border-radius: 12px; background: var(--color-gray-900); color: var(--color-white);
  box-shadow: var(--shadow-xl); font-size: 14px; line-height: 22px; }
.hang-return[hidden] { display: none; }
.hang-return-text { min-width: 0; overflow-wrap: anywhere; }
.hang-return .hang-return-x { color: var(--color-white); border-color: transparent; background: transparent; }
@media (max-width: 600px) {
  .hang-return { left: 16px; right: 16px; transform: none; bottom: 16px; flex-wrap: wrap; }
  .hang-return-text { flex: 1 1 100%; }
}

/* 기기 추가 - TV 가 앞, 전자종이는 옵션 */
.dev-add h2 { margin: 0 0 12px; }
.dev-add-kinds { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 10px; }
.dev-add-kind { display: flex; align-items: center; gap: 16px; padding: 16px; text-align: left; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--radius-ctl); background: var(--bg); cursor: pointer; }
.dev-add-kind.tv { border: 2px solid var(--primary); background: var(--primary-soft); }
.dev-add-kind:hover { background: var(--surface); }
.dev-add-icon svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.dev-add-kind.tv .dev-add-icon { color: var(--primary); }
.dev-add-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dev-add-name { font-weight: 700; font-size: 14px; line-height: 22px; color: var(--text); }
.dev-add-desc { font-size: 12px; line-height: 20px; color: var(--text-sub); }
@media (max-width: 600px) { .dev-add-kinds { grid-template-columns: 1fr; } }
.dev-form-tv { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 14px; padding: 10px 12px;
  border-radius: var(--radius-ctl); background: var(--surface); font-size: 12px; line-height: 20px; color: var(--text-sub); }

/* 기기 탭 상태 칩 · 매장 거르개 */
.dev-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 10px; }
.dev-state { display: flex; gap: 8px; flex-wrap: wrap; }
.dev-state-chip { display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; min-height: 36px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--bg); color: var(--text); font-size: 14px; line-height: 22px; cursor: pointer; }
.dev-state-chip.on { border-color: var(--text); background: var(--sel-bg); font-weight: 700; }
.dev-state-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-hint); }
.dev-state-chip.online .dev-state-dot { background: var(--color-green-600); }
.dev-state-chip.offline .dev-state-dot { background: var(--danger); }
.dev-state-chip.waiting .dev-state-dot { background: var(--warn); }
.dev-state-n { color: var(--text-sub); }
.dev-store-filter { margin-left: auto; min-width: 140px; max-width: 100%; }
@media (max-width: 600px) { .dev-store-filter { margin-left: 0; flex: 1 1 100%; } }

/* 개통 창 - TV 안내 두 줄과 큰 코드 칸 */
.claim-tv-note { margin: 0 0 14px; padding: 12px 12px 12px 32px; border-radius: var(--radius-ctl); background: var(--primary-soft);
  font-size: 14px; line-height: 22px; color: var(--text); }
.claim-tv-note[hidden] { display: none; }
input.code-input.code-input-lg { font-size: 36px !important; line-height: 54px; padding: 16px 8px; min-height: 64px; }
.claim-new-store { margin: 0 0 12px; }
.claim-new-store[hidden] { display: none; }
.claim-new-row { display: flex; gap: 8px; }
.claim-new-row input { flex: 1 1 auto; min-width: 0; }
.field[hidden] { display: none; }

/* 사진 · 손글씨로 만들기 (2026-09-24). 점주가 눈으로 확인만 하게 큰 글씨 · 큰 단추다. */
#edit-banner:not(.hidden) ~ #photo-ai-card { display: none; }
.photo-ai-card { padding: 0; overflow: hidden; }
.photo-ai-entry { display: flex; align-items: center; gap: 16px; width: 100%; padding: 20px 20px; border: 0; background: var(--color-blue-50, #eef4ff); color: inherit; text-align: left; cursor: pointer; font: inherit; }
.photo-ai-entry:hover { background: var(--color-blue-100, #e0ebff); }
.photo-ai-entry strong { display: block; font-size: 20px; line-height: 30px; margin-bottom: 4px; }
.photo-ai-entry .hint { display: block; margin: 0; }
.photo-ai-entry-icon { font-size: 36px; line-height: 1; }
.photo-ai-dialog { font-size: 16px; line-height: 24px; }
.photo-ai-steps { display: flex; gap: 8px; list-style: none; margin: 0 0 16px; padding: 0; counter-reset: pa; }
.photo-ai-steps li { flex: 1; padding: 8px 8px; border-radius: 6px; background: var(--color-gray-100, #f2f2f4); color: var(--color-gray-600, #666); font-size: 14px; line-height: 22px; counter-increment: pa; }
.photo-ai-steps li::before { content: counter(pa) ". "; }
.photo-ai-steps li.on { background: var(--primary); color: #fff; }
.photo-ai-steps li.done { color: var(--color-gray-900, #222); }
.photo-ai-lead { font-size: 18px; line-height: 28px; margin: 0 0 14px; }
.photo-ai-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
.photo-ai-bigbtn { display: flex; align-items: center; justify-content: center; min-height: 72px; border: 2px solid var(--primary); border-radius: 10px; font-size: 20px; line-height: 30px; font-weight: 600; cursor: pointer; color: var(--primary); background: #fff; }
.photo-ai-bigbtn.primary-like { background: var(--primary); color: #fff; }
.photo-ai-preview { display: block; max-width: 100%; max-height: 220px; margin: 0 auto 12px; border-radius: 8px; }
.photo-ai-opts { border: 0; padding: 0; margin: 0 0 10px; display: grid; gap: 8px; }
.photo-ai-opts legend { font-weight: 600; margin-bottom: 4px; }
.photo-ai-more { margin: 0 0 12px; }
.photo-ai-more > label { display: block; margin-top: 8px; }
.photo-ai-go { width: 100%; min-height: 56px; font-size: 18px; line-height: 28px; }
.photo-ai-warns { margin: 0 0 12px; padding-left: 20px; color: var(--color-orange-700, #a24b00); }
.photo-ai-tax { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 12px 0; }
.photo-ai-fields { display: grid; gap: 10px; }
.photo-ai-field { display: grid; grid-template-columns: 7.5em 1fr; align-items: center; gap: 4px 10px; }
.photo-ai-field input, .photo-ai-field textarea, .photo-ai-item input { font-size: 18px; line-height: 28px; padding: 8px 10px; min-width: 0; }
.photo-ai-label { font-weight: 600; }
.photo-ai-flag { grid-column: 2; font-size: 14px; line-height: 22px; color: var(--color-orange-700, #a24b00); }
.photo-ai-field.low input, .photo-ai-field.low textarea, .photo-ai-item input.low { outline: 3px solid #f5b400; background: #fff8e1; }
.photo-ai-sub { margin: 18px 0 8px; font-size: 16px; line-height: 24px; }
.photo-ai-items { display: grid; gap: 8px; margin-bottom: 8px; }
.photo-ai-item { display: grid; grid-template-columns: 2fr 1fr 2fr auto; gap: 8px; }
.photo-ai-actions { margin-top: 14px; gap: 10px; justify-content: space-between; }
.photo-ai-cands { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.photo-ai-cand { display: flex; flex-direction: column; gap: 8px; padding: 8px; border: 2px solid var(--color-gray-300, #ddd); border-radius: 10px; background: #fff; text-align: left; cursor: pointer; font: inherit; color: inherit; }
.photo-ai-cand img { width: 100%; border-radius: 6px; background: #eee; }
.photo-ai-cand.picked { border-color: var(--primary); box-shadow: 0 0 0 3px var(--color-blue-100, #e0ebff); }
.photo-ai-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.photo-ai-tags .tag { font-size: 14px; line-height: 22px; padding: 2px 8px; border-radius: 4px; background: var(--color-gray-100, #f2f2f4); }
.photo-ai-tags .tag.warn { background: #fff1d6; color: #8a4b00; }
/* 2026-09-25 고도화 - 여러 장 · 구획 · 여러 가격 · 음식 사진 */
.photo-ai-thumbs { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.photo-ai-thumb { position: relative; display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
.photo-ai-thumb img { width: 88px; height: 88px; object-fit: cover; border-radius: 8px; background: #eee; }
.photo-ai-thumb button { position: absolute; top: -6px; right: -6px; min-width: 28px; min-height: 28px; padding: 0; border-radius: 50%; background: #fff; }
.photo-ai-piclist { display: grid; gap: 10px; margin-bottom: 8px; }
.photo-ai-pic { display: grid; grid-template-columns: 96px 1fr; gap: 10px; align-items: start; }
.photo-ai-pic-src { width: 96px; height: 96px; object-fit: cover; border-radius: 8px; background: #eee; }
.photo-ai-pic-side { display: grid; gap: 6px; min-width: 0; }
.photo-ai-pic-side select, .photo-ai-pic-side input { font-size: 17px; padding: 6px 8px; min-width: 0; }
.photo-ai-pair { display: flex; gap: 8px; flex-wrap: wrap; }
.photo-ai-pairbtn { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 4px; border: 2px solid var(--color-gray-300, #ddd); border-radius: 8px; background: #fff; font: inherit; font-size: 14px; cursor: pointer; color: inherit; }
.photo-ai-pairbtn img { width: 96px; height: 72px; object-fit: cover; border-radius: 4px; background: #eee; }
.photo-ai-pairbtn.on { border-color: var(--primary); box-shadow: 0 0 0 3px var(--color-blue-100, #e0ebff); }
.photo-ai-sec { display: grid; gap: 6px; padding: 8px; border: 1px solid var(--color-gray-200, #e6e6e9); border-radius: 8px; }
.photo-ai-sec .sec-name { font-size: 17px; font-weight: 700; padding: 6px 8px; }
.photo-ai-items.solo .photo-ai-sec { border: 0; padding: 0; }
.photo-ai-items.solo .sec-name, .photo-ai-items.solo .photo-ai-sec > button { display: none; }
.photo-ai-secrows { display: grid; gap: 8px; }
.photo-ai-item { grid-template-columns: 2fr 1.4fr 2fr auto auto; }
.photo-ai-flags { display: flex; gap: 8px; align-items: center; font-size: 14px; white-space: nowrap; }
.photo-ai-flags label { display: inline-flex; gap: 3px; align-items: center; }
.photo-ai-addrow { gap: 8px; flex-wrap: wrap; }
.photo-ai-palette { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.photo-ai-swatches { display: inline-flex; gap: 4px; }
.photo-ai-swatch { width: 22px; height: 22px; border-radius: 4px; border: 1px solid rgba(0, 0, 0, .15); display: inline-block; }
.photo-ai-more-pages { display: flex; gap: 4px; }
.photo-ai-more-pages img { width: 48%; border-radius: 4px; }
@media (max-width: 640px) {
  .photo-ai-item { grid-template-columns: 1fr 1fr; }
  .photo-ai-item .ds { grid-column: 1 / -1; }
}
.photo-ai-done { margin-top: 16px; padding: 16px; border-radius: 10px; background: var(--color-blue-50, #eef4ff); }
@media (max-width: 560px) { .photo-ai-item { grid-template-columns: 1fr 1fr auto; } .photo-ai-item .ds { grid-column: 1 / 3; } .photo-ai-field { grid-template-columns: 1fr; } .photo-ai-flag { grid-column: 1; } }
@media (max-width: 560px) { .photo-ai-dialog { padding: 16px; width: 100vw; max-height: 100dvh; } .photo-ai-steps li { font-size: 14px; line-height: 22px; } }

/* DESIGN.md v3.2 자간 - 편집기 캔버스와 미리보기 판 안은 기기 콘텐츠라 화면 자간을 물려주지 않는다 */
button, input, select, textarea { letter-spacing: inherit; } /* 브라우저 기본값이 단추 · 입력칸 자간을 0 으로 되돌린다 */
.gfe__stage, .gfe__canvas, .yd-stage, .yd-preview-stage { letter-spacing: normal; }

/* ============================================================ DESIGN.md v3.2 3단계 - gency 대시보드 틀
   사이드바가 위에서 아래까지 서고(폭 264 · gray-200) 로고가 그 머리에 앉는다. 머리 막대는 사이드바 오른쪽에만
   있고 본문과 같은 gray-100 이라 선 없이 색으로만 갈린다. 카드는 그림자 대신 1px gray-300 · 모서리 10.
   🔴 `nav class="tabbar"` 는 그대로 두고 자리만 CSS 로 옮긴다 (검사 스크립트가 이 이름표를 잡는다). */
@media (min-width: 768px) {
  :root { --rail-w: 264px; }
  body.has-tabbar { background: var(--color-gray-100); }
  body.has-tabbar .topbar { margin-left: 0; background: var(--color-gray-100); border-bottom: 0; }
  .topbar .wrap { padding: 0 40px; }
  .tabbar {
    top: 0; padding: calc(var(--header-h) + 4px) 20px 20px;
    background: var(--color-gray-200); border-right: 0;
  }
  body.has-tabbar .topbar .brand {
    position: fixed; top: 0; left: 0; z-index: 22; width: var(--rail-w); height: var(--header-h);
    padding: 0 20px; display: grid; grid-template-columns: auto auto 1fr; column-gap: 8px;
    align-items: center; align-content: center;
  }
  body.has-tabbar .topbar .brand .org {
    grid-column: 2 / -1; margin: 0; padding: 0; border: 0;
  }
  body.has-tabbar main.wrap { padding: 16px 30px 24px; }

  /* 카드 - 그림자 대신 선 */
  .card, .home-card, .dash-card { border: 1px solid var(--color-gray-300); border-radius: 10px; box-shadow: none; padding: 20px; }
  .dash-card.dash-hello { border-color: transparent; }
  .home { gap: 40px; }
  .home > .home-card { margin-bottom: 0; }  /* 섹션 사이 40 은 .home 의 gap 하나로 준다 */
  .home > #onboard:empty { display: none; }  /* 빈 자리가 gap 을 한 번 더 먹는다 */
  .home-card-title, .dash-card-title, .home-row .dash-card-title { font-size: 16px; line-height: 24px; font-weight: 700; }
}
/* 단추 높이 - 마우스로 쓰는 화면만. 손가락 화면은 44 를 지킨다 */
@media (min-width: 768px) and (hover: hover) and (pointer: fine) {
  button, .btn { min-height: 38px; }
  button.sm, .btn.sm { min-height: 36px; padding: 0 12px; }
  button.primary:not(.sm) { min-height: 38px; padding: 0 16px; }
  .topbar .linkbtn { min-height: 38px; padding: 0 16px; }
  .home-btn-main, .home-btn-sub { min-height: 48px; padding: 0 20px; border-radius: 10px; font-size: 16px; line-height: 24px; font-weight: 600; }
}

/* 전자종이 · 가격표는 운영자 전용 (2026-10-02). `/me` 의 `features.eink` 가 참일 때만 body 에
   `eink-on` 이 붙는다. 고객 화면에서는 `.eink-only` 를 단 메뉴 · 단추 · 안내 · 기기 종류가 통째로 숨는다. */
body:not(.eink-on) .eink-only { display: none !important; }

/* ============================================================ 탭 한 양식 (2026-10-02 대표 「모바일에서 탭이 자주 쓰이는데 탭 디자인 이쁘게」)
   앱의 탭은 두 층뿐이다. 모양이 달라야 어느 줄이 위인지 읽힌다.
   1차 탭 `.lf-tabs > .lf-tab` - 화면 갈래(내 TV [내 매장 | 기기 관리] · 디자인 [내 디자인 | 사진·영상] ·
      앱 [내 앱 | 앱 찾기]). 바탕 없이 글자 16/600 + 고른 칸 아래 2px 파랑 줄, 줄 전체 아래 1px 선.
      폰에서는 칸을 똑같이 나눠(가로 밀기 없음) 줄 전체를 쓴다.
   2차 탭 `.segtog` · `.ops-tv-navigation` - 한 화면 안의 거르개(기기 · 재생목록 · 스케줄, 7일 · 30일,
      추가할 것 고르기 등). 회색 홈(gray-200, 패딩 2) 위에 고른 칸만 흰 알약 + 그림자 2단계, 글자 14/600.
      폰에서 `.ops-tv-navigation` 은 폭을 다 쓰고 칸을 똑같이 나눈다. 세 칸이 390 폭에 넉넉히 들어간다. */
.lf-tabs {
  display: flex; gap: 24px; margin: 0 0 20px; padding: 0;
  background: none; border: 0; border-bottom: 1px solid var(--color-gray-300); border-radius: 0;
  overflow-x: auto; scrollbar-width: none;
}
.lf-tabs::-webkit-scrollbar { display: none; }
.lf-tab {
  position: relative; flex: none; min-height: 44px; padding: 10px 2px 11px; margin: 0;
  border: 0; border-radius: 0; background: transparent; box-shadow: none; cursor: pointer;
  color: var(--text-sub); font-size: 16px; line-height: 24px; font-weight: 600; white-space: nowrap;
}
.lf-tab:hover:not(.active) { color: var(--text); background: transparent; }
.lf-tab.active { color: var(--text); background: transparent; box-shadow: none; }
.lf-tab.active::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  border-radius: 2px 2px 0 0; background: var(--primary);
}
.lf-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; border-radius: 6px; }

.segtog, .ops-tv-navigation {
  display: inline-flex; flex: none; align-items: stretch; gap: 2px; padding: 2px;
  border: 0; border-radius: 10px; background: var(--color-gray-200); overflow: visible;
}
.segtog button, .ops-tv-navigation button {
  flex: none; min-height: 36px; min-width: 0; padding: 0 14px; margin: 0;
  border: 0; border-radius: 8px; background: transparent; box-shadow: none;
  color: var(--text-sub); font-size: 14px; line-height: 22px; font-weight: 600; white-space: nowrap;
}
.segtog button:hover, .ops-tv-navigation button:hover { background: transparent; color: var(--text); }
.segtog button.active, .ops-tv-navigation button.active,
.segtog button.active:hover, .ops-tv-navigation button.active:hover {
  background: var(--bg); color: var(--text); box-shadow: var(--shadow-elevation-2);
}
.segtog button:focus-visible, .ops-tv-navigation button:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
@media (max-width: 767px) {
  .lf-tabs { gap: 0; margin-bottom: 16px; }
  .lf-tab { flex: 1 1 0; min-width: 0; padding: 10px 4px 11px; text-align: center; justify-content: center; }
  .segtog button, .ops-tv-navigation button { min-height: 40px; padding: 0 12px; }
  .ops-tv-navigation { display: flex; width: 100%; }
  .ops-tv-navigation button { flex: 1 1 0; }
}

/* ============================================================ 고르기 칸 한 양식 (2026-10-02 대표 「한국어 드롭다운 상자 디자인이 이상하다」)
   브라우저 기본 화살표를 그대로 두면 운영체제마다 모양이 다르고(안드로이드는 회색 덩어리, 맥은 파란 알약),
   언어 칸은 둥근 알약 테두리 안에 기본 화살표가 따로 놀았다. 앱의 모든 select 를 입력칸과 같은 상자
   (1px gray-300 · 모서리 8 · 흰 바탕)에 오른쪽 선 화살표 하나로 맞춘다. 편집기(`.gfe`)는 자기 부품이라 뺀다.
   ⚠ 화살표 색은 data URI 라 토큰을 못 쓴다 - gray-600(#5b6973) 값을 그대로 적었다. */
select:not([multiple]):not([size]):not(.gfe select) {
  -webkit-appearance: none; appearance: none; cursor: pointer;
  border: 1px solid var(--color-gray-300); border-radius: var(--radius-ctl); background-color: var(--bg); color: var(--text);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b6973' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6.5 9.5 5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 16px 16px;
  padding-left: 12px; padding-right: 34px; text-overflow: ellipsis;
}
select:not([multiple]):not([size]):not(.gfe select):hover { border-color: var(--color-gray-400); }
select:not([multiple]):not([size]):not(.gfe select):disabled { background-color: var(--surface); cursor: not-allowed; }

/* 언어 칸 - 머리 막대의 다른 칸(보내기 · 알림 · 로그아웃)과 같은 높이 · 모서리. 앞에 지구 모양 하나를
   붙여 「언어를 고르는 칸」인 것이 글자를 못 읽어도 보이게 한다. */
select.langsel:not([multiple]):not([size]):not(.gfe select) {
  min-height: 36px; height: 36px; padding: 0 32px 0 34px; width: auto;
  border-radius: 8px; font-size: 14px; line-height: 22px; font-weight: 600; color: var(--color-gray-700);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b6973' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M3.5 12h17M12 3.5c2.3 2.4 3.4 5.2 3.4 8.5s-1.1 6.1-3.4 8.5c-2.3-2.4-3.4-5.2-3.4-8.5S9.7 5.9 12 3.5z'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b6973' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6.5 9.5 5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
  background-position: left 10px center, right 10px center; background-size: 18px 18px, 16px 16px;
}
@media (max-width: 1023px) {
  select.langsel:not([multiple]):not([size]):not(.gfe select) { min-height: 44px; height: 44px; font-size: 16px; line-height: 24px; }
}

/* ============================================================ 알림 종 (2026-10-02 대표 「우측 상단 종 모양이 너무 작다」)
   보이는 판 36 · 그림 18 이라 머리의 다른 그림(아래 메뉴 24)보다 작았고, 누르는 자리도 가짜 요소로만 44 였다.
   판 자체를 44 로, 그림을 22(폰 24)로 키운다. 숫자 점은 그림의 오른쪽 위 어깨에 붙인다. */
.topbar .bellbtn { width: 44px; height: 44px; min-width: 44px; min-height: 44px; padding: 0; border-radius: 10px; color: var(--color-gray-700); }
.topbar .bellbtn .bell-ico svg { width: 22px; height: 22px; stroke-width: 1.8; }
.topbar .bellbtn .bell-dot { top: 6px; right: 6px; border: 2px solid var(--color-gray-100); min-width: 18px; height: 18px; line-height: 14px; }
@media (max-width: 767px) {
  .topbar .bellbtn .bell-ico svg { width: 24px; height: 24px; }
  .topbar .bellbtn .bell-dot { border-color: var(--bg); }
}

/* ============================================================ 네모 칸 · 동그라미 칸 한 양식 (2026-10-02 전수 점검)
   브라우저 기본 모양(accent-color 16 · 18 · 22 세 크기)과 폰에서 직접 그린 22px 네모(모서리 없음)가 섞여 있었다.
   이제 전부 같은 그림 하나다 - 20px, 모서리 4.5, 테두리 gray-400 1.5, 켜지면 주 파랑에 흰 체크.
   그림은 배경 SVG 라 크기가 44 인 칸(폰의 맨 칸)에도 가운데 20 으로 똑같이 그려진다(mobile.css 1절).
   ⚠ 사용 기간 켜기(`.media-edit-row > input`)는 스위치라 뺀다. 편집기(`.gfe`)는 자기 부품이다.
   ⚠ 색은 data URI 라 토큰을 못 쓴다 - gray-400 #c6cdd2, blue-600 #0a8ff5 를 그대로 적었다. */
input[type=checkbox]:not(.media-edit-row > input):not(.gfe input):not(.sch-day input):not(.asset-weekdays input),
input[type=radio]:not(.gfe input):not(.sch-day input):not(.asset-weekdays input) {
  -webkit-appearance: none; appearance: none; flex: none; margin: 0; padding: 0; border: 0;
  width: 20px; height: 20px; min-height: 0; vertical-align: middle; cursor: pointer;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect x='.75' y='.75' width='18.5' height='18.5' rx='4.5' fill='white' stroke='%23c6cdd2' stroke-width='1.5'/%3E%3C/svg%3E") center / 20px 20px no-repeat;
}
input[type=radio]:not(.gfe input):not(.sch-day input):not(.asset-weekdays input) {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9.25' fill='white' stroke='%23c6cdd2' stroke-width='1.5'/%3E%3C/svg%3E");
}
input[type=checkbox]:not(.media-edit-row > input):not(.gfe input):not(.sch-day input):not(.asset-weekdays input):checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect width='20' height='20' rx='4.5' fill='%230a8ff5'/%3E%3Cpath d='m5.5 10.3 3 3 6-6.3' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
input[type=radio]:not(.gfe input):not(.sch-day input):not(.asset-weekdays input):checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9.25' fill='white' stroke='%230a8ff5' stroke-width='1.5'/%3E%3Ccircle cx='10' cy='10' r='5' fill='%230a8ff5'/%3E%3C/svg%3E");
}
input[type=checkbox]:not(.media-edit-row > input):not(.gfe input):not(.sch-day input):not(.asset-weekdays input):disabled,
input[type=radio]:not(.gfe input):not(.sch-day input):not(.asset-weekdays input):disabled { opacity: .45; cursor: not-allowed; }
input[type=checkbox]:not(.media-edit-row > input):not(.gfe input):not(.sch-day input):not(.asset-weekdays input):focus-visible,
input[type=radio]:not(.gfe input):not(.sch-day input):not(.asset-weekdays input):focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 6px; }
input[type=radio]:not(.gfe input):not(.sch-day input):not(.asset-weekdays input):focus-visible { border-radius: 50%; }

/* 스케줄의 요일 고르개(폰)도 2차 탭이다 - 파랑 채움 칸 일곱 개 대신 회색 홈 위 흰 알약 (2026-10-02). */
.sch-daytabs { gap: 2px; padding: 2px; border-radius: 10px; background: var(--color-gray-200); }
.sch-daytab { min-height: 40px; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--text-sub); font-weight: 600; }
.sch-daytab.on { background: var(--bg); border: 0; color: var(--text); font-weight: 700; box-shadow: var(--shadow-elevation-2); }
.sch-daytab.today:not(.on) { color: var(--primary); border: 0; }

/* ============================================================ 단추 네 가지 (2026-10-02 전수 점검)
   잰 결과 화면의 단추가 42가지 모양이었다(높이 6 · 모서리 6 · 굵기 4 · 안쪽 여백 8). 종류를 넷으로 줄인다.
     주     `.primary`  파랑 바탕 · 흰 글자
     보조   (기본)       흰 바탕 · 1px gray-300 · 검정 글자 - DESIGN.md 의 테두리 단추
     텍스트 `.ghost`    바탕 · 테두리 없음 · gray-600 글자, 올리면 gray-150
     위험   `.danger`   빨강 바탕
   글자는 넷 다 14/600, 모서리 8. 높이는 마우스 화면 38(작은 것 36) · 손가락 화면 44.
   아래는 각자 다른 값을 쓰던 목록 도구 단추를 이 틀에 맞춘 것이다. */
.lf-tools .lf-btn, .lf-pager button { border-radius: 8px; font-size: 14px; line-height: 22px; font-weight: 600; color: var(--text); }
.lf-pager button.active { color: var(--color-white); }
.media-kind-picker button { border-radius: 8px; font-weight: 600; }
.lf-make { padding: 0 16px; }
.lf-sort { background: transparent; }
