﻿/* ═══════════════════════════════════════════════════════════
   미디어 사이니지 관리자 콘솔 — 디자인 시스템
   등록 어휘(클래스명)는 JS 렌더링 코드와 1:1로 맞물려 있으므로
   이름을 바꾸지 말 것. 스타일만 이 파일에서 관리한다.
   ═══════════════════════════════════════════════════════════ */

/* 본문 폰트 — Pretendard(한글 최적, 가변폰트 1파일). 서버에서 직접 서빙한다.
   CDN을 쓰면 ① 외부 장애·경로 변경에 화면이 휘둘리고(실제로 gh 경로가 죽어 404였다)
   ② 관리자 콘솔의 CSP를 외부 출처까지 열어야 한다. 파일 하나면 되니 함께 배포한다.
   @font-face + swap이라 폰트를 받기 전에도 시스템 스택(--font)으로 즉시 그려진다. */
@font-face {
  font-family: "Pretendard Variable";
  font-weight: 45 920; font-style: normal; font-display: swap;
  src: url("/fonts/PretendardVariable.woff2") format("woff2-variations");
}

/* ── 디자인 토큰 ─────────────────────────────────────────── */
:root {
  /* 표면 (라이트 콘텐츠 영역) — 배경에 은은한 인디고 틴트, 테두리는 한 단계 또렷하게 */
  --bg: oklch(0.966 0.009 274);            /* 본문 배경 — 인디고 틴트 뉴트럴 */
  --card: #ffffff;                          /* 카드 표면 */
  --card-sunken: oklch(0.962 0.009 274);    /* 카드 안 한 단계 가라앉은 면 (슬롯 행 등) */
  --border: oklch(0.884 0.013 273);         /* 기본 테두리 */
  --border-strong: oklch(0.815 0.017 273);  /* 호버 시 테두리 */
  --divider: oklch(0.928 0.011 273);        /* 표 행 구분선 등 옅은 선 */

  /* 텍스트 — 본문 대비 4.5:1 이상, 보조 텍스트도 5.5:1 수준으로 또렷하게 */
  --fg: oklch(0.235 0.022 272);
  --fg-muted: oklch(0.45 0.026 270);
  --fg-soft: oklch(0.39 0.023 270);        /* 설명·안내문용 — 뮤트보다 진해 시인성↑(대비 ~7:1) */

  /* 브랜드 (기존 인디고 유지 — ui.js의 SweetAlert 버튼색 #4f46e5와 동일 계열) */
  --accent: #4f46e5;
  --accent-hover: #4338ca;
  --accent-soft: oklch(0.948 0.032 277);
  --accent-ring: oklch(0.63 0.19 277 / 0.35);

  /* 사이니지 상태색 — 온라인/오프라인/오류를 한눈에 */
  --green: oklch(0.55 0.16 150);
  --green-soft: oklch(0.955 0.045 152);
  --red: oklch(0.55 0.2 26);
  --red-soft: oklch(0.955 0.03 22);
  --amber: oklch(0.6 0.14 70);
  --amber-soft: oklch(0.965 0.055 85);
  --gray-dot: oklch(0.7 0.015 264);

  /* 사이드바 (인디고 틴트가 도는 다크 패널) */
  --sidebar-bg: oklch(0.205 0.03 278);
  --sidebar-fg: oklch(0.73 0.022 278);
  --sidebar-fg-dim: oklch(0.56 0.025 278);
  --sidebar-hover: oklch(1 0 0 / 0.06);
  --sidebar-line: oklch(1 0 0 / 0.09);

  /* 형태 — radius 스케일(한 스케일로 고정). 배지·칩=xs / 컨트롤·입력=sm / 카드=base / 큰 패널=lg / 점·아바타·pill=pill.
     이 5단계 밖의 값(5·7·9·10·14px 등)을 새로 쓰지 말 것 — 가까운 단계로 맞춘다. */
  --radius-xs: 6px;
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-pill: 999px;
  --shadow: 0 1px 2px oklch(0.25 0.02 270 / 0.05), 0 1px 3px oklch(0.25 0.02 270 / 0.05);
  --shadow-md: 0 2px 6px oklch(0.25 0.02 270 / 0.07), 0 8px 24px oklch(0.25 0.02 270 / 0.07);
  --shadow-lg: 0 12px 36px oklch(0.25 0.02 270 / 0.16);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --speed: 160ms;

  /* z-index 의미 스케일 — 임의 숫자 금지 */
  --z-sticky: 20;
  --z-modal-backdrop: 90;
  --z-modal: 91;
  --z-tooltip: 95;  /* 썸네일 미리보기 등 떠 있는 안내 — 모달(91) 위, 토스트(100) 아래 */
  --z-toast: 100;

  --font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Malgun Gothic", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;

  /* 타이포 스케일 — 이 단계 밖 크기·반픽셀(12.5 등) 새로 쓰지 말 것. 가까운 단계로 맞춘다. */
  --text-2xs: 10px;   /* 배지·미세 라벨 */
  --text-xs: 11px;    /* 작은 메타 */
  --text-sm: 12px;    /* 보조 텍스트 */
  --text-md: 13px;    /* 조밀 본문·표 셀 */
  --text-base: 14px;  /* 기본 본문 */
  --text-lg: 15px;    /* 강조 본문 */
  --text-xl: 17px;    /* 카드/소제목 */
  --text-2xl: 20px;   /* 페이지 h2 */
  --text-3xl: 24px;   /* 큰 제목 */
}

/* ── 기본 리셋 ───────────────────────────────────────────── */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--fg);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
.hidden { display: none !important; }
a { color: var(--accent); text-decoration: none; }
h1, h2, h3 { margin: 0; text-wrap: balance; }
input, select, textarea, button { font-family: inherit; font-size: 14px; }
.mono { font-family: ui-monospace, Consolas, monospace; font-size: 12px; }
.muted { color: var(--fg-muted); }
/* 텍스트 선택 하이라이트도 브랜드 인디고로 */
::selection { background: oklch(0.88 0.07 277); }

/* 키보드 포커스 링 — 마우스 클릭에는 나타나지 않음 */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

/* ── 로그인 ─────────────────────────────────────────────── */
.login-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; position: relative; overflow: hidden;
  /* 야간 사이니지 화면을 연상시키는 딥 인디고 배경 + 오로라·상하 광원 (달은 은하수로 대체하며 제거) */
  background:
    radial-gradient(58% 30% at 22% 6%, oklch(0.62 0.15 195 / 0.16), transparent 72%),  /* 오로라 청록 */
    radial-gradient(52% 26% at 70% 3%, oklch(0.55 0.2 320 / 0.14), transparent 72%),   /* 오로라 보라 */
    radial-gradient(70% 50% at 50% -5%, oklch(0.42 0.13 282 / 0.5), transparent 70%),
    radial-gradient(50% 40% at 88% 105%, oklch(0.36 0.1 300 / 0.35), transparent 70%),
    oklch(0.16 0.028 278);
}
/* 은은한 격자 — 사이니지 스크린의 픽셀 그리드를 연상시키는 배경 텍스처 */
.login-wrap::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(oklch(1 0 0 / 0.03) 1px, transparent 1px),
    linear-gradient(90deg, oklch(1 0 0 / 0.03) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(70% 60% at 50% 40%, #000, transparent);
}
.login-card {
  position: relative;
  background: var(--card);
  border-radius: var(--radius-lg);
  /* 다크 배경 위 '기계 가공된 유리판' — 밝은 헤어라인 + 상단 내부 하이라이트 + 인디고 틴트 확산 그림자(순수검정 지양) */
  border: 1px solid oklch(1 0 0 / 0.65);
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.9),
    0 1px 3px oklch(0.15 0.03 278 / 0.35),
    0 30px 80px oklch(0.12 0.05 278 / 0.55);
  padding: 44px 40px 36px;
  width: 100%;
  max-width: 400px;
  display: flex; flex-direction: column; gap: 16px;
  animation: login-in 0.5s var(--ease-out);
}
@keyframes login-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
.login-logo { text-align: center; margin-bottom: 6px; }
.login-logo .logo-mark { width: 46px; height: 46px; border-radius: 12px; }
.login-logo .logo-mark::after { inset: 12px; }
.login-logo h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.015em; margin-top: 14px; }
.login-logo p { margin: 4px 0 0; color: var(--fg-muted); font-size: 13px; }
/* 로그인 폼 컨트롤은 조금 크게 — 첫 화면의 밀도는 낮고 신뢰감 있게 */
.login-card input { padding: 10px 12px; }
.login-card .btn-block { padding: 11px 14px; font-size: 14px; margin-top: 4px; }
.login-error {
  margin: 0; padding: 9px 12px; border-radius: var(--radius-sm);
  background: var(--red-soft); border: 1px solid oklch(0.85 0.06 25);
  color: var(--red); font-size: 13px; text-align: center;
}

/* 로고 마크 — 사이니지 화면(모니터) 형상 */
.logo-mark {
  display: inline-block; width: 38px; height: 38px; border-radius: 12px;
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  box-shadow: 0 4px 12px oklch(0.51 0.23 277 / 0.35);
  position: relative;
}
.logo-mark::after {
  content: ""; position: absolute; inset: 10px;
  border-radius: 6px; border: 2.5px solid oklch(1 0 0 / 0.92);
  border-bottom-width: 6px;
}
/* 업로드된 사이트 로고가 있을 때 — 그라데이션/모니터 아이콘 대신 이미지 표시
   (background-image는 applyBranding이 인라인으로 지정) */
.logo-mark.has-image {
  background-color: #fff;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  border: 1px solid var(--border);
  box-shadow: none;
}
.logo-mark.has-image::after { display: none; }

/* ── 앱 셸 레이아웃 ─────────────────────────────────────── */
.app { display: flex; min-height: 100vh; }
.sidebar {
  width: 224px; flex-shrink: 0;
  /* 위→아래로 미세하게 어두워지는 그라데이션 — 평면 단색의 단조로움을 던다 */
  background: linear-gradient(180deg, oklch(0.22 0.033 278), oklch(0.19 0.028 278));
  color: var(--sidebar-fg);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; z-index: var(--z-sticky);
}
.sidebar-brand {
  display: flex; align-items: center; gap: 12px;
  padding: 20px 20px 16px;
  border-bottom: 1px solid var(--sidebar-line);
  margin-bottom: 6px;
}
.sidebar-brand .logo-mark { width: 34px; height: 34px; border-radius: 8px; box-shadow: none; }
.sidebar-brand .logo-mark::after { inset: 9px; border-width: 2px; border-bottom-width: 5px; }
.sidebar-brand strong { display: block; color: oklch(0.97 0.005 278); font-size: 15px; line-height: 1.25; letter-spacing: -0.01em; }
.sidebar-brand small { font-size: 11px; color: var(--sidebar-fg-dim); }

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px; flex: 1; }
.sidebar-nav a {
  display: flex; align-items: center; gap: 10px;
  color: oklch(0.78 0.02 278); padding: 10px 12px; border-radius: var(--radius-sm);
  font-weight: 500;
  transition: background var(--speed) var(--ease-out), color var(--speed) var(--ease-out);
}
.sidebar-nav a svg { width: 16px; height: 16px; flex: none; opacity: 0.85; }
.sidebar-nav a:hover { background: var(--sidebar-hover); color: oklch(0.92 0.01 278); }
.sidebar-nav a.active {
  background: var(--accent); color: #fff;
  box-shadow: 0 2px 10px oklch(0.51 0.23 277 / 0.45);
}
.sidebar-nav a.active svg { opacity: 1; }
/* 사이드바 그룹 라벨 — 현황/제작/운영/관리/도구·도움 섹션 구분 */
.sidebar-nav .nav-group {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: oklch(0.62 0.03 278); padding: 13px 12px 3px;
  user-select: none; pointer-events: none;
}
.sidebar-nav .nav-group:first-child { padding-top: 4px; }

.sidebar-foot {
  padding: 12px 16px 16px; border-top: 1px solid var(--sidebar-line);
  display: flex; flex-direction: column; gap: 10px;
}
.session-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.session-user {
  flex: 1; font-size: 12px; color: oklch(0.85 0.012 278);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: flex; align-items: center; gap: 7px; min-width: 0;
}
/* 접속 중 표시점 — 관리자 세션이 살아있음을 나타냄 */
.session-user::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: oklch(0.72 0.17 152);
}

/* 아파트(테넌트) 전환기 — 총관리자 전용, display는 app.js가 flex/none으로 제어 */
.tenant-switch { flex-direction: column; gap: 6px; min-width: 0; }
.tenant-switch .ts-label {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; color: var(--sidebar-fg-dim);
}
.tenant-switch .ts-label svg { width: 12px; height: 12px; flex: none; }
.tenant-switch select {
  width: 100%; background: oklch(0.26 0.032 278); color: oklch(0.92 0.01 278);
  border: 1px solid oklch(1 0 0 / 0.14); border-radius: 8px;
  padding: 7px 10px; font-size: 12px; outline: none;
  transition: border-color var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
.tenant-switch select:hover { border-color: oklch(1 0 0 / 0.28); }
.tenant-switch select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px oklch(0.51 0.23 277 / 0.35); }

/* 본문은 남는 폭을 그대로 채운다(해상도에 맞춰 100%). 넓은 화면은 좌우 여백만 넉넉히.
   상단에 은은한 인디고 광원을 깔아 단조로움을 덜되 콘텐츠 가독성은 해치지 않는다. */
.main {
  flex: 1; min-width: 0; padding: 28px 32px 64px;
  background: radial-gradient(640px 220px at 16% -60px, oklch(0.93 0.035 277 / 0.55), transparent 70%);
}
@media (min-width: 1680px) { .main { padding: 30px 48px 72px; } }

/* ── 페이지 헤더 ────────────────────────────────────────── */
.page-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 16px; margin-bottom: 20px; flex-wrap: wrap;
}
/* 제목이 있는 페이지 헤더는 하단 구분선으로 모든 페이지에서 동일한 리듬 유지
   (콘텐츠 페이지의 필터 행처럼 h2 없는 page-head에는 적용 안 함) */
.page-head:has(h2) {
  padding-bottom: 16px;
  border-bottom: 1px solid var(--divider);
  margin-bottom: 22px;
}
.page-head h2 { font-size: 20px; font-weight: 700; letter-spacing: -0.015em; line-height: 1.4; }
.page-head .sub { color: var(--fg-soft); font-size: 13px; margin-top: 3px; }

/* 페이지 타이틀 아이콘 칩 — 로고 마크와 같은 인디고 그라데이션 언어 */
.page-title { display: inline-flex; align-items: center; gap: 10px; min-width: 0; }
.pt-icon {
  width: 32px; height: 32px; flex: none; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, oklch(0.58 0.19 277), var(--accent));
  color: #fff;
  box-shadow: 0 2px 8px oklch(0.51 0.23 277 / 0.3);
}
.pt-icon svg { width: 16px; height: 16px; }
/* 대시보드로 돌아가기 — 알약형 버튼, 화살표는 CSS 셰브론 하나만 */
.back-link {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 13px 6px 10px; margin-bottom: 12px;
  background: #fff; border: 1px solid var(--border); border-radius: 999px;
  font-size: 12px; font-weight: 600; color: var(--fg-muted);
  box-shadow: 0 1px 2px oklch(0.25 0.02 270 / 0.05);
  transition: color var(--speed) var(--ease-out), border-color var(--speed) var(--ease-out),
    background var(--speed) var(--ease-out), transform var(--speed) var(--ease-out);
}
.back-link::before {
  content: ""; width: 6px; height: 6px; flex: none;
  border-left: 2px solid currentColor; border-bottom: 2px solid currentColor;
  border-radius: 6px; transform: rotate(45deg);
  transition: transform var(--speed) var(--ease-out);
}
.back-link:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.back-link:hover::before { transform: rotate(45deg) translate(1px, -1px); }
.back-link:active { transform: translateY(1px); }

/* ── 카드 ───────────────────────────────────────────────── */
.card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 22px;
}
.card + .card { margin-top: 18px; }
.card h3 {
  font-size: 15px; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 14px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
/* 설명문은 어디에 쓰이든 잘 읽히게 — 뮤트보다 진한 --fg-soft + 13px + 넉넉한 줄간격 */
.card-desc { color: var(--fg-soft); font-size: 13px; line-height: 1.62; }
.card .card-desc { margin: -6px 0 14px; }

/* ── 안내 콜아웃 — 등록 안내·주의 등 "사용자에게 꼭 알려야 하는" 문구 강조 ──
   전체 테두리 + 옅은 틴트 + 선행 아이콘. (side-stripe 금지) */
.callout {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px 13px; border-radius: var(--radius-sm);
  background: var(--accent-soft); border: 1px solid oklch(0.885 0.035 277);
  color: var(--fg); font-size: 13px; line-height: 1.6;
}
.callout .callout-ico { flex: none; width: 17px; height: 17px; margin-top: 1px; color: var(--accent); }
.callout .callout-ico svg { width: 100%; height: 100%; display: block; }
.callout code { background: oklch(1 0 0 / 0.6); padding: 1px 5px; border-radius: 6px; font-size: 12px; }
.callout-warn { background: var(--amber-soft); border-color: oklch(0.85 0.06 82); }
.callout-warn .callout-ico { color: var(--amber); }
.callout-danger { background: var(--red-soft); border-color: oklch(0.86 0.05 24); }
.callout-danger .callout-ico { color: var(--red); }
.callout-muted { background: var(--card-sunken); border-color: var(--border); }
.callout-muted .callout-ico { color: var(--fg-muted); }

/* 폼 라벨 아이콘 — 텍스트만 있던 입력 필드에 작은 아이콘을 붙여 인지성↑ */
.lbl-ico { display: inline-flex; align-items: center; gap: 6px; }
.lbl-ico > svg { width: 14px; height: 14px; flex: none; color: var(--accent); stroke-width: 2; }

/* 편집 화면 하위 섹션 — 소제목을 키우고(15px/700) 구분선을 또렷하게(border-strong) */
.lsec { border-top: 1px solid var(--border-strong); padding-top: 18px; margin-top: 6px; }
.lsec-title {
  display: flex; align-items: center; gap: 7px;
  font-size: 15px; font-weight: 700; color: var(--fg);
  letter-spacing: -0.01em; margin-bottom: 11px;
}
.lsec-title > svg { width: 16px; height: 16px; flex: none; color: var(--accent); stroke-width: 2; }

/* 카드 섹션 제목 — 아이콘 칩 + 라벨 (기기 상세 등) */
.card h3 .card-title { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.card h3 .ct-icon {
  width: 26px; height: 26px; flex: none; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.card h3 .ct-icon svg { width: 14px; height: 14px; }

.grid { display: grid; gap: 16px; }
.grid-cards { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* ── 대시보드 기기 카드 ─────────────────────────────────── */
.device-card {
  cursor: pointer;
  transition: border-color var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out),
    transform var(--speed) var(--ease-out);
}
.device-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px); }
/* 상태 스트라이프 — 정상 카드엔 색이 없으므로, 색이 보이는 카드가 곧 확인할 기기다.
   (빨강=지금 못 나가거나 곧 멈춤 / 앰버=지켜볼 것. 카드가 수십 개로 늘어도 스캔이 된다) */
.device-card.dev-alarm, .device-card.dev-warn { position: relative; overflow: hidden; }
.device-card.dev-alarm::before, .device-card.dev-warn::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; z-index: 1;
}
.device-card.dev-alarm::before { background: var(--red); }
.device-card.dev-warn::before { background: var(--amber); }
.device-card.dev-alarm { border-color: color-mix(in srgb, var(--red) 40%, var(--border)); }
.device-card.dev-warn { border-color: color-mix(in srgb, var(--amber) 40%, var(--border)); }
.device-card .dev-name { font-size: 15px; font-weight: 650; display: flex; align-items: center; gap: 8px; letter-spacing: -0.01em; }
/* 기기 카드 — 기기명 헤더(구분선) + 본문 분리. (테넌트 카드는 제외) */
.device-card:not(.tenant-card) { padding: 0; }
.device-card .dev-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 15px; border-bottom: 1px solid var(--divider);
  font-size: 15px; font-weight: 700; letter-spacing: -0.01em;
}
.device-card .dev-head .dot { flex: none; }
.device-card .dev-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.device-card .dev-body { padding: 13px 15px 15px; }
.device-card .dev-body > :first-child { margin-top: 0; }
.device-card .dev-status-row { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 12px; }

/* ── 기기 카드 = 디지털 사이니지 실물 목업 (세로형) ───────────────── */
.dev-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 16px; }
/* 그리드는 .grid 클래스가 아니므로 `.card + .card{margin-top:18px}`가 안 풀린다 → 2번째 카드가 18px 밀려
   높이·상단이 어긋난다. 카드 마진을 0으로 리셋하면 grid align-items:stretch가 높이를 동일하게 맞춘다. */
.dev-grid > .card { margin: 0; }

/* 일괄 설정 모달 단계 제목 — 대상 선택 / 바꿀 항목을 시각적으로 분리 */
.bulk-h {
  font-size: 13px; font-weight: 700; color: var(--fg-soft);
  letter-spacing: .02em; margin-bottom: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
/* 디바이스 목업: 어두운 베젤 프레임 + 실제 레이아웃 미리보기 화면 */
.dev-device { display: flex; justify-content: center; }
.dev-bezel {
  position: relative; width: 100%; max-width: 190px;
  padding: 9px 9px 17px; border-radius: 16px;
  background: linear-gradient(160deg, #30343f 0%, #191b22 60%, #0f1116 100%);
  box-shadow: 0 8px 20px rgba(0,0,0,.30), inset 0 1px 0 rgba(255,255,255,.10), inset 0 0 0 1px rgba(0,0,0,.5);
}
.dev-screen {
  position: relative; border-radius: 6px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(0,0,0,.7); background: #000; transition: box-shadow var(--speed) var(--ease-out);
}
/* 화면 안 layoutScreenHtml 미리보기가 꽉 차도록 (자체 테두리는 목업에선 불필요) */
.dev-screen > div:first-child { border: 0 !important; border-radius: 6px; }
/* 켜짐: 은은한 화면 발광 / 꺼짐: 어둡게 */
.dev-device.is-on .dev-screen { box-shadow: 0 0 0 1px rgba(0,0,0,.7), 0 0 16px rgba(99,102,241,.38); }
.dev-device.is-off .dev-screen > div:first-child { filter: grayscale(0.5) brightness(0.5); }
/* 화면 유리 반사(글로시) — 미세한 대각 하이라이트 */
.dev-screen::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: 6px;
  background: linear-gradient(133deg, rgba(255,255,255,.12) 0%, rgba(255,255,255,0) 38%);
}
/* 오프라인·화면꺼짐 오버레이 */
.dev-screen-off {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  background: rgba(7,9,14,.78); color: #9aa4b5; font-size: 12px; font-weight: 700;
}
.dev-screen-off svg { width: 22px; height: 22px; opacity: .85; }
/* 미등록 기기 = 화면에 등록 코드 표시(실제 기기처럼) */
.dev-screen-enroll {
  aspect-ratio: 9/16; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: radial-gradient(120% 80% at 50% 30%, #1e2540 0%, #0b0e18 70%); color: #cbd5e1; text-align: center; padding: 8px;
}
.dev-screen-enroll .dse-label { font-size: 10px; letter-spacing: .12em; color: #8b93a7; }
.dev-screen-enroll .dse-code { font-family: ui-monospace, monospace; font-size: 20px; font-weight: 800; letter-spacing: .10em; color: #fff; }
.dev-screen-enroll .dse-hint { font-size: 9px; color: #7c8398; }
/* 전원 LED (베젤 하단) */
.dev-led {
  position: absolute; bottom: 6px; left: 50%; transform: translateX(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: #40485a;
}
.dev-led.on { background: #22c55e; box-shadow: 0 0 7px #22c55e; }
/* 레이아웃 카드 썸네일 — 기기목록과 동일한 베젤 목업을 고정높이 영역에 중앙정렬(짙은 배경 박스 제거).
   화면 크기가 고정이라 베젤이 화면을 감싸도록 width:auto + max-width 해제, 여백은 살짝 줄여 THUMB_H 안에. */
.preset-thumb { display: flex; align-items: center; justify-content: center; }
.preset-thumb .dev-bezel { width: auto; max-width: none; padding: 7px 7px 14px; }
.device-card .dev-meta { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; font-size: 13px; color: var(--fg-soft); }
.device-card .dev-meta b { color: var(--fg); font-weight: 550; }
/* 긴 재생 파일명이 카드를 넘치지 않도록 한 줄 말줄임(전체 이름은 title 툴팁) */
.device-card .dev-meta span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.device-card .dev-foot {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--divider);
}
/* 버전 등 보조 수치 칩 */
.chip {
  display: inline-block; padding: 2.5px 9px; border-radius: 6px;
  background: var(--card-sunken); border: 1px solid var(--divider);
  font-size: 11px; color: var(--fg-soft); font-variant-numeric: tabular-nums;
}

/* ── 아파트(테넌트) 카드 — 총관리자 대시보드 ──────────── */
.tenant-head { display: flex; align-items: center; gap: 12px; }
.tenant-icon {
  width: 40px; height: 40px; flex: none; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.tenant-icon svg { width: 20px; height: 20px; }
/* 아파트 로고가 있으면 아이콘 칸을 로고 이미지로 채움 */
.tenant-icon.has-logo { background: #fff; overflow: hidden; }
.tenant-icon img { width: 100%; height: 100%; object-fit: cover; }
.tenant-title { min-width: 0; display: flex; align-items: center; gap: 7px; }
/* 이름은 한 줄 말줄임 — 이름 길이·배지 유무와 무관하게 헤더 높이를 고정해 카드 내용 정렬을 맞춘다 */
.tenant-title strong { font-size: 15px; letter-spacing: -0.01em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 현재 선택 배지 — 우측 하단 foot에 고정(흐름에서 헤더를 늘리지 않음) */
.tenant-cur { flex: none; margin-left: auto; }
.tenant-stats { display: flex; gap: 8px; margin-top: 14px; }
.tstat {
  flex: 1; text-align: center; padding: 9px 6px; border-radius: 8px;
  background: var(--card-sunken); border: 1px solid var(--divider);
  font-size: 12px; color: var(--fg-soft);
  display: flex; flex-direction: column; gap: 1px;
}
.tstat b { font-size: 16px; color: var(--fg); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.tenant-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--divider);
  font-size: 12px;
}
/* 호버 시에만 나타나는 진입 안내 — 카드 전체가 클릭 대상임을 암시 */
.tenant-enter {
  color: var(--accent); font-weight: 600; font-size: 12px; white-space: nowrap;
  opacity: 0; transform: translateX(-4px);
  transition: opacity var(--speed) var(--ease-out), transform var(--speed) var(--ease-out);
}
.tenant-card:hover .tenant-enter { opacity: 1; transform: none; }
/* 현재 선택된 아파트 — 인디고 라운드 외곽선(테두리+링)으로 즉시 식별 */
.tenant-card.tenant-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring), var(--shadow);
}
.tenant-card.tenant-selected:hover {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring), var(--shadow-md);
}

/* 미등록/재등록 기기 안내 — 콜아웃과 동일한 언어(실선 테두리·틴트·반경). 코드는 강조 유지 */
.pairing-block {
  margin-top: 12px; background: var(--accent-soft); border: 1px solid oklch(0.885 0.035 277);
  border-radius: var(--radius-sm); padding: 12px 13px; text-align: center;
}
.pairing-block small { display: block; color: var(--fg-soft); margin-bottom: 6px; font-size: 12px; line-height: 1.5; }
.pairing-code {
  font-size: 27px; font-weight: 750; letter-spacing: 6px; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* ── 상태 점 / 뱃지 ─────────────────────────────────────── */
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.dot.on { background: var(--green); animation: dot-pulse 2.4s var(--ease-out) infinite; }
.dot.off { background: var(--gray-dot); box-shadow: 0 0 0 3px oklch(0.93 0.006 264); }
.dot.err { background: var(--red); box-shadow: 0 0 0 3px var(--red-soft); }
/* 온라인 점만 은은하게 맥동 — "지금 살아있음"을 전달 */
@keyframes dot-pulse {
  0%   { box-shadow: 0 0 0 0 oklch(0.55 0.16 150 / 0.45); }
  70%  { box-shadow: 0 0 0 6px oklch(0.55 0.16 150 / 0); }
  100% { box-shadow: 0 0 0 0 oklch(0.55 0.16 150 / 0); }
}

.badge {
  display: inline-block; padding: 2.5px 9px; border-radius: 999px;
  font-size: 12px; font-weight: 600; vertical-align: middle; line-height: 1.6;
}
.badge-green { background: var(--green-soft); color: var(--green); }
.badge-gray { background: oklch(0.943 0.008 273); color: var(--fg-muted); }
.badge-red { background: var(--red-soft); color: var(--red); }
.badge-amber { background: var(--amber-soft); color: var(--amber); }
.badge-block { background: var(--red, #dc2626); color: #fff; font-weight: 700; }  /* 재생금지 — 가장 강한 경고(솔리드 레드) */

/* 서버 최적화 진행 중 — 콘텐츠 영역 작업중 레이어(완료 시 자동 해제)
   viewport에 fixed로 고정 → 스크롤해도 안내 박스가 항상 콘텐츠 영역 중앙에 보인다.
   사이드바(좌 224px)는 덮지 않아 다른 메뉴로 이동은 계속 가능. */
.stab-overlay {
  position: fixed; top: 0; right: 0; bottom: 0; left: 224px; z-index: 40;
  background: color-mix(in oklab, var(--surface) 72%, transparent);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
}
@media (max-width: 880px) { .stab-overlay { left: 0; } } /* 사이드바가 상단바로 전환되는 폭 */
.stab-box {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 26px 34px; box-shadow: 0 12px 40px rgba(0,0,0,.18); text-align: center; max-width: 420px;
}
.stab-box b { font-size: 15px; }
.stab-names { font-size: 13px; color: var(--fg-soft); word-break: break-all; }
.stab-hint { font-size: 12px; color: var(--fg-muted); line-height: 1.6; }
.stab-spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid var(--border); border-top-color: var(--accent, #4f46e5);
  animation: stabSpin 0.9s linear infinite;
}
@keyframes stabSpin { to { transform: rotate(360deg); } }

/* 기기 카드 안정성 경고 배지 — 최근 15분 내 크래시/중단 감지(감시앱 보고, 하트비트보다 빠름) */
.dev-issue { animation: devIssuePulse 1.6s ease-in-out infinite; }
@keyframes devIssuePulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .dev-issue { animation: none; } }

/* ── 아파트 현황 요약(대시보드): 공지·7일 그래프·이슈 ─────── */
.sum-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 14px; }
@media (max-width: 860px) { .sum-wrap { grid-template-columns: 1fr; } }
.sum-col { display: flex; flex-direction: column; gap: 12px; }
.sum-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 13px 15px; }
.sum-head { font-size: 13px; font-weight: 700; color: var(--fg); display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.sum-more { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--accent); text-decoration: none; }
.sum-total { margin-left: auto; font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 800; color: var(--fg-soft); }
.sum-total.neg { color: var(--red); }
.sum-total.ok { color: var(--green); }
.sum-empty { font-size: 12px; color: var(--fg-muted); padding: 8px 2px; }
.mini-chart { width: 100%; height: auto; display: block; overflow: visible; margin-top: 2px; }
.sum-chart-card .sum-head { margin-bottom: 12px; }
/* 기기 상세 — 적용된 레이아웃 헤더 + '고급 직접 편집' 접힘 */
.layout-cur {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 14px; margin-bottom: 12px;
}
.ladv { border: 1px dashed var(--border); border-radius: 12px; padding: 0 14px; margin-top: 12px; }
.ladv[open] { padding-bottom: 14px; }
.ladv > summary {
  cursor: pointer; list-style: none; padding: 12px 0;
  font-weight: 600; font-size: 13px; color: var(--fg-muted);
  display: flex; align-items: center; gap: 8px; user-select: none;
}
.ladv > summary::-webkit-details-marker { display: none; }
.ladv > summary::before { content: '▸'; transition: transform .15s; }
.ladv[open] > summary::before { transform: rotate(90deg); }
.ladv > summary:hover { color: var(--fg); }

/* 레이아웃 카드 '기본' 마크 — 이름 앞 고정 크기 사각 별(헤더 높이를 흔들지 않게) */
.preset-star {
  flex: none; width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px; background: var(--green); color: #fff;
  font-size: 12px; line-height: 1;
}
/* 기본 지정 레이아웃 카드 — 목록 맨 앞으로 오고(presets.js 정렬), 굵은 초록 테두리로 강조(★배지와 같은 색).
   전역 box-sizing:border-box라 테두리를 굵혀도 카드 크기·그리드 정렬은 그대로. */
.preset-default { border: 2px solid var(--green); }

.color-field { flex: 0 0 auto; }
.color-field .color-row { display: flex; gap: 6px; align-items: center; }
.color-field input[type="color"] { flex: none; }
.color-field .color-hex { width: 92px; padding: 7px 8px; text-transform: uppercase; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; letter-spacing: .4px; }
.dash-sep { border: 0; border-top: 1px solid var(--border); margin: 18px 0 14px; }
.dash-shead { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; color: var(--fg); margin-bottom: 12px; }
.dash-shead svg { width: 18px; height: 18px; color: var(--fg-muted); }
.dash-shead-n { font-size: 13px; font-weight: 600; color: var(--fg-muted); }

/* 공지 — 좌측 색 밴드로 심각도를 전주의적으로 표시 */
.sum-ann { display: flex; flex-direction: column; gap: 8px; }
.ann-item { display: flex; gap: 9px; padding: 7px 10px; border-radius: 8px; background: rgba(127,127,127,.05); border-left: 3px solid var(--fg-muted); }
.ann-item.ann-warning { border-left-color: var(--amber); background: var(--amber-soft); }
.ann-item.ann-critical { border-left-color: var(--red); background: var(--red-soft); }
.ann-mark { font-size: 14px; line-height: 1.4; flex: none; }
.ann-title { font-size: 13px; font-weight: 700; color: var(--fg); }
.ann-text { font-size: 12px; color: var(--fg-soft); margin-top: 2px; line-height: 1.5; }
.ann-meta { font-size: 11px; color: var(--fg-muted); margin-top: 3px; }

/* 최근 이슈 리스트 — 유형 필(색)로 심각도 구분 */
.sum-issues { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.sum-issues li { display: flex; align-items: center; gap: 8px; padding: 6px 2px; border-bottom: 1px dashed var(--divider); font-size: 12px; }
.sum-issues li:last-child { border-bottom: 0; }
.sum-pill { font-size: 10px; font-weight: 800; border: 1px solid; border-radius: var(--radius-pill); padding: 1px 8px; flex: none; min-width: 58px; text-align: center; }
.sum-idev { font-weight: 600; color: var(--fg); white-space: nowrap; flex: none; }
.sum-icause { color: var(--fg-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
.sum-itime { color: var(--fg-muted); font-variant-numeric: tabular-nums; flex: none; }
/* 심각도 띠 — 목록이 심각도순으로 묶여 보이게. 색은 배지와 같은 어휘(빨강=긴급, 앰버=경고). */
.sum-issues li { padding-left: 8px; border-left: 3px solid transparent; }
.sum-issues li.sum-sev0 { border-left-color: var(--red); }
.sum-issues li.sum-sev1 { border-left-color: var(--amber); }
.sum-issues li.sum-sev2 { border-left-color: var(--divider); }

/* 공지 관리 페이지 */
.notice-list { display: flex; flex-direction: column; gap: 10px; }
.notice-row { display: flex; gap: 12px; align-items: flex-start; background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--fg-muted); border-radius: 12px; padding: 12px 14px; }
.notice-row.notice-warning { border-left-color: var(--amber); }
.notice-row.notice-critical { border-left-color: var(--red); }
.notice-row.notice-off { opacity: .55; }
.notice-main { flex: 1; min-width: 0; }
.notice-top { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.notice-pin { font-size: 13px; }
.notice-title { font-size: 14px; font-weight: 700; }
.notice-body { font-size: 13px; color: var(--fg-soft); margin-top: 5px; line-height: 1.55; white-space: pre-wrap; }
.notice-meta { font-size: 11px; color: var(--fg-muted); margin-top: 5px; }
.notice-acts { display: flex; gap: 6px; flex: none; flex-wrap: wrap; justify-content: flex-end; max-width: 200px; }
.chk { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--fg-soft); }

/* ── 영상 안정성 알림 카드(대시보드) ─────────────────────── */
.video-warn {
  border: 1px solid color-mix(in oklab, var(--amber) 45%, var(--border));
  border-left: 4px solid var(--amber);
  background: var(--amber-soft);
  border-radius: 12px; padding: 14px 16px; margin-bottom: 14px;
  display: flex; flex-direction: column; gap: 8px; font-size: 13px;
}
/* 하드웨어 급사 블록 — 경고(주황)와 구분되게 정보(파랑) 톤. "이 영상 문제 아님" 성격이라 덜 위협적으로. */
.video-warn.vw-hw {
  border-color: color-mix(in oklab, var(--accent) 40%, var(--border));
  border-left-color: var(--accent);
  background: var(--accent-soft);
}
.video-warn .vw-head { color: var(--fg); }
.video-warn .vw-list { margin: 0; padding-left: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; color: var(--fg); }
.video-warn .vw-list li { display: flex; align-items: center; gap: 8px; }
.video-warn .vw-name { flex: 1 1 auto; min-width: 0; }
.video-warn .vw-clear { flex: none; width: 22px; height: 22px; border-radius: 6px; border: 1px solid var(--border); background: transparent; color: var(--fg-muted); font-size: 12px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all .12s; }
.video-warn .vw-clear:hover { border-color: var(--red); color: var(--red); background: color-mix(in srgb, var(--red) 14%, transparent); }
.video-warn .vw-guide { color: var(--fg-soft); }
.video-warn .vw-actions { display: flex; gap: 8px; margin-top: 2px; flex-wrap: wrap; }
.video-warn .vw-actions .btn { text-decoration: none; }

/* ── 에러 대처 페이지(총관리자) ─────────────────────────── */
.err-sub { color: var(--fg-soft); font-size: 13px; margin: 2px 0 16px; line-height: 1.6; }
.err-toggle { font-size: 13px; color: var(--fg-soft); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.err-tools { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.err-tenant { font-size: 13px; padding: 6px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--fg); max-width: 240px; }
.err-tn { font-size: 11px; font-weight: 700; color: var(--fg-muted); background: rgba(127,127,127,.09); border-radius: 6px; padding: 2px 7px; white-space: nowrap; }
.err-pill { min-width: 64px; text-align: center; border-radius: var(--radius-pill); flex: none; }  /* 상태 필 — 폭 통일로 열 정렬 */
.err-list { display: flex; flex-direction: column; gap: 10px; }
.err-card { border: 1px solid var(--border); border-radius: 12px; background: var(--surface); overflow: hidden; }
.err-card.is-resolved { opacity: .6; }
.err-card > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 12px;
  padding: 13px 16px; font-size: 13px;
}
.err-card > summary::-webkit-details-marker { display: none; }
.err-card > summary::before { content: '▸'; color: var(--fg-muted); font-size: 11px; transition: transform .15s; }
.err-card[open] > summary::before { transform: rotate(90deg); }
.err-card > summary:hover { background: rgba(127,127,127,.04); }
.err-time { font-variant-numeric: tabular-nums; color: var(--fg-soft); white-space: nowrap; }
.err-dev { font-weight: 600; color: var(--fg); white-space: nowrap; }
.err-cause-short { color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
.err-body { padding: 4px 16px 16px 34px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 14px; cursor: default; }  /* 상세내용은 클릭 대상 아님 — 포인터 커서 제거(접기/펼치기는 summary만) */
.err-del-x { margin-left: auto; flex: none; border: 0; background: transparent; color: var(--fg-muted); font-size: 15px; line-height: 1; width: 24px; height: 24px; border-radius: 6px; cursor: pointer; }
.err-del-x:hover { background: var(--red-soft); color: var(--red); }
.err-innocent { margin-top: 6px; font-size: 12px; color: var(--green); background: var(--green-soft); border-radius: 6px; padding: 7px 10px; line-height: 1.5; }
.err-culprit-warn { margin-top: 6px; font-size: 12px; color: var(--amber); background: var(--amber-soft); border-radius: 6px; padding: 7px 10px; line-height: 1.5; }
.err-section { display: flex; flex-direction: column; gap: 6px; }
.err-k { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--fg-muted); }
.err-section > div { font-size: 13px; color: var(--fg); line-height: 1.6; }
.err-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 5px; font-size: 13px; color: var(--fg); line-height: 1.55; }
.err-culprit { margin-top: 4px; font-size: 13px; color: var(--fg-soft); }
.err-detail { margin-top: 4px; font-family: ui-monospace, monospace; font-size: 12px; color: var(--fg-soft);
  background: rgba(127,127,127,.06); border-radius: 6px; padding: 8px 10px; white-space: pre-wrap; word-break: break-all; }
.err-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding-top: 2px; }
.err-resolve { background: var(--surface); border: 1px solid var(--border); }
.err-del { background: var(--surface); border: 1px solid var(--border); color: var(--red); margin-left: auto; }  /* 삭제는 오른쪽 끝·위험색 */
.err-resolved { font-size: 12px; color: var(--green); font-weight: 600; }
.badge-indigo { background: var(--accent-soft); color: var(--accent); }

/* ── 폼 ─────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 5px; }
.field > span { font-size: 13px; font-weight: 600; color: var(--fg-soft); }
/* ── 통일 입력 컨트롤 — 모든 텍스트 입력·선택·여러줄 입력이 동일한 모양(높이·테두리·포커스링) ── */
/* input:not([type]) = type 속성이 없는 순수 <input>(기본 text)도 포함 — 누락 방지 */
input:not([type]),
input[type="text"], input[type="password"], input[type="number"], input[type="time"],
input[type="date"], input[type="search"], input[type="email"], input[type="url"], input[type="tel"],
input[type="file"], select, textarea {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 8px 11px; min-height: 38px; background: #fff; color: var(--fg);
  outline: none; width: 100%; font-size: 14px; line-height: 1.35;
  transition: border-color var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
textarea { min-height: 66px; resize: vertical; }
/* 선택(select) — 네이티브 화살표를 감추고 통일된 커스텀 셰브론 사용 */
select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none; cursor: pointer;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center;
}
input:hover, select:hover, textarea:hover { border-color: var(--border-strong); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}
input:disabled, select:disabled, textarea:disabled {
  background: var(--card-sunken); color: var(--fg-muted); cursor: not-allowed; border-color: var(--divider);
}
input::placeholder, textarea::placeholder { color: oklch(0.62 0.015 264); }
/* 검색창 안의 input은 자체 스타일(테두리 없음)을 유지 — 위 통일 규칙보다 우선 */
.search-bar input[type="search"] { border: none; min-height: 0; padding: 0; background: transparent; }
/* 웹킷 검색창 기본 장식(취소 X) 정리 */
input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
input[type="color"] {
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px;
  width: 44px; height: 34px; background: #fff; cursor: pointer;
}
/* 파일 입력 — 내장 "파일 선택"을 버튼 모양으로 (APK 업로드 등) */
input[type="file"] { padding: 6px 8px; cursor: pointer; }
input[type="file"]::file-selector-button {
  font-family: inherit; font-size: 12px; font-weight: 600;
  padding: 6px 13px; margin-right: 10px; cursor: pointer;
  color: var(--fg); border: 1px solid var(--border); border-radius: 6px;
  background: linear-gradient(to bottom, #fff, oklch(0.968 0.005 264));
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.9), 0 1px 2px oklch(0.25 0.02 270 / 0.07);
  transition: color var(--speed) var(--ease-out), border-color var(--speed) var(--ease-out),
    background var(--speed) var(--ease-out);
}
input[type="file"]::file-selector-button:hover {
  color: var(--accent); border-color: var(--accent); background: var(--accent-soft);
}
input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.form-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.form-row .field { flex: 1; min-width: 130px; }
.form-row .field.narrow { flex: 0 0 auto; min-width: 0; }
.check-inline { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; font-size: 13px; }
.form-actions { margin-top: 16px; display: flex; gap: 8px; justify-content: flex-end; }
/* 긴 편집 카드(레이아웃 등)의 저장 바 — 스크롤 중에도 항상 하단에 떠 있음(카드를 벗어나면 함께 사라짐) */
.sticky-actions {
  position: sticky; bottom: 0; z-index: 6;
  background: var(--card);
  margin: 14px -22px -22px; padding: 12px 22px;
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
  box-shadow: 0 -6px 14px -8px rgba(0, 0, 0, .25);
  align-items: center;
}
/* 미저장 상태의 레이아웃 저장 바 — 작은 '저장 안 됨' 글씨만으론 놓쳐서, 바 자체를 물들인다.
   (고급 섹션이 길어 저장 버튼이 화면 밖으로 밀리면 편집분을 그대로 두고 나가게 된다) */
.layout-save-bar.is-dirty {
  background: var(--amber-soft);
  border: 1px solid color-mix(in srgb, var(--amber) 38%, var(--divider));
  border-radius: var(--radius-sm); padding: 10px 12px;
}
.dirty-hint { font-size: 12px; color: var(--amber); font-weight: 600; display: none; }
.dirty-hint::before { content: '●'; margin-right: 5px; }
.dirty-hint.on { display: inline; }

/* ── 버튼 ───────────────────────────────────────────────── */
/* 미세한 세로 그라데이션 + 상단 하이라이트로 눌리는 물성 표현.
   호버 시 살짝 떠오르고, 클릭 시 가라앉는다. */
.btn {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 8px 14px; font-weight: 600; cursor: pointer;
  background: linear-gradient(to bottom, #fff, oklch(0.968 0.005 264));
  color: var(--fg);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.9), 0 1px 2px oklch(0.25 0.02 270 / 0.07);
  transition: background var(--speed) var(--ease-out), border-color var(--speed) var(--ease-out),
    color var(--speed) var(--ease-out), transform var(--speed) var(--ease-out),
    box-shadow var(--speed) var(--ease-out);
}
.btn:hover {
  border-color: var(--border-strong);
  background: linear-gradient(to bottom, #fff, oklch(0.955 0.006 264));
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.9), 0 3px 8px oklch(0.25 0.02 270 / 0.1);
}
.btn:active {
  transform: translateY(0);
  box-shadow: inset 0 1px 3px oklch(0.25 0.02 270 / 0.12);
  background: oklch(0.955 0.006 264);
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }
.btn-primary {
  background: linear-gradient(to bottom, oklch(0.56 0.21 277), var(--accent));
  border-color: var(--accent-hover); color: #fff;
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.22), 0 1px 3px oklch(0.51 0.23 277 / 0.35);
}
.btn-primary:hover {
  background: linear-gradient(to bottom, oklch(0.59 0.21 277), var(--accent-hover));
  border-color: var(--accent-hover);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.22), 0 4px 12px oklch(0.51 0.23 277 / 0.4);
}
.btn-primary:active {
  background: var(--accent-hover);
  box-shadow: inset 0 2px 4px oklch(0.3 0.15 277 / 0.4);
}
.btn-danger {
  background: linear-gradient(to bottom, #fff, oklch(0.975 0.01 22));
  border-color: oklch(0.82 0.07 25); color: var(--red);
}
.btn-danger:hover {
  background: var(--red-soft); border-color: var(--red);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.6), 0 3px 8px oklch(0.55 0.2 26 / 0.15);
}
.btn-danger:active { background: oklch(0.93 0.04 22); box-shadow: inset 0 1px 3px oklch(0.55 0.2 26 / 0.2); }
.btn-sm { padding: 5px 10px; font-size: 12px; border-radius: 6px; }
.btn-block { width: 100%; padding: 10px 14px; }
.btn-ghost-dark { background: transparent; border-color: oklch(1 0 0 / 0.16); color: var(--sidebar-fg); box-shadow: none; }
.btn-ghost-dark:hover { background: var(--sidebar-hover); border-color: oklch(1 0 0 / 0.28); color: #fff; }
.btn-icon { padding: 4px 8px; font-size: 12px; line-height: 1; }

/* ── 테이블 ─────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.tbl th {
  text-align: left; color: var(--fg-soft); font-weight: 650; font-size: 12px;
  padding: 9px 10px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.tbl td { padding: 10px; border-bottom: 1px solid var(--divider); vertical-align: middle; }
.tbl tr:last-child td { border-bottom: none; }
.tbl tbody tr { transition: background var(--speed) var(--ease-out); }
.tbl tbody tr:hover td { background: oklch(0.972 0.008 274); }
/* 현재 배포 버전 행 강조 — 배경 틴트 + 볼드는 마크업에서 */
.tbl tr.row-latest td, .tbl tr.row-latest:hover td { background: var(--accent-soft); }

/* ── 업로드 드롭존 / 진행률 ─────────────────────────────── */
.dropzone {
  border: 2px dashed var(--border-strong); border-radius: var(--radius);
  padding: 32px 20px; text-align: center; color: var(--fg-muted);
  cursor: pointer; background: var(--card-sunken);
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out),
    color var(--speed) var(--ease-out);
}
/* 업로드 방향을 암시하는 원형 화살표 아이콘 */
.dropzone::before {
  content: "↑"; display: block; width: 38px; height: 38px; margin: 0 auto 10px;
  line-height: 38px; font-size: 18px; font-weight: 700; border-radius: 50%;
  background: #fff; border: 1px solid var(--border); color: var(--fg-muted);
  transition: inherit;
}
.dropzone:hover, .dropzone.dragover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.dropzone:hover::before, .dropzone.dragover::before { border-color: var(--accent); color: var(--accent); }
.dropzone strong { display: block; font-size: 15px; margin-bottom: 4px; color: var(--fg); }
.dropzone:hover strong, .dropzone.dragover strong { color: var(--accent); }

.progress-list { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.progress-list:empty { margin-top: 0; }
.progress-item { font-size: 12px; color: var(--fg-muted); }
.progress-item .bar { height: 6px; background: var(--divider); border-radius: 6px; overflow: hidden; margin-top: 4px; }
.progress-item .bar > i {
  display: block; height: 100%; background: var(--accent); border-radius: 6px;
  transition: width 0.2s var(--ease-out);
}
.progress-item.done .bar > i { background: var(--green); }
.progress-item.error .bar > i { background: var(--red); }
.progress-item.error { color: var(--red); }

/* ── 콘텐츠 카드 ───────────────────────────────────────── */
.content-card { display: flex; flex-direction: column; gap: 8px; }
/* 이름은 1줄 말줄임 → 카드 높이가 이름 길이에 따라 달라지지 않음 */
.content-card .c-name {
  font-weight: 600; font-size: 13px; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: normal;
}
.content-card .c-badges { min-height: 20px; }
.content-card .c-meta { font-size: 12px; color: var(--fg-muted); }

/* 분류별 섹션 */
.cat-section { margin-bottom: 22px; }
.cat-section:last-child { margin-bottom: 0; }
.cat-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 700; margin: 4px 0 10px;
  padding-bottom: 6px; border-bottom: 2px solid var(--divider);
}
.cat-head svg { width: 15px; height: 15px; flex: none; color: var(--accent); }
/* 폴더 접기 — 분류가 여럿이고 각각 수십 장이면 화면이 통째로 길어져 원하는 걸 못 찾는다.
   접어도 이름과 개수 배지는 남으므로 그 상태로도 카드를 끌어다 놓을 수 있다. */
.cat-head { cursor: pointer; user-select: none; }
.cat-head:hover { border-bottom-color: var(--accent); }
.cat-caret { flex: none; font-size: 11px; color: var(--fg-muted); transition: transform var(--speed, .15s) var(--ease-out, ease); }
.cat-section.collapsed .cat-caret { transform: rotate(-90deg); }
.cat-section.collapsed > .grid { display: none; }
.cat-section.collapsed .cat-head { margin-bottom: 0; opacity: 0.85; }

/* ── 업로드 규격 안내 타일 (콘텐츠 페이지) ─────────────── */
.upload-specs {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 8px; margin-top: 12px;
}
.spec-tile {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 13px; border: 1px solid var(--divider); border-radius: 12px;
  background: var(--card-sunken);
}
.spec-ico {
  width: 36px; height: 36px; flex: none; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.spec-ico svg { width: 17px; height: 17px; }
.spec-body { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.spec-body b { font-size: 12px; }
.spec-body span { font-size: 12px; color: var(--fg-soft); }
.spec-body small { font-size: 11px; color: var(--fg-muted); line-height: 1.5; }
.spec-body .spec-warn { color: var(--amber); font-weight: 600; }
/* 세로/가로 설치 미니 화면 다이어그램 — 해상도 타일용 */
.spec-screens { gap: 4px; }
.spec-screens .mini-screen {
  display: inline-block; border: 2px solid var(--accent); border-radius: 6px;
  background: oklch(1 0 0 / 0.65);
}
.mini-screen.portrait { width: 11px; height: 18px; }
.mini-screen.landscape { width: 18px; height: 11px; }
/* 같은 줄 카드 높이 정렬 */
.grid-cards { align-items: stretch; }
/* '.card + .card'의 세로 스택용 상단 여백이 그리드 카드에 붙어 첫 카드만 커지던 문제 해소 */
.grid .card + .card { margin-top: 0; }

/* ── 타임라인 편성 편집기 ─────────────────────────────── */
.btn-xs { padding: 2px 7px; font-size: 11px; line-height: 1.5; box-shadow: none; min-width: 0; }
.timeline { display: flex; gap: 10px; overflow-x: auto; padding: 6px 2px 10px; align-items: stretch; }
.seg-block { flex: 0 0 auto; min-width: 168px; border: 1px solid var(--border); border-radius: 12px; background: rgba(127,127,127,.06); padding: 8px; }
/* 전체화면 세그먼트 — 인디고 전체 테두리 + 틴트로 구분 (좌측 스트라이프 대신) */
.seg-block.seg-full { border-color: oklch(0.7 0.13 277); background: var(--accent-soft); }
/* 헤드단 — 분할/전체화면 모두 동일 구조(번호+유형 뱃지+지속+도구)의 상단 띠.
   블록 패딩(8px)을 음수 마진으로 상쇄해 블록 전체 폭을 차지하고,
   고정 높이(34px) + 하단 구분선으로 세그먼트끼리 기준선이 항상 맞는다 */
.seg-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; white-space: nowrap;
  /* 마감일 입력이 들어오면서 한 줄에 다 안 들어갈 수 있다 → 잘리는 대신 줄바꿈.
     한 줄로 들어갈 때는 종전과 똑같이 34px 고정이라 세그먼트끼리 기준선이 유지된다. */
  flex-wrap: wrap; row-gap: 4px; align-content: center;
  min-height: 34px;
  margin: -8px -8px 8px; padding: 4px 8px;
  background: oklch(1 0 0 / 0.55);
  border-bottom: 1px solid var(--divider);
  border-radius: 8px 8px 0 0;
}
.seg-head .seg-no { font-weight: 750; font-variant-numeric: tabular-nums; }
.seg-tools { margin-left: auto; display: inline-flex; gap: 3px; align-items: center; }
.seg-dur { font-size: 11px; color: var(--fg-muted); display: inline-flex; align-items: center; gap: 3px; font-weight: 400; }
/* 지속/표시 컨트롤은 콤팩트 고정 높이 — 전역 input의 min-height:38px·padding을 반드시 덮어야 헤드단(34px)을 안 넘는다 */
.seg-dur input, .seg-dur select {
  height: 22px; min-height: 0; padding: 0 6px; font-size: 12px; line-height: 20px; border-radius: 6px; width: auto;
  box-sizing: border-box; vertical-align: middle;
}
.seg-dur select { padding: 0 19px 0 6px; background-position: right 4px center; background-size: 11px; }
.seg-dur input[type="number"] { width: 52px; }
/* 전체/전체+정보형: 콘텐츠 1개 → 가운데 정렬 + 세로로 채워 아래 여백 최소화 */
.seg-body-full { display: flex; flex-direction: column; gap: 8px; align-items: center; justify-content: center; text-align: center; padding: 6px 0 2px; }
.seg-full-info { display: flex; flex-direction: column; gap: 7px; align-items: center; min-width: 0; width: 100%; }
.seg-full-info .btn { min-width: 120px; }
.seg-full-info .seg-dur { justify-content: center; }
.seg-name { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; text-align: center; }
.seg-empty { width: 84px; height: 84px; border-radius: 8px; background: #0f172a; display: flex; align-items: center; justify-content: center; font-size: 11px; color: #64748b; flex: none; text-align: center; }
/* 분할 세그먼트 — 단말기 화면 형태 미리보기 (위=상/좌 존, 아래=하/우 존) */
.seg-screen {
  min-width: 210px; margin-top: 2px;
  border: 3px solid oklch(0.34 0.015 275); border-radius: 12px; background: #0b1220;
  padding: 5px; display: flex; flex-direction: column; gap: 4px;
}
.seg-zone { background: oklch(0.17 0.012 275); border-radius: 8px; padding: 8px; min-height: 62px; }
.seg-zone-label { font-size: 10px; font-weight: 600; color: oklch(0.72 0.02 275); margin-bottom: 6px; letter-spacing: 0.02em; }
.seg-screen-div { height: 3px; background: oklch(0.42 0.02 275); border-radius: 6px; margin: 0 auto; width: calc(100% - 20px); }
.seg-zone .seg-chips { gap: 0; align-items: flex-start; }
.seg-zone.drop-hover { outline: 2px dashed var(--accent); outline-offset: 1px; background: oklch(0.24 0.03 277); border-radius: 8px; }
.seg-zone-add { flex: none; margin-left: 6px; color: oklch(0.78 0.02 275); border-color: oklch(1 0 0 / 0.18); background: oklch(1 0 0 / 0.05); }
/* (구 레인 스타일 — 하위호환) */
.seg-lanes { display: flex; flex-direction: column; gap: 6px; }
.seg-lane { display: flex; align-items: center; gap: 6px; }
.seg-lane-label { font-size: 10px; color: var(--fg-muted); width: 14px; flex: none; text-align: center; }
.seg-chips { display: flex; gap: 0; flex-wrap: wrap; align-items: flex-start; }
.seg-chip { display: flex; flex-direction: column; gap: 3px; align-items: stretch; min-width: 36px; }
.seg-chip-thumb { position: relative; width: 100%; height: 52px; border-radius: 6px; background: #0f172a; overflow: hidden; cursor: grab; }
.seg-chip-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.seg-clip-ic { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 15px; color: #94a3b8; }
/* 제거(X) — 부모가 overflow:hidden이라 음수 오프셋은 잘린다. 안쪽에 두고 흰 링으로 썸네일과 분리.
   보이는 원은 22px, ::after로 탭 영역만 30px까지 넓혀 작은 칩에서도 누르기 쉽게 한다. */
.seg-chip-x {
  position: absolute; top: 1px; right: 1px; z-index: 2;
  width: 22px; height: 22px; border-radius: 50%; border: none; padding: 0;
  background: var(--red); color: #fff; font-size: 16px; font-weight: 700; line-height: 22px;
  text-align: center; cursor: pointer;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .9), 0 1px 3px rgba(0, 0, 0, .35);
  transition: transform .12s ease, filter .12s ease;
}
.seg-chip-x::after { content: ''; position: absolute; inset: -5px; border-radius: 50%; }

/* 마감일 지정(📅) — X와 대칭으로 좌상단. 숨은 date 입력의 달력만 띄우는 트리거다. */
.seg-chip-cal {
  position: absolute; top: 1px; left: 1px; z-index: 2;
  width: 22px; height: 22px; border-radius: 50%; border: none; padding: 0;
  background: rgba(15, 23, 42, .75); color: #fff; font-size: 11px; line-height: 22px;
  text-align: center; cursor: pointer;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .9), 0 1px 3px rgba(0, 0, 0, .35);
}
.seg-chip-cal.on { background: var(--amber); }
.seg-chip-cal:hover { filter: brightness(1.15); }
/* 달력을 열기 위한 실제 입력 — 보이지 않지만 포커스는 가능해야 showPicker()가 동작한다. */
.seg-chip-expin { position: absolute; left: 1px; top: 1px; width: 22px; height: 22px; opacity: 0; pointer-events: none; }
/* 전체화면 세그먼트 머리글의 마감일 입력 —
   .seg-dur와 마찬가지로 전역 input의 min-height:38px·padding을 반드시 덮어야 34px 머리글을 안 넘는다.
   width는 'YYYY-MM-DD' + 달력 아이콘이 잘리지 않을 만큼 확보(한글 플레이스홀더 '연도-월-일' 기준). */
.seg-exp {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  font-size: 11px; color: var(--fg-muted); font-weight: 400;
}
.seg-exp-lbl { font-size: 11px; }
.seg-exp input[type="date"] {
  width: 148px; min-width: 148px; height: 22px; min-height: 0;
  padding: 0 6px; font-size: 12px; line-height: 20px; border-radius: 6px;
  box-sizing: border-box; vertical-align: middle;
  font-variant-numeric: tabular-nums;
}
.seg-exp input[type="date"]::-webkit-calendar-picker-indicator { padding: 0; margin-left: 2px; cursor: pointer; }
.seg-chip-x:hover { transform: scale(1.12); filter: brightness(1.1); }
.seg-chip-x:active { transform: scale(.94); }
.seg-chip-fit { width: 100%; font-size: 10px; height: 18px; min-height: 0; padding: 0 14px 0 4px; min-width: 0; line-height: 16px; box-sizing: border-box; background-position: right 2px center; background-size: 10px; border-radius: 6px; }
.seg-chip-dur { font-size: 10px; color: var(--fg-muted); display: inline-flex; align-items: center; gap: 1px; }
.seg-chip-dur input { width: 34px; padding: 1px 3px; font-size: 10px; }
.seg-chip-time { font-size: 10px; color: var(--accent); font-weight: 600; }

/* 드래그 팔레트 */
.prog-palette { border: 1px solid var(--border); border-radius: 12px; padding: 8px; margin-bottom: 12px; background: rgba(127,127,127,.04); }
.prog-pal-search { width: 100%; max-width: 320px; margin-bottom: 8px; }
/* 화면 절반(48vh)까지는 스크롤 없이 다 보이고, 그 이상일 때만 세로 스크롤 */
.prog-pal-groups { max-height: 48vh; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.prog-pal-cat { font-size: 11px; font-weight: 700; color: var(--fg-muted); margin-bottom: 4px; padding-bottom: 2px; border-bottom: 1px solid var(--divider); }
/* 가로 스크롤 대신 줄바꿈 → 가로 스크롤바 제거 */
.prog-pal-items { display: flex; flex-wrap: wrap; gap: 8px; }
.pal-item { flex: 0 0 auto; width: 52px; display: flex; flex-direction: column; align-items: center; gap: 3px; cursor: grab; padding: 3px; border-radius: 8px; }
.pal-item:hover { background: rgba(127,127,127,.12); }
.pal-item:active { cursor: grabbing; }
.pal-name { font-size: 9px; max-width: 52px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--fg-muted); }
.seg-drop.drop-hover { outline: 2px dashed var(--accent); outline-offset: 2px; background: rgba(79,70,229,.08); border-radius: 6px; }
.seg-miss { width: 40px; height: 40px; border-radius: 8px; background: #7f1d1d; color: #fff; display: flex; align-items: center; justify-content: center; }

/* 섹션 비활성(타임라인 편성 사용 시 스케줄 회색처리) */
.section-lock { background: rgba(127,127,127,.12); border: 1px dashed var(--border); border-radius: 8px; padding: 8px 10px; font-size: 12px; color: var(--fg-muted); margin-bottom: 12px; }
.section-disabled { opacity: .45; pointer-events: none; user-select: none; }

/* 전원 스케줄 일괄 적용 바 */
.power-bulk { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; padding: 8px 10px; margin-bottom: 12px; background: rgba(127,127,127,.06); border: 1px solid var(--border); border-radius: 8px; }
.power-bulk-label { font-size: 12px; font-weight: 600; color: var(--fg-muted); align-self: center; }
.content-card .c-foot {
  /* 버튼 수가 카드마다 달라도(적합성 초기화·서버 최적화 등) 높이·크기가 흐트러지지 않게:
     균일 gap 줄바꿈 + 카드 바닥 고정(margin-top:auto) + 버튼 크기 통일 */
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-top: auto; padding-top: 10px; border-top: 1px solid var(--divider);
}
.content-card .c-foot .btn-sm {
  padding: 4px 9px; font-size: 12px; line-height: 1.5; white-space: nowrap; flex: 0 0 auto;
}
.content-card .c-foot .btn-danger { margin-left: auto; }  /* 삭제는 오른쪽 끝 고정 */

/* ── 플레이리스트 편집기 ───────────────────────────────── */
/* 항목 행 — 라벨이 있는 칸(재생시간·표시방식·마감일)과 없는 것(전체화면 체크·제거 버튼)이 섞여 있다.
   center로 맞추면 라벨 높이만큼 어긋나므로, 입력의 '아래선'을 기준으로 정렬한다.
   썸네일·이름·순서 버튼은 행 전체 기준으로 가운데가 자연스러워 따로 center로 되돌린다. */
.pl-item-row {
  display: flex; align-items: flex-end; gap: 8px; padding: 8px 0;
  border-bottom: 1px solid var(--divider); flex-wrap: wrap;
}
.pl-item-row:last-child { border-bottom: none; }
.pl-item-row > .order-btns,
.pl-item-row > .pl-name,
.pl-item-row > span:not(.order-btns):not(.pl-name),
.pl-item-row > div { align-self: center; }
.pl-item-row .pl-name { flex: 1; min-width: 140px; font-size: 13px; }
.pl-item-row .field { margin: 0; }
/* 라벨 줄 높이를 '고정'한다 — '마감' 배지가 붙어도 그 칸만 커져 행이 어긋나지 않게. */
.pl-item-row .field > span { height: 18px; line-height: 18px; white-space: nowrap; overflow: visible; }
.pl-item-row .field > span .badge { line-height: 1; vertical-align: middle; padding: 1px 5px; }
.pl-item-row input[type="number"] { width: 76px; }
.pl-item-row select { width: auto; min-width: 100px; }
.pl-item-row input[type="date"] { width: 148px; }
/* 라벨 없는 컨트롤은 입력과 같은 아래선에 오도록 살짝 띄운다(입력 높이 대비 시각 보정) */
.pl-item-row > .check-inline { align-self: flex-end; padding-bottom: 9px; white-space: nowrap; }
.pl-item-row > .btn { align-self: flex-end; }
/* 마감된 항목 — 지우지 않고 '사선'으로 덮어 한눈에 구분. 마감일만 비우면 그대로 재개된다.
   사선은 장식이므로 클릭을 막지 않도록 pointer-events: none (입력·버튼은 그대로 눌린다). */
.pl-item-expired { position: relative; }
.pl-item-expired::after {
  content: ''; position: absolute; inset: 2px 0; pointer-events: none; border-radius: 6px;
  background: repeating-linear-gradient(-45deg,
    rgba(220, 38, 38, .14) 0 6px, transparent 6px 13px);
}
.pl-item-expired .pl-name { color: var(--fg-muted); text-decoration: line-through; }

/* ── 타임라인 편성 목록: 세그먼트 미리보기 스트립 ─────────────
   목록에서 "5세그먼트" 글자만 보이면 편집기를 열기 전엔 구성을 알 수 없다.
   각 세그먼트를 작은 '화면'으로 그려 재생 순서·구성(전체/정보형/분할)을 한눈에 보이게 한다. */
.prog-row { padding: 10px 0; border-bottom: 1px solid var(--divider); }
.prog-row:last-child { border-bottom: none; }
.prog-row-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.prog-row-head .pl-name { flex: 1; min-width: 140px; font-size: 13px; }
.prog-strip { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.prog-seg { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 44px; }
/* 세로 기기(1080×1920) 비율에 가깝게 — 실제 화면 느낌을 유지 */
.ps-screen {
  width: 44px; height: 62px; border-radius: 5px; overflow: hidden;
  background: #0f172a; border: 1px solid var(--divider);
  display: flex; flex-direction: column; position: relative;
}
.ps-cell { position: relative; display: block; overflow: hidden; background: #111827; }
.ps-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ps-fill { flex: 1; }
.ps-fill-info { flex: 1; }
.ps-half { flex: 1; }
.ps-divider { height: 2px; background: #64748b; flex: none; }
.ps-infobar { height: 9px; background: linear-gradient(90deg, #1e3a8a, #2563eb); flex: none; }
.ps-miss { flex: 1; display: flex; align-items: center; justify-content: center; background: #7f1d1d; color: #fff; font-size: 11px; font-weight: 700; }
.ps-vid { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 13px; font-style: normal; }
.ps-cap { font-size: 10px; color: var(--fg-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ps-cap b { color: var(--accent); }
.ps-kind { font-size: 9px; color: var(--fg-muted); white-space: nowrap; }

.order-btns { display: flex; flex-direction: column; gap: 2px; }
.order-btns .btn { padding: 0 6px; font-size: 10px; line-height: 1.6; box-shadow: none; }

/* ── 기기 상세: 슬롯/요일/전원 행 ──────────────────────── */
.slot-row {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px;
  margin-bottom: 8px; background: var(--card-sunken);
}

/* 기기 카드 hover → '지금 이렇게 나옵니다' 가상 재생 미리보기 (마우스 환경 전용) */
.np-pop {
  position: fixed; z-index: 800; pointer-events: none;
  max-width: min(660px, calc(100vw - 24px));
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: 0 18px 42px rgba(2, 6, 23, .3);
  animation: np-in .14s ease-out;
}
@keyframes np-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.np-head {
  padding: 8px 12px; border-bottom: 1px solid var(--divider);
  font-size: 12.5px; font-weight: 700; color: var(--fg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.np-body { display: flex; gap: 14px; padding: 12px; align-items: flex-start; }
.np-screen { flex: none; position: relative; }
/* 전체화면 세그먼트 — 정보바·자막까지 덮는다(앱과 동일) */
.np-full { position: absolute; inset: 0; border-radius: 6px; overflow: hidden; display: none; }
/* 존 영역만 덮는 full_info 덮개 — 화면 모서리가 아니므로 둥글릴 이유가 없다 */
[data-zones-area] > .np-full { border-radius: 0; }
.np-side { width: 246px; flex: none; font-size: 12px; line-height: 1.6; color: var(--fg-soft); }
.np-now { font-size: 11px; color: var(--fg-muted); margin-bottom: 6px; }
.np-block + .np-block { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--divider); }
.np-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-line b { color: var(--fg); }
.np-line .muted { font-size: 11px; }
/* 편성에 담긴 장들 — 지금 나가는 장에 테두리가 붙어 어디쯤 돌고 있는지 보인다 */
.np-strip {
  display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px;
  max-height: 186px; overflow-y: auto;
}
.np-th {
  position: relative; width: 44px; height: 44px; flex: none;
  border-radius: 5px; overflow: hidden; background: #0a0d16;
  border: 2px solid transparent; opacity: .55; transition: opacity .2s, border-color .2s;
}
.np-th img { width: 100%; height: 100%; object-fit: contain; display: block; }
.np-th i {
  position: absolute; left: 0; bottom: 0; font-style: normal;
  background: rgba(2, 6, 23, .74); color: #cbd5e1;
  font-size: 9px; line-height: 1; padding: 2px 3px; border-top-right-radius: 4px;
}
.np-th.is-now { opacity: 1; border-color: var(--accent); }
.np-th.is-now i { background: var(--accent); color: #fff; }
.np-note { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--divider); font-size: 11px; color: var(--fg-muted); }
.np-loading { padding: 22px 26px; font-size: 12.5px; color: var(--fg-muted); }
/* 안내문(화면 꺼짐·정액 아님 등) — 글자가 레이어 밖으로 새지 않게 폭을 확실히 묶는다.
   flex 자식은 min-width:auto라 긴 문장이 상자를 밀어낸다 → min-width:0 + 줄바꿈 허용이 필수. */
.np-off {
  display: flex; gap: 10px; align-items: flex-start; padding: 18px 20px;
  font-size: 12.5px; line-height: 1.6; color: var(--fg-soft);
  width: 360px; max-width: 100%; box-sizing: border-box;
}
.np-off > :first-child { font-size: 22px; flex: none; line-height: 1.2; }
.np-off > span { min-width: 0; white-space: normal; overflow-wrap: anywhere; word-break: keep-all; }
.np-off .muted { white-space: normal; }

/* 타임라인 세그먼트 목록 — 지금 도는 구간에 강조 */
.np-segs { margin-top: 6px; max-height: 190px; overflow-y: auto; }
.np-seg {
  display: flex; align-items: center; gap: 6px; padding: 4px 6px; border-radius: 5px;
  font-size: 11px; color: var(--fg-muted); border: 1px solid transparent;
}
.np-seg-n { flex: none; width: 16px; text-align: center; font-variant-numeric: tabular-nums; }
.np-seg-t { flex: none; padding: 0 5px; border-radius: 3px; background: var(--card-sunken); }
.np-seg-d { flex: none; font-variant-numeric: tabular-nums; }
.np-seg-x { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-seg.is-now { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 34%, var(--border)); color: var(--fg); }
.np-seg.is-now .np-seg-t { background: var(--accent); color: #fff; }

/* 자동 채움 — 뉴스와 함께 넣을 단지 데이터 카드 고르기 */
.af-cards { display: grid; gap: 8px; }
.af-card {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card);
}
.af-card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.af-card input { flex: none; }
.af-card-ico { font-size: 20px; flex: none; }
.af-card-body { display: flex; flex-direction: column; min-width: 0; }
.af-card-body b { font-size: 13px; }
.af-card-body small { color: var(--fg-muted); font-size: 11.5px; }

/* 오늘 브리핑 편집 — 연도(짧게) + 내용(넓게) + 빼기. 연도가 세로로 줄지어야 목록으로 읽힌다. */
.bf-row { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; }
.bf-row .bf-year { width: 84px; flex: none; text-align: center; }
.bf-row .bf-text { flex: 1; min-width: 0; }

/* 브랜드 마크(텔레그램 등) — 선 아이콘과 달리 색이 든 로고라 currentColor를 물려받지 않는다.
   기존 .ct-icon은 배경 칩을 씌우므로, 브랜드용은 칩을 벗겨 로고 자체가 보이게 한다. */
.tg-mark { display: block; flex: none; }
/* 특이도 주의: 기본 규칙이 `.card h3 .ct-icon`(0,2,1)이라 `.ct-icon.ct-brand`(0,2,0)로는 안 이긴다.
   같은 경로에 클래스를 하나 더 붙여 확실히 덮는다. svg 크기 고정 규칙도 함께 풀어 준다. */
.card h3 .ct-icon.ct-brand { background: none; border-radius: 0; width: auto; height: auto; }
.card h3 .ct-icon.ct-brand svg { width: 22px; height: 22px; }
.more-item .mi-mark { display: inline-flex; vertical-align: -3px; margin-right: 6px; }
.gd-h .gd-h-mark { display: inline-flex; vertical-align: -4px; margin-right: 7px; }
.gd-tab-ico .tg-mark { margin: 0 auto; }

/* 텔레그램 연결 — 발급된 1회용 코드는 눈에 확 들어와야 방에 옮겨 적기 쉽다 */
.tg-steps { margin: 0 0 4px; padding-left: 20px; font-size: 13px; line-height: 1.9; color: var(--fg-soft); }
.tg-steps b { color: var(--fg); }
.tg-steps code, .tg-chat code { background: var(--card-sunken); border: 1px solid var(--border); border-radius: 5px; padding: 1px 6px; font-size: 12.5px; }
.tg-code {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 14px 16px; border-radius: var(--radius-sm);
  background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--divider));
}
.tg-code-v {
  font-family: Menlo, Consolas, monospace; font-size: 30px; font-weight: 800;
  letter-spacing: .18em; color: var(--accent); user-select: all;
}
.tg-code-m { font-size: 12.5px; line-height: 1.6; color: var(--fg-soft); }
.tg-chat {
  display: flex; align-items: center; gap: 10px; justify-content: space-between;
  padding: 9px 12px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card);
}
/* 글 올릴 수 있는 사람 — 자물쇠(번호 확정)와 모래시계(첫 글 대기)를 구분해 보인다 */
.tg-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 10px; }
.tg-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 6px 5px 10px; border-radius: 999px; font-size: 13px;
  border: 1px solid var(--border); background: var(--card-sunken); color: var(--fg);
}
.tg-chip.is-pinned { border-color: color-mix(in srgb, var(--accent) 34%, var(--border)); background: var(--accent-soft); }
.tg-chip small { color: var(--fg-muted); font-size: 11.5px; }
.tg-chip button {
  border: 0; background: none; cursor: pointer; color: var(--fg-muted);
  font-size: 16px; line-height: 1; padding: 0 3px; border-radius: 4px;
}
.tg-chip button:hover { color: var(--red); background: var(--card); }
.tg-row { display: flex; gap: 10px; flex-wrap: wrap; }
.tg-row > .input { flex: 1; min-width: 0; }
.tg-mini { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--fg-soft); }
.tg-mini .input { width: 68px; text-align: center; }
.tg-add { display: flex; gap: 8px; }
.tg-add .input { flex: 1; min-width: 0; }
.tg-fold { margin-top: 18px; border-top: 1px solid var(--divider); padding-top: 12px; }
.tg-fold > summary { cursor: pointer; font-size: 13px; color: var(--fg-soft); }

/* 알림 카드 본문 서식 도구 — 마크업을 외우지 않아도 되게 버튼으로 넣는다 */
.ncw-tools {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 6px; margin-bottom: -1px;
  background: var(--card-sunken);
  border: 1px solid var(--border); border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.ncw-tools button {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 10px; font-size: 12.5px; font-family: inherit; color: var(--fg);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-xs);
  cursor: pointer; transition: border-color var(--speed) var(--ease-out), color var(--speed) var(--ease-out);
}
.ncw-tools button:hover { border-color: var(--accent); color: var(--accent); }
/* 알림 카드에 붙이는 사진 한 장 — 파일 상자를 그대로 두면 투박해 버튼 + 파일명으로 감싼다. */
.ncw-photo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ncw-photo .muted { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ncw-tools button:active { background: var(--accent-soft); }
.ncw-tools-hint { font-size: 11.5px; color: var(--fg-muted); margin-left: auto; padding-right: 4px; }
/* 도구 모음과 입력칸이 한 덩어리로 보이게 위쪽 모서리를 없앤다 */
.ncw-tools + textarea { border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
@media (max-width: 560px) { .ncw-tools-hint { display: none; } }

/* 화면 방향 안내 — 이 설정이 화면을 돌리지 않는다는 걸 상시 알린다(기기 Rotate Setting 안내) */
.orient-hint { margin: -4px 0 0; font-size: 12px; line-height: 1.6; }
.orient-warn {
  margin: -4px 0 0; padding: 11px 13px; border-radius: var(--radius-sm);
  background: var(--amber-soft); border: 1px solid color-mix(in srgb, var(--amber) 34%, var(--divider));
  font-size: 12.5px; line-height: 1.65;
}
.orient-warn > b { display: block; color: color-mix(in srgb, var(--amber) 70%, #000); margin-bottom: 3px; }
.orient-fix { margin-top: 5px; color: var(--fg-soft); }

/* 존별 스케줄 블록 — 존마다 '기본 플레이리스트 + 시간대 분할'을 한 덩어리로 묶는다 */
.zone-block {
  margin-top: 12px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card-sunken);
}
.zone-block .slot-row { background: var(--card); }
.zone-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.zone-name { font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.zone-dot { width: 10px; height: 10px; border-radius: 3px; background: var(--fs-c, var(--accent)); display: inline-block; }
.zone-def { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-soft); }
.zone-spacer { flex: 1 1 auto; }
.zone-split-label { font-size: 12px; font-weight: 600; color: var(--fg-soft); }
.btn-split { min-width: 32px; padding: 5px 9px; }
.btn-split.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.zone-empty {
  padding: 14px; text-align: center; font-size: 12.5px; line-height: 1.7;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-sm);
  background: var(--card); color: var(--fg-soft);
}
/* 존 스케줄 편집 옵션 — 밴드 경계 연동 스위치 */
.sched-opt {
  display: flex; align-items: flex-start; gap: 8px; cursor: pointer;
  padding: 9px 12px; margin: -4px 0 4px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card);
  font-size: 12.5px; line-height: 1.5;
}
.sched-opt:hover { border-color: var(--border-strong); }
.sched-opt input { margin-top: 2px; flex: none; }
.sched-opt-hint { display: block; font-weight: 400; color: var(--fg-soft); }

/* 플레이리스트 선택 버튼 — 이름만으론 무엇이 나가는지 안 보여 앞쪽 썸네일을 함께 깐다 */
.pl-pick {
  display: flex; align-items: center; gap: 8px; min-width: 240px; flex: 1 1 240px;
  padding: 5px 8px; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; text-align: left;
  font-family: inherit; font-size: 13px; color: var(--fg);
  transition: border-color var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
.pl-pick:hover { border-color: var(--accent); }
.pl-pick:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.pl-thumbs { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.pl-more { font-size: 11px; color: var(--fg-muted); font-weight: 600; padding: 0 3px; }
.pl-pick-body { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.35; }
.pl-pick-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-pick-name.is-empty { color: var(--fg-muted); font-weight: 500; }
.pl-pick-meta { font-size: 11px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.pl-pick-caret { flex: none; color: var(--fg-muted); font-size: 11px; }

/* 선택 레이어 — 썸네일 카드 그리드 */
.pl-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.pl-card {
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  padding: 10px; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; text-align: left;
  font-family: inherit; font-size: 13px; color: var(--fg);
  transition: border-color var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
.pl-card:hover { border-color: var(--accent); }
.pl-card.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--accent-soft); }
.pl-card .pl-thumbs { flex-wrap: wrap; gap: 4px; }
.pl-card-name { font-weight: 700; }
.pl-card-meta { font-size: 11.5px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.pl-card-none { justify-content: center; min-height: 74px; }

.zone-def-lbl { font-weight: 600; }

/* 화면 꺼짐 구간 빗금 — 편성해도 표출되지 않는 시간대. 위에 깔되 드래그는 통과시킨다. */
.fs-band.sc-off {
  background: repeating-linear-gradient(45deg,
    oklch(0.86 0.012 273 / 0.55) 0 5px, transparent 5px 10px);
  border: none; pointer-events: none;
}
.slot-row select, .slot-row input { width: auto; background: #fff; }
.days-check { display: flex; gap: 4px; flex-wrap: wrap; }
.days-check label {
  font-size: 11px; padding: 3px 8px; border: 1px solid var(--border);
  border-radius: 6px; cursor: pointer; user-select: none; background: #fff;
  transition: background var(--speed) var(--ease-out), border-color var(--speed) var(--ease-out),
    color var(--speed) var(--ease-out);
}
.days-check label:hover { border-color: var(--border-strong); }
.days-check input { display: none; }
.days-check label:has(input:checked) { background: var(--accent); border-color: var(--accent); color: #fff; }

.power-row { display: grid; grid-template-columns: 52px 150px 1fr 1fr; gap: 10px; align-items: center; padding: 6px 0; }
.power-row .day-label { font-weight: 600; font-size: 13px; }
/* 요일 행 줄맞춤 — '켜짐/꺼짐'을 컬럼 헤더로 한 번만 두고, 각 행에는 입력만 남긴다.
   (행마다 라벨이 입력 위에 쌓이면 그 셀만 높아져 요일·선택박스와 줄이 어긋난다) */
.power-head { padding: 2px 0 0; }
.power-head .ph { font-size: 12px; font-weight: 600; color: var(--fg-muted); }
.power-row .field > span { display: none; }

.cmd-btns { display: flex; gap: 8px; flex-wrap: wrap; }

/* 실시간 갱신 표시 배지 — 맥동하는 점 + 라벨 (명령 이력 헤더 등) */
.live-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px 3px 9px; border-radius: 999px;
  background: var(--green-soft); color: oklch(0.42 0.13 150);
  font-size: 11px; font-weight: 600; line-height: 1.6;
  white-space: nowrap;
}
.live-badge i {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--green);
  animation: dot-pulse 2.4s var(--ease-out) infinite;
}
/* 원격 명령 버튼 — 아이콘 + 라벨. 아이콘은 살짝 흐리게 두고 호버 시 브랜드색으로 강조 */
.cmd-btns .btn { display: inline-flex; align-items: center; gap: 7px; }
.cmd-btns .btn svg {
  width: 15px; height: 15px; flex: none;
  color: var(--fg-muted);
  transition: color var(--speed) var(--ease-out);
}
.cmd-btns .btn:hover svg { color: var(--accent); }
.cmd-btns .btn-danger svg { color: var(--red); }

/* ── 기기 상태 시각화 (상태 카드) ──────────────────────── */
/* 연결 상태 히어로 — 온라인/오프라인이 카드에서 가장 먼저 읽히는 정보 */
.status-hero {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; border-radius: 12px; margin-bottom: 10px;
  border: 1px solid var(--border); background: var(--card-sunken);
}
.status-hero.on { background: var(--green-soft); border-color: oklch(0.85 0.08 152); }
.status-hero .dot { width: 11px; height: 11px; }
.status-hero-main { flex: 1; min-width: 0; }
.status-hero-state { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; }
.status-hero.on .status-hero-state { color: oklch(0.42 0.13 150); }
.status-hero-sub { font-size: 12px; color: var(--fg-muted); margin-top: 1px; }
.status-hero-tags { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }

/* 스탯 타일 — 숫자는 텍스트 토큰(잉크색), 색은 상태 뱃지/미터만 사용 */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; }
.stat-tile {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 12px; background: #fff; min-width: 0;
}
.stat-tile.stat-wide { margin-top: 8px; }
.stat-tile .st-label { font-size: 11px; font-weight: 600; color: var(--fg-soft); letter-spacing: 0.01em; }
.stat-tile .st-value {
  font-size: 16px; font-weight: 700; letter-spacing: -0.01em; margin-top: 2px;
  font-variant-numeric: tabular-nums; word-break: break-all;
}
.stat-tile .st-value.st-sm { font-size: 13px; font-weight: 600; }

/* 저장공간 사용률 미터 — 4px 라운드, 기본 인디고 / 75%↑ 황색 / 90%↑ 적색 */
.meter { height: 8px; border-radius: 6px; background: var(--divider); overflow: hidden; margin-top: 8px; }
.meter > i {
  display: block; height: 100%; border-radius: 6px; background: var(--accent);
  transition: width 0.3s var(--ease-out);
}
.meter.warn > i { background: var(--amber); }
.meter.crit > i { background: var(--red); }
.meter.good > i { background: var(--green, #22c55e); }
/* 임계 눈금 — 값만으론 '한계까지 얼마 남았나'가 안 읽힌다. 막대 위에 선을 그어 둔다.
   (눈금이 잘리지 않도록 이 변형에서만 overflow를 푼다) */
.meter.meter-lim { overflow: visible; position: relative; }
.meter-tick {
  position: absolute; top: -2px; bottom: -2px; width: 2px; border-radius: 2px;
  background: var(--red); opacity: 0.5;
}
/* 통신 점수 옆 최근 표본(n/N) 보조 표기 */
.du-sub { font-size: 10px; color: var(--fg-muted); font-weight: 500; margin-left: 2px; }
.du-val.du-muted { color: var(--fg-muted); font-weight: 500; }

/* 모달 내 구분선 */
.modal-sep { border: none; border-top: 1px solid var(--divider); margin: 16px 0 4px; }

/* 단지 카드 통신 프로파일 배지 */
.tenant-profile { margin-top: 8px; }
/* KT LTE 참고 프리셋 칩 (종량 예산 빠른 선택) */
.kt-presets { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.kt-presets-lbl { font-size: 11px; color: var(--fg-muted); margin-right: 2px; }
.kt-chip {
  font-size: 12px; padding: 3px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--divider); background: var(--surface, #fff); color: var(--fg);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.kt-chip:hover { border-color: var(--accent); color: var(--accent); }
.kt-chip.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* 종량제 단지 — 남은 데이터 미터 */
.tenant-data { margin-top: 8px; }

/* ═══════════════ 이용 안내(가이드) 페이지 ═══════════════ */
.gd-tabbar { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 18px; border-bottom: 2px solid var(--divider); padding-bottom: 0; }
.gd-tab {
  display: inline-flex; align-items: center; gap: 7px; padding: 10px 16px; cursor: pointer;
  border: none; background: none; color: var(--fg-muted); font-size: 14px; font-weight: 600;
  border-bottom: 3px solid transparent; margin-bottom: -2px; border-radius: 8px 8px 0 0; transition: color .15s, background .15s;
}
.gd-tab:hover { color: var(--fg); background: var(--accent-soft); }
.gd-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.gd-tab-ico { font-size: 17px; }
.gd-body { animation: gdfade .25s ease; }
@keyframes gdfade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.gd-lead { font-size: 15px; line-height: 1.7; color: var(--fg); background: var(--accent-soft); border-radius: var(--radius-sm); padding: 16px 18px; margin: 0 0 22px; }
.gd-sec { margin: 0 0 26px; }
.gd-h { font-size: 17px; margin: 0 0 6px; color: var(--fg); }
.gd-sub { font-size: 13px; color: var(--fg-muted); line-height: 1.6; margin: 0 0 14px; }
/* 섹션 안의 소제목 — 한 섹션에 갈래가 둘 이상일 때(예: 배정 → 시간대 분할) 번호를 늘리지 않고 나눈다 */
.gd-h4 { font-size: 14.5px; font-weight: 700; margin: 0 0 6px; color: var(--fg); padding-top: 14px; border-top: 1px solid var(--divider); }
/* 안내 노트 — 좌측 스트라이프 대신 선행 이모지 + 옅은 강조 배경/테두리 */
/* 안내 상자 — 내용이 '이모지 + 문장'뿐이라 block이 맞다.
   flex로 두면 <b> 하나하나가 개별 flex 항목이 되어 '단지코드는 | GD43 | 입니다.'처럼
   낱말이 세로 칸으로 쪼개진다(실제로 텔레그램 연결 창에서 그렇게 나왔다). */
.gd-note { display: block; font-size: 13px; line-height: 1.6; color: var(--fg); background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--divider)); border-radius: 8px; padding: 11px 14px; margin-top: 14px; word-break: keep-all; overflow-wrap: anywhere; }
/* 타임라인 홀드·자동균형 시각화 */
.gd-balance { margin-top: 14px; padding: 14px 16px; border: 1px solid var(--divider); border-radius: 12px; background: var(--surface, #fff); }
.gd-balance-h { font-size: 13px; font-weight: 600; margin-bottom: 12px; color: var(--fg); display: flex; align-items: center; gap: 7px; }
.gd-balance-ico { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: rgba(245,158,11,.16); color: #b45309; font-size: 13px; }
.gd-lane-demo { display: flex; align-items: center; gap: 10px; margin: 7px 0; }
.gd-lane-tag { flex: 0 0 34px; font-size: 11px; font-weight: 700; color: var(--fg-muted, #64748b); text-align: right; }
.gd-lane-bar { flex: 1; display: flex; gap: 3px; height: 34px; border-radius: 6px; overflow: hidden; }
.gd-seg { display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; color: #fff; white-space: nowrap; overflow: hidden; border-radius: 6px; padding: 0 4px; }
.gd-seg.vid { background: linear-gradient(135deg, #6366f1, #4338ca); }
.gd-seg.img { background: linear-gradient(135deg, #0d9488, #0f766e); }
.gd-seg.hold { background: repeating-linear-gradient(45deg, #94a3b8, #94a3b8 6px, #cbd5e1 6px, #cbd5e1 12px); color: #1e293b; font-weight: 700; }
.gd-lane-sum { flex: 0 0 96px; font-size: 11px; font-weight: 700; color: var(--accent); }
.gd-lane-sum.warn { color: #b45309; }
.gd-lane-sum.ok { color: #15803d; }
.gd-balance-arrow { margin: 10px 0 6px 44px; font-size: 12px; color: var(--fg); font-weight: 500; }
.gd-balance-arrow b { color: #0d9488; }

/* 용어 점선 밑줄 */
.gl-term { border-bottom: 1.5px dotted var(--accent); cursor: help; font-weight: 600; color: var(--accent); white-space: nowrap; }

/* 흐름도: 기기 ↔ 서버 */
.gd-flow { display: flex; align-items: stretch; gap: 12px; flex-wrap: wrap; }
.gd-node { flex: 1; min-width: 130px; text-align: center; background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 16px 12px; }
.gd-node-ico { font-size: 34px; line-height: 1; margin-bottom: 6px; }
.gd-node small { display: block; color: var(--fg-muted); font-size: 11px; margin-top: 3px; }
.gd-flow-mid { flex: 1.4; min-width: 180px; display: flex; flex-direction: column; justify-content: center; gap: 6px; }
.gd-beat { font-size: 12px; text-align: center; color: var(--green, #16a34a); font-weight: 600; }
.gd-beat.down { color: var(--accent); }
.gd-beat-line { display: flex; gap: 5px; align-items: center; justify-content: center; }
.gd-beat-line span { flex: 1; height: 2px; background: linear-gradient(90deg, var(--green, #16a34a), transparent); animation: gdbeat 1.6s infinite; }
.gd-beat-line span:nth-child(2) { animation-delay: .3s; } .gd-beat-line span:nth-child(3) { animation-delay: .6s; }
@keyframes gdbeat { 0%,100% { opacity: .3; } 50% { opacity: 1; } }

/* 단계 흐름 */
.gd-steps { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; margin-top: 16px; }
.gd-steps.vert { flex-direction: column; }
.gd-step { flex: 1; min-width: 120px; display: flex; align-items: center; gap: 8px; background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 11px 13px; font-size: 13px; font-weight: 500; }
.gd-step small { display: block; color: var(--fg-muted); font-weight: 400; font-size: 11px; }
.gd-step.done { border-color: var(--green, #16a34a); background: var(--green-soft, #e7f6ee); }
.gd-step-n { flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--accent); color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 700; }
.gd-step.done .gd-step-n { background: var(--green, #16a34a); }
.gd-arrow { display: flex; align-items: center; color: var(--fg-muted); font-size: 20px; font-weight: 700; }
@media (max-width: 640px) { .gd-arrow { transform: rotate(90deg); align-self: center; } }

/* 정책 카드 */
.gd-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.gd-cards.two { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 720px) { .gd-cards, .gd-cards.two { grid-template-columns: 1fr; } }
.gd-card { background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 16px; }
.gd-card.green { border-top: 3px solid var(--green, #16a34a); } .gd-card.amber { border-top: 3px solid var(--amber, #d97706); } .gd-card.gray { border-top: 3px solid var(--fg-muted); }
.gd-card-top { margin-bottom: 8px; } .gd-card-ico { font-size: 30px; margin: 2px 0 6px; }
.gd-card p { font-size: 13px; line-height: 1.6; margin: 0 0 8px; }
.gd-card ul { margin: 0; padding-left: 18px; font-size: 12px; line-height: 1.7; color: var(--fg-muted); }
.gd-card ul.gd-o li::marker { content: '✓ '; color: var(--green, #16a34a); }
.gd-card ul.gd-x li::marker { content: '✕ '; color: var(--red, #dc2626); }
.gd-badge { font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px; }
.b-green { background: var(--green-soft, #e7f6ee); color: var(--green, #16a34a); }
.b-amber { background: #fdf0dd; color: var(--amber, #d97706); }
.b-gray { background: var(--divider); color: var(--fg-muted); }
.b-indigo { background: var(--accent-soft); color: var(--accent); }
.b-red { background: #fee2e2; color: var(--red, #dc2626); }

/* 사용/사용안함 등 라디오 두 개를 나란히 두는 토글 줄 */
.seg-toggle { display: flex; gap: 8px; }
.seg-toggle .check-inline {
  flex: 1; justify-content: center; gap: 6px;
  padding: 8px 12px; border: 1px solid var(--divider); border-radius: 9px;
  font-weight: 600; cursor: pointer;
}
.seg-toggle .check-inline:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }

/* ── 설정 페이지: 카드 2단 배치 ─────────────────────────────
   서브 섹션(브랜딩·기상청 키·네이버 키)이 세로로만 늘어져 여백이 낭비됐다.
   좌우 2열로 묶고, 계정 권한 설정만 전체 폭(양열)을 차지하게 한다. */
.settings-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px; align-items: start; max-width: 1120px;
}
.settings-grid > .set-card { margin: 0; max-width: none; }
.settings-grid > .set-card-full { grid-column: 1 / -1; }
@media (max-width: 900px) { .settings-grid { grid-template-columns: 1fr; } }

/* ── 계정 권한 설정 (설정 화면) ─────────────────────────── */
.cap-tabs { display: flex; gap: 6px; margin: 4px 0 0; }
.cap-tab {
  padding: 7px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
  border: 1px solid var(--border); border-radius: 999px;
  background: transparent; color: var(--fg-soft); box-shadow: none;
}
.cap-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.cap-group { margin-top: 18px; }
.cap-group:first-child { margin-top: 4px; }
/* 그룹 머리글 — 아이콘 칩 + 제목 + 보조설명. 각 그룹이 무엇인지 아이콘으로 먼저 읽힌다. */
.cap-group-h {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; color: var(--fg);
  padding-bottom: 8px; margin-bottom: 10px; border-bottom: 1px solid var(--divider);
}
.cap-group-h .muted { font-weight: 400; font-size: 12px; }
.cgh-ico {
  display: inline-flex; width: 22px; height: 22px; flex: none;
  align-items: center; justify-content: center; border-radius: 6px;
  background: var(--accent-soft); color: var(--accent);
}
.cgh-ico svg { width: 14px; height: 14px; }

/* 전체 폭 카드에선 항목이 짧으니 2열로 채워 넓은 폭을 활용한다(좁아지면 1열로) */
.cap-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 8px; }
.cap-row {
  display: flex; align-items: center; gap: 11px; cursor: pointer;
  padding: 9px 12px; border: 1px solid var(--divider); border-radius: 10px;
  background: var(--card); transition: border-color .12s, background .12s;
}
.cap-row:hover { border-color: var(--accent); background: rgba(127, 127, 127, .04); }
/* 항목 아이콘 — 그 권한의 의미를 담는 칩. 켜지면 액센트로 물든다. */
.cap-ico {
  display: inline-flex; width: 32px; height: 32px; flex: none;
  align-items: center; justify-content: center; border-radius: 8px;
  background: rgba(127, 127, 127, .10); color: var(--fg-muted);
  transition: background .12s, color .12s;
}
.cap-ico svg { width: 17px; height: 17px; }
.cap-row.is-on { border-color: color-mix(in oklab, var(--accent) 45%, var(--divider)); background: var(--accent-soft); }
.cap-row.is-on .cap-ico { background: var(--accent); color: #fff; }
.cap-row.is-off { border-color: color-mix(in oklab, var(--red) 40%, var(--divider)); background: rgba(220, 38, 38, .06); }
.cap-row.is-off .cap-ico { background: var(--red); color: #fff; }
.cap-row-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cap-row-txt b { font-size: 13px; }
.cap-row-txt small { font-size: 11px; color: var(--fg-muted); }
/* 계정 대상일 때의 3단 선택(역할기본값/허용/차단) */
.cap-sel { width: 172px; flex: none; }
.cap-row-sel { cursor: default; }

/* 레이아웃 마스터가 꺼지면 영역별 설정은 의미가 없다 → 흐리게 + 조작 불가로 '전체 사용불가'를 분명히 */
.cap-group-off { opacity: .55; }
.cap-group-off .cap-list { pointer-events: none; }
.cap-group-off .cap-row { border-style: dashed; }

/* 권한으로 잠긴 레이아웃 영역 — 자리를 비우지 않고 '잠김'으로 표시해, 그런 설정이 있다는 건 알 수 있게 */
.lsec-locked { background: rgba(127, 127, 127, .06); border-style: dashed; }
.lsec-locked .lsec-title { color: var(--fg-muted); }

/* 하루 타임라인 (운영/유휴) */
.gd-day { display: flex; gap: 3px; height: 62px; border-radius: 12px; overflow: hidden; }
.gd-day-seg { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; padding: 4px; font-size: 12px; font-weight: 600; }
.gd-day-seg small { font-weight: 400; font-size: 10px; opacity: .85; }
.gd-day-seg.day { background: linear-gradient(180deg, #fff6df, #ffedc4); color: #92600a; }
.gd-day-seg.night { background: linear-gradient(180deg, #24314f, #1a2540); color: #cdd8f0; }
.gd-daylabel { display: flex; justify-content: space-between; font-size: 10px; color: var(--fg-muted); margin-top: 4px; }

/* 신호등 */
.gd-light { display: flex; gap: 12px; flex-wrap: wrap; }
.gd-light-item { flex: 1; min-width: 140px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px; background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 14px; }
.gd-light-item small { color: var(--fg-muted); font-size: 11px; }
.gd-dot { width: 26px; height: 26px; border-radius: 50%; box-shadow: 0 0 0 4px rgba(0,0,0,.05); }
.gd-dot.g { background: var(--green, #22c55e); } .gd-dot.a { background: var(--amber, #f59e0b); } .gd-dot.r { background: var(--red, #ef4444); }

/* 데이터 미터 데모 */
.gd-meterdemo { display: flex; flex-direction: column; gap: 10px; }
.gd-md-row { display: grid; grid-template-columns: 74px 1fr auto; align-items: center; gap: 10px; font-size: 12px; }
.gd-md-row .meter { height: 10px; }
.gd-md-row b { font-size: 12px; white-space: nowrap; }

/* 플레이리스트 반복 / 타임라인 칩 */
.gd-loop { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 10px 0; }
.gd-chip { background: var(--accent-soft); color: var(--accent); font-size: 12px; font-weight: 600; padding: 5px 11px; border-radius: 8px; }
.gd-loop-back { font-size: 11px; color: var(--fg-muted); font-weight: 600; }
.gd-hint { display: block; font-size: 12px; color: var(--fg-muted); margin-top: 6px; }
.gd-tl { display: flex; gap: 3px; height: 58px; border-radius: 12px; overflow: hidden; margin: 8px 0; }
.gd-tl.big { height: 66px; }
.gd-tl-seg { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; padding: 4px; font-size: 12px; color: #334155; }
.gd-tl-seg small { font-weight: 400; font-size: 10px; color: #64748b; }

/* 화면 목업 (레이아웃) */
.gd-screenwrap { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
.gd-screen { flex: 0 0 300px; max-width: 100%; aspect-ratio: 16/10; background: #0f172a; border: 3px solid #334155; border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; }
.gd-scr-info { background: #1e293b; color: #cbd5e1; font-size: 11px; padding: 6px 8px; display: flex; align-items: center; gap: 6px; position: relative; }
.gd-scr-main { flex: 1; display: grid; place-items: center; }
.gd-scr-vid { color: #e2e8f0; font-size: 14px; position: relative; }
.gd-scr-ticker { background: #1e293b; color: #93c5fd; font-size: 10px; padding: 5px 8px; white-space: nowrap; overflow: hidden; position: relative; }
.gd-scr-tag { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); background: var(--accent); color: #fff; font-size: 9px; padding: 1px 6px; border-radius: 6px; }
.gd-scr-vid .gd-scr-tag { position: static; transform: none; margin-left: 8px; }
.gd-legend { flex: 1; min-width: 220px; margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.9; }

/* 존 데모 */
.gd-zones { display: flex; gap: 18px; flex-wrap: wrap; }
.gd-zone-demo { text-align: center; }
.gd-zbox { width: 180px; height: 112px; border: 2px solid var(--accent); border-radius: 8px; display: flex; overflow: hidden; }
.gd-zbox.full { align-items: center; justify-content: center; flex-direction: column; background: var(--accent-soft); font-weight: 600; font-size: 13px; color: var(--accent); }
.gd-zbox.split { flex-direction: column; }
.gd-zbox.split > div { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--accent-soft); font-size: 12px; font-weight: 600; color: var(--accent); }
.gd-zbox small { display: block; font-weight: 400; font-size: 10px; color: var(--fg-muted); }
.gd-zdiv { flex: none !important; height: 3px; background: var(--accent); }
.gd-zcap { display: block; font-size: 11px; color: var(--fg-muted); margin-top: 6px; }

/* 용어집 */
.gd-gloss { background: var(--surface-2, oklch(0.97 0.01 260)); border: 1px solid var(--divider); border-radius: 12px; padding: 16px 18px; margin-top: 24px; }
.gd-gloss-head { font-weight: 700; font-size: 14px; margin-bottom: 10px; }
.gd-gloss dl { margin: 0; }
.gd-gloss-row { display: grid; grid-template-columns: 130px 1fr; gap: 12px; padding: 8px 0; border-top: 1px solid var(--divider); }
.gd-gloss-row:first-child { border-top: none; }
.gd-gloss dt { font-weight: 700; font-size: 13px; color: var(--accent); }
.gd-gloss dd { margin: 0; font-size: 12px; line-height: 1.6; color: var(--fg); }
@media (max-width: 560px) { .gd-gloss-row { grid-template-columns: 1fr; gap: 2px; } }

/* 메뉴 경로 칩 (예: 기기 상세 › 레이아웃) */
.gd-path { display: inline-flex; align-items: center; gap: 3px; flex-wrap: wrap; background: var(--card-sunken); border: 1px solid var(--divider); border-radius: 6px; padding: 2px 8px; font-size: 12px; vertical-align: middle; }
.gd-path b { font-weight: 700; color: var(--fg); }
.gd-path i { color: var(--fg-muted); font-style: normal; }
/* 핵심 강조 박스 */
.gd-key { background: var(--accent-soft); border: 1px solid var(--accent); border-radius: 12px; padding: 16px 18px; margin: 0 0 22px; }
.gd-key-title { font-weight: 800; font-size: 15px; color: var(--accent); margin-bottom: 8px; }
.gd-key-body { font-size: 13px; line-height: 1.7; color: var(--fg); }
.gd-key-body b { color: var(--fg); }
/* 순서 요약 (① → ② → ③ → ④) */
.gd-order { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.gd-order-i { background: var(--card); border: 1px solid var(--accent); color: var(--accent); font-weight: 700; font-size: 12px; padding: 6px 12px; border-radius: 999px; }
/* 시작하기 — 큰 번호 흐름 리스트 */
.gd-flowlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.gd-flowlist > li { display: flex; gap: 12px; align-items: flex-start; }
.gd-fl-n { flex: none; width: 30px; height: 30px; border-radius: 50%; background: var(--accent); color: #fff; display: grid; place-items: center; font-weight: 800; font-size: 15px; }
.gd-fl-body { flex: 1; min-width: 0; background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 13px 15px; }
.gd-fl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 15px; margin-bottom: 4px; }
.gd-fl-body p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--fg-soft); }
.gd-tag { font-size: 11px; font-weight: 700; color: var(--accent); background: var(--accent-soft); border-radius: 6px; padding: 2px 7px; white-space: nowrap; }
/* 레이아웃 항목 리스트 */
.gd-optlist { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
@media (max-width: 640px) { .gd-optlist { grid-template-columns: 1fr; } }
.gd-opt { display: flex; align-items: center; gap: 10px; background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 10px 12px; }
.gd-opt.hl { border-color: var(--accent); background: var(--accent-soft); }
.gd-opt-ico { flex: none; width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; background: var(--card-sunken); font-size: 15px; }
.gd-opt.hl .gd-opt-ico { background: #fff; }
.gd-opt b { font-size: 13px; } .gd-opt small { display: block; color: var(--fg-muted); font-size: 11px; line-height: 1.5; margin-top: 1px; }
/* 실제 화면 예시 목업 프레임 */
.gd-shot { margin: 12px 0 0; border: 1px solid var(--divider); border-radius: 12px; overflow: hidden; background: var(--card-sunken); }
.gd-shot-view { padding: 14px; }
.gd-shot-cap { font-size: 11px; color: var(--fg-muted); padding: 8px 14px; border-top: 1px solid var(--divider); background: var(--card); }
.gd-thumb { display: inline-flex; align-items: center; justify-content: center; flex: none; color: #cbd5e1; }
/* 목업용 미니 버튼(비활성 장식) */
.gd-mini-btn { display: inline-block; font-size: 11px; font-weight: 600; padding: 4px 9px; border-radius: 6px; border: 1px solid var(--border); background: var(--card); color: var(--fg-soft); }
.gd-mini-btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
/* 최적화 탭 CTA — 위 스텝과 겹치지 않게 간격 확보 */
.gd-cta { margin-top: 18px; }
/* 표시방식(채움/레터박스/늘림) 실제 표출 비교 */
.gd-fitgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 640px) { .gd-fitgrid { grid-template-columns: 1fr; } }
.gd-fitcard { border: 1px solid var(--divider); border-radius: 12px; background: var(--surface, #fff); padding: 12px; text-align: center; }
/* 세로 화면 틀 — 그 안에 SVG가 실제 fit 방식대로 그려진다 */
.gd-fitscreen {
  width: 96px; height: 160px; margin: 0 auto 10px; border-radius: 8px; overflow: hidden;
  background: #000; border: 3px solid #334155; box-shadow: 0 3px 10px rgba(0,0,0,.18);
}
.gd-fitscreen svg { display: block; width: 100%; height: 100%; }
.gd-fitname { font-size: 14px; font-weight: 800; }
.gd-fiteng { font-size: 11px; font-weight: 600; color: var(--fg-muted); }
.gd-fittag { display: inline-block; font-size: 11px; font-weight: 700; color: var(--accent); background: var(--accent-soft); border-radius: 999px; padding: 2px 10px; margin: 5px 0 8px; }
.gd-fitdesc { font-size: 12px; line-height: 1.55; color: var(--fg-soft); margin: 0; }
.gd-fitguide { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 14px; font-size: 12px; color: var(--fg); }
.gd-fitguide > div { display: flex; align-items: center; gap: 7px; }
.gd-fitdot { width: 9px; height: 9px; border-radius: 50%; flex: none; }

/* 기기 설치 탭 — 코드 핸드셰이크 + 2레인 */
.gd-pair { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; }
.gd-pair-side { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.gd-pair-cap { font-size: 12px; font-weight: 700; color: var(--fg-soft); }
.gd-pair-mid { display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--fg-muted); font-size: 11px; text-align: center; }
.gd-pair-arr { font-size: 30px; color: var(--accent); line-height: 1; }
@media (max-width: 620px) { .gd-pair-arr { transform: rotate(90deg); } }
/* 기기 화면 목업 */
.gd-devscreen { width: 230px; max-width: 78vw; aspect-ratio: 16/10; background: #0f172a; border: 3px solid #334155; border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; }
.gd-ds-top { background: #1e293b; color: #cbd5e1; font-size: 11px; padding: 6px 10px; }
.gd-ds-mid { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; color: #94a3b8; font-size: 10px; text-align: center; padding: 6px; }
.gd-codebox { font-family: ui-monospace, monospace; font-size: 30px; font-weight: 800; letter-spacing: 3px; color: #fff; background: #4f46e5; padding: 8px 16px; border-radius: 12px; box-shadow: 0 4px 16px rgba(79,70,229,.5); }
/* 관리자 등록 모달 목업 */
.gd-admbox { width: 230px; max-width: 78vw; background: var(--surface, #fff); border: 1px solid var(--divider); border-radius: 12px; padding: 14px; box-shadow: var(--shadow-md, 0 6px 24px rgba(0,0,0,.1)); }
.gd-adm-title { font-weight: 800; font-size: 14px; margin-bottom: 10px; }
.gd-adm-field { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: var(--fg-muted); border: 1px solid var(--divider); border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; }
.gd-adm-field b { color: var(--fg); font-family: ui-monospace, monospace; letter-spacing: 1px; }
.gd-adm-btn { text-align: center; background: var(--accent); color: #fff; font-weight: 700; font-size: 13px; padding: 9px; border-radius: 8px; }
/* 설치 방법 카드 내 미니 순서 목록 + URL 박스 */
.gd-mini-ol { margin: 8px 0 0; padding-left: 18px; font-size: 12px; line-height: 1.7; color: var(--fg-soft); }
.gd-mini-ol > li { margin-bottom: 5px; }
.gd-urlbox { font-family: ui-monospace, monospace; font-size: 13px; color: var(--fg); background: var(--card-sunken, #eef2ff); border: 1px dashed var(--accent); border-radius: 8px; padding: 7px 10px; margin: 5px 0 2px; word-break: break-all; }
.gd-urlbox b { color: var(--accent); }

/* ── 기기 설치 탭 — 실기기 목업 + 히어로 + 3단계 그림 ── */
.gd-dev { display: inline-flex; }
.gd-dev-bezel {
  position: relative; background: linear-gradient(160deg,#30343f 0%,#191b22 60%,#0f1116 100%);
  border-radius: 16px; padding: 9px 9px 16px;
  box-shadow: 0 10px 24px rgba(0,0,0,.32), inset 0 1px 0 rgba(255,255,255,.1), inset 0 0 0 1px rgba(0,0,0,.5);
}
.gd-dev-screen {
  width: 158px; aspect-ratio: 3/4; border-radius: 6px; overflow: hidden;
  background: radial-gradient(120% 90% at 50% 22%, #1e2540 0%, #0b0e18 72%);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px;
  padding: 12px; text-align: center; box-shadow: 0 0 18px rgba(99,102,241,.4), inset 0 0 0 1px rgba(0,0,0,.6);
}
.gd-dev.mini .gd-dev-screen { width: 104px; gap: 5px; padding: 8px; }
.gd-dev-wait { font-size: 10px; font-weight: 700; color: #4ade80; }
.gd-dev.mini .gd-dev-wait { font-size: 9px; }
.gd-dev-code {
  font-family: ui-monospace, monospace; font-size: 22px; font-weight: 800; letter-spacing: 2px; color: #fff;
  background: #4f46e5; padding: 7px 13px; border-radius: 8px; box-shadow: 0 4px 14px rgba(79,70,229,.55);
}
.gd-dev-code.sm { font-size: 13px; padding: 5px 8px; letter-spacing: 1px; }
.gd-dev-hint { font-size: 9px; color: #94a3b8; }
.gd-dev-lbl { color: #fff; font-size: 11px; }
.gd-dev-led { position: absolute; bottom: 5px; left: 50%; transform: translateX(-50%); width: 6px; height: 6px; border-radius: 50%; background: #22c55e; box-shadow: 0 0 8px #22c55e; }
/* 히어로 — 기기 + 요약 문장 */
.gd-inhero { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; background: var(--accent-soft); border: 1px solid var(--divider); border-radius: 16px; padding: 20px 22px; }
.gd-inhero-txt { flex: 1; min-width: 220px; }
.gd-inhero-h { font-size: 18px; font-weight: 800; margin-bottom: 8px; letter-spacing: -0.01em; text-wrap: balance; }
.gd-inhero-code { color: var(--accent); }
.gd-inhero-txt p { font-size: 13px; line-height: 1.7; margin: 0; color: var(--fg); }
/* 3단계 그림 흐름 */
.gd-insteps { display: flex; align-items: stretch; justify-content: center; gap: 8px; flex-wrap: wrap; }
.gd-instep { margin: 0; flex: 1; min-width: 150px; max-width: 220px; display: flex; flex-direction: column; align-items: center; gap: 10px; border: 1px solid var(--divider); border-radius: 12px; padding: 16px 12px; background: var(--surface, #fff); }
.gd-instep-ill { height: 150px; display: flex; align-items: center; justify-content: center; }
.gd-instep figcaption { text-align: center; }
.gd-instep-n { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--accent); color: #fff; font-weight: 800; font-size: 13px; margin-bottom: 5px; }
.gd-instep figcaption b { display: block; font-size: 13px; }
.gd-instep figcaption small { display: block; color: var(--fg-muted); font-size: 11px; margin-top: 2px; }
.gd-instep-arr { display: flex; align-items: center; color: var(--accent); font-size: 26px; font-weight: 700; }
@media (max-width: 680px) { .gd-instep-arr { transform: rotate(90deg); } .gd-instep { max-width: none; } }
/* 미니 관리자 등록 박스 (3단계 · 3번) */
.gd-admbox.mini { width: 130px; padding: 9px; box-shadow: var(--shadow-sm, 0 2px 8px rgba(0,0,0,.08)); }
.gd-admbox.mini .gd-adm-title { font-size: 11px; margin-bottom: 7px; }
.gd-admbox.mini .gd-adm-field { font-size: 10px; padding: 5px 7px; margin-bottom: 5px; }
.gd-admbox .gd-adm-field.hl { border-color: var(--accent); background: var(--accent-soft); }
.gd-admbox .gd-adm-field.hl b { color: var(--accent); }
.gd-admbox.mini .gd-adm-btn { font-size: 11px; padding: 6px; }
/* 레인 헤더용 — 3단계 미니보다 살짝 크게(실기기 목업과 균형) */
.gd-admbox.mini.lane { width: 156px; padding: 11px; }
.gd-admbox.mini.lane .gd-adm-title { font-size: 12px; margin-bottom: 8px; }
.gd-admbox.mini.lane .gd-adm-field { font-size: 10px; padding: 6px 8px; margin-bottom: 6px; }
.gd-admbox.mini.lane .gd-adm-btn { font-size: 12px; padding: 7px; }
.gd-urlnote { display: block; font-size: 11px; color: var(--fg-muted); }

/* 2레인 (기기측/관리자측) */
.gd-lanes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
@media (max-width: 720px) { .gd-lanes { grid-template-columns: 1fr; } }
.gd-lane { border: 1px solid var(--divider); border-radius: 12px; padding: 16px; background: var(--surface, #fff); border-top: 4px solid var(--accent); }
.gd-lane.dev { border-top-color: #0ea5e9; }
.gd-lane.adm { border-top-color: #6366f1; }
/* 레인 헤더 — 실기기/관리자 목업 일러스트 + 제목 (두 레인 높이 정렬) */
.gd-lane-head { display: flex; flex-direction: column; align-items: center; gap: 11px; padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--divider); }
/* min-height로 두 레인 일러스트 영역을 맞추되, 내용이 넘쳐 상단 라인/제목과 겹치지 않게 */
.gd-lane-ill { min-height: 172px; display: flex; align-items: center; justify-content: center; padding: 4px 0; }
.gd-lane-title { text-align: center; }
.gd-lane-title b { font-size: 15px; }
.gd-lane-title small { display: block; color: var(--fg-muted); font-size: 11px; margin-top: 2px; }
.gd-dev-play { font-size: 26px; color: #a5b4fc; }
/* 단계 목록 — flex 정렬로 번호·본문 기준선 일치, 간격 균일 */
.gd-lanesteps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.gd-lanesteps > li { display: flex; gap: 11px; align-items: flex-start; }
.ls-n { flex: none; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; font-weight: 800; font-size: 12px; background: var(--card-sunken, #eef2ff); color: var(--accent); margin-top: 1px; }
.gd-lane.dev .ls-n { background: rgba(14,165,233,.14); color: #0284c7; }
.gd-lanesteps > li.done .ls-n { background: var(--green, #16a34a); color: #fff; }
.ls-b { min-width: 0; }
/* 제목만 블록 — 설명 span 안의 강조 <b>는 인라인 유지(줄바꿈 방지) */
.ls-b > b { display: block; font-size: 13px; line-height: 1.4; }
.ls-b > span { display: block; color: var(--fg-soft); font-size: 12px; line-height: 1.6; margin-top: 3px; }
.ls-b > span b { color: var(--fg); }
.ls-b .gd-urlbox { margin: 6px 0 0; }

@media (prefers-color-scheme: dark) {
  .gd-note, .gd-gloss { background: rgba(255,255,255,.03); }
  .gd-tl-seg { color: #e2e8f0; } .gd-tl-seg small { color: #94a3b8; }
  .b-amber { background: rgba(217,119,6,.18); }
  .gd-opt.hl .gd-opt-ico, .gd-order-i { background: rgba(255,255,255,.06); }
  .gd-lanesteps > li::before { background: rgba(255,255,255,.08); }
}
.tenant-data .tdm-top { display: flex; justify-content: space-between; align-items: baseline; font-size: 11px; margin-bottom: 4px; }
.tenant-data .tdm-val { font-size: 12px; color: var(--fg); }
.tenant-data .tdm-val b { font-size: 13px; }
.tenant-data .tdm-val.du-over { color: var(--red); font-weight: 600; }
.tenant-data .meter { height: 6px; margin-top: 0; }

/* ── 대시보드: 아파트별 기기 통합뷰 (하단 섹션) ── */
.apt-sec-divider { display: flex; align-items: center; gap: 12px; margin: 30px 0 16px; color: var(--fg-muted); font-size: 13px; font-weight: 700; }
.apt-sec-divider::before, .apt-sec-divider::after { content: ""; flex: 1; height: 1px; background: var(--divider); }
/* 현장(아파트)별 기기 그룹 박스 — 액센트 바 헤더 + 하단 구분선으로 단지별 명확히 구분 */
.apt-devs { margin-bottom: 16px; padding: 13px 16px 16px; border: 1px solid var(--divider); border-radius: 12px; background: var(--surface-2, rgba(127,127,127,.035)); }
.apt-devs-title { display: flex; align-items: center; gap: 10px; font-size: 15px; margin: 0 0 14px; padding-bottom: 11px; font-weight: 700; border-bottom: 1px solid var(--divider); }
.apt-devs-title::before { content: ""; width: 4px; height: 17px; border-radius: 6px; background: var(--accent); flex: none; }
.apt-devs-title a { color: var(--fg); text-decoration: none; }
.apt-devs-title a:hover { color: var(--accent); text-decoration: underline; }
.apt-devs-title .muted { margin-left: auto; font-weight: 500; font-size: 12px; }
.mini-dev { padding: 12px 14px; cursor: pointer; display: flex; flex-direction: column; gap: 8px; transition: border-color .12s, transform .12s; }
.mini-dev:hover { border-color: var(--accent); transform: translateY(-2px); }
.mini-dev .md-head { display: flex; align-items: center; gap: 7px; font-size: 14px; }
.mini-dev .md-head b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-dev .md-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.mini-dev .md-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 11px; }
.chip.chip-sync { color: var(--amber, #d97706); border-color: var(--amber, #d97706); font-weight: 600; }

/* ── 사용자·아파트 관리 목록 (검색·정렬·필터 툴바 + 아바타 행) ── */
.list-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 12px 0 10px; }
.list-count { margin-left: auto; font-size: 12px; color: var(--fg-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.role-filter { display: flex; gap: 5px; flex-wrap: wrap; }
.rf-chip {
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  padding: 5px 11px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--card); color: var(--fg-soft);
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out), color var(--speed) var(--ease-out);
}
.rf-chip:hover { border-color: var(--accent); }
.rf-chip.active { background: var(--accent); border-color: var(--accent); color: #fff; }
/* 클릭 정렬 헤더 */
.tbl th.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.tbl th.th-sort::after { content: '↕'; margin-left: 5px; font-size: 10px; opacity: .35; }
.tbl th.th-sort:hover::after { opacity: .7; }
.tbl th.th-sort.sorted-asc::after { content: '↑'; opacity: 1; color: var(--accent); }
.tbl th.th-sort.sorted-desc::after { content: '↓'; opacity: 1; color: var(--accent); }
/* 스크롤 표 + 고정 헤더 */
.table-wrap.scrolly { max-height: 460px; overflow: auto; }
.table-wrap.scrolly thead th { position: sticky; top: 0; z-index: 1; background: var(--card); }
/* 이름/아이디 셀 — 아바타 + 텍스트 */
.ent-cell { display: inline-flex; align-items: center; gap: 9px; min-width: 0; max-width: 100%; }
.ent-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ent-ava {
  width: 28px; height: 28px; flex: none; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); font-size: 12px; font-weight: 800;
}
.ent-ava svg { width: 15px; height: 15px; }
.ent-ava.ava-super { background: var(--accent); color: #fff; }
.ent-ava.ava-regional { background: #fef3c7; color: #b45309; }
.ent-ava.ava-tenant { background: #dbeafe; color: #1d4ed8; }
.ent-logo { width: 28px; height: 28px; flex: none; border-radius: 8px; object-fit: contain; background: #fff; border: 1px solid var(--divider); }
.tbl .no-res td { text-align: center; color: var(--fg-muted); padding: 22px 12px; }

/* ── 아파트 설정 모달 (공공데이터 + 통신 정책) ─────────────── */
.tset-sec + .tset-sec { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--divider); }
.tset-head {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; margin: 0 0 12px; letter-spacing: -0.01em;
}
.tset-head svg { width: 15px; height: 15px; flex: none; color: var(--accent); }
/* 공공데이터 연동 상태 pill (헤더 우측) */
.link-status {
  margin-left: auto; display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
}
.link-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; flex: none; }
.link-status.on { color: #15803d; background: #dcfce7; }
.link-status.on::before { background: #22c55e; }
.link-status.off { color: var(--fg-muted); background: var(--card-sunken); }
.link-status.off::before { background: #9ca3af; }
/* 입력 필드 묶음 패널 — 연동 정보 한 덩어리로 시각 그룹화 */
.link-panel {
  margin-top: 2px; padding: 13px; border: 1px solid var(--divider);
  border-radius: 12px; background: var(--card-sunken);
}
/* 이 데이터로 켜지는 자막 기능 칩 (입력값에 따라 활성) */
.link-feats { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 13px; padding-top: 12px; border-top: 1px dashed var(--divider); }
.link-feats-lbl { font-size: 11px; color: var(--fg-muted); }
.feat-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 600; padding: 5px 10px; border-radius: 8px;
  border: 1px solid var(--divider); background: var(--card); color: var(--fg-muted);
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out), color var(--speed) var(--ease-out);
}
.feat-chip svg { width: 13px; height: 13px; flex: none; opacity: .8; }
.feat-chip.on { border-color: #86efac; background: #f0fdf4; color: #15803d; }
.feat-chip.on svg { opacity: 1; }
.feat-chip.on::after { content: '✓'; font-weight: 800; }
/* 통신 정책 선택 카드 */
.policy-cards { display: flex; flex-direction: column; gap: 8px; }
.policy-card {
  position: relative; display: flex; align-items: center; gap: 11px; cursor: pointer;
  padding: 11px 13px; border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
.policy-card input { position: absolute; opacity: 0; width: 0; height: 0; }
.policy-card:hover { border-color: var(--accent); }
.policy-card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.policy-card:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--accent-ring); }
.pc-ico {
  width: 34px; height: 34px; flex: none; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card-sunken); color: var(--fg-muted);
  transition: background var(--speed) var(--ease-out), color var(--speed) var(--ease-out);
}
.pc-ico svg { width: 17px; height: 17px; }
.policy-card:has(input:checked) .pc-ico { background: #fff; color: var(--accent); }
.pc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pc-body b { font-size: 13px; }
.pc-body small { font-size: 11px; color: var(--fg-soft); line-height: 1.45; }
.pc-check {
  width: 18px; height: 18px; flex: none; border-radius: 50%; border: 2px solid var(--border-strong); position: relative;
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out);
}
.policy-card:has(input:checked) .pc-check { border-color: var(--accent); background: var(--accent); }
.policy-card:has(input:checked) .pc-check::after { content: ''; position: absolute; inset: 4px; border-radius: 50%; background: #fff; }
/* 종량제 이번 달 사용량 미터 */
.data-usage {
  margin-top: 12px; padding: 11px 13px; border: 1px solid var(--divider);
  border-radius: 12px; background: var(--card-sunken);
}
.du2-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--fg-soft); }
.du2-val { font-weight: 700; color: var(--fg); font-variant-numeric: tabular-nums; }
.du2-val.over { color: var(--red); }

/* 기기 상세 — 통신 안정성 점수 타일 */
.conn-score { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; }
.conn-score .cs-num { font-size: 15px; font-weight: 700; }
.conn-score .cs-lbl { font-size: 12px; color: var(--fg-muted); }
.conn-score .cs-recent { font-size: 11px; }
.conn-score .cs-meter { flex: 1 1 100%; height: 6px; margin-top: 3px; }

/* 최근 오류 경고 박스 — 오류가 있을 때만 노출 */
.status-alert {
  position: relative; margin-top: 12px; padding: 10px 34px 10px 12px; border-radius: var(--radius-sm);
  background: var(--red-soft); border: 1px solid oklch(0.85 0.06 25);
  color: var(--red); font-size: 12px; word-break: break-all;
}
.status-alert-x {
  position: absolute; top: 5px; right: 5px; width: 22px; height: 22px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 6px; background: transparent; color: var(--red);
  font-size: 13px; line-height: 1; cursor: pointer; opacity: .7;
}
.status-alert-x:hover { opacity: 1; background: oklch(0.85 0.06 25 / 0.35); }

/* 키-값 정보 표 (기기 기본 정보 등) */
.kv { display: grid; grid-template-columns: 110px 1fr; gap: 6px 10px; font-size: 13px; }
.kv dt { color: var(--fg-muted); }
.kv dd { margin: 0; word-break: break-all; }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }

/* ── 설정: 사이트 로고 업로드 행 ───────────────────────── */
.brand-logo-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.brand-logo-row input[type="file"] { flex: 1; min-width: 200px; }
.brand-logo-preview {
  width: 52px; height: 52px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--card-sunken); overflow: hidden; font-size: 11px;
}
.brand-logo-preview img { width: 100%; height: 100%; object-fit: contain; }
/* 대시보드 브랜딩(아파트별) — 아파트 카드 목록에서 선택 → 아래 편집 폼 */
.brand-apt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.brand-apt { display: flex; align-items: center; gap: 10px; text-align: left; padding: 10px; border: 1px solid var(--border); border-radius: 12px; background: var(--card); cursor: pointer; transition: border-color .12s, background .12s; min-width: 0; }
.brand-apt:hover { border-color: var(--accent); }
.brand-apt.sel { border: 2px solid var(--accent); background: var(--accent-soft); padding: 9px; }
.brand-apt-logo { flex: none; width: 44px; height: 44px; border-radius: 8px; background: #0f172a; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.brand-apt-logo img { width: 100%; height: 100%; object-fit: contain; }
.brand-apt-logo .ba-nologo { font-size: 9px; color: var(--fg-muted); text-align: center; line-height: 1.2; }
.brand-apt-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.brand-apt-body b { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand-apt-body small { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── 모달 (ui.js modal — 폼 포함용 자체 모달) ──────────── */
.modal-backdrop {
  position: fixed; inset: 0; background: oklch(0.2 0.02 270 / 0.55); z-index: var(--z-modal-backdrop);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  animation: fade-in var(--speed) var(--ease-out);
}
.modal {
  background: #fff; border-radius: 12px; box-shadow: var(--shadow-lg);
  width: 100%; max-width: 440px; padding: 22px 24px;
  max-height: calc(100vh - 48px); overflow-y: auto; /* 긴 모달도 화면 안에서 스크롤 */
  position: relative; z-index: var(--z-modal);
  animation: rise-in 0.18s var(--ease-out);
}
/* 제목 — 상단에 고정돼 길게 스크롤해도 어떤 창인지 유지 */
.modal h3 {
  font-size: 16px; font-weight: 700; letter-spacing: -0.01em;
  margin: -22px -24px 16px; padding: 16px 24px 13px;
  border-bottom: 1px solid var(--divider); background: #fff;
  position: sticky; top: -22px; z-index: 1;
}

/* 넓은 모달 — 기기 적용/레이아웃 선택처럼 목록·미리보기가 많은 창 */
.modal.modal--wide { max-width: min(860px, calc(100vw - 48px)); }

/* 아파트 설정 — 섹션이 많아 한 단으로 두면 세로로 한없이 길어진다.
   넓은 화면에서만 2단으로 접어 스크롤을 줄이고, 좁은 화면(모바일)은 지금처럼 한 단으로 둔다.
   섹션이 두 단에 걸쳐 잘리면 안 되므로 columns가 아니라 grid를 쓴다. */
@media (min-width: 900px) {
  .modal:has(.tset) { max-width: min(920px, calc(100vw - 48px)); }
  .tset {
    display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px;
    align-items: start;
  }
  /* 단이 나뉘면 '위 섹션과의 구분선'이 어색해진다 — 각 단의 첫 섹션은 선을 없앤다.
     대신 모든 섹션에 같은 위/아래 여백을 줘 두 단의 리듬을 맞춘다. */
  .tset .tset-sec + .tset-sec { margin-top: 0; }
  .tset > .tset-sec { padding: 18px 0; border-top: 1px solid var(--divider); }
  .tset > .tset-sec:nth-child(1), .tset > .tset-sec:nth-child(2) { padding-top: 4px; border-top: 0; }
  /* 저장/취소 줄은 두 단에 걸쳐 아래에 붙인다 */
  .tset > .form-actions { grid-column: 1 / -1; border-top: 1px solid var(--divider); padding-top: 16px; }
}

/* 하단 자막 내용 설정 모달 — 소스 섹션 */
.modal:has(.tk-modal) { max-width: 560px; }
.tk-modal { max-height: 72vh; overflow: auto; padding-right: 4px; }
.tk-sec { margin-top: 14px; padding: 12px 14px; background: oklch(0.97 0.006 274); border-radius: 12px; }
.tk-sec-t { font-weight: 600; font-size: 13px; margin-bottom: 8px; }
.tk-modal textarea { font: inherit; padding: 8px 10px; border-radius: 8px; border: 1px solid oklch(0.9 0.01 274); resize: vertical; }
@keyframes tk-marq { from { transform: translateX(100%); } to { transform: translateX(-100%); } }

/* 전체화면 스케줄 — 요일 선택 토글 칩(시인성 강화) */
.fs-days { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.fs-day { cursor: pointer; }
.fs-day input { position: absolute; opacity: 0; width: 0; height: 0; }
.fs-day span {
  display: inline-block; min-width: 34px; text-align: center; padding: 6px 2px;
  border-radius: 8px; border: 1px solid var(--border); font-size: 13px; font-weight: 700;
  color: var(--fg-muted); background: var(--card); user-select: none; transition: all var(--speed) var(--ease-out);
}
.fs-day input:checked + span { background: var(--accent); color: #fff; border-color: var(--accent); }
.fs-day:hover span { border-color: var(--accent); }
/* 전체화면 스케줄 섹션 — 아래 프리셋/저장 버튼과 시각적으로 분리 */
#l-fs-sec { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; background: var(--card-sunken); }

/* 전체화면 스케줄 — 슬롯 색상 (오버뷰 밴드·번호칩 공용, 흰 글자 4.5:1 이상 확보) */
.fs-c0 { --fs-c: #4f46e5; }  /* 인디고(브랜드) */
.fs-c1 { --fs-c: #0f766e; }  /* 틸 */
.fs-c2 { --fs-c: #b45309; }  /* 앰버 */
.fs-c3 { --fs-c: #be185d; }  /* 핑크 */
.fs-c4 { --fs-c: #0369a1; }  /* 스카이 */
.fs-c5 { --fs-c: #6d28d9; }  /* 바이올렛 */

/* 전체화면 스케줄 — 24시간 배치 오버뷰 */
.fs-ov {
  margin: 4px 0 12px; padding: 12px 14px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.fs-ov-head {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  font-size: 12px; font-weight: 700; color: var(--fg-soft); margin-bottom: 8px;
}
.fs-ov-head > svg { width: 13px; height: 13px; flex: none; color: var(--accent); }
.fs-ov-hint { font-weight: 400; color: var(--fg-muted); }
.fs-lane { display: grid; grid-template-columns: 20px 1fr; gap: 6px; align-items: center; margin-top: 5px; }
.fs-lane-no {
  width: 20px; height: 20px; border-radius: 6px; flex: none;
  background: var(--fs-c, var(--accent)); color: #fff;
  font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center;
}
.fs-lane-track {
  position: relative; height: 24px; border-radius: 6px; overflow: hidden;
  background: var(--card-sunken);
  /* 3시간 간격 눈금선 */
  background-image: linear-gradient(to right, var(--divider) 1px, transparent 1px);
  background-size: 12.5% 100%;
}
.fs-band {
  position: absolute; top: 3px; bottom: 3px; border-radius: 6px; min-width: 4px;
  background: var(--fs-c, var(--accent)); color: #fff;
  font-size: 10px; font-weight: 600; line-height: 1;
  display: flex; align-items: center; padding: 0;
  overflow: hidden; white-space: nowrap;
}
/* 밴드 라벨 — 칸이 좁아져도 글자를 지우지 않는다. 좌측 정렬로 두고 넘치는 만큼만 …으로 줄인다.
   여백은 밴드가 아니라 라벨이 갖는다(밴드 패딩 + 라벨 패딩이 겹치면 좁은 칸에서 글자 자리가 없어짐). */
.fs-band-txt {
  flex: 1 1 auto; min-width: 0; padding: 0 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 자정 넘김 슬롯: 잘린 쪽 모서리를 직각으로 — 이어짐을 표현 */
.fs-cut-r { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.fs-cut-l { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.fs-band-empty {
  background: transparent; color: var(--fg-soft); padding: 0 8px;
  border: 1px dashed var(--border-strong); justify-content: center;
}
.fs-now { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--red); opacity: 0.75; }
/* 넓은 라벨 변형 — 존 이름(메인/상단/하단)용 */
.fs-ov--wide .fs-lane, .fs-ov--wide .fs-ov-axis { grid-template-columns: 40px 1fr; }
.fs-zone-tag {
  height: 20px; border-radius: 6px; background: var(--fs-c, var(--accent)); color: #fff;
  font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center;
}
/* 존 기본 플레이리스트 밴드 — 옅은 틴트(슬롯이 없는 시간의 바탕 재생을 표현) */
.fs-band.sc-default {
  background: color-mix(in srgb, var(--fs-c, var(--accent)) 13%, #fff);
  border: 1px solid color-mix(in srgb, var(--fs-c, var(--accent)) 32%, #fff);
  color: color-mix(in srgb, var(--fs-c, var(--accent)) 88%, #000);
}
/* 전원 스케줄 — 화면 켜짐(초록) 밴드와 요일 라벨 */
.fs-band.pw-on { --fs-c: #15803d; }
.fs-band.pw-always { background: #dcfce7; border: 1px solid #86efac; color: #166534; }
.fs-lane-day { font-size: 12px; font-weight: 700; color: var(--fg-soft); text-align: center; }
.fs-lane-day.pw-sat { color: #2563eb; }
.fs-lane-day.pw-sun { color: #dc2626; }
.fs-ov-axis { display: grid; grid-template-columns: 20px 1fr; gap: 6px; margin-top: 4px; }
.fs-ax-track { position: relative; height: 14px; }
.fs-ax-track > span {
  position: absolute; transform: translateX(-50%); white-space: nowrap;
  font-size: 10px; color: var(--fg-soft); font-variant-numeric: tabular-nums;
}

/* 전체화면 스케줄 — 슬롯 편집 카드 */
.fs-slot {
  margin-top: 8px; padding: 12px 14px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.fs-slot-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.fs-slot-sum {
  flex: 1; min-width: 0; font-size: 12px; font-weight: 600; color: var(--fg-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fs-empty {
  margin-top: 8px; padding: 18px 14px; text-align: center;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-sm);
  background: var(--card); color: var(--fg-soft); font-size: 13px; line-height: 1.7;
}

/* 타임라인 편성 — 표시방식(채움/레터박스/늘림) 예시 도해 */
.fit-demos {
  display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap;
  margin-top: 10px; padding: 10px 12px;
  background: var(--card-sunken); border: 1px solid var(--divider); border-radius: 12px;
}
.fit-demos-cap { font-size: 12px; font-weight: 700; align-self: center; }
.fit-demo { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.fit-screen {
  width: 76px; height: 40px; display: block; overflow: hidden;
  background: #0b1220; border: 1px solid var(--border-strong); border-radius: 6px;
}
.fit-screen svg { width: 100%; height: 100%; display: block; }
.fit-lbl { font-size: 10px; color: var(--fg-muted); text-align: center; line-height: 1.35; }
.fit-lbl b { display: block; font-size: 11px; color: var(--fg); }

/* 콘텐츠 분류 드래그앤드롭 */
.content-card[draggable="true"] { cursor: grab; }
.content-card.dragging { opacity: 0.45; cursor: grabbing; }
/* 터치 기기 — 카드에 우리 롱프레스 드래그(분류 이동)가 걸려 있어, 브라우저 기본 롱프레스
   (이미지 컨텍스트 메뉴·텍스트 선택)와 겹치면 둘 다 어정쩡하게 동작한다. 기본 동작을 접는다.
   touch-action은 manipulation — 세로 스크롤은 살리고 더블탭 줌만 막는다. */
@media (hover: none) {
  .content-card {
    -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
    touch-action: manipulation;
  }
  .content-card img { -webkit-touch-callout: none; pointer-events: none; }
  /* 파일명은 길어서 확인·복사할 일이 있다 — 이름만 선택 허용 */
  .content-card .c-name { -webkit-user-select: text; user-select: text; }
}
.cat-section { border-radius: var(--radius); transition: background var(--speed) var(--ease-out), outline-color var(--speed) var(--ease-out); }
.cat-section.drop-hover { outline: 2px dashed var(--accent); outline-offset: 4px; background: var(--accent-soft); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } }

/* 레거시 토스트 컨테이너 — 현재는 SweetAlert2 토스트를 사용, 폴백용으로만 유지 */
/* 타임라인 편집 — 작은 썸네일에 마우스를 올리면 뜨는 큰 미리보기 레이어(program-editor.js).
   pointer-events:none 이 핵심 — 레이어가 커서를 가로채면 hover가 깜빡이고 드래그가 끊긴다. */
.thumb-pop {
  position: fixed; z-index: var(--z-tooltip); pointer-events: none;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28); padding: 6px;
}
.thumb-pop img {
  display: block; max-width: 320px; max-height: 240px;
  border-radius: 6px; background: #0f172a;
}
.thumb-pop-name {
  margin-top: 5px; max-width: 320px; text-align: center;
  font-size: 12px; color: var(--fg-soft); word-break: break-all;
}
/* 좁은 화면 안전망 — 320px 고정이면 폰에서 좌우로 들어갈 자리가 없어 잘린다.
   (터치 전용 기기는 hover 미리보기를 아예 설치하지 않지만, 터치스크린 노트북·태블릿엔 필요) */
@media (max-width: 560px) {
  .thumb-pop img { max-width: calc(100vw - 32px); max-height: 40vh; }
  .thumb-pop-name { max-width: calc(100vw - 32px); }
}

/* ── 터치용 미리보기 시트 ─────────────────────────────────
   모바일엔 hover가 없다. 썸네일을 탭하면 하단에서 올라오는 시트로 크게 보여준다. */
.thumb-sheet-back {
  position: fixed; inset: 0; z-index: var(--z-modal, 1000);
  background: oklch(0.2 0.02 270 / 0.5);
  display: flex; align-items: flex-end; justify-content: center;
  opacity: 0; transition: opacity 160ms var(--ease-out);
}
.thumb-sheet-back.on { opacity: 1; }
.thumb-sheet {
  width: 100%; max-width: 520px; background: var(--card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom, 0px));
  text-align: center; box-shadow: var(--shadow-lg);
  transform: translateY(14px); transition: transform 180ms var(--ease-out);
}
.thumb-sheet-back.on .thumb-sheet { transform: translateY(0); }
.thumb-sheet-grab {
  display: block; width: 38px; height: 4px; margin: 0 auto 12px;
  border-radius: 999px; background: var(--border-strong);
}
.thumb-sheet-media {
  border-radius: var(--radius-sm); background: #0f172a; overflow: hidden;
  min-height: 60px; display: flex; align-items: center; justify-content: center;
}
.thumb-sheet-media img { display: block; max-width: 100%; max-height: 56vh; }
.thumb-sheet-media.is-empty::after { content: '미리보기를 만들지 못했습니다'; color: #94a3b8; font-size: 12px; padding: 24px; }
.thumb-sheet-name { margin-top: 11px; font-size: 14px; font-weight: 700; word-break: break-all; }
.thumb-sheet-meta { margin-top: 3px; font-size: 12.5px; color: var(--fg-muted); }
.thumb-sheet-close { margin-top: 14px; width: 100%; padding: 12px; font-size: 15px; }
@media (prefers-reduced-motion: reduce) {
  .thumb-sheet-back, .thumb-sheet { transition: none; }
}
.toast-root { position: fixed; bottom: 24px; right: 24px; display: flex; flex-direction: column; gap: 8px; z-index: var(--z-toast); }
.toast {
  background: oklch(0.22 0.02 270); color: #fff; padding: 11px 16px; border-radius: 12px;
  box-shadow: var(--shadow-lg); font-size: 13px; max-width: 360px;
}
.toast.error { background: var(--red); }
.toast.success { background: var(--green); }

/* ── 빈 상태 / 로딩 ─────────────────────────────────────── */
.empty {
  text-align: center; color: var(--fg-soft); padding: 52px 20px; font-size: var(--text-base); line-height: 1.6;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--card-sunken);
}
/* 빈 상태: 인디고 소프트 칩 안에 아이콘 — "버그가 아니라 비어 있음"을 차분하게 (마크업 변경 없이) */
.empty::before {
  content: ''; display: block; width: 52px; height: 52px; margin: 0 auto 16px;
  border-radius: var(--radius-pill); background: var(--empty-ico-accent) center / 24px no-repeat, var(--accent-soft);
  box-shadow: inset 0 0 0 1px oklch(0.63 0.19 277 / 0.12);
}
:root {
  --empty-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'/%3E%3Cpath d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/%3E%3C/svg%3E");
  --empty-ico-accent: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234f46e5' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'/%3E%3Cpath d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/%3E%3C/svg%3E");
}
/* 인라인 배치(그리드 셀 등)에서는 아이콘 생략 */
.empty[style*="grid-column"]::before, p.empty::before { display: none; }

/* ── 현장 건강 상태 바 (대시보드) — 통신·재생·저장을 한눈에 ── */
.fleet-bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.fleet-pill {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 12px; font-size: 13px; font-weight: 600;
  border: 1px solid var(--border); background: var(--card); color: var(--fg-soft);
}
.fleet-pill b { font-size: 17px; font-weight: 800; color: var(--fg); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.fleet-pill .fp-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.fleet-pill.total { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
.fleet-pill.total b { color: var(--accent); }
.fleet-pill.on { border-color: color-mix(in srgb, var(--green) 40%, var(--border)); }
.fleet-pill.on .fp-dot { background: var(--green); animation: fp-pulse 2.2s var(--ease-out) infinite; }
.fleet-pill.on b { color: #15803d; }
.fleet-pill.off .fp-dot { background: #9ca3af; }
.fleet-pill.dim b { color: var(--fg-muted); }
.fleet-pill.warn { background: rgba(245,158,11,.10); border-color: #f59e0b; color: #92600a; }
.fleet-pill.warn b { color: #b45309; }
/* 온라인 점 라이브 펄스 — 하트비트가 살아있음을 시각화 (통신 안정성) */
@keyframes fp-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 45%, transparent); }
  70%, 100% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--green) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .fleet-pill.on .fp-dot { animation: none; } }
.loading {
  color: var(--fg-muted); padding: 40px; text-align: center;
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
/* CSS 스피너 — 콘텐츠 자리 대신 짧게만 노출되는 로딩 표시 */
.loading::before {
  content: ""; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--divider); border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ═══ SweetAlert2 테마 오버라이드 ═══════════════════════════
   전역 Swal 팝업/토스트를 콘솔 디자인 토큰에 맞춘다.
   (버튼 색상은 ui.js에서 인라인 지정 — 동일한 인디고 계열) */
.swal2-popup {
  font-family: var(--font) !important;
  font-size: 14px !important;
  border-radius: var(--radius-lg) !important;
  box-shadow: var(--shadow-lg) !important;
  color: var(--fg) !important;
}
.swal2-title { font-size: 17px !important; font-weight: 700 !important; letter-spacing: -0.01em; color: var(--fg) !important; }
.swal2-html-container { font-size: 13px !important; color: var(--fg-muted) !important; line-height: 1.6 !important; }
.swal2-styled {
  border-radius: var(--radius-sm) !important;
  font-weight: 600 !important;
  font-size: 13px !important;
  padding: 9px 18px !important;
  box-shadow: none !important;
}
.swal2-styled:focus-visible { outline: 2px solid var(--accent) !important; outline-offset: 2px; }
.swal2-input {
  border: 1px solid var(--border) !important; border-radius: var(--radius-sm) !important;
  font-size: 14px !important; box-shadow: none !important;
  /* 전역 input width:100% 규칙이 팝업 밖으로 넘치지 않게 폭을 팝업 안쪽으로 제한 */
  width: calc(100% - 4em) !important;
  margin: 1em auto 3px !important;
  box-sizing: border-box;
}
.swal2-input:focus { border-color: var(--accent) !important; box-shadow: 0 0 0 3px var(--accent-ring) !important; }
/* 토스트형 알림 — 우상단, 카드와 같은 표면 언어 */
.swal2-popup.swal2-toast {
  border-radius: var(--radius) !important;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md) !important;
  padding: 10px 14px !important;
}
.swal2-popup.swal2-toast .swal2-title { font-size: 13px !important; font-weight: 600 !important; }
.swal2-timer-progress-bar { background: oklch(0.51 0.23 277 / 0.35) !important; }

/* ── 반응형 — 좁은 화면에서 사이드바를 상단 바로 전환 ──── */
@media (max-width: 1000px) {
  .two-col { grid-template-columns: 1fr; }
}
@media (max-width: 880px) {
  .app { flex-direction: column; }
  .sidebar { width: 100%; height: auto; position: static; }
  .sidebar-brand { padding: 14px 16px 10px; }
  /* 좁은 화면에서는 메뉴가 가로 줄로 접힌다. 항목이 많으면 뒤쪽(사용자 관리·설정 등)이
     화면 밖으로 밀리는데, 스크롤할 수 있다는 신호가 없으면 '메뉴가 없다'고 오해한다.
     → 줄바꿈을 허용해 전부 보이게 하고, 그래도 넘치면 스크롤 + 우측 페이드로 알린다. */
  .sidebar-nav {
    flex-direction: row; flex-wrap: wrap; overflow-x: auto; padding: 0 12px 10px; gap: 2px;
    -webkit-overflow-scrolling: touch;
  }
  .sidebar-nav a { white-space: nowrap; padding: 8px 12px; }
  .sidebar-nav .nav-group {
    /* 섹션 라벨은 줄 구분자로만 남긴다 — 폭을 100%로 잡아 그룹마다 줄이 나뉜다 */
    display: block; width: 100%; margin: 6px 0 2px; padding: 0 4px; font-size: .68rem; opacity: .55;
  }
  .sidebar-foot { padding: 10px 16px; }
  .main { padding: 20px 16px 48px; }
  /* 2열로 접히면 컬럼 헤더 정렬이 깨짐 → 헤더 숨기고 행마다 켜짐/꺼짐 라벨을 되살려 구분 */
  .power-row { grid-template-columns: 44px 1fr; }
  .power-head { display: none; }
  .power-row .field > span { display: block; }
}

/* ── 모션 최소화 환경 — 애니메이션 전부 즉시 처리 ──────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .dot.on { box-shadow: 0 0 0 3px var(--green-soft); }
}

/* ── 로그인 배경 장면 — 야간 아파트 스카이라인 + 엘리베이터 + 사이니지 ──
   엘리베이터 미디어 사이니지 제품의 무대를 배경으로 은은하게 깔아준다.
   장식 요소(aria-hidden)이므로 카드 가독성을 해치지 않게 저채도·저대비 유지. */
.login-bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.login-bg svg { width: 100%; height: 100%; display: block; opacity: 0.9; }
/* 은하수 — 대각선으로 하늘을 가로지르는 성운 띠(발광). 잘 보이도록 밝게 */
.login-bg::before {
  content: ""; position: absolute; inset: -20%; z-index: 0;
  background:
    linear-gradient(112deg, transparent 30%,
      oklch(0.82 0.06 265 / 0.22) 42%, oklch(0.85 0.11 305 / 0.16) 49%,
      oklch(0.9 0.09 250 / 0.2) 52%, oklch(0.86 0.09 40 / 0.14) 55%,
      oklch(0.82 0.06 265 / 0.22) 62%, transparent 74%);
  filter: blur(9px);
}
/* 은하수 별먼지 — 대각선 띠에 촘촘히 몰린 별(여러 타일 크기로 반복감 완화) */
.lb-mw-stars {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    radial-gradient(1.7px 1.7px at 40px 60px, #fff, transparent 60%),
    radial-gradient(1.2px 1.2px at 118px 22px, oklch(0.92 0.05 255), transparent 60%),
    radial-gradient(1.8px 1.8px at 92px 150px, #fff, transparent 60%),
    radial-gradient(1.2px 1.2px at 190px 96px, #fff, transparent 60%),
    radial-gradient(1.5px 1.5px at 24px 182px, #fff, transparent 60%),
    radial-gradient(1.2px 1.2px at 150px 190px, oklch(0.95 0.06 95), transparent 60%),
    radial-gradient(1.3px 1.3px at 70px 110px, #fff, transparent 60%),
    radial-gradient(1.1px 1.1px at 168px 60px, #fff, transparent 60%);
  background-size: 190px 190px, 150px 150px, 214px 214px, 138px 138px, 176px 176px, 122px 122px, 160px 160px, 104px 104px;
  filter: drop-shadow(0 0 2px oklch(0.9 0.06 255 / 0.8));
  -webkit-mask-image: linear-gradient(112deg, transparent 20%, #000 40%, #000 62%, transparent 82%);
  mask-image: linear-gradient(112deg, transparent 20%, #000 40%, #000 62%, transparent 82%);
  opacity: 1; /* 항상 밝게 유지(전체 깜빡임 없음). 반짝임은 별자리 별만 */
}
/* 별자리 — 북두칠성·카시오페아 (연결선 + 반짝이는 별). 은하수 위 밝은 하이라이트 */
.lb-cline { fill: none; stroke: oklch(0.82 0.07 255 / 0.32); stroke-width: 1.3; stroke-linejoin: round; stroke-linecap: round; }
.lb-star { fill: #fff; filter: drop-shadow(0 0 3px oklch(0.88 0.08 255)); animation: lb-twinkle 3.8s ease-in-out infinite alternate; }
.lb-star.s1 { animation-delay: 0s; }
.lb-star.s2 { animation-delay: 1.3s; }
.lb-star.s3 { animation-delay: 2.5s; }
/* 이따금 스쳐 지나가는 별똥별 */
.login-bg::after {
  content: ""; position: absolute; top: 12%; left: -8%;
  width: 140px; height: 1.5px; border-radius: 6px;
  background: linear-gradient(90deg, transparent, #fff, oklch(0.9 0.06 250 / 0.6), transparent);
  filter: drop-shadow(0 0 3px #fff);
  transform: rotate(16deg); opacity: 0;
  animation: lb-shoot 9s ease-in 3s infinite;
}
@keyframes lb-shoot {
  0% { transform: translate(0,0) rotate(16deg); opacity: 0; }
  4% { opacity: 1; }
  12% { transform: translate(62vw, 20vh) rotate(16deg); opacity: 0; }
  100% { opacity: 0; }
}

/* 건물 실루엣 — 배경보다 살짝 밝은 인디고, 먼 건물은 더 어둡게(공기원근) */
.lb-bld { fill: oklch(0.215 0.038 278); }
.lb-bld.lb-far { fill: oklch(0.19 0.032 278); }
.lb-ground { fill: oklch(0.23 0.04 278); }
/* 꺼진 창 — 아주 옅게 */
.lb-win-off { fill: oklch(1 0 0 / 0.05); }
/* 켜진 창 — 따뜻한 불빛이 은은하게 깜빡임 (지연을 달리해 자연스럽게) */
.lb-lit { fill: oklch(0.8 0.09 85 / 0.75); animation: lb-twinkle 6s ease-in-out infinite alternate; }
.lb-lit.d1 { animation-delay: 1.6s; }
.lb-lit.d2 { animation-delay: 3.1s; }
.lb-lit.d3 { animation-delay: 4.4s; }
@keyframes lb-twinkle {
  0%, 55% { opacity: 0.25; }
  100%    { opacity: 0.9; }
}
/* 엘리베이터 — 샤프트를 따라 천천히 오르내리는 카 (인디고 글로우) */
.lb-shaft { fill: oklch(0.26 0.045 278); }
.lb-car rect { fill: #8b5cf6; }
.lb-car {
  filter: drop-shadow(0 0 8px oklch(0.6 0.2 285 / 0.8));
  animation: lb-elev 11s ease-in-out infinite alternate;
}
@keyframes lb-elev {
  from { transform: translateY(0); }
  to   { transform: translateY(-440px); }
}
/* 옥상 사이니지 스크린 — 광고를 트는 것처럼 밝기·색이 순환(생동감) */
.lb-screen {
  fill: url(#lb-scr);
  transform-box: fill-box; transform-origin: center;
  animation: lb-glow 5.5s ease-in-out infinite alternate, lb-ads 14s linear infinite;
}
@keyframes lb-glow {
  from { opacity: 0.5; }
  to   { opacity: 1; }
}
@keyframes lb-ads { /* 재생 중인 콘텐츠가 바뀌듯 색조가 천천히 순환 */
  0%   { filter: hue-rotate(0deg) drop-shadow(0 0 6px oklch(0.6 0.2 285 / 0.6)); }
  33%  { filter: hue-rotate(60deg) drop-shadow(0 0 8px oklch(0.65 0.2 200 / 0.6)); }
  66%  { filter: hue-rotate(-50deg) drop-shadow(0 0 8px oklch(0.6 0.2 340 / 0.6)); }
  100% { filter: hue-rotate(0deg) drop-shadow(0 0 6px oklch(0.6 0.2 285 / 0.6)); }
}
/* 좁은 화면에서는 장면이 카드와 겹치므로 숨김 */
@media (max-width: 720px) { .login-bg { display: none; } }

/* ── 로그인 웰컴 타이포그래피 — 스크립트체 Welcome + 볼드 한글 헤드라인 ──
   엘리베이터 웰컴보드의 인사말 톤을 관리자 로그인에도 잇는다.
   로그인 카드 위에 중앙 정렬로 넓게 배치(세로 스택). */
.login-wrap { flex-direction: column; gap: 46px; }
.login-hero {
  position: relative; text-align: center; max-width: 760px; min-width: 0;
  animation: login-in 0.55s var(--ease-out);
}
.lh-eyebrow {
  margin: 0; font-size: 13px; font-weight: 700;
  letter-spacing: 0.4em; color: oklch(0.72 0.06 277);
}
/* 필기체 Welcome — 시스템 스크립트 폰트 사용(CDN 없이). 화면 폭에 따라 유연하게 */
.lh-script {
  margin: 4px 0 0;
  font-family: "Segoe Script", "Brush Script MT", "Apple Chancery", cursive;
  font-size: clamp(56px, 9vw, 96px); line-height: 1.1; color: #fff;
}
.lh-line {
  display: block; width: 92px; height: 4px; border-radius: 6px;
  background: linear-gradient(90deg, #8b5cf6, #4f46e5);
  margin: 22px auto 24px;
}
.lh-title {
  margin: 0; font-size: clamp(28px, 4.2vw, 44px); font-weight: 800;
  line-height: 1.3; letter-spacing: -0.02em; color: #fff;
}
.lh-desc {
  margin: 16px 0 0; font-size: 16px; line-height: 1.7;
  color: oklch(0.79 0.02 278);
}
/* 낮은 화면에서는 히어로를 줄여 카드가 잘리지 않게 */
@media (max-height: 760px) {
  .login-wrap { gap: 24px; }
  .lh-script { font-size: 48px; }
  .lh-title { font-size: 24px; }
  .lh-desc { display: none; }
}

/* ── 아이콘 버튼 / 공공데이터 모달 보조 스타일 ─────────── */
/* 라벨+아이콘 버튼 (조회·미리보기 등) */
.btn-ico { display: inline-flex; align-items: center; gap: 6px; }
.btn-ico svg { width: 14px; height: 14px; flex: none; }
/* 공공데이터 미리보기 출력 박스 — 결과가 있을 때만 표시 */
.pd-out {
  margin-top: 10px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--card-sunken); border: 1px solid var(--divider);
  font-size: 12px; color: var(--fg-soft); white-space: pre-line; line-height: 1.7;
}
.pd-out:empty { display: none; }
/* 세그먼트 존 라벨 앞 방향 아이콘 (상=▲ / 하=▼) */
.seg-zone-label { display: flex; align-items: center; gap: 4px; }
.seg-zone-label svg { width: 11px; height: 11px; flex: none; }

/* ── 긴 목록 접기 "더보기/접기" 컨트롤 (applyCollapse) ── */
.cl-more-row > td { padding: 0 !important; border-top: 1px solid var(--border); }
.cl-more {
  width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 12px; background: transparent; border: none; cursor: pointer;
  color: var(--accent, #4f46e5); font-size: 13px; font-weight: 600;
  transition: background .15s;
}
.cl-more:hover { background: rgba(79, 70, 229, .07); }
.cl-more b { font-weight: 700; }
.cl-more-ico { width: 16px; height: 16px; flex: none; transition: transform .2s; }
.cl-more.cl-open .cl-more-ico { transform: rotate(180deg); }
.cl-more-wrap { display: flex; justify-content: center; margin-top: 8px; }
.cl-more-wrap .cl-more { border: 1px solid var(--border); border-radius: 8px; }

/* ── 편성 세그먼트: 전체 영상 자동 지속 표시 / 분할 실제 재생시간 힌트 ── */
.seg-dur-auto { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; font-size: 12px; }
.seg-dur-auto b { color: var(--accent); }
.seg-chip-auto { color: var(--accent); font-size: 9px; font-weight: 700; }
.seg-eff-hint { margin: 2px 0 6px; font-size: 12px; color: var(--text-soft, #64748b); }
.seg-eff-hint b { color: var(--accent); }
.seg-hint-balance { margin: 4px 0 8px; padding: 7px 10px; font-size: 12px; line-height: 1.45; color: var(--fg, #1f2937); background: rgba(245,158,11,.10); border: 1px solid rgba(245,158,11,.5); border-radius: 8px; }
.seg-hint-balance b { color: #b45309; }
/* 타임라인 편집기 — 표시방식 자동선택 안내 */
.prog-autofit-note { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 12px; padding: 11px 14px; font-size: 12px; line-height: 1.6; color: var(--fg, #1f2937); background: var(--accent-soft, rgba(79,70,229,.08)); border: 1px solid var(--accent, #4f46e5); border-left-width: 4px; border-radius: 12px; }
.prog-autofit-ico { font-size: 18px; line-height: 1.2; flex: none; }
.prog-autofit-note b { color: var(--accent, #4f46e5); }
.prog-autofit-note .muted { color: var(--text-soft, #64748b); }
/* 분할 존 재생시간 합계 배지 (상단/하단 비교) */
.lane-total { margin-left: 6px; font-size: 11px; font-weight: 700; color: var(--accent, #4f46e5); background: rgba(79,70,229,.10); padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.lane-total.lane-short { color: #b45309; background: rgba(245,158,11,.18); box-shadow: inset 0 0 0 1px rgba(245,158,11,.55); }
/* 분할 레인 칩 순서 이동(썸네일 드래그 핸들) */
.seg-chip-thumb[draggable="true"] { cursor: grab; }
.seg-chip-thumb[draggable="true"]:active { cursor: grabbing; }
.seg-chip-dragging { opacity: .45; }
/* ── 다운로드 · 도구 페이지 ── */
.btn-lg { padding: 10px 18px; font-size: 15px; font-weight: 700; }
.dl-note { border-radius: 12px; padding: 12px 14px; font-size: 13px; line-height: 1.6; }
.dl-warn { background: rgba(220, 38, 38, .08); border: 1px solid rgba(220, 38, 38, .35); color: var(--text, #1f2937); }
.dl-h { margin: 18px 0 8px; font-size: 14px; font-weight: 700; }
.dl-steps { margin: 0; padding-left: 22px; line-height: 1.85; }
.dl-steps ul { margin: 4px 0; padding-left: 18px; line-height: 1.7; }
.dl-steps code, .dl-note code, .tbl code { background: rgba(120,120,140,.15); padding: 1px 5px; border-radius: 6px; font-size: .92em; }

/* 다운로드 — 프로그램 미리보기 */
.dl-shots { display: grid; grid-template-columns: repeat(auto-fit, minmax(370px, 1fr)); gap: 16px; max-width: 900px; }
@media (max-width: 460px) { .dl-shots { grid-template-columns: 1fr; } }
.dl-shot { margin: 0; }
.dl-shot figcaption { font-size: 12px; color: var(--fg-soft); margin-top: 8px; text-align: center; }
/* 실제 스크린샷 PNG로 교체 시 이 스타일 사용 */
.dl-shot > img { width: 100%; border: 1px solid var(--divider); border-radius: 12px; display: block; }

/* 사이니지 영상 최적화기 화면 재현(목업) — 실제 Windows 앱 모양 */
.ow-win { border: 1px solid #c9ced6; border-radius: 12px; overflow: hidden; background: #fff; box-shadow: 0 6px 18px rgba(0,0,0,.14); font-size: 11px; color: #1f2937; }
.ow-title { display: flex; align-items: center; gap: 6px; background: #eef0f3; padding: 6px 8px; border-bottom: 1px solid #dfe3e8; }
.ow-tico { font-size: 12px; }
.ow-tname { font-weight: 600; font-size: 11px; }
.ow-tctrl { margin-left: auto; display: flex; align-items: center; gap: 11px; color: #6b7280; }
.ow-tctrl i { width: 9px; height: 1px; background: #6b7280; display: inline-block; }
.ow-tctrl i:nth-child(2) { width: 8px; height: 8px; background: none; border: 1px solid #6b7280; }
.ow-tctrl i.x { width: auto; height: auto; background: none; font-style: normal; font-size: 11px; line-height: 1; }
.ow-body { padding: 10px 11px; display: flex; flex-direction: column; gap: 7px; background: #fafbfc; }
.ow-head { display: flex; align-items: baseline; gap: 8px; }
.ow-head b { font-size: 14px; }
.ow-ffmpeg { margin-left: auto; color: #15803d; font-weight: 600; font-size: 10px; }
.ow-sec { color: #6b7280; font-size: 10px; margin-top: 2px; }
.ow-sec small { color: #9aa1ac; }
/* 파일 목록 */
.ow-list { border: 1px solid #d3d8df; border-radius: 6px; background: #fff; overflow: hidden; }
.ow-lh, .ow-row { display: grid; grid-template-columns: 1fr 70px 1.1fr; gap: 6px; padding: 4px 8px; align-items: center; }
.ow-lh { background: #f2f4f7; color: #6b7280; border-bottom: 1px solid #e5e8ec; font-size: 10px; }
.ow-lh span:nth-child(2), .ow-row span:nth-child(2) { text-align: right; }
.ow-row.sel { background: #2563eb; color: #fff; }
.ow-file { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ow-done { font-size: 10px; } .ow-done b { font-weight: 800; }
.ow-btnrow { display: flex; gap: 6px; }
/* 버튼 */
.ow-btn { border: 1px solid #c3c9d2; background: linear-gradient(#fff,#f3f5f8); border-radius: 6px; padding: 3px 9px; font-size: 10px; color: #374151; white-space: nowrap; }
.ow-btn.primary { background: linear-gradient(#5a93f7,#2563eb); border-color: #1d4ed8; color: #fff; font-weight: 700; }
.ow-btn.dim { color: #9aa1ac; }
/* 설정 */
.ow-settings { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 12px; }
.ow-settings label { display: flex; flex-direction: column; gap: 3px; color: #4b5563; font-size: 10px; }
.ow-select { display: flex; align-items: center; gap: 4px; border: 1px solid #c3c9d2; background: #fff; border-radius: 6px; padding: 4px 7px; color: #1f2937; font-size: 10px; }
.ow-select svg { width: 11px; height: 11px; margin-left: auto; color: #6b7280; flex: none; }
.ow-opt { display: flex; align-items: center; }
.ow-chk { display: inline-flex; align-items: center; gap: 6px; font-size: 10px; color: #374151; }
.ow-box { width: 13px; height: 13px; border: 1px solid #9aa1ac; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; font-size: 9px; color: #fff; flex: none; }
.ow-box.on { background: #2563eb; border-color: #2563eb; }
/* 저장 폴더 */
.ow-save { display: flex; align-items: center; gap: 7px; }
.ow-save .ow-lbl { color: #4b5563; flex: none; }
.ow-path { flex: 1; min-width: 0; border: 1px solid #c3c9d2; background: #fff; border-radius: 6px; padding: 4px 7px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #1f2937; }
/* 하단 진행 */
.ow-foot { display: flex; align-items: center; gap: 7px; margin-top: 1px; }
.ow-prog { flex: 1; height: 16px; border: 1px solid #c3c9d2; border-radius: 6px; background: #eef0f3; overflow: hidden; }
.ow-prog > i { display: block; height: 100%; background: repeating-linear-gradient(45deg,#e5e8ec,#e5e8ec 6px,#dfe3e8 6px,#dfe3e8 12px); }
.ow-prog > i.done { background: linear-gradient(#22c55e,#16a34a); }
.ow-pstat { font-size: 10px; color: #6b7280; white-space: nowrap; }
.ow-pstat.done { color: #15803d; font-weight: 700; }

/* 다운로드 — 변환 전후 비교 시각화 */
.dl-convert {
  display: grid; grid-template-columns: 1fr 44px 1fr; gap: 10px; align-items: stretch;
  max-width: 720px;
}
.dlc-tile {
  padding: 12px 14px; border: 1px solid var(--divider); border-radius: 12px;
  background: var(--card-sunken);
}
.dlc-tile.dlc-after { border-color: #86efac; background: #f0fdf4; }
.dlc-head {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; margin-bottom: 9px;
}
.dlc-head svg { width: 16px; height: 16px; flex: none; color: var(--fg-soft); }
.dlc-after .dlc-head svg { color: #15803d; }
.dlc-head code { font-weight: 600; }
.dlc-bar {
  position: relative; height: 18px; border-radius: 6px; background: oklch(0.93 0.008 274);
  overflow: hidden; margin-bottom: 9px;
}
.dlc-bar > i { position: absolute; inset: 0 auto 0 0; border-radius: 6px; background: oklch(0.52 0.02 274); }
.dlc-bar > span {
  position: absolute; inset: 0; display: flex; align-items: center; padding: 0 8px;
  font-size: 10px; font-weight: 700; color: #fff;
}
.dlc-bar-after > i { background: #16a34a; }
/* 라벨을 초록 채움(30%) 뒤의 밝은 트랙 위에 놓아 대비 확보 */
.dlc-bar-after > span { color: #14532d; padding-left: calc(30% + 8px); }
.dlc-list { margin: 0; padding-left: 17px; font-size: 12px; color: var(--fg-soft); line-height: 1.8; }
.dlc-after .dlc-list { color: #166534; }
.dlc-arrow {
  align-self: center; display: flex; flex-direction: column; align-items: center; gap: 2px;
  color: var(--accent); font-size: 11px; font-weight: 700;
}
.dlc-arrow svg { width: 20px; height: 20px; }
@media (max-width: 700px) {
  .dl-convert { grid-template-columns: 1fr; }
  .dlc-arrow { transform: rotate(90deg); padding: 4px 0; }
}

/* 공용(전체 공유) 콘텐츠 카드 · 섹션 */
.content-shared { box-shadow: inset 3px 0 0 var(--green, #16a34a); }
.cat-shared .cat-head { color: var(--green, #16a34a); }

/* 삭제된 콘텐츠(붕 뜬 참조) 표시 */
.seg-empty.seg-missing { color: var(--red, #dc2626); border-color: var(--red, #dc2626); font-weight: 700; line-height: 1.1; }
.seg-missing-txt { color: var(--red, #dc2626); font-weight: 600; }
.seg-block-missing { outline: 1px solid var(--red, #dc2626); outline-offset: -1px; }

/* ── Tenant picker overlay (card-style apartment selection) ── */
.tenant-picker-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(15, 18, 34, 0.62); backdrop-filter: blur(3px);
  padding: 24px;
}
.tenant-picker-overlay.hidden { display: none; }
.tenant-picker-overlay .tp-box {
  position: relative; background: var(--card); color: var(--text, #111);
  border-radius: 16px; padding: 28px 30px; width: min(880px, 100%);
  max-height: 88vh; overflow-y: auto; box-shadow: 0 24px 60px rgba(0,0,0,.35);
}
.tp-title { margin: 0 0 4px; font-size: 1.4rem; }
.tp-sub { margin: 0 0 18px; color: var(--muted, #667); font-size: .92rem; }
.tp-close {
  position: absolute; top: 14px; right: 16px; border: none; background: transparent;
  font-size: 1.2rem; cursor: pointer; color: var(--muted, #667); line-height: 1;
}
.tp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px; }
.tp-card {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 20px 14px; border: 1px solid var(--border, #e5e7eb); border-radius: 12px;
  background: var(--card-sunken, #f7f7fb); cursor: pointer; text-align: center;
  transition: transform .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.tp-card:hover { transform: translateY(-2px); border-color: var(--accent, #4f46e5); box-shadow: 0 8px 20px rgba(79,70,229,.18); }
.tp-card strong { font-size: 1rem; }
.tp-card small { color: var(--muted, #667); font-size: .8rem; }
.tp-logo { width: 56px; height: 56px; border-radius: 12px; object-fit: cover; background: #fff; }
.tp-logo-ph { display: flex; align-items: center; justify-content: center; font-size: 28px; }
.tp-card-global { background: var(--accent-soft, #eef); border-style: dashed; }
.tp-empty { grid-column: 1 / -1; color: var(--muted, #667); text-align: center; padding: 20px; }

/* ── Ad broadcast report (게첨보고서) ─────────────────────
   화면 = STEP 단계 카드 + 거점/기기 선택 칩, 인쇄물 = 광고주 제출용 공문서 컨셉
   (레터스페이스 표제 + 인디고 이중 괘선 + 서식형 표) */
.rp-step {
  flex: none; font-size: 10px; font-weight: 800; letter-spacing: 0.08em;
  color: var(--accent); background: var(--accent-soft);
  border-radius: 999px; padding: 3px 10px;
}
.rp-preview-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 22px; padding: 12px 16px;
  background: var(--card-sunken); border: 1px dashed var(--border-strong); border-radius: var(--radius);
}
.rp-preview-title { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: 14px; }
.rp-preview-title svg { width: 16px; height: 16px; color: var(--accent); }
.rp-preview-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; cursor: pointer; padding: 4px 10px; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--card); }
.rp-preview-toggle input { margin: 0; }
.rp-preview-hint { flex: 1; font-size: 12px; color: var(--fg-soft); }

/* 캡처 대상 선택 — 거점 그룹 + 기기 칩 */
.rsel-group {
  border: 1px solid var(--border); border-radius: 12px; padding: 11px 13px; margin-bottom: 8px;
  background: var(--card-sunken);
}
.rsel-apt { display: flex; align-items: center; gap: 7px; margin-bottom: 9px; cursor: pointer; flex-wrap: wrap; }
.rsel-apt-ico {
  width: 24px; height: 24px; border-radius: 6px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.rsel-apt-ico svg { width: 13px; height: 13px; }
.rsel-devs { display: flex; flex-wrap: wrap; gap: 6px; }
.rsel-dev {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12px; cursor: pointer;
  padding: 6px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--card);
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out);
}
.rsel-dev:hover { border-color: var(--accent); }
.rsel-dev:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.rsel-name { font-weight: 600; }
.rsel-shot { font-size: 11px; color: var(--fg-muted); }
.rsel-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.rsel-dot.on { background: #16a34a; } .rsel-dot.off { background: #9ca3af; }

/* 게첨 작업 진행률 */
.jobs-meter { max-width: 340px; margin: 2px 0 10px; }
.jobs-meter-done > i { background: var(--green); }

/* ── 보고서 문서 (미리보기 + 인쇄) ── */
.report-doc { margin-top: 12px; }

/* ── 광고주 제출용 게첨보고서 양식 (단지당 A4 한 장) ─────────────
   엑셀 출력물이 아니라 '제출 문서'로 읽히게 짰다. 원본 서식의 뼈대(정보표 → 단지명 → 장치목록 + 캡처)는
   그대로 두되, 격자로 가둔 인상을 걷어내고 활자·여백·괘선으로 격을 만든다.
   화면 테마(다크모드 등)를 따르지 않는다 — 종이에 찍히는 것과 화면이 같아야 한다. */
.gr-sheet {
  --ink: #1b2a4a;          /* 제목·괘선 — 먹빛 남색 */
  --line: #b9c0cd;         /* 표 안쪽 가는 선 */
  --head: #eef1f6;         /* 항목 셀 바탕 */
  --zebra: #f8fafc;        /* 장치 목록 짝수 줄 */
  --body: #16191f;
  --accent: #a52016;       /* 값 강조 — 원본의 빨강을 톤만 낮춰 이었다 */
  --dim: #7b8494;
  background: #fff; color: var(--body); width: 210mm; min-height: 297mm; box-sizing: border-box;
  padding: 16mm 14mm; margin: 0 auto 16px; border: 1px solid #dfe3ea;
  font-family: 'Malgun Gothic', '맑은 고딕', 'Apple SD Gothic Neo', sans-serif;
  font-size: 10.5pt; line-height: 1.5;
}
.gr-title {
  text-align: center; font-size: 20pt; font-weight: 800; color: var(--ink);
  margin: 0 0 3mm; letter-spacing: .14em;
}
/* 제목 아래 겹줄 — 공문서에서 제목과 본문을 가르는 관용 표현. 굵은 선 + 가는 선 */
.gr-rule { border-top: 2px solid var(--ink); border-bottom: 0.6px solid var(--ink); height: 1.6mm; margin: 0 0 7mm; }

.gr-meta { width: 100%; border-collapse: collapse; table-layout: fixed; }
.gr-meta th, .gr-meta td { border: 0.6px solid var(--line); padding: 2.8mm 3mm; font-size: 10pt; }
.gr-meta th {
  background: var(--head); font-weight: 700; color: var(--ink);
  text-align: center; letter-spacing: .02em; white-space: nowrap;
}
.gr-meta .gr-v { color: var(--accent); font-weight: 700; text-align: center; overflow-wrap: anywhere; }
/* 칸 너비는 고정이므로, 긴 값은 줄바꿈 대신 글자를 줄여 한 줄에 앉힌다
   (칸이 늘었다 줄었다 하면 장마다 표 모양이 달라져 문서로 안 보인다) */
.gr-meta .gr-v-sm { font-size: 9pt; letter-spacing: -.02em; }
.gr-meta .gr-v-xs { font-size: 8pt; letter-spacing: -.04em; }
/* 표 바깥선만 진하게 — 안은 가늘게 둬야 격자에 갇힌 인상이 사라진다 */
.gr-meta { border: 1.2px solid var(--ink); }
.gr-meta .gr-c-th { width: 26mm; }
.gr-meta .gr-c-day { width: 34mm; }

/* 송출단지명 — 박스를 없애고 라벨 + 큰 이름 + 밑줄. 이 장이 '어느 단지 것'인지가 표제 역할을 한다 */
.gr-apt {
  display: flex; align-items: baseline; gap: 4mm;
  margin: 9mm 0 4mm; padding-bottom: 2.2mm; border-bottom: 1.2px solid var(--ink);
}
.gr-apt-label {
  font-size: 9pt; font-weight: 700; color: var(--dim); letter-spacing: .16em; flex: none;
}
.gr-apt-name { font-size: 15pt; font-weight: 800; color: var(--ink); letter-spacing: -.01em; }

.gr-body { display: flex; gap: 6mm; align-items: flex-start; }

.gr-devs { border-collapse: collapse; table-layout: fixed; width: 92mm; flex: none; border: 1px solid var(--ink); }
/* 행 높이 — 25행이 A4 한 장을 알맞게 채우는 값. 더 낮추면 아래가 허전하고, 키우면 넘친다 */
.gr-devs th, .gr-devs td { border: 0.5px solid var(--line); font-size: 9pt; padding: 1.4mm 2mm; height: 7.2mm; }
.gr-devs thead th {
  background: var(--head); color: var(--ink); font-weight: 700; text-align: center;
  border-bottom: 1px solid var(--ink); letter-spacing: .04em;
}
.gr-devs tbody tr:nth-child(even) td { background: var(--zebra); }   /* 25줄을 눈으로 따라가기 쉽게 */
.gr-devs .gr-no { width: 11mm; text-align: center; color: var(--dim); }
.gr-devs .gr-dev { text-align: left; }
.gr-devs .gr-ok { width: 15mm; text-align: center; color: var(--accent); font-weight: 700; }
.gr-devs .gr-off { color: var(--dim); }   /* 연결이 끊긴 기기 — 눈에 띄되 붉게 경고하지는 않는다 */
/* 노출량 별지 — 본문 양식과 같은 활자를 쓰되 '참고 자료'로 읽히게 한 단계 눌러 둔다 */
.gr-exp { border-collapse: collapse; width: 100%; margin-top: 4mm; }
.gr-exp th, .gr-exp td { border: 0.5px solid var(--line); padding: 1.8mm 2mm; font-size: 9pt; text-align: center; }
.gr-exp thead th { background: var(--head); color: var(--ink); font-weight: 700; }
.gr-exp td:first-child { text-align: left; }
.gr-exp-sum { margin: 3mm 0 0; font-size: 10pt; font-weight: 700; color: var(--ink); }
.gr-exp-note { margin: 2mm 0 0; font-size: 8.5pt; color: var(--dim); }
.gr-devs thead .gr-no, .gr-devs thead .gr-ok { color: var(--ink); }

.gr-shot { flex: 1; min-width: 0; }
.gr-shot-img { border: 1px solid var(--ink); padding: 1mm; line-height: 0; background: #fff; }
.gr-shot-img img { width: 100%; display: block; }
/* 캡처 설명 — 불릿이 아니라 '항목: 값'의 서식. 라벨은 작고 흐리게, 값은 또렷하게 */
.gr-shot-meta {
  display: grid; grid-template-columns: auto 1fr; gap: 1.4mm 3mm;
  margin: 3.5mm 0 0; font-size: 9.5pt;
}
.gr-shot-meta dt {
  color: var(--dim); font-weight: 700; font-size: 8.5pt; letter-spacing: .1em;
  white-space: nowrap; padding-top: .3mm;
}
.gr-shot-meta dd { margin: 0; font-weight: 700; color: var(--body); }
.gr-shot-empty {
  border: 0.8px dashed var(--line); padding: 16mm 4mm; text-align: center;
  color: var(--dim); font-size: 9.5pt; line-height: 1.8;
}
/* 문서 마무리 — 이 자료가 무엇인지 한 줄로 밝힌다. 제출 문서에는 끝맺음이 있어야 한다 */
.gr-foot {
  margin: 7mm 0 0; padding-top: 2.5mm; border-top: 0.6px solid var(--line);
  font-size: 8.5pt; color: var(--dim); display: flex; justify-content: space-between; gap: 4mm;
}

@media print {
  .gr-sheet {
    width: auto; min-height: 0; margin: 0; padding: 0; border: none;
    page-break-after: always; page-break-inside: avoid;
  }
  .gr-sheet:last-child { page-break-after: auto; }
  /* '배경 그래픽 없이 인쇄'를 골라도 괘선과 항목 바탕은 남아야 표가 표로 보인다 */
  .gr-meta, .gr-devs { border-color: var(--ink) !important; }
  .gr-meta th, .gr-meta td, .gr-devs th, .gr-devs td { border-color: var(--line) !important; }
  .gr-meta th, .gr-devs thead th { background: var(--head) !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .gr-devs tbody tr:nth-child(even) td { background: var(--zebra) !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .gr-apt, .gr-devs thead th { border-bottom-color: var(--ink) !important; }
  .gr-shot-img { border-color: var(--ink) !important; }
}
.rd-cover {
  background: var(--card, #fff); border: 1px solid var(--border, #e5e7eb); border-radius: 12px;
  padding: 26px 30px 22px; margin-bottom: 16px;
}
.rd-band {
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  font-size: 11px; font-weight: 700; letter-spacing: 0.14em; color: var(--accent, #4f46e5);
  padding-bottom: 10px; margin-bottom: 18px; border-bottom: 1px solid var(--border, #e5e7eb);
}
.rd-cover h1 {
  margin: 0; padding: 20px 0; text-align: center;
  font-size: 27px; font-weight: 800; letter-spacing: 0.3em; text-indent: 0.3em; text-wrap: balance;
  border-top: 3px solid #312e81; border-bottom: 1px solid #312e81;
}
.rd-meta { border-collapse: collapse; width: 100%; max-width: 640px; margin: 22px auto 0; }
.rd-meta th, .rd-meta td { text-align: left; padding: 9px 14px; border: 1px solid #cbd5e1; font-size: 13px; }
.rd-meta th { width: 120px; font-weight: 700; background: var(--accent-soft, #eef2ff); color: #312e81; }
.rd-foot { margin: 18px auto 0; max-width: 640px; font-size: 12px; color: var(--fg-soft, #556); text-align: center; }

.report-apt {
  background: var(--card, #fff); border: 1px solid var(--border, #e5e7eb); border-radius: 12px;
  padding: 18px 22px; margin-bottom: 16px;
}
.ra-head2 {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-bottom: 10px; margin-bottom: 14px; border-bottom: 2px solid #312e81;
}
.ra-no {
  flex: none; font-size: 12px; font-weight: 800; color: #fff; background: #4f46e5;
  border-radius: 6px; padding: 4px 10px; letter-spacing: 0.04em;
}
.ra-no-spot { background: #15803d; }
.ra-name { font-size: 17px; font-weight: 800; letter-spacing: -0.01em; }
.ra-cap { margin-left: auto; font-size: 12px; color: var(--fg-soft, #667); }
.ra-auto { font-weight: 700; color: #15803d; }
/* 2단 구성 — 좌: 기기 목록, 우: 실제 캡처 (번호 배지로 상호 연결) */
.ra-cols { display: flex; gap: 22px; align-items: flex-start; flex-wrap: wrap; }
.ra-list {
  flex: 1 1 250px; min-width: 230px; max-width: 360px;
  list-style: none; margin: 0; padding: 0; border-top: 2px solid #312e81;
}
.ra-row {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 9px 10px; border-bottom: 1px solid var(--border, #e5e7eb); font-size: 12px;
}
.ra-row-shot { background: var(--accent-soft, #eef2ff); }
.ra-row-name { font-weight: 600; }
.ra-mark {
  margin-left: auto; width: 18px; height: 18px; border-radius: 50%; flex: none;
  background: #4f46e5; color: #fff; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.ra-mark-spot { background: #15803d; }
.ra-code { color: var(--fg-muted, #8a94a6); font-variant-numeric: tabular-nums; }
.ra-none { margin-left: auto; font-size: 11px; color: var(--fg-muted, #99a); }
.ra-shots { flex: 1.6 1 320px; display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; }
.ra-shots-empty {
  flex: 1; padding: 40px 16px; text-align: center; font-size: 13px; color: var(--fg-muted, #99a);
  border: 1px dashed var(--border-strong, #ccc); border-radius: 8px;
}
/* 캡처가 1장이면 샘플 양식처럼 크게(페이지의 주인공), 여러 장이면 그리드 */
.ra-shots figure:only-child img { max-width: 100%; max-height: 74vh; }
.ra-shots figcaption .ra-mark { margin: 0 6px 0 0; vertical-align: -4px; }
/* display:table + table-caption: 캡션 폭이 이미지 폭을 따라가 흰 여백이 안 생긴다 */
.ra-shots figure {
  margin: 0; display: table; border: 1px solid #cbd5e1; border-radius: 8px; overflow: hidden; background: var(--card, #fff);
}
.ra-shots img { display: block; max-height: 62vh; max-width: 320px; width: auto; background: #000; }
.ra-shots figcaption {
  display: table-caption; caption-side: bottom;
  font-size: 11px; color: var(--fg-soft, #556); padding: 6px 10px; text-align: center;
  background: oklch(0.97 0.006 274); border: 1px solid #cbd5e1; border-top: 0;
  border-radius: 0 0 8px 8px;
}
.ra-noshot { border-style: dashed; }
.ra-noshot > div {
  width: 200px; height: 280px; display: flex; align-items: center; justify-content: center;
  color: var(--fg-muted, #999); font-size: 13px;
}

/* Print: only the report document, one 거점 per page */
@media print {
  .no-print, .sidebar, #tenant-picker, #modal-root, .swal2-container { display:none !important; }
  .app, .main, #app-view { display:block !important; margin:0 !important; padding:0 !important; }
  body { background:#fff !important; }
  .report-doc { margin:0; }
  .rd-cover { page-break-after:always; border:none; border-radius:0; }
  .report-apt { page-break-inside:avoid; page-break-before:always; border:none; border-radius:0; box-shadow:none; }
  .ra-cols { flex-wrap: nowrap; }
  .ra-shots img { max-height:none; max-width:340px; }
  .ra-shots figure:only-child img { max-width:100%; max-height:215mm; }
  /* 배경 생략 인쇄 설정에서도 괘선·칩·서식 배경 유지 */
  .rd-cover h1, .ra-head2, .rd-meta th, .rd-meta td, .ra-list, .ra-row, .ra-row-shot,
  .ra-no, .ra-mark, .ra-shots figure, .ra-shots figcaption, .rd-band {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
}

/* ── 검색 바 (전체메뉴 단지명/콘텐츠 검색 공용) ── */
.search-bar {
  display: flex; align-items: center; gap: 8px;
  max-width: 480px; margin: 0 0 14px;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); transition: border-color var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
.search-bar:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.search-bar .search-ico { display: inline-flex; flex: none; color: var(--fg-muted); }
.search-bar .search-ico svg { width: 16px; height: 16px; }
.search-bar input {
  flex: 1; min-width: 0; border: none; outline: none; background: transparent;
  font: inherit; font-size: 13px; padding: 0;
}
.search-bar .search-count { flex: none; font-size: 12px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
/* 검색으로 전부 숨겨진 단지 그룹은 접힘 표시 자체를 감춤 */
.gc-tenant.gc-hidden { display: none; }

/* 전체 플레이리스트 — 단지 그룹 안의 플레이리스트 카드 그리드 + 타임라인 편성 구분 헤더 */
.gpl-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 10px; margin-top: 8px;
}
.gpl-cards .card { height: 100%; }
.gpl-subhead {
  margin: 14px 0 6px; padding-top: 12px; border-top: 1px solid var(--divider);
}
/* .ct-icon 사이징은 원래 `.card h3` 스코프라, h3가 아닌 이 헤더에도 동일 규칙을 재적용 */
.gpl-subhead .card-title { display: inline-flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 700; }
.gpl-subhead .ct-icon {
  width: 24px; height: 24px; flex: none; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.gpl-subhead .ct-icon svg { width: 13px; height: 13px; }

/* ── Global-menu content overview (전체메뉴 콘텐츠 통합뷰) ── */
.gc-tenant { border:1px solid var(--border,#e5e7eb); border-radius: 12px; padding:6px 12px 12px; margin-bottom:10px; }
.gc-tenant > summary { cursor:pointer; padding:8px 2px; display:flex; align-items:center; gap:10px; list-style:none; }
.gc-tenant > summary::-webkit-details-marker { display:none; }
.gc-tenant > summary b { font-size:1rem; }
.gc-tenant > summary [data-enter] { margin-left:auto; }
.gc-card { display:flex; flex-direction:column; gap:5px; align-items:center; text-align:center; padding:7px; }
.gc-card .c-name { font-size:.8rem; max-width:118px; }
.gc-meta { display:flex; gap:4px; flex-wrap:wrap; justify-content:center; }
.gc-actions { display:flex; gap:4px; margin-top:2px; }
/* 전체 콘텐츠(전체메뉴) — 카드를 약간 작게 + 한 줄에 더 많이 배치해 세로 스크롤 감소 */
#gc-shared .grid-cards, #gc-tenants .grid-cards { grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 10px; }

/* ── apt capability toggles (settings) — 기기 상세 화면 축소판 위 섹션별 토글 ── */
.capv {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--card-sunken); padding: 12px; margin-top: 6px;
}
.capv-pagehead {
  display: flex; align-items: center; gap: 8px; font-size: 13px;
  padding: 2px 2px 10px; border-bottom: 1px solid var(--divider); margin-bottom: 10px;
}
.capv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; }
.capv-sec {
  position: relative; display: flex; flex-direction: column; gap: 7px;
  padding: 11px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  cursor: pointer;
  transition: border-color var(--speed) var(--ease-out), background var(--speed) var(--ease-out), box-shadow var(--speed) var(--ease-out);
}
.capv-sec:not(.capv-fixed):hover { border-color: var(--accent); box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,.08)); }
.capv-fixed { cursor: default; }
.capv-head { display: flex; align-items: center; gap: 7px; min-width: 0; }
.capv-head b { flex: 1; min-width: 0; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.capv-ico {
  width: 22px; height: 22px; border-radius: 6px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.capv-ico svg { width: 12px; height: 12px; }
.capv-skel { display: flex; flex-direction: column; gap: 4px; }
.capv-skel i { height: 5px; border-radius: 6px; background: var(--divider); }
.capv-skel i:nth-child(2) { width: 78%; }
.capv-skel i:nth-child(3) { width: 52%; }
.capv-desc { font-size: 11px; color: var(--fg-soft); line-height: 1.5; }
.capv-always {
  flex: none; font-size: 10px; font-weight: 700; color: var(--fg-muted);
  background: var(--card-sunken); border: 1px solid var(--divider); border-radius: 999px; padding: 2px 8px;
}
.capv-foot {
  display: flex; align-items: center; gap: 6px; margin-top: 10px;
  font-size: 11px; color: var(--fg-soft);
}
.capv-foot svg { width: 12px; height: 12px; flex: none; color: var(--fg-muted); }
/* 토글 스위치 */
.capv-switch { position: relative; flex: none; width: 34px; height: 20px; }
.capv-switch input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.capv-switch i {
  position: absolute; inset: 0; border-radius: 999px; pointer-events: none;
  background: oklch(0.82 0.012 274); transition: background var(--speed) var(--ease-out);
}
.capv-switch i::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.28);
  transition: transform var(--speed) var(--ease-out);
}
.capv-switch input:checked + i { background: var(--accent); }
.capv-switch input:checked + i::after { transform: translateX(14px); }
.capv-switch input:focus-visible + i { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 차단(스위치 OFF) 상태 — 점선·회색 처리 + 잠금 라벨로 "숨겨짐"을 그대로 보여줌 */
.capv-lock { display: none; align-items: center; gap: 5px; font-size: 11px; font-weight: 700; color: var(--fg-soft); }
.capv-lock svg { width: 11px; height: 11px; flex: none; }
.capv-sec:has(input[data-cap]:not(:checked)) { border-style: dashed; background: var(--card-sunken); }
.capv-sec:has(input[data-cap]:not(:checked)) .capv-head b { color: var(--fg-muted); }
.capv-sec:has(input[data-cap]:not(:checked)) .capv-ico { background: var(--divider); color: var(--fg-muted); }
.capv-sec:has(input[data-cap]:not(:checked)) .capv-skel i { opacity: 0.55; }
.capv-sec:has(input[data-cap]:not(:checked)) .capv-desc { display: none; }
.capv-sec:has(input[data-cap]:not(:checked)) .capv-lock { display: inline-flex; }

/* ── Draggable lane-chart band handles (전원·전체화면 스케줄 시각화 조절) ── */
.fs-band-edit { padding: 0; cursor: grab; touch-action: none; }
.fs-band-edit:active { cursor: grabbing; }
/* 드래그 밴드 라벨 — 좌측 정렬 + …축약. 가운데 정렬 + 좌우 12px 패딩이던 것을 바꿨다:
   칸을 좁히면 패딩이 글자 자리를 다 먹어 라벨이 통째로 사라졌다(핸들 3px 바와는 6px로 충분히 비껴간다). */
.fs-band-edit .fs-band-txt { text-align: left; pointer-events: none; }
/* 핸들 폭을 밴드 폭 비례(40%·상한 14px)로 잡아 좁은 밴드에서도 좌/우 핸들이 겹치지 않게 한다.
   (고정 13px일 때 26px 미만 밴드에서 두 핸들이 포개져 시작 핸들을 못 잡던 문제 해결) */
.fs-band .fs-h { position: absolute; top: 0; bottom: 0; width: 40%; max-width: 14px; cursor: ew-resize; z-index: 4; touch-action: none; }
.fs-band .fs-h-l { left: 0; } .fs-band .fs-h-r { right: 0; }
.fs-band .fs-h::after {
  content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 3px; height: 56%; border-radius: 6px; background: rgba(255,255,255,.85);
}
.fs-band-edit:hover .fs-h::after, .fs-band .fs-h:active::after { background: #fff; box-shadow: 0 0 3px rgba(0,0,0,.55); }

/* ── Ad-capture jobs panel (게첨 캡처 작업) ── */
.jobs-spot { border: 2px solid var(--border,#e5e7eb); border-radius: 12px; padding: 10px 12px; margin-bottom: 8px; cursor: pointer; }
.jobs-spot:hover { border-color: var(--accent,#4f46e5); }
.jobs-spot.sel { border-color: var(--accent,#4f46e5); box-shadow: 0 0 0 3px var(--accent-ring, rgba(79,70,229,.25)); background: var(--accent-ring, rgba(79,70,229,.06)); }
.jobs-spot-head { margin-bottom: 8px; }
.jobs-rows.collapsed > .jobs-row:nth-child(n+6) { display: none; }
.jobs-more { margin-top: 6px; }
/* 실패(미송출/취소) 캡처 행 — 비활성처럼 흐리게 */
.jobs-row.failed { opacity: .5; }
.jobs-row.failed .jobs-dev { text-decoration: line-through; }
.jobs-failreason { margin-top: 8px; padding: 8px 11px; border-radius: 8px; background: rgba(239,68,68,.09); border: 1px solid rgba(239,68,68,.35); color: var(--fg, #1f2937); font-size: 12px; line-height: 1.5; }
.jobs-rows { display: flex; flex-direction: column; gap: 6px; }
.jobs-row { display: flex; align-items: center; gap: 10px; }
.jobs-thumb { width: 40px; height: 64px; object-fit: cover; border-radius: 6px; background: #000; flex: none; border: 1px solid var(--border,#ddd); }
.jobs-thumb-none {
  display: flex; align-items: center; justify-content: center; color: var(--fg-muted,#999);
  background: var(--card-sunken, #f6f7fb); border-style: dashed;
}
.jobs-dev { flex: 1; min-width: 0; font-size: .9rem; }

/* ── Fullscreen schedule zoom + horizontal scroll (좁은 구간 확대) ── */
.fs-ov-scroll { overflow-x: auto; overflow-y: hidden; }
.fs-ov-scroll > .fs-ov { width: 100%; }        /* JS가 확대 배율(zoom%)로 덮어씀 */
.fs-ov-zoom { display: flex; align-items: center; gap: 4px; margin: 6px 0; font-size: 12px; color: var(--fg-muted); flex-wrap: wrap; }
.fs-ov-zoom .btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.fs-ov-zoom-hint { margin-left: 6px; }

/* ── Jobs cleanup bar (게첨 캡처 정리 도구) ── */
.jobs-cleanup { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }

/* ── Ad picker thumbnail cards (게첨보고서 광고 선택) ── */
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; max-height: 320px; overflow-y: auto; padding: 4px; }
.pick-card { display: flex; flex-direction: column; gap: 4px; padding: 6px; border: 2px solid var(--border,#e5e7eb); border-radius: 12px; background: var(--card,#fff); cursor: pointer; text-align: center; min-height: 108px; box-sizing: border-box; }
.pick-card:hover { border-color: var(--accent,#4f46e5); }
.pick-card.sel { border-color: var(--accent,#4f46e5); box-shadow: 0 0 0 3px var(--accent-ring, rgba(79,70,229,.35)); }
.pick-thumb { position: relative; width: 100%; height: 74px; flex: 0 0 74px; border-radius: 6px; overflow: hidden; background: #0f172a; display: flex; align-items: center; justify-content: center; }
.pick-thumb img { width: 100%; height: 100%; object-fit: cover; }
.pick-vid { font-size: 24px; color: #cbd5e1; }
.pick-name { font-size: .74rem; line-height: 1.2; max-height: 2.4em; overflow: hidden; word-break: break-all; }
.pick-badge { align-self: center; font-size: .66rem; }
/* 재생 위험 영상 강조 경고 배너 (STEP3 자동 캡처) */
.rp-warn { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 12px; padding: 11px 14px; border: 1px solid #f59e0b; border-radius: 12px; background: rgba(245,158,11,.10); color: var(--fg, #1f2937); font-size: 13px; line-height: 1.5; }
.rp-warn-ico { color: #b45309; }
.rp-warn-ico { font-size: 20px; line-height: 1.2; flex: none; }
/* 위험 광고 카드 표시 */
.pick-card.risky { border-color: #ef4444; }
.pick-card.risky.sel { border-color: var(--accent, #4f46e5); }
.pick-risk { position: absolute; top: 3px; right: 3px; z-index: 2; background: #dc2626; color: #fff; font-size: 12px; line-height: 1; padding: 2px 4px; border-radius: 6px; box-shadow: 0 1px 2px rgba(0,0,0,.4); }
/* 예상 노출량 패널/표 (게첨보고서) */
.exposure-box:empty { display: none; }
.exposure-inner { margin-top: 12px; padding: 12px 14px; border: 1px solid var(--border-strong, #cbd5e1); border-radius: 12px; background: var(--card-sunken, #f8fafc); }
.exposure-head { margin-bottom: 8px; font-size: 14px; }
.exposure-total { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.exposure-stat { flex: 1 1 200px; padding: 10px 12px; border-radius: 12px; background: var(--accent-ring, rgba(79,70,229,.08)); border: 1px solid var(--accent, #4f46e5); }
.exposure-stat span { display: block; font-size: 12px; color: var(--fg-soft, #64748b); }
.exposure-stat b { font-size: 17px; }
.exposure-stat-dim { background: transparent; border-color: var(--border, #e5e7eb); }
.exposure-stat-dim b { font-size: 13px; font-weight: 500; color: var(--fg-soft, #64748b); }
.exposure-scroll { overflow-x: auto; }
.exposure-tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.exposure-tbl th, .exposure-tbl td { padding: 6px 8px; text-align: left; border-bottom: 1px solid var(--border, #e5e7eb); white-space: nowrap; }
.exposure-tbl th { color: var(--fg-soft, #64748b); font-weight: 600; }
.rd-exposure { padding: 14px 16px; }
/* 대시보드 저장공간 표시/경고 */
.dev-storage { margin-top: 6px; font-size: 12px; color: var(--fg-soft, #64748b); }
.dev-storage.warn { color: #b91c1c; font-weight: 600; }

/* 기기 카드 — 저장 사용량 / 편성량 시각화 (미터 바) */
.dev-usage { margin-top: 10px; display: flex; flex-direction: column; gap: 7px; }
.du-row { display: grid; grid-template-columns: 46px 1fr auto; align-items: center; gap: 9px; }
.du-key { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--fg-muted); }
.du-key svg { width: 12px; height: 12px; flex: none; }
.du-val {
  font-size: 11px; font-weight: 700; color: var(--fg-soft);
  font-variant-numeric: tabular-nums; text-align: right; min-width: 42px;
}
.du-val.du-over { color: var(--red); }
.dev-usage .meter { margin-top: 0; height: 6px; }
.du-nocap { font-size: 11px; color: var(--fg-muted); font-style: italic; }
/* 저장공간 경고 배너 — 좌측 스트라이프 대신 선행 아이콘 칩 + 전체 테두리 */
.storage-warn {
  display: flex; align-items: flex-start; gap: 11px;
  margin: 0 0 16px; padding: 12px 15px; border: 1px solid #f59e0b; border-radius: 12px;
  background: rgba(245,158,11,.10); font-size: 13px; line-height: 1.6; color: #7c4a03;
}
.storage-warn::before {
  content: '⚠'; flex: none; width: 26px; height: 26px; border-radius: 8px;
  display: grid; place-items: center; font-size: 15px;
  background: #f59e0b; color: #fff;
}
.storage-warn b { color: #92400e; }

/* 게첨보고서: 작성/발행 이력 탭 + 이력 목록 */
.rv-tabs { display: flex; gap: 6px; margin: 14px 0 4px; }
.rv-tab { padding: 8px 16px; border: 1px solid var(--border-strong); background: var(--card); border-radius: 8px 8px 0 0; font-weight: 600; font-size: 14px; cursor: pointer; color: var(--fg-soft); }
.rv-tab.active { background: var(--accent, #4f46e5); color: #fff; border-color: var(--accent, #4f46e5); }
.hist-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border: 1px solid var(--border, #e5e7eb); border-radius: 12px; margin-bottom: 8px; background: var(--card, #fff); }
.hist-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.hist-main b { font-size: 14px; }
.hist-meta { font-size: 12px; color: var(--fg-soft); }
.hist-actions { display: flex; gap: 6px; flex: none; }
/* 발행 이력 상세 — STEP 카드처럼 라운드 아웃라인으로 구분 */
.rv-doc-frame { border: 2px solid var(--accent, #4f46e5); border-radius: 16px; padding: 16px; margin-top: 14px; background: var(--card-sunken, #f8fafc); box-shadow: 0 1px 3px rgba(0,0,0,.06); }
.rv-doc-frame-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px dashed var(--border-strong, #cbd5e1); }
.rv-doc-frame-title { font-weight: 800; font-size: 16px; }
@media print { .rv-doc-frame { border: none; padding: 0; margin: 0; background: none; box-shadow: none; } }

/* ── 계정 권한 설정 개편 — ①계정 목록 / ②프리셋 / ③요약 / 저장바 ── */
.cap-layout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 18px; align-items: start; }
@media (max-width: 900px) { .cap-layout { grid-template-columns: 1fr; } }
.cap-step-h { font-weight: 700; font-size: 13px; margin: 0 0 8px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cap-step-h .muted { font-weight: 400; font-size: 12px; }

.acct-list { display: flex; flex-direction: column; gap: 4px; max-height: 420px; overflow: auto; border: 1px solid var(--border); border-radius: 12px; padding: 8px; background: var(--card-sunken); }
.acct-apt { font-size: 12px; font-weight: 700; color: var(--fg-muted); padding: 6px 6px 2px; }
.acct-apt:not(:first-child) { margin-top: 6px; border-top: 1px dashed var(--divider); padding-top: 10px; }
.acct-row { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; width: 100%;
  background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; cursor: pointer; }
.acct-row small { color: var(--fg-muted); font-size: 11px; }
.acct-row:hover { border-color: var(--accent); }
.acct-row.is-sel { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.role-def-entry { margin-top: 10px; border: 1px dashed var(--border); border-radius: 10px; padding: 8px 10px; }
.role-def-entry summary { cursor: pointer; font-size: 12px; color: var(--fg-muted); font-weight: 600; }

.preset-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
.preset-card { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left;
  background: var(--card); border: 2px solid var(--border); border-radius: 14px; padding: 12px 14px; cursor: pointer; min-height: 96px; }
.preset-card small { color: var(--fg-muted); font-size: 11px; line-height: 1.5; }
.preset-card:hover { border-color: var(--accent); }
.preset-card.is-cur { border-color: var(--accent); background: var(--accent-soft); }
.preset-emoji { font-size: 20px; line-height: 1; }
.preset-cur { position: absolute; top: 8px; right: 10px; font-size: 10px; font-weight: 700; color: var(--accent);
  background: var(--card); border: 1px solid var(--accent); border-radius: 99px; padding: 2px 8px; }

.cap-summary { border: 1px solid var(--border); border-radius: 12px; background: var(--card-sunken); padding: 10px 14px; display: flex; flex-direction: column; gap: 6px; }
.cap-sum-line { display: flex; gap: 10px; font-size: 13px; line-height: 1.5; }
.cap-sum-line > b { flex: none; width: 92px; }
.cap-sum-line > span { min-width: 0; }

.cap-adv { margin-top: 14px; border: 1px solid var(--border); border-radius: 12px; padding: 0 14px; }
.cap-adv > summary { cursor: pointer; font-weight: 700; font-size: 13px; padding: 12px 0; list-style-position: inside; }
.cap-adv[open] > summary { border-bottom: 1px solid var(--divider); margin-bottom: 10px; }
.cap-adv .cap-group { margin-bottom: 14px; }

.cap-savebar { position: sticky; bottom: 0; margin-top: 14px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); padding: 10px 14px; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  box-shadow: 0 -4px 14px rgba(0,0,0,.05); z-index: 2; }
.cap-savebar.has-changes { border-color: var(--accent); background: var(--accent-soft); }
.cap-savebar-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; min-width: 0; }
.cap-savebar-btns { display: flex; gap: 8px; flex: none; }
.capch { display: inline-flex; gap: 4px; align-items: center; background: var(--card); border: 1px solid var(--border); border-radius: 99px; padding: 3px 10px; font-size: 11px; }
.capch-on { border-color: oklch(0.75 0.12 150); }
.capch-off { border-color: oklch(0.8 0.09 24); }
.capch small { color: var(--fg-muted); }

/* ── 플레이리스트·편성 사용처 상세 — 어느 기기의 어느 자리에 쓰이는지(접힘) ── */
.use-none { margin: 8px 0 0; padding: 6px 10px; border-radius: 8px; font-size: 12px; font-weight: 600;
  background: var(--amber-soft); border: 1px solid oklch(0.85 0.08 80); color: var(--amber); display: inline-block; }
details.use-det { margin: 8px 0 0; padding-top: 8px; border-top: 1px dashed var(--divider); }
details.use-det > summary { cursor: pointer; font-size: 12px; color: var(--accent); font-weight: 600; list-style-position: inside; }
details.use-det > summary:hover { text-decoration: underline; }
.use-tbl { margin-top: 8px; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.use-tr { display: flex; align-items: center; gap: 8px; padding: 6px 10px; font-size: 12px; border-bottom: 1px solid var(--divider); }
.use-tr:last-child { border-bottom: none; }
.use-tr:nth-child(odd) { background: var(--card-sunken); }
.use-tr .use-d { flex: none; font-weight: 700; min-width: 96px; }
.use-tr .use-w { color: var(--fg-muted); min-width: 0; }
.use-dot { width: 7px; height: 7px; border-radius: 99px; background: var(--green); flex: none; }
.use-dot.off { background: oklch(0.75 0.02 270); }

/* ── 대시보드 제목 옆 단지코드 배지 — 누르면 설치 링크 복사 ── */
.join-chip { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; margin-left: 8px;
  background: var(--accent-soft); border: 1px solid oklch(0.885 0.035 277); color: var(--accent);
  border-radius: 99px; padding: 3px 11px; font-size: 12px; cursor: pointer; line-height: 1.4; }
.join-chip:hover { background: var(--card); }
.join-chip b { font-family: ui-monospace, Menlo, monospace; font-size: 13px; letter-spacing: 0.06em; font-weight: 800; }
.join-chip-k { font-size: 10px; font-weight: 700; opacity: 0.75; }

/* ── 사용자·아파트 관리: 아파트 카드 그리드 (A안) ── */
.apt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 13px; align-items: stretch; }
.apt-grid .apt-nores { grid-column: 1 / -1; }
/* 카드 내부를 '영역'으로 고정해 카드마다 줄 수가 달라도 가로줄이 맞도록 한다.
   (칩이 1줄인 카드는 남는 만큼 공백으로 채워지고, 버튼은 항상 카드 맨 아래) */
.apt-card { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px; margin: 0; height: 100%; }
.apt-card:hover { border-color: oklch(0.82 0.03 273); }
.apt-top { display: flex; align-items: center; gap: 11px; min-height: 46px; flex: none; }
/* 카드 안에서는 아바타/로고를 크게 — 표(28px)용 기본값을 덮어쓴다 */
.apt-card .ent-ava, .apt-card .ent-logo { width: 42px; height: 42px; border-radius: 11px; }
.apt-card .ent-ava svg { width: 21px; height: 21px; }
.apt-id { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.apt-nm { font-weight: 800; font-size: 15px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apt-code { display: inline-flex; align-items: center; gap: 5px; background: var(--accent-soft); color: var(--accent);
  border: 1px solid oklch(0.885 0.035 277); border-radius: 99px; padding: 2px 9px; font-size: 11px; cursor: pointer; }
.apt-code:hover { background: var(--card); }
.apt-code b { font-family: ui-monospace, Menlo, monospace; letter-spacing: 0.05em; font-weight: 800; }
.apt-stat { display: flex; gap: 14px; align-items: center; font-size: 12px; color: var(--fg-muted);
  padding: 8px 0; border-top: 1px dashed var(--divider); border-bottom: 1px dashed var(--divider);
  min-height: 38px; flex: none; }
.apt-stat b { color: var(--fg); font-size: 14px; }
/* 칩 영역 — 2줄 분량을 미리 확보(칩이 적은 카드는 아래가 공백). 3줄 이상이면 자연히 늘어난다 */
.apt-chips { display: flex; flex-wrap: wrap; gap: 5px; align-content: flex-start; min-height: 49px; }
.apt-chip { display: inline-flex; align-items: center; gap: 4px; border-radius: 99px; padding: 2.5px 9px; font-size: 11px;
  background: var(--card-sunken); border: 1px solid var(--border); color: var(--fg-muted); }
.apt-chip.on { background: var(--green-soft); border-color: oklch(0.85 0.08 150); color: var(--green); }
.apt-chip.warn { background: var(--amber-soft); border-color: oklch(0.85 0.08 80); color: var(--amber); }
.apt-owner { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--fg-muted);
  min-height: 34px; flex: none; }
.apt-owner select { flex: 1; min-width: 0; font-size: 12px; padding: 4px 8px; }
.apt-acts { display: flex; gap: 6px; margin-top: auto; padding-top: 2px; }
.apt-acts .btn { flex: 1; }
.apt-acts .apt-kebab { flex: none; width: 34px; }

/* 더보기(⋯) 메뉴 */
.more-list { display: flex; flex-direction: column; gap: 6px; }
.more-item { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; width: 100%;
  background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; cursor: pointer; }
.more-item:hover { border-color: var(--accent); background: var(--accent-soft); }
.more-item small { color: var(--fg-muted); font-size: 11px; }
.more-item.danger:hover { border-color: var(--red); background: var(--red-soft); }
.more-item.danger b { color: var(--red); }

/* 사용자 표 '권한 설정' 요약 칸 */
.cap-sum-cell { display: inline-flex; gap: 4px; flex-wrap: wrap; }

/* 아파트 카드 선택 — 고르면 아래 사용자 목록이 그 아파트 관련 계정으로 좁혀진다 */
.apt-card { cursor: pointer; }
/* 선택 표시 — 테두리 두께를 바꾸면 카드 크기가 흔들리므로 inset 그림자로 굵기를 흉내 낸다 */
.apt-card.is-sel { border-color: var(--accent); background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 3px oklch(0.885 0.035 277 / 0.45); }
.apt-card.is-sel .apt-stat { border-color: oklch(0.885 0.035 277); }
/* 사용자 목록 상단 — 어떤 아파트로 좁혀져 있는지 + [전체 보기] */
.u-tfilter { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  background: var(--accent-soft); border: 1px solid oklch(0.885 0.035 277); border-radius: 10px;
  padding: 8px 12px; margin: 0 0 10px; font-size: 12.5px; }
.u-tfilter-txt { color: var(--accent); }

/* 검색·권한 필터가 걸려 있음을 알리는 줄 — 목록이 줄어든 이유를 말로 알려 오해를 막는다.
   (숫자만 "1 / 6명"으로 바뀌면 계정이 사라진 줄 안다) */
.u-filterbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; width: 100%;
  background: oklch(0.972 0.035 85); border: 1px solid oklch(0.855 0.075 80);
  color: oklch(0.42 0.09 60); border-radius: 10px; padding: 7px 12px; font-size: 12.5px; }
.u-filterbar b { color: oklch(0.36 0.11 55); }

/* ── 대시보드 '최근 7일 현황' — 장애·다운로드가 날짜축을 공유하는 통합 카드 ── */
.wk-card .sum-head { align-items: center; }
.wk-totals { display: flex; gap: 10px; align-items: center; }
.sum-total.acc { color: var(--accent); }
.wk-rowt { display: flex; justify-content: space-between; align-items: center;
  font-size: 11px; font-weight: 700; color: var(--fg-muted); margin: 2px 0 6px; }
.wk-rowt.mt { margin-top: 14px; }
.wk-unit { font-weight: 500; opacity: 0.8; }
.wk-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 7px; }
/* 장애 셀 — 1~2건은 연한 앰버로 조용히, 3건↑ 붉은 틴트, 5건↑ 진한 빨강 */
.wk-f { height: 34px; border-radius: 9px; display: grid; place-items: center;
  font-size: 14px; font-weight: 800; border: 1px solid transparent; }
.wk-f.v0 { background: oklch(0.97 0.012 152); color: oklch(0.62 0.06 152); }
.wk-f.v1 { background: var(--amber-soft); color: oklch(0.5 0.13 70); border-color: oklch(0.88 0.06 82); }
.wk-f.v3 { background: var(--red-soft); color: var(--red); border-color: oklch(0.87 0.05 25); }
.wk-f.v5 { background: var(--red); color: #fff; }
.wk-f.today { box-shadow: 0 0 0 2px var(--accent); }
/* 다운로드 막대 — 최소 높이를 줘 작은 값도 보이게, 라벨은 최대·오늘만 */
/* 위쪽 16px은 값 라벨 전용 여백 — 막대는 그 아래에서만 자라므로 라벨이 제목 줄과 겹치지 않는다
   (전역 border-box라 padding이 높이 안에 포함되고, 막대의 height:100%는 남은 영역 기준이 된다) */
.wk-dslot { height: 60px; padding-top: 16px; display: flex; align-items: flex-end; justify-content: center; }
.wk-d { width: 100%; border-radius: 5px 5px 2px 2px; background: var(--accent); opacity: 0.55; position: relative; }
.wk-d.today { opacity: 1; }
.wk-d b { position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  font-size: 9.5px; line-height: 1; color: var(--accent); white-space: nowrap; font-weight: 700; }
.wk-axis { height: 1px; background: var(--divider); margin-top: 0; }
.wk-labels { margin-top: 7px; }
.wk-labels span { text-align: center; font-size: 10.5px; color: var(--fg-muted); }
.wk-labels span.today { color: var(--accent); font-weight: 800; }
