/* ══════════════════════════════════════════════════════════════════════════
   skin_yongin.css — 용인 사이트 전용 스킨 (밝은 뉴트럴 + 로그인 에메랄드)

   ⚠ 전부 `body.skin-yongin` 스코프다. 이 클래스는 index.html 부트스트랩이
     `SiteConfig.get('skin') === 'yongin'` 일 때만 붙인다 → 기존 Pi 사이트는
     이 파일이 로드돼도 한 규칙도 적용되지 않는다(무영향).
     되돌리려면 서버 settings.yaml 의 `site.layout.skin` 한 줄만 지우면 된다.

   ── 색 규칙 (이 스킨의 계약) ──────────────────────────────────────────────
   지표색은 **역할별로 세 벌**이다. 하나로 겸용하면 반드시 어딘가 대비가 깨진다.
     --yg-c-*      호(arc)·그래픽 : 밝은 톤        (트랙 대비는 도트가 책임)
     --yg-c-*-dot  값 위치 표시    : 트랙 대비 3:1
     --yg-c-*-tx   글자           : 흰 배경 4.5:1
   유리(팝업) 위에서는 흰 카드용 글자색이 4.5:1 을 못 넘는다 → `.yg-pop` 안에서
   토큰을 한 단 더 낮춘다(파일 하단).
   ══════════════════════════════════════════════════════════════════════════ */

body.skin-yongin {
  --yg-bg:        #f5f7fa;
  --yg-surface:   #ffffff;
  --yg-surface-2: #fafbfd;
  --yg-line:      #e6eaf0;
  --yg-line-2:    #eef1f6;
  --yg-line-mute: #c2cddb;   /* 미연동 카드 테두리. 면이 페이지색에 가까워
                                기본 --yg-line(페이지 대비 1.13:1)으로는 윤곽이 안 보인다 */
  --yg-tx:        #0f172a;
  --yg-tx2:       #475569;
  --yg-tx3:       #5f6b7d;
  --yg-accent:    #10b981;   /* 로그인 login-btn 과 같은 에메랄드 */
  --yg-accent-2:  #34d399;
  --yg-accent-sf: #ecfdf5;
  --yg-accent-dp: #047857;
  --yg-ring:      rgba(52, 211, 153, .22);   /* login-input:focus 와 동일 */
  --yg-warn:      #f9a826;
  --yg-warn-dot:  #ba7e1c;
  --yg-warn-sf:   #fef3c7;
  --yg-warn-tx:   #b45309;

  --yg-c-temp: #fa8f6e;  --yg-c-temp-dot: #c97359;  --yg-c-temp-tx: #a76049;
  --yg-c-hum:  #63b3e8;  --yg-c-hum-dot:  #5091bc;  --yg-c-hum-tx:  #43789c;
  --yg-c-vpd:  #c085d4;  --yg-c-vpd-dot:  #ab76bd;  --yg-c-vpd-tx:  #8e629d;
  --yg-c-co2:  #48c9a0;  --yg-c-co2-dot:  #379b7b;  --yg-c-co2-tx:  #2e8066;
  --yg-c-pfd:  #f0c651;  --yg-c-pfd-dot:  #a38737;  --yg-c-pfd-tx:  #87702e;
  --yg-c-ec:   #b98fe0;  --yg-c-ec-dot:   #9f7bc1;  --yg-c-ec-tx:   #8466a0;
  --yg-c-ph:   #f7a76b;  --yg-c-ph-dot:   #b87c50;  --yg-c-ph-tx:   #996842;

  --yg-shadow:    0 1px 2px rgba(16,24,40,.04), 0 10px 22px -14px rgba(16,24,40,.28);
  --yg-shadow-lg: 0 1px 2px rgba(16,24,40,.05), 0 22px 44px -18px rgba(16,24,40,.36);
  --yg-r:         16px;
  --yg-r-sm:      11px;
}

/* ── 셸: renewal 의 보라 그라디언트를 걷어낸다 ───────────────────────────── */
body.skin-yongin,
body.skin-yongin .layout,
body.skin-yongin .main,
/* renewal 이 .content 에 두른 **시안 네온 링**을 걷어낸다.
   renewal.css 스스로 "시안 네온 링"이라 부르는 그 프레임이다
   (`body.renewal:not([data-page="overview"]) .content` — 2px 시안 테두리 +
   18px 글로우 + blur + 20px 라운드 + 바깥 여백). 배경만 덮고 테두리·글로우를
   그대로 두는 바람에, 밝은 용인 화면 바깥에 **파란 네온 테**가 계속 남아 있었다.
   화면마다 다르게 보인 건 프레임이 페이지마다 다른 게 아니라, 안쪽 내용이
   프레임을 얼마나 가리느냐가 달랐기 때문이다. */
body.skin-yongin .content {
  background: var(--yg-bg) !important;
  color: var(--yg-tx);
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  margin: 0 !important;
}
/* 상단바 로고 타일 — 보라 그라디언트 + 보라 글로우. 용인 브랜드와 어긋난다. */
body.skin-yongin .topbar-logo-icon {
  background: var(--yg-accent) !important;
  background-image: none !important;
  box-shadow: none !important;
}
body.skin-yongin .nav-item.active { box-shadow: none !important; }
/* 옛 설비 제어 화면의 서브탭 바 — 용인은 상단바 탭이 그 역할을 한다. 둘 다 두면
   같은 버튼 네 개가 위아래로 겹쳐 보인다. */
body.skin-yongin .ctrl-subtab-bar { display: none !important; }
body.skin-yongin .content::before,
body.skin-yongin .content::after { display: none !important; }
body.skin-yongin[data-page="overview"] .content { padding: 16px 18px 18px; }
body.skin-yongin .sidebar,
body.skin-yongin .topbar {
  background: var(--yg-surface) !important;
  border-color: var(--yg-line) !important;
  box-shadow: none !important;
}
body.skin-yongin .sidebar { color: var(--yg-tx2); }
body.skin-yongin .nav-item,
body.skin-yongin .nav-sub-item { color: var(--yg-tx2) !important; }
body.skin-yongin .nav-item.active,
body.skin-yongin .nav-sub-item.active {
  background: var(--yg-accent-sf) !important;
  color: var(--yg-accent-dp) !important;
}
body.skin-yongin .sidebar-logo-ci { mix-blend-mode: multiply; }
body.skin-yongin .topbar-nav { background: var(--yg-line-2); }
body.skin-yongin .topbar-nav-btn { color: var(--yg-tx2); }
body.skin-yongin .topbar-nav-btn.active {
  background: var(--yg-surface); color: var(--yg-accent-dp); box-shadow: var(--yg-shadow);
}
body.skin-yongin :focus-visible { outline: none; box-shadow: 0 0 0 3px var(--yg-ring); }

/* ══ 오버뷰 ══════════════════════════════════════════════════════════════ */
body.skin-yongin .yg-wrap { display: flex; flex-direction: column; height: 100%; gap: 14px; min-height: 0; }

/* ── 상태 바: 실외 · 룸 · 양액을 하나의 판 위 그리드로 ────────────────────
   흰 pill 을 여러 개 띄우면 배경 위에서 앵커 없이 떠 보인다. 한 장의 카드에
   1px 간극을 구분선으로 써야 줄바꿈이 일어나도 열이 어긋나지 않는다. */
.yg-statusbar {
  flex: none; display: grid; gap: 1px; grid-template-columns: repeat(8, 1fr);
  background: var(--yg-line); border: 1px solid var(--yg-line); border-radius: var(--yg-r);
  overflow: hidden; box-shadow: var(--yg-shadow);
}
.yg-cell { position: relative; background: var(--yg-surface); padding: 10px 13px 9px;
           min-width: 0; transition: background .15s; }
.yg-cell-out { grid-column: span 2; background: var(--yg-surface-2); }
.yg-cell-nut { grid-column: span 2; }
.yg-cell-room { cursor: pointer; }
.yg-cell-room:hover { background: #f6fdfa; }
.yg-cell-room.on { background: linear-gradient(180deg, #f0fdf7, #fff 66%); }
.yg-cell-room.on::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
                           background: var(--yg-accent); }

.yg-ch { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; min-width: 0; }
.yg-ch .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--yg-accent);
              box-shadow: 0 0 0 3px rgba(16,185,129,.14); }
.yg-ch.warn .dot { background: var(--yg-warn); box-shadow: 0 0 0 3px rgba(249,168,38,.18); }
.yg-ch .nm { font-size: 13px; font-weight: 800; letter-spacing: -.2px; }
.yg-ch .sub { font-size: 10px; color: var(--yg-tx3); white-space: nowrap;
              overflow: hidden; text-overflow: ellipsis; }
.yg-ch .bg { margin-left: auto; font-size: 9.5px; font-weight: 800; padding: 2px 7px;
             border-radius: 6px; white-space: nowrap; }
.yg-ch .bg.ok { background: var(--yg-line-2); color: var(--yg-tx2); }
.yg-ch .bg.bad { background: var(--yg-warn-sf); color: var(--yg-warn-tx); }

.yg-gauges { display: flex; gap: 6px; flex-wrap: wrap; }
/* 게이지는 `viewBox="0 0 60 44"` 고정이라 **컨테이너를 키우면 안의 숫자·호가 함께
   커진다**. 60px 에서는 호 안에 값·단위·목표가 겹쳐 보여 답답하다는 지적을 받았다. */
.yg-g { width: 74px; flex: none; text-align: center; }
.yg-g .gk { font-size: 9.5px; font-weight: 800; margin-bottom: 2px; }
.yg-g svg { display: block; width: 74px; height: 54px; }

.yg-nutbody { display: flex; align-items: center; gap: 10px; }
.yg-badlist { display: flex; flex-wrap: wrap; gap: 5px; min-width: 0; }
.yg-badpill { font: inherit; font-size: 10px; font-weight: 700; cursor: pointer; white-space: nowrap;
              padding: 4px 9px; border-radius: 8px; background: var(--yg-warn-sf);
              border: 1px solid #fcd34d; color: var(--yg-warn-tx); }
.yg-badpill:hover { background: #fde68a; }
.yg-allok { font-size: 10.5px; font-weight: 700; color: var(--yg-accent-dp); }

/* ── 본문 2열 ─────────────────────────────────────────────────────────── */
.yg-body { flex: 1; display: flex; gap: 14px; min-height: 0; }
.yg-stage { flex: 1; position: relative; min-width: 0; border-radius: var(--yg-r); overflow: hidden;
            background: #dfe5ed; border: 1px solid var(--yg-line); box-shadow: var(--yg-shadow); }
.yg-canvas { position: absolute; inset: 0; }
/* 로그인 카드의 유리 질감은 사진/3D 위에서만 의미가 있다 → HUD·팝업에만 계승 */
.yg-hud { position: absolute; z-index: 4; font-size: 10px; font-weight: 600; color: var(--yg-tx2);
          background: rgba(255,255,255,.72); border: 1px solid rgba(255,255,255,.9);
          border-radius: 9px; padding: 5px 10px; pointer-events: none;
          backdrop-filter: blur(12px) saturate(1.3); -webkit-backdrop-filter: blur(12px) saturate(1.3);
          box-shadow: 0 2px 10px rgba(16,24,40,.1); }
.yg-hud.tl { top: 12px; left: 12px; } .yg-hud.tr { top: 12px; right: 12px; }
.yg-hud.bl { bottom: 12px; left: 12px; }
#yg-autopop { position: absolute; top: 44px; right: 12px; pointer-events: auto; cursor: pointer;
              font-size: 10px; font-weight: 700; }
#yg-autopop.on { color: var(--yg-accent-dp); border-color: rgba(16,185,129,.45);
                 background: rgba(236,253,245,.85); }

/* ── 우측 패널 (룸 → 랙 계층) ─────────────────────────────────────────── */
.yg-panel { width: 348px; flex: none; display: flex; flex-direction: column; gap: 12px;
            overflow-y: auto; padding-right: 2px; }
.yg-card { background: var(--yg-surface); border: 1px solid var(--yg-line); border-radius: var(--yg-r);
           padding: 13px 15px; box-shadow: var(--yg-shadow); }
.yg-card > .h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 11px; }
.yg-card > .h .t { font-size: 14px; font-weight: 800; letter-spacing: -.2px; }
.yg-card > .h .s { font-size: 10.5px; color: var(--yg-tx3); }
.yg-card > .h .r { margin-left: auto; font-size: 10px; color: var(--yg-tx3); }

/* 4실 비교 트랙 — 게이지를 더 얹으면 화면이 계기판이 된다. 지표당 4px 선 하나. */
.yg-cmp { margin-bottom: 11px; }
.yg-cmp:last-child { margin-bottom: 0; }
.yg-cmp-h { display: flex; align-items: baseline; gap: 6px; margin-bottom: 6px; }
.yg-cmp-h .k { font-size: 9.5px; font-weight: 800; }
.yg-cmp-h .sp { font-size: 9px; color: var(--yg-tx3); }
.yg-cmp-h .v { margin-left: auto; font-size: 16px; font-weight: 800; letter-spacing: -.35px; }
.yg-cmp-h .v .u { font-size: 9px; color: var(--yg-tx3); margin-left: 1px; font-weight: 700; }
.yg-cmp-t { position: relative; height: 4px; border-radius: 3px; background: var(--yg-line);
            margin: 0 6px 2px; }
.yg-cmp-t .band { position: absolute; top: 0; bottom: 0; border-radius: 3px;
                  background: rgba(52,211,153,.34); }
.yg-cmp-t .tick { position: absolute; top: -3px; bottom: -3px; width: 1.5px; border-radius: 2px;
                  background: #6b7789; opacity: .95; }
.yg-cmp-t .d { position: absolute; top: 50%; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
               border-radius: 50%; background: #aab4c2; }
.yg-cmp-t .d.on { width: 12px; height: 12px; margin: -6px 0 0 -6px; border: 2.5px solid #fff;
                  box-shadow: 0 1px 5px rgba(16,24,40,.4); z-index: 2; }

.yg-secl { font-size: 10px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .04em;
           margin: 12px 0 7px; }
.yg-rackchips { display: flex; flex-wrap: wrap; gap: 6px; }
.yg-rackchip { font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; padding: 6px 11px;
               border-radius: var(--yg-r-sm); color: var(--yg-tx2);
               background: var(--yg-surface-2); border: 1px solid var(--yg-line); }
.yg-rackchip:hover { border-color: #a7f3d0; background: #f0fdf9; }
.yg-rackchip.on { background: var(--yg-accent-sf); border-color: var(--yg-accent);
                  color: var(--yg-accent-dp); }
.yg-rackchip.off { opacity: .5; }
.yg-rackchip .w { color: var(--yg-warn-tx); }

.yg-kind { display: inline-block; font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 6px; }
.yg-kind.gutter { background: var(--yg-accent-sf); color: var(--yg-accent-dp); }
.yg-kind.tank   { background: #eff6ff; color: #1d4ed8; }

.yg-cropbadge { font: inherit; font-size: 10px; font-weight: 800; cursor: pointer; padding: 4px 10px;
                border-radius: 8px; border: 1px solid transparent;
                display: inline-flex; align-items: center; gap: 6px; }
.yg-cropbadge:hover { border-color: var(--yg-accent); box-shadow: 0 0 0 3px var(--yg-ring); }
.yg-cropbadge .d { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.yg-cropbadge.none { background: var(--yg-line-2); color: var(--yg-tx3); }

.yg-tank { display: flex; align-items: center; gap: 10px; padding: 9px 11px;
           border-radius: var(--yg-r-sm); background: var(--yg-surface-2);
           border: 1px solid var(--yg-line); flex-wrap: wrap; }
.yg-tank.bad { background: #fffbeb; border-color: #fcd34d; }
.yg-tank .id { font-size: 11px; font-weight: 800; color: var(--yg-c-ec-tx); white-space: nowrap; }
.yg-tank .m { display: flex; align-items: baseline; gap: 3px; }
.yg-tank .m .k { font-size: 9.5px; font-weight: 700; color: var(--yg-tx3); }
.yg-tank .m .v { font-size: 15px; font-weight: 800; }
.yg-tank .m .v.bad { color: var(--yg-warn-tx); }
.yg-tank .st { margin-left: auto; font-size: 9.5px; font-weight: 800; padding: 2px 8px;
               border-radius: 6px; background: var(--yg-accent-sf); color: var(--yg-accent-dp);
               white-space: nowrap; }
.yg-tank.bad .st { background: var(--yg-warn-sf); color: var(--yg-warn-tx); }

/* 3단 = 표(행). 카드 스택보다 층 비교가 쉽고 세로를 아낀다.
   셀 배경 막대는 그 랙 3단의 국지 스케일 → 층간 기울기가 보인다. */
.yg-tiers { width: 100%; border-collapse: collapse; margin-top: 11px; }
.yg-tiers th { font-size: 9.5px; font-weight: 800; color: var(--yg-tx3); text-align: right;
               padding: 4px 6px; border-bottom: 1px solid var(--yg-line); white-space: nowrap; }
.yg-tiers th:first-child { text-align: left; }
.yg-tiers td { padding: 9px 6px; text-align: right; font-weight: 800; font-size: 14px;
               border-bottom: 1px solid var(--yg-line-2); }
.yg-tiers td:first-child { text-align: left; font-size: 11.5px; font-weight: 700; color: var(--yg-tx2); }
.yg-tiers tr:last-child td { border-bottom: none; }
.yg-tiers .sub { display: block; font-size: 9px; color: var(--yg-tx3); font-weight: 600; }

.yg-offline { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 22px 10px; }
.yg-offline .b { font-size: 11px; font-weight: 800; letter-spacing: .1em; color: var(--yg-warn-tx);
                 background: var(--yg-warn-sf); border-radius: 20px; padding: 3px 12px; }
.yg-offline .m { font-size: 10.5px; color: var(--yg-tx3); }

/* ── 재배 현황 팝업 (유리 · 드래그 이동) ───────────────────────────────
   알파를 .86 같은 값으로 두면 밝은 스테이지 위에서 비침이 안 보인다.
   .62 로 낮추고, 떨어진 대비는 아래 토큰 재정의로 되찾는다. */
.yg-pop {
  position: absolute; z-index: 8; left: 14px; top: 46px; width: 366px; max-width: calc(100% - 28px);
  background: rgba(255,255,255,.62); border: 1px solid rgba(255,255,255,.88);
  border-radius: var(--yg-r);
  backdrop-filter: blur(9px) saturate(1.35) brightness(1.1);
  -webkit-backdrop-filter: blur(9px) saturate(1.35) brightness(1.1);
  box-shadow: var(--yg-shadow-lg), inset 0 1px 0 rgba(255,255,255,.7);
  overflow: hidden; animation: ygPop .16s ease-out;
  /* 유리 위 글자용 — 흰 카드용보다 한 단 진하다 */
  --yg-tx3: #45505f; --yg-tx2: #313d51; --yg-accent-dp: #024a36;
}
@keyframes ygPop { from { opacity: 0; transform: translateY(-6px) scale(.985); } }
/* 좁은 폭에서는 패널 카드로 강등된다(JS 가 DOM 위치를 옮긴다) → 뒤에 3D 가 없으니 불투명 */
.yg-pop.static { position: static; width: auto; max-width: none; background: var(--yg-surface);
                 backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: var(--yg-shadow); }
.yg-pop .ph { display: flex; align-items: center; gap: 8px; padding: 10px 13px;
              border-bottom: 1px solid var(--yg-line); background: rgba(250,251,253,.42);
              cursor: grab; user-select: none; touch-action: none; }
.yg-pop.drag .ph { cursor: grabbing; }
.yg-pop.drag { box-shadow: 0 1px 2px rgba(16,24,40,.06), 0 30px 60px -20px rgba(16,24,40,.5); }
.yg-pop.static .ph, .yg-pop.static .pf { background: var(--yg-surface-2); }
.yg-pop.static .ph { cursor: default; }
.yg-pop.static .ph .grip { display: none; }
.yg-pop .ph .grip { color: var(--yg-tx3); font-size: 13px; line-height: 1; letter-spacing: -3px; flex: none; }
.yg-pop .ph .t { font-size: 12.5px; font-weight: 800; }
.yg-pop .ph .s { font-size: 10px; color: var(--yg-tx3); }
.yg-pop .ph .x { margin-left: auto; cursor: pointer; border: none; background: transparent;
                 font-size: 15px; line-height: 1; color: var(--yg-tx3); padding: 2px 4px; }
.yg-pop .ph .x:hover { color: var(--yg-tx); }
.yg-pop .pb { padding: 12px 13px; }
.yg-pop .pf { padding: 9px 13px; border-top: 1px solid var(--yg-line);
              background: rgba(250,251,253,.42); display: flex; align-items: center; gap: 8px; }
.yg-pop .pf .hint { font-size: 9.5px; color: var(--yg-tx3); }
/* login-btn 의 문법(에메랄드 그라디언트+글로우)은 잇되 램프를 낮춘다 —
   로그인의 #10b981 위 흰 글자는 2.56:1 로 밝은 화면에서 못 쓴다. */
.yg-pop .pf .edit { margin-left: auto; font-size: 11px; font-weight: 700; padding: 6px 14px;
                    border-radius: var(--yg-r-sm); cursor: pointer; color: #fff; border: none;
                    background: linear-gradient(120deg, #047857, #065f46);
                    box-shadow: 0 6px 18px rgba(4,120,87,.32); }
.yg-pop .pf .edit:hover { filter: brightness(1.08); }

.yg-crop { display: flex; align-items: center; gap: 9px; }
.yg-crop .leaf { width: 28px; height: 28px; border-radius: 9px; flex: none;
                 display: flex; align-items: center; justify-content: center; font-size: 14px; }
.yg-crop .nm { font-size: 15px; font-weight: 800; }
.yg-crop .var { font-size: 10.5px; color: var(--yg-tx3); }
.yg-crop .exp { margin-left: auto; font-size: 9.5px; font-weight: 800; color: #6d28d9;
                background: #f5f3ff; border-radius: 6px; padding: 3px 9px; white-space: nowrap; }
.yg-prog { margin-top: 10px; }
.yg-prog .bar { height: 6px; border-radius: 20px; background: var(--yg-line); overflow: hidden; }
.yg-prog .bar i { display: block; height: 100%; border-radius: 20px; }
.yg-prog .lg { display: flex; justify-content: space-between; font-size: 9.5px;
               color: var(--yg-tx3); margin-top: 5px; }
.yg-prog .lg b { color: var(--yg-tx); font-size: 11px; }

.yg-cond { width: 100%; border-collapse: collapse; margin-top: 12px; }
.yg-cond th { font-size: 9px; font-weight: 800; color: var(--yg-tx3); text-align: left;
              padding: 3px 5px; border-bottom: 1px solid var(--yg-line); }
.yg-cond th.r, .yg-cond td.r { text-align: right; }
.yg-cond td { font-size: 11.5px; padding: 7px 5px; border-bottom: 1px solid var(--yg-line-2); }
.yg-cond td.k { color: var(--yg-tx3); font-weight: 700; font-size: 10.5px; white-space: nowrap; }
.yg-cond td.tgt, .yg-cond td.act { font-weight: 800; }
.yg-cond td.act.ok { color: var(--yg-accent-dp); }
.yg-cond td.act.bad { color: #7c3d05; }   /* 유리 위 기준 — 흰 카드용 #b45309 는 2.8:1 */
.yg-cond td.act.na { color: var(--yg-tx3); font-weight: 600; }
.yg-cond tr:last-child td { border-bottom: none; }

.yg-croplist { width: 100%; border-collapse: collapse; }
.yg-croplist td { font-size: 11.5px; padding: 7px 4px; border-bottom: 1px solid var(--yg-line-2); }
.yg-croplist tr:last-child td { border-bottom: none; }
.yg-croplist tr { cursor: pointer; }
.yg-croplist tr:hover td { background: #f0fdf9; }
.yg-croplist tr.on td { background: var(--yg-accent-sf); }
.yg-croplist .rk { font-weight: 800; color: var(--yg-tx2); white-space: nowrap; }
.yg-croplist .cp { font-weight: 700; }
.yg-croplist .dd { color: var(--yg-tx3); text-align: right; white-space: nowrap; }
.yg-croplist .st { text-align: right; font-size: 10px; font-weight: 800; white-space: nowrap; }
.yg-croplist .st.ok { color: var(--yg-accent-dp); }
.yg-croplist .st.bad { color: #7c3d05; }
.yg-croplist .none { color: var(--yg-tx3); font-weight: 600; }

/* ── 반응형 ─────────────────────────────────────────────────────────── */
@media (max-width: 1200px) { .yg-statusbar { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 900px) {
  .yg-body { flex-direction: column; overflow-y: auto; }
  .yg-stage { flex: none; height: 320px; }
  .yg-panel { width: 100%; overflow: visible; }
}
@media (max-width: 700px) {
  .yg-statusbar { grid-template-columns: repeat(2, 1fr); }
  .yg-cell { padding: 8px 10px 7px; }
  .yg-ch { margin-bottom: 4px; } .yg-ch .nm { font-size: 12px; }
  .yg-gauges { gap: 3px; }
  .yg-g { width: 50px; } .yg-g svg { width: 50px; height: 35px; }
  .yg-stage { height: 260px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   셸 — 64px 아이콘 레일 + 상단 서브탭 (YGShell 이 DOM 을 만든다)

   원본 사이드바는 그룹(.nav-item)과 하위(.nav-sub-item)를 **한 열에 다** 쌓는다.
   그 두 층을 두 축으로 나눈다: 좌측 = 그룹 / 상단 = 그 그룹의 화면.
   콘텐츠 가로가 200px → 64px 로 136px 넓어진다.

   ⚠ 원본 topbar-nav 3개(scada·control·analytics)는 여기서 숨긴다. YGShell 의 탭이
     7개 그룹 전부를 덮으므로 중복이고, 남겨두면 두 줄이 겹쳐 보인다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .sidebar { width: 70px !important; padding: 10px 0; align-items: center; }
body.skin-yongin .sidebar-nav { display: none !important; }   /* 원본 메뉴 — 레일이 대신한다 */
body.skin-yongin .sidebar-toggle { display: none !important; } /* 64px 에서 더 접을 것이 없다 */
body.skin-yongin .sidebar-header { justify-content: center; padding: 0 0 10px; width: 100%; }
body.skin-yongin .sidebar-logo-ci { display: none; }
/* 로그인 히어로의 '&' 를 브랜드 마크로 — 워드마크(92px)는 64px 레일에 안 들어간다 */
body.skin-yongin .sidebar-logo {
  width: 36px; height: 36px; border-radius: 11px; overflow: hidden;
  background: linear-gradient(120deg, #10b981, #059669);
  box-shadow: 0 6px 18px rgba(5,150,105,.32);
  display: flex; align-items: center; justify-content: center;
}
body.skin-yongin .sidebar-logo::after {
  content: '&'; color: #fff; font-size: 20px; font-weight: 900; letter-spacing: -.5px;
}

.yg-rail { flex: 1 1 auto; min-height: 0; overflow-y: auto; width: 100%;
           display: flex; flex-direction: column; align-items: center; gap: 3px; }
/* 크기: 아이콘·글자를 아주 살짝 키웠다(17→19px / 8→9px). 띠 폭도 함께 늘렸는데,
   활성 표시(`.on::before`)가 항목 왼쪽 -9px 에 붙기 때문이다 — 폭을 안 늘리면
   그 막대가 띠 밖으로 나가 잘린다. (70-52)/2 = 9 로 딱 맞춘다. */
.yg-rail-it {
  width: 52px; height: 50px; border: none; background: transparent; border-radius: 12px;
  color: var(--yg-tx3); cursor: pointer; position: relative; flex: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  transition: background .14s, color .14s;
}
.yg-rail-it:hover { background: var(--yg-line-2); color: var(--yg-tx2); }
.yg-rail-it.on { background: var(--yg-accent-sf); color: var(--yg-accent-dp); }
.yg-rail-it.on::before { content: ''; position: absolute; left: -9px; top: 10px; bottom: 10px;
                         width: 3px; border-radius: 0 3px 3px 0; background: var(--yg-accent); }
.yg-rail-it .lb { font-size: 9px; font-weight: 800; letter-spacing: -.2px; white-space: nowrap; }

/* 원본 상단 탭 3그룹은 숨긴다 — YGShell 탭이 7그룹 전부를 덮는다 */
body.skin-yongin .topbar-nav { display: none !important; }
.yg-tabs { display: flex; gap: 2px; background: var(--yg-line-2); padding: 3px;
           border-radius: 10px; overflow-x: auto; max-width: 100%; }
.yg-tab { font: inherit; font-size: 12px; font-weight: 700; padding: 6px 12px; border-radius: 8px;
          border: none; background: transparent; color: var(--yg-tx2); cursor: pointer; white-space: nowrap; }
.yg-tab:hover { color: var(--yg-tx); }
.yg-tab.on { background: var(--yg-surface); color: var(--yg-accent-dp); box-shadow: var(--yg-shadow); }

@media (max-width: 700px) {
  /* 모바일은 기존 햄버거 오버레이가 사이드바를 밀어 넣는다 — 레일 그대로 쓰면 된다 */
  .yg-tabs { order: 3; width: 100%; }
  .yg-rail-it .lb { display: none; }
}

/* ── 상단 브랜드 + LIVE ────────────────────────────────────────────────
   원본 topbar 의 .topbar-logo(Plant OS 아이콘+텍스트)는 숨기고 CI 워드마크를 쓴다.
   로그인 카드의 farmn 로고와 같은 자산이라 로그인 → 대시보드 브랜드가 이어진다. */
body.skin-yongin .topbar { gap: 14px; padding: 0 18px; align-items: center; }
body.skin-yongin .topbar-logo { display: none !important; }
.yg-brand { display: flex; align-items: center; gap: 12px; flex: none; }
.yg-brand .ci {
  width: 84px; height: 30px; flex: none;
  background: url('/img/farmn_ci_white.png') no-repeat left center / contain;
  mix-blend-mode: multiply;   /* 흰 배경 PNG 를 흰 topbar 에 녹인다(style.css 라이트 규칙과 동일) */
}
.yg-brand .div { width: 1px; height: 22px; background: var(--yg-line); flex: none; }
.yg-brand .ttl { font-size: 15px; font-weight: 800; letter-spacing: -.3px; white-space: nowrap;
                 color: var(--yg-tx); }
.yg-live { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none;
           font-size: 11px; color: var(--yg-tx3); white-space: nowrap; }
.yg-live .lv { display: inline-flex; align-items: center; gap: 5px; font-weight: 700;
               color: var(--yg-accent-dp); }
.yg-live .lv i { width: 6px; height: 6px; border-radius: 50%; background: var(--yg-accent);
                 box-shadow: 0 0 0 3px rgba(16,185,129,.16); }
.yg-live .up:not(:empty)::before { content: '· '; }
@media (max-width: 900px) { .yg-live .up { display: none; } }
@media (max-width: 700px) { .yg-brand .ttl, .yg-live { display: none; } }
.yg-nodata { font-size: 10.5px; font-weight: 600; color: var(--yg-tx3); }
.yg-rackchip .o { color: var(--yg-tx3); font-weight: 900; }

/* ══════════════════════════════════════════════════════════════════════════
   셸 마감 — 글꼴 · 경계선 · 상단바 높이
   ══════════════════════════════════════════════════════════════════════════ */

/* ① 글꼴 — style.css 는 'Inter' 를 쓰는데 **Inter 에는 한글 글리프가 없다.**
   그래서 한글이 브라우저 기본 폰트로 폴백되어 데모와 다른 얼굴·굵기로 보였다.
   데모와 같은 스택으로 고정한다(Pretendard 없으면 Windows 는 Malgun Gothic 으로 간다). */
body.skin-yongin,
body.skin-yongin button,
body.skin-yongin input,
body.skin-yongin select,
body.skin-yongin textarea,
body.skin-yongin table {
  font-family: "Pretendard", "Pretendard Variable", -apple-system, BlinkMacSystemFont,
               "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* 숫자는 자릿수가 흔들리면 표가 떨린다 — 표·게이지는 등폭 숫자로 */
body.skin-yongin .yg-tiers,
body.skin-yongin .yg-cond,
body.skin-yongin .yg-croplist,
body.skin-yongin .yg-cmp-h .v,
body.skin-yongin .yg-tank .m .v { font-variant-numeric: tabular-nums; }

/* ② 구분 실선 — renewal 이 `border: none` 으로 지운다(그라디언트 사이드바 전제).
   밝은 판에서는 면과 면 사이에 선이 있어야 구조가 읽힌다. shorthand 로 되살린다. */
/* ⚠ 사이드바에 우측 실선을 주면 그 선이 **다크 헤더 띠를 세로로 관통**해
   좌상단이 잘려 보인다. 선은 띠 아래(.yg-rail)에만 둔다. */
body.skin-yongin .sidebar { border-right: none !important; box-shadow: none !important; }
body.skin-yongin .yg-rail { border-right: 1px solid var(--yg-line); }
body.skin-yongin .topbar  { border-bottom: 1px solid var(--yg-line) !important; }

/* ③ 상단바 높이 — 지금은 높이가 없어 **탭 박스가 상단바 높이를 정한다** → 탭 위아래
   여백이 0 이라 답답해 보였다. 높이를 먼저 정하고 탭을 그 안에 앉힌다. */
body.skin-yongin .topbar {
  height: 58px; min-height: 58px; padding: 0 18px;
  align-items: center; overflow: visible;
}
body.skin-yongin .yg-tabs { padding: 3px; }
body.skin-yongin .yg-tab { padding: 6px 13px; line-height: 1.2; }

/* 목표 대비 편차 — 게이지 아래 한 줄 (▲ 초과 / ▼ 미달 / · 도달) */
.yg-g .dv { font-size: 9px; font-weight: 800; line-height: 1.3; margin-top: 1px;
            color: var(--yg-tx3); letter-spacing: -.2px; white-space: nowrap; }
.yg-g .dv.eq  { color: var(--yg-accent-dp); }   /* 목표 도달 */
.yg-g .dv.bad { color: var(--yg-warn-tx); }     /* 허용 범위 밖 */

/* ══════════════════════════════════════════════════════════════════════════
   상단 헤더 밴드 — 로그인 화면의 다크 시네마틱 톤을 잇는다.

   로그인은 `#070b11` 위 유리 카드 + 에메랄드다. 본문은 장시간 데이터를 읽는 화면이라
   밝게 두되, **머리 띠만 어둡게** 해서 진입 화면의 인상을 화면 상단에 남긴다.
   좌측 레일의 머리(.sidebar-header)까지 같은 색으로 칠해 **띠가 전폭으로 이어지게** 한다
   — 상단바만 어둡게 하면 좌상단에 흰 사각형이 남아 띠가 끊겨 보인다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin {
  --yg-hd:      linear-gradient(180deg, #131e2b 0%, #0c141e 100%);
  --yg-hd-line: rgba(255, 255, 255, .09);
  --yg-hd-tx:   #f1f5f9;
  --yg-hd-tx2:  #a8b6c8;   /* 다크 위 4.5:1 이상 (#94a3b8 은 4.45 라 미달) */
  --yg-hd-tx3:  #93a7c2;
  --yg-hd-ac:   #6ee7b7;   /* 다크 위 에메랄드 — 로그인 히어로의 #34d399 계열 */
}
/* 다크는 **상단바에만**. 겹치는 머리(.sidebar-header)는 좌측 컬럼의 톤을 따른다
   — 좌측 컬럼(머리 + 레일)이 하나의 밝은 판으로 읽히고, 다크 띠는 그 오른쪽에서
   시작한다. 흰↔다크 색 경계 자체가 구분선이라 그 자리엔 선을 덧대지 않는다. */
body.skin-yongin .topbar {
  background-color: #0f1823 !important;          /* 그라디언트 미지원/덮임 대비 바탕색 */
  background-image: var(--yg-hd) !important;
  border-bottom: 1px solid var(--yg-hd-line) !important;
  color: var(--yg-hd-tx);
}
body.skin-yongin .sidebar-header {
  background-color: var(--yg-surface) !important;
  background-image: none !important;
  color: var(--yg-tx);
  /* 좌측 컬럼의 세로 실선을 머리에서도 이어 붙인다 — 레일에만 주면 선이 y=58 에서
     시작해 끊겨 보인다. */
  border-right: 1px solid var(--yg-line);
  border-bottom: 1px solid var(--yg-line);
  /* 상단바와 **같은 높이**여야 아래 모서리가 한 줄로 맞는다. 어긋나면 계단이 생긴다. */
  height: 58px; min-height: 58px; padding: 0; margin: 0;
  width: 100%; flex: none; justify-content: center; align-items: center;
}
/* 레일은 띠 바로 아래에서 시작한다(사이드바의 위쪽 패딩이 띠를 밀어내지 않게) */
body.skin-yongin .sidebar { padding: 0 0 10px; }
body.skin-yongin .yg-rail { padding-top: 10px; }
/* 다크 띠 위에서는 흰 배경 워드마크가 뜬다 → 검정판 + screen 블렌드(renewal 다크와 같은 규칙) */
.yg-brand .ci { background-image: url('/img/farmn_ci_black.png'); mix-blend-mode: screen; }
.yg-brand .div { background: rgba(255, 255, 255, .16); }
.yg-brand .ttl { color: var(--yg-hd-tx); }

body.skin-yongin .yg-tabs { background: rgba(255, 255, 255, .07); }
body.skin-yongin .yg-tab { color: var(--yg-hd-tx2); }
body.skin-yongin .yg-tab:hover { color: var(--yg-hd-tx); }
body.skin-yongin .yg-tab.on {
  background: rgba(255, 255, 255, .14); color: var(--yg-hd-ac);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .28);
}
body.skin-yongin .yg-live { color: var(--yg-hd-tx3); }
body.skin-yongin .yg-live .lv { color: var(--yg-hd-ac); }
body.skin-yongin .yg-live .lv i { background: #34d399; box-shadow: 0 0 0 3px rgba(52, 211, 153, .2); }
/* 다크 띠 위 요소들 — 원본 renewal 은 그라디언트 topbar 를 전제로 흰 글자를 쓴다.
   내 스킨이 topbar 를 흰색으로 만들면서 이것들이 안 보였다. 다시 보이게 된다. */
body.skin-yongin .mobile-hamburger { color: var(--yg-hd-tx); }
body.skin-yongin .topbar-right { color: var(--yg-hd-tx2); }
body.skin-yongin .corner-time { color: var(--yg-hd-tx3); }

/* ══════════════════════════════════════════════════════════════════════════
   분석 화면 공통 (단일 랙 분석부터) — 현장 뷰의 카드/톤 언어를 그대로 쓴다.
   컨트롤은 상단 다크 띠가 아니라 **본문 카드 안**에 둔다. 띠는 내비게이션 자리이고
   화면별 조작은 본문에 있어야 "지금 무엇을 보고 있나" 와 붙어 읽힌다.
   ══════════════════════════════════════════════════════════════════════════ */
.yg-analysis { gap: 12px; }
/* 상단 도구 바는 **기본이 가로 배치**다. 예전엔 `.row` 를 쓴 화면만 flex 였고, 자식을
   바로 넣은 화면(디바이스 상태 등)은 블록으로 쌓여 **줄 사이 간격이 0** 이 됐다 —
   글자가 위아래로 붙어 보인다는 지적이 거기서 나왔다. `.yg-ctrl` 자체를 flex 로 두면
   어느 화면이 어떻게 쓰든 같은 간격이 나온다. `.row` 를 쓰는 화면은 그대로 동작한다
   (행이 하나짜리 flex 아이템이 될 뿐이고, `.row` 가 100% 폭을 차지한다). */
.yg-ctrl { padding: 12px 15px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.yg-ctrl .row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex-basis: 100%; }
.yg-ctrl .row + .row { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--yg-line-2); }
.yg-ctrl .lb { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em; }
.yg-ctrl .sp { flex: 1; }

/* 칩 묶음 — **전 화면 공통**. 화면마다 정의하면 새 화면에서 반드시 빠뜨린다. */
.chips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

.yg-seg { display: flex; gap: 2px; background: var(--yg-line-2); padding: 3px; border-radius: 10px; }
.yg-seg-btn { font: inherit; font-size: 12px; font-weight: 700; padding: 5px 11px; border: none;
              border-radius: 7px; background: transparent; color: var(--yg-tx2); cursor: pointer; }
.yg-seg-btn:hover { color: var(--yg-tx); }
.yg-seg-btn.on { background: var(--yg-surface); color: var(--yg-accent-dp); box-shadow: var(--yg-shadow); }
/* 이 지표로는 쓸 수 없는 비교 축. 지우지 않고 남겨 둔다 — 사라지면 버튼이 몇 개인지
   매번 달라져 위치를 못 외운다. title 에 막힌 이유를 적는다. */
/* 비활성이라도 **읽혀야 한다** — 무슨 축이 막혔는지 알아야 title 을 볼 마음이 든다.
   트랙(#eef1f6) 위 3.7:1 (활성은 6.7:1) — 확실히 죽었지만 글자는 보인다. */
.yg-seg-btn.off { color: #717d8c; cursor: not-allowed; }
.yg-seg-btn.off:hover { color: #717d8c; }

.yg-select { font: inherit; font-size: 12px; font-weight: 700; padding: 6px 10px;
             border-radius: var(--yg-r-sm); border: 1px solid var(--yg-line);
             background: var(--yg-surface); color: var(--yg-tx2); cursor: pointer; }

/* 지표 선택 — 색은 그 지표의 글자색(--m)을 쓴다. 선택 시 그 색으로 밑줄을 그어
   "지금 보는 값이 무슨 색으로 그려지는가" 가 차트와 이어지게 한다. */
.yg-metric { font: inherit; font-size: 12px; font-weight: 800; padding: 6px 12px 5px;
             border: 1px solid var(--yg-line); border-radius: var(--yg-r-sm);
             background: var(--yg-surface-2); color: var(--yg-tx2); cursor: pointer;
             display: inline-flex; align-items: baseline; gap: 5px; }
.yg-metric:hover { border-color: #a7f3d0; }
.yg-metric .u { font-size: 9px; font-weight: 700; color: var(--yg-tx3); }
.yg-metric.on { background: var(--yg-surface); color: var(--m); border-color: currentColor;
                box-shadow: inset 0 -2px 0 currentColor, var(--yg-shadow); }
.yg-metric.on .u { color: inherit; opacity: .7; }

.yg-chartcard { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.yg-chartcard .note { font-size: 11px; color: var(--yg-tx3); margin: -4px 0 10px; }
.yg-chartcard .note b { color: var(--yg-tx2); font-weight: 800; }
.yg-chartcard .note b.warn { color: #9a6314; }
.yg-chartcard #ryc-chart,
.yg-chartcard #gyc-chart { flex: 1; min-height: 260px; position: relative; }

/* 차트 등장 — 기존 대시보드의 효과를 그대로 쓴다.
   style.css 의 `@keyframes chartReveal` 을 `#rc-chart-wrap > div` / `#gc-chart-wrap > div`
   에 걸던 것과 **같은 선택자 모양**이라 동작도 같다: 자리에 새 자식이 들어올 때마다
   좌→우로 1.4s 와이프. 스피너 → 차트 순서까지 원본과 동일하다.
   (keyframes 를 다시 정의하지 않는다 — 한쪽만 고치면 두 화면의 리듬이 갈린다.) */
.yg-chartcard #ryc-chart > div,
.yg-chartcard #gyc-chart > div { animation: chartReveal 1.4s cubic-bezier(0.4, 0, 0.2, 1) both; }

/* 움직임을 줄이도록 설정한 사용자에게는 걸지 않는다 — 등장 연출은 정보가 아니다. */
@media (prefers-reduced-motion: reduce) {
  .yg-chartcard #ryc-chart > div,
  .yg-chartcard #gyc-chart > div { animation: none; }
}
.yg-chartbox { position: relative; height: 100%; min-height: 260px; }
.yg-empty { display: flex; flex-direction: column; align-items: center; justify-content: center;
            gap: 6px; height: 100%; min-height: 220px; font-size: 12.5px; font-weight: 700;
            color: var(--yg-tx2); }
.yg-empty span { font-size: 11px; font-weight: 600; color: var(--yg-tx3); }

@media (max-width: 700px) {
  .yg-ctrl .row { gap: 7px; }
  .yg-ctrl .sp { display: none; }
  .yg-metric { padding: 5px 9px 4px; font-size: 11px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   전력 모니터링 (용인) — 분석 화면과 같은 문법을 쓰되, 세로로 쌓인 차트 5개라
   `.yg-analysis` 의 "차트 하나가 남은 높이를 전부 먹는" 규칙을 여기서만 되돌린다.
   ══════════════════════════════════════════════════════════════════════════ */
.yg-power { overflow: auto; }
.yg-power .yg-ctrl { position: sticky; top: 0; z-index: 3; }

/* 숫자·날짜 입력 — .yg-select 와 같은 옷 */
.yg-num, .yg-date {
  font: inherit; font-size: 12px; font-weight: 700; padding: 6px 10px;
  border-radius: var(--yg-r-sm); border: 1px solid var(--yg-line);
  background: var(--yg-surface); color: var(--yg-tx2);
}
.yg-num { width: 76px; text-align: right; }
/* 포커스는 파일 맨 아래 '포커스 링' 절에서 한 번에 정의한다 */
.yg-ctrl .note-inline { font-size: 11px; color: var(--yg-tx3); }

/* KPI — 카드가 아니라 한 줄짜리 지표 타일. 랙별이면 6장까지 늘어난다. */
.yg-kpis { display: grid; gap: 10px; margin-bottom: 12px;
           grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); }
.yg-kpi { background: var(--yg-surface); border: 1px solid var(--yg-line);
          border-radius: var(--yg-r-sm); padding: 11px 13px 10px; box-shadow: var(--yg-shadow); }
.yg-kpi .l { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3);
             display: flex; align-items: center; gap: 6px; }
.yg-kpi .l i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.yg-kpi .v { font-size: 19px; font-weight: 800; color: var(--yg-tx); margin: 5px 0 6px;
             letter-spacing: -.01em; }
.yg-kpi .f { display: flex; justify-content: space-between; font-size: 10.5px;
             color: var(--yg-tx3); border-top: 1px solid var(--yg-line-2); padding-top: 6px; }
.yg-kpi .f b { color: var(--yg-tx2); font-weight: 800; }
/* 합계 타일만 강조 — 색을 쓰지 않고 배경 톤으로만 구분한다(선 색과 경쟁하지 않게) */
.yg-kpi.tot { background: linear-gradient(180deg, #0f1823, #172231); border-color: #22303f; }
.yg-kpi.tot .l { color: #9fb0c3; }
.yg-kpi.tot .v { color: #ecfdf5; }
.yg-kpi.tot .f { color: #9fb0c3; border-top-color: #22303f; }
.yg-kpi.tot .f b { color: #6ee7b7; }

.yg-pchart { padding: 13px 15px 11px; }
.yg-pchart + .yg-pchart { margin-top: 12px; }
.yg-pchart .h { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 9px; }
.yg-pchart .h .t { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
.yg-pchart .h .s { font-size: 10.5px; font-weight: 600; color: var(--yg-tx3); }
.yg-pchart .box { position: relative; height: 210px; }
.yg-pchart:first-of-type .box { height: 168px; }

/* 등장 효과 — 2·3번 화면과 같은 와이프. 차트가 5개라 살짝 어긋나게 들어와
   위에서 아래로 훑는 것처럼 보이게 한다(같은 keyframes, delay 만 다르다). */
.yg-power .yg-pchart .box { animation: chartReveal 1.4s cubic-bezier(0.4, 0, 0.2, 1) both; }
.yg-power .yg-pchart:nth-of-type(2) .box { animation-delay: .06s; }
.yg-power .yg-pchart:nth-of-type(3) .box { animation-delay: .12s; }
.yg-power .yg-pchart:nth-of-type(4) .box { animation-delay: .18s; }
.yg-power .yg-pchart:nth-of-type(5) .box { animation-delay: .24s; }
@media (prefers-reduced-motion: reduce) {
  .yg-power .yg-pchart .box { animation: none; }
}

@media (max-width: 700px) {
  .yg-kpis { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
  .yg-kpi .v { font-size: 16px; }
  .yg-pchart .box { height: 180px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   작물 기록 (용인 CCTV) — 실시간 감시가 아니라 **기록 열람**이 본체인 화면.
   그래서 가장 큰 면적을 사진에 준다. 실시간은 모달로만 뜬다.
   ══════════════════════════════════════════════════════════════════════════ */
.yg-cctv { overflow: auto; }
.yg-cctv .yg-ctrl { position: sticky; top: 0; z-index: 3; }
.yg-btn { font: inherit; font-size: 12px; font-weight: 800; padding: 6px 12px;
          border-radius: var(--yg-r-sm); border: 1px solid var(--yg-line);
          background: var(--yg-surface); color: var(--yg-tx2); cursor: pointer; }
.yg-btn:hover { border-color: var(--yg-accent-2); color: var(--yg-accent-dp); }
.yg-btn.on { background: var(--yg-accent-sf); border-color: var(--yg-accent-2); color: var(--yg-accent-dp); }
.yg-btn.danger { color: #a3402f; }
.yg-btn.danger:hover { border-color: #e79b8c; color: #8f3527; }
.yg-back { font: inherit; font-size: 12px; font-weight: 800; padding: 6px 11px;
           border-radius: var(--yg-r-sm); border: 1px solid var(--yg-line);
           background: var(--yg-surface-2); color: var(--yg-tx2); cursor: pointer; }
.yg-back:hover { color: var(--yg-accent-dp); border-color: var(--yg-accent-2); }

/* 자동 기록 스위치 */
.cy-sw { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
.cy-sw input { position: absolute; opacity: 0; width: 0; height: 0; }
.cy-sw .tr { width: 34px; height: 19px; border-radius: 999px; background: #cdd5e0;
             position: relative; transition: background .15s; flex: none; }
.cy-sw .th { position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%;
             background: #fff; box-shadow: 0 1px 2px rgba(16,24,40,.3); transition: transform .15s; }
.cy-sw input:checked + .tr { background: var(--yg-accent); }
.cy-sw input:checked + .tr .th { transform: translateX(15px); }

.cy-sw .tx { font-size: 11px; font-weight: 800; color: var(--yg-tx2); }

/* 구역 목록 — 최신 기록 한 장이 곧 그 구역의 얼굴이다 */
.cy-zones { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); }
.cy-zone { background: var(--yg-surface); border: 1px solid var(--yg-line); border-radius: var(--yg-r);
           box-shadow: var(--yg-shadow); overflow: hidden; cursor: pointer;
           transition: box-shadow .15s, transform .15s; }
.cy-zone:hover { box-shadow: var(--yg-shadow-lg); transform: translateY(-2px); }
.cy-zone .ph { position: relative; aspect-ratio: 4 / 3; background: #0f1823; }
.cy-zone .ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cy-zone .ph .no { display: flex; align-items: center; justify-content: center; height: 100%;
                   color: #8fa0b4; font-size: 11.5px; font-weight: 700; }
.cy-livebtn { position: absolute; right: 8px; bottom: 8px; font: inherit; font-size: 10.5px;
              font-weight: 800; padding: 5px 10px; border-radius: 999px; cursor: pointer;
              border: 1px solid rgba(255,255,255,.28); background: rgba(15,24,35,.82); color: #fdecec; }
.cy-livebtn:hover { background: #7f1d1d; border-color: #b91c1c; }
.cy-zone .mt { padding: 9px 11px 10px; }
.cy-zone .nm { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
.cy-zone .sb { font-size: 10.5px; font-weight: 600; color: var(--yg-tx3); margin-top: 3px; }

/* 뷰어 */
.cy-view { padding: 13px 15px 12px; }
.cy-view .h { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 10px; }
.cy-view .h .t { font-size: 13px; font-weight: 800; color: var(--yg-tx); }
.cy-view .h .s { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
.cy-view .h .sp { flex: 1; }
.cy-stage { position: relative; background: #0f1823; border-radius: var(--yg-r-sm); overflow: hidden;
            display: flex; align-items: center; justify-content: center; min-height: 300px; }
.cy-stage img { max-width: 100%; max-height: 62vh; display: block; }
.cy-cap { position: absolute; left: 12px; bottom: 10px; font-size: 12px; font-weight: 800;
          color: #f1f5f9; background: rgba(15,24,35,.72); padding: 5px 10px; border-radius: 8px; }
.cy-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 38px; height: 54px;
          border: none; border-radius: 8px; background: rgba(15,24,35,.5); color: #fff;
          font-size: 24px; line-height: 1; cursor: pointer; }
.cy-nav:hover { background: rgba(15,24,35,.8); }
.cy-nav.l { left: 8px; }
.cy-nav.r { right: 8px; }

/* 두 시점 비교 — 같은 구역의 A/B */
.cy-cmp { display: grid; gap: 10px; grid-template-columns: 1fr 1fr; }
.cy-cmp-1 { background: var(--yg-surface-2); border: 1px solid var(--yg-line);
            border-radius: var(--yg-r-sm); padding: 8px; }
.cy-cmp-h { display: flex; align-items: baseline; gap: 7px; margin-bottom: 6px; }
.cy-cmp-h b { font-size: 11px; font-weight: 900; color: var(--yg-accent-dp); }
.cy-cmp-h span { font-size: 11px; font-weight: 700; color: var(--yg-tx2); }
.cy-cmp-1 img { width: 100%; aspect-ratio: 4 / 3; object-fit: contain;
                background: #0f1823; border-radius: 8px; display: block; }

.cy-bar { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.cy-play { font: inherit; font-size: 12px; font-weight: 800; padding: 6px 14px; min-width: 84px;
           border-radius: var(--yg-r-sm); border: 1px solid var(--yg-accent-2);
           background: var(--yg-accent-sf); color: var(--yg-accent-dp); cursor: pointer; }
.cy-range { flex: 1; min-width: 140px; }

/* 필름스트립 */
.cy-strip { display: flex; gap: 6px; overflow-x: auto; padding: 10px 2px 4px; margin-top: 8px;
            border-top: 1px solid var(--yg-line-2); }
/* color 를 명시한다 — 버튼은 상위 스타일에서 흰 글자를 물려받는데, 지금은 안쪽
   span 이 자기 색을 갖고 있어 티가 안 날 뿐이다. 여기에 글자가 하나라도 직접
   들어오는 순간 흰 배경에 흰 글자가 된다. */
.cy-th { flex: none; width: 76px; border: 2px solid transparent; border-radius: 8px;
         background: none; padding: 0; cursor: pointer; color: var(--yg-tx3); }
.cy-th img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px; display: block; }
.cy-th span { display: block; font-size: 9.5px; font-weight: 700; color: var(--yg-tx3); margin-top: 2px; }
.cy-th.on { border-color: var(--yg-accent); }
.cy-th.on span { color: var(--yg-accent-dp); }

/* 실시간 모달 — 열려 있는 동안만 스트림을 문다 */
.cy-modal { position: fixed; inset: 0; z-index: 200; background: rgba(9,14,22,.68);
            display: flex; align-items: center; justify-content: center; padding: 20px;
            backdrop-filter: blur(3px); }
.cy-modal-in { background: var(--yg-surface); border-radius: var(--yg-r); box-shadow: var(--yg-shadow-lg);
               width: min(980px, 100%); overflow: hidden; }
.cy-modal-h { display: flex; align-items: center; gap: 8px; padding: 11px 14px;
              border-bottom: 1px solid var(--yg-line); }
.cy-modal-h b { font-size: 13px; font-weight: 800; color: var(--yg-tx); }
.cy-modal-h .sp { flex: 1; }
.cy-modal-h .dot { width: 8px; height: 8px; border-radius: 50%; background: #dc2626;
                   animation: ygLivePulse 1.6s ease-in-out infinite; }
.cy-modal-h .lv { font-size: 10.5px; font-weight: 800; color: #a3402f; }
@keyframes ygLivePulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.cy-live { position: relative; background: #0b111a; aspect-ratio: 16 / 9; }
.cy-live video { width: 100%; height: 100%; object-fit: contain; display: block; }
.cy-live-err { position: absolute; inset: 0; display: none; flex-direction: column; gap: 6px;
               align-items: center; justify-content: center; background: #0b111a; color: #fca5a5;
               font-size: 13px; font-weight: 800; text-align: center; padding: 16px; }
.cy-live-err.on { display: flex; }
.cy-live-err span { font-size: 11px; font-weight: 600; color: #cbd5e1; }
.cy-modal-f { padding: 9px 14px 11px; font-size: 11px; color: var(--yg-tx3); }

@media (prefers-reduced-motion: reduce) {
  .cy-modal-h .dot { animation: none; }
  .cy-zone:hover { transform: none; }
}
@media (max-width: 700px) {
  .cy-zones { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .cy-cmp { grid-template-columns: 1fr; }
  .cy-stage img { max-height: 46vh; }
}

/* ══════════════════════════════════════════════════════════════════════════
   공조기 (용인) — 설비 계통도가 아니라 **룸이 목표를 지키는가**를 보는 화면.
   그래서 가장 큰 면적은 룸 카드 4장이고, 설비 상태는 카드 발치의 한 줄이다.
   ══════════════════════════════════════════════════════════════════════════ */
.yg-hvac { overflow: auto; }
.yg-hvac .hy-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
                   position: sticky; top: 0; z-index: 3; }
.yg-hvac .hy-top .sp { flex: 1; }

.hy-cards { display: grid; gap: 11px; margin-bottom: 12px;
            grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.hy-card { background: var(--yg-surface); border: 1px solid var(--yg-line);
           border-radius: var(--yg-r); box-shadow: var(--yg-shadow); padding: 12px 14px 10px; }
.hy-card .hd { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.hy-card .hd b { font-size: 13px; font-weight: 800; color: var(--yg-tx); }
.hy-card .hd .ph { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
.hy-card .rows { display: flex; flex-direction: column; gap: 6px; }
.hy-card .r { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.hy-card .r .k { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); }
.hy-card .r .v { font-size: 16px; font-weight: 800; color: var(--yg-tx); letter-spacing: -.01em; }
.hy-card .r .v i { font-size: 10px; font-weight: 700; font-style: normal;
                   color: var(--yg-tx3); margin-left: 2px; }
.hy-card .r .sp { font-size: 10.5px; font-weight: 700; color: var(--yg-tx2); }
.hy-card .r.sub { padding-top: 6px; border-top: 1px solid var(--yg-line-2); }
.hy-card .r.sub .v { font-size: 12.5px; }
/* 편차 — 현장 뷰와 같은 문법(▲ 초과 / ▼ 미달 / · 도달). 앰버는 밴드 밖일 때만. */
.hy-card .d { font-size: 10.5px; font-weight: 800; margin-left: auto; }
.hy-card .d.ok { color: var(--yg-accent-dp); }
.hy-card .d.off { color: var(--yg-warn-tx); }
.hy-card .d.none { color: var(--yg-tx3); font-weight: 700; }
.hy-card .ft { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--yg-line-2);
               font-size: 10.5px; color: var(--yg-tx3); }
.hy-card .ft .on { font-weight: 800; color: var(--yg-accent-dp); }
.hy-card .ft .off { font-weight: 800; color: var(--yg-tx2); }
.hy-card .ft .warn { font-weight: 800; color: var(--yg-warn-tx); }
.hy-card .ft b { color: var(--yg-tx2); font-weight: 800; }
.hy-card.oa { background: linear-gradient(180deg, var(--yg-surface), #f7fbfa); }
.hy-card.meter .hd b { color: var(--yg-accent-dp); }

.hy-panel { padding: 11px 14px 12px; }
.hy-panel + .hy-panel { margin-top: 11px; }
.hy-panel .h { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 9px; }
.hy-panel .h .sp { flex: 1; }
.hy-panel .box { position: relative; height: 232px; }
/* 등장 효과 — 다른 화면과 같은 와이프 */
.yg-hvac .hy-panel .box { animation: chartReveal 1.4s cubic-bezier(0.4, 0, 0.2, 1) both; }
.yg-hvac .hy-panel:nth-of-type(3) .box { animation-delay: .08s; }
@media (prefers-reduced-motion: reduce) {
  .yg-hvac .hy-panel .box { animation: none; }
}

@media (max-width: 700px) {
  .hy-cards { grid-template-columns: 1fr; }
  .hy-panel .box { height: 190px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   설비 제어 > 양액 (용인) — 랙마다 탱크 1대. 18장을 한 판에 놓고
   **목표에서 벗어난 것만 눈에 띄게** 하는 것이 이 화면의 전부다.
   ══════════════════════════════════════════════════════════════════════════ */
.yg-nutrient { overflow: auto; }
.yg-nutrient .nt-subs { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
                        position: sticky; top: 0; z-index: 4; }
.yg-nutrient .nt-subs .sp { flex: 1; }

.nt-grid { display: grid; gap: 10px; margin-bottom: 12px;
           grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); }
.nt-card { background: var(--yg-surface); border: 1px solid var(--yg-line);
           border-radius: var(--yg-r-sm); padding: 10px 12px 9px; box-shadow: var(--yg-shadow);
           cursor: pointer; transition: box-shadow .15s, border-color .15s; }
.nt-card:hover { box-shadow: var(--yg-shadow-lg); }
/* 선택된 랙 — 테두리만으로는 약하다(활성 표시가 미세하다는 지적을 받은 적이 있다).
   왼쪽에 굵은 액센트 띠를 더해 목록에서 바로 찾히게 한다. */
.nt-card.sel { border-color: var(--yg-accent-2); box-shadow: 0 0 0 3px var(--yg-ring), var(--yg-shadow); }
.nt-card.sel::before { content: ''; display: block; width: 26px; height: 3px; border-radius: 2px;
                       background: var(--yg-accent); margin: -2px 0 6px; }
/* 목표 밖 — 색만으로 구분하지 않는다. 발치에 '목표 밖' 글자가 함께 붙는다. */
.nt-card.bad { border-color: var(--yg-warn); background: linear-gradient(180deg, #fffaf0, #fff); }
/* 미연동 — **점선 테두리를 쓰지 않는다.** 1px 점선은 이 크기에서 "윤곽이 깨진 것"
   으로 읽히고, 지금처럼 카드가 전부 미연동이면 화면 전체가 미완성으로 보인다(실제
   지적을 받은 자리다). 상태는 **면**으로 말한다 — 가라앉은 바닥색 + 중성 왼쪽 띠 +
   '탱크 미연동' 글자. `opacity` 도 쓰지 않는다(글자 대비가 같이 내려간다).

   ⚠ **그림자는 그대로 둔다.** 이 디자인에서 카드의 형태를 그리는 건 테두리가 아니라
   그림자다 — 테두리(#e6eaf0)는 페이지 배경 대비 1.13:1, 흰 면조차 1.07:1 이라
   그림자를 빼면 카드가 배경에 녹아 "윤곽이 없어진다". 한 번 그렇게 고쳤다가 되돌렸다.
   대신 면이 페이지색에 가까워진 만큼 테두리만 조금 더 진하게 한다(1.50:1). */
.nt-card.none { cursor: default; background: var(--yg-surface-2);
                border-color: var(--yg-line-mute); }
.nt-card.none .hd b { color: var(--yg-tx2); }
.nt-card.none .hd { border-left-color: var(--yg-line-mute); }
.nt-card.none:hover { box-shadow: var(--yg-shadow); }

.nt-card .hd { display: flex; align-items: baseline; gap: 6px; margin-bottom: 8px; flex-wrap: wrap; }
.nt-card .hd b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
.nt-card .hd .rm { font-size: 10px; font-weight: 700; color: var(--yg-tx3); }
.nt-card .hd .crop { margin-left: auto; font-size: 10px; font-weight: 800;
                     color: var(--yg-accent-dp); background: var(--yg-accent-sf);
                     padding: 2px 7px; border-radius: 999px; }
.nt-card .nodev { font-size: 11.5px; font-weight: 700; color: var(--yg-tx3);
                  padding: 12px 0 6px; text-align: center; }

.nt-card .ms { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.nt-m { display: flex; flex-direction: column; gap: 1px; }
.nt-m .k { font-size: 9.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em; }
.nt-m .v { font-size: 17px; font-weight: 800; color: var(--yg-tx); letter-spacing: -.01em; }
.nt-m .v em { font-size: 9.5px; font-weight: 700; font-style: normal; color: var(--yg-tx3); margin-left: 2px; }
.nt-m i { font-size: 9.5px; font-weight: 700; font-style: normal; color: var(--yg-tx3); }
.nt-m.ok i { color: var(--yg-accent-dp); }
.nt-m.off i { color: var(--yg-warn-tx); }
.nt-m.off .v { color: var(--yg-warn-tx); }

.nt-card .ft { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--yg-line-2);
               font-size: 10.5px; color: var(--yg-tx3); display: flex; align-items: center; gap: 6px; }
.nt-card .ft b { color: var(--yg-tx2); font-weight: 800; }
.nt-card .ft .warn { margin-left: auto; font-weight: 800; color: var(--yg-warn-tx);
                     background: var(--yg-warn-sf); padding: 1px 7px; border-radius: 999px; }

#nt-summary b { color: var(--yg-tx); font-weight: 800; }
#nt-summary b.warn { color: var(--yg-warn-tx); }
#nt-summary b.ok { color: var(--yg-accent-dp); }
#nt-summary .none { color: var(--yg-tx3); font-weight: 700; }

.nt-trend { padding: 11px 14px 12px; }
.nt-trend .h { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 9px; }
.nt-trend .h .t { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
.nt-trend .h .sp { flex: 1; }
.nt-trend .box { position: relative; height: 236px; }
.yg-nutrient .nt-trend .box { animation: chartReveal 1.4s cubic-bezier(0.4, 0, 0.2, 1) both; }

.nt-note { margin-top: 11px; padding: 11px 14px; font-size: 11px; line-height: 1.65;
           color: var(--yg-tx3); background: var(--yg-surface-2); }
.nt-note b { color: var(--yg-tx2); font-weight: 800; }

@media (prefers-reduced-motion: reduce) {
  .yg-nutrient .nt-trend .box { animation: none; }
}
@media (max-width: 700px) {
  .nt-grid { grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
  .nt-m .v { font-size: 15px; }
  .nt-trend .box { height: 190px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   설비 제어 > LED (용인) — 접은 줄 + 펼침.

   ⚠ 여기가 한 번 크게 어긋났던 자리다. 첫 판의 `.led-row { display:grid;
   grid-template-columns: 128px 190px 152px 1fr 68px }` 를 남겨 둔 채 접기/펼치기
   구조로 바꾸는 바람에, 펼침 패널이 **190px 짜리 두 번째 칸에 갇혀** 왼쪽에
   몰리고 글자가 겹쳤다. 줄은 그리드가 아니라 **세로 스택**이고, 가로 배치는
   안쪽의 `.hd` 와 `.led-panel` 이 각자 한다.
   ══════════════════════════════════════════════════════════════════════════ */
/* ⚠ `.yg-analysis` 는 **flex 세로 컬럼**이다 — 분석 화면에서 차트 카드가 남은 높이를
   전부 채우게 하려고 그렇게 뒀다. 목록형 화면(제어·전력·기록·공조)은 그 규칙이
   해가 된다: 높이가 정해진 flex 컨테이너 안에서 `overflow:hidden` 을 가진 카드는
   min-height:auto 가 풀려 **내용이 있어도 0 으로 눌린다**(일괄 바가 2px 로 찌그러졌다).
   목록형은 그냥 블록 스크롤로 되돌린다. */
body.skin-yongin .yg-led,
body.skin-yongin .yg-nutrient,
body.skin-yongin .yg-power,
body.skin-yongin .yg-cctv,
body.skin-yongin .yg-hvacctl,
body.skin-yongin .yg-explorer,
body.skin-yongin .yg-design,
body.skin-yongin .yg-vision,
body.skin-yongin .yg-history,
body.skin-yongin .yg-logs,
body.skin-yongin .yg-health,
body.skin-yongin .yg-system,
body.skin-yongin .yg-hvac { display: block; }

/* **세로 간격을 여기서 다시 세운다.** `.yg-wrap` 이 flex 였을 때는 `gap: 14px` 이
   블록 사이를 벌려 줬는데, 위에서 `display: block` 으로 되돌리면서 그 간격이 사라졌다.
   남은 건 각 블록이 스스로 가진 `margin-bottom` 뿐이라, 그게 없는 **상단 도구 바
   바로 아래가 0px** 이 됐다. 도구 바는 `position: sticky` + 그림자를 지녀서
   (`0 10px 22px -14px` → 아래로 약 7px 뻗는다) 그 그림자가 첫 카드 위에 얹혀
   "박스를 침범한" 것처럼 보인다. 양액·전력에서 함께 지적된 자리다.

   개별 화면에 margin 을 덧대지 않고 한 줄로 세운다 — 네 화면에 흩어 두면 새 화면을
   만들 때마다 같은 일이 반복된다. 값을 통일하므로 블록이 제 margin-bottom 을
   갖고 있어도 이중 간격이 생기지 않는다(선택자가 더 구체적이라 이긴다). */
body.skin-yongin .yg-led > *,
body.skin-yongin .yg-nutrient > *,
body.skin-yongin .yg-power > *,
body.skin-yongin .yg-cctv > *,
body.skin-yongin .yg-hvacctl > *,
body.skin-yongin .yg-explorer > *,
body.skin-yongin .yg-design > *,
body.skin-yongin .yg-vision > *,
body.skin-yongin .yg-history > *,
body.skin-yongin .yg-logs > *,
body.skin-yongin .yg-health > *,
body.skin-yongin .yg-system > *,
body.skin-yongin .yg-hvac > * { margin-bottom: 12px; }
body.skin-yongin .yg-led > *:last-child,
body.skin-yongin .yg-nutrient > *:last-child,
body.skin-yongin .yg-power > *:last-child,
body.skin-yongin .yg-cctv > *:last-child,
body.skin-yongin .yg-hvacctl > *:last-child,
body.skin-yongin .yg-explorer > *:last-child,
body.skin-yongin .yg-design > *:last-child,
body.skin-yongin .yg-vision > *:last-child,
body.skin-yongin .yg-history > *:last-child,
body.skin-yongin .yg-logs > *:last-child,
body.skin-yongin .yg-health > *:last-child,
body.skin-yongin .yg-system > *:last-child,
body.skin-yongin .yg-hvac > *:last-child { margin-bottom: 0; }

.led-rows { display: flex; flex-direction: column; gap: 10px; }
.led-row { background: var(--yg-surface); border: 1px solid var(--yg-line);
           border-radius: var(--yg-r); box-shadow: var(--yg-shadow); overflow: hidden;
           transition: box-shadow .15s, border-color .15s; }
.led-row:hover { box-shadow: var(--yg-shadow-lg); }
/* 상태를 왼쪽 띠로 — 목록에서 훑을 때 색만 보고 찾을 수 있게 */
.led-row .hd { display: flex; align-items: center; gap: 14px; padding: 11px 14px 11px 12px;
               border-left: 4px solid var(--yg-line); }
.led-row.lit .hd { border-left-color: #f0c651; background: linear-gradient(90deg, #fffdf5, #fff 42%); }
.led-row.dirty { border-color: var(--yg-warn); }
.led-row.dirty .hd { border-left-color: var(--yg-warn);
                     background: linear-gradient(90deg, #fffaf0, #fff 42%); }
.led-row.open { border-color: var(--yg-accent-2); box-shadow: 0 0 0 3px var(--yg-ring), var(--yg-shadow); }
/* LED·펌프 미연동 줄도 같은 이유로 점선·opacity 를 쓰지 않는다 (위 .nt-card.none 참조) */
.led-row.none { background: var(--yg-surface-2); border-color: var(--yg-line-mute); }
.led-row.none .hd { border-left-color: var(--yg-line-mute); }
.led-row.none .hd b { color: var(--yg-tx2); }
.led-row .nodev { flex: 1; min-width: 0; font-size: 11.5px; font-weight: 700; color: var(--yg-tx3); }

.led-row .rk { flex: none; width: 118px; display: flex; flex-direction: column; gap: 1px; }
.led-row .rk b { font-size: 13px; font-weight: 800; color: var(--yg-tx); letter-spacing: -.01em; }
.led-row .rk span { font-size: 10px; font-weight: 700; color: var(--yg-tx3); }
.led-row .rk .crop { color: var(--yg-accent-dp); }

.led-row .pw { flex: none; display: flex; align-items: center; gap: 6px; }
.led-row .sw { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 11px;
               font-weight: 800; padding: 5px 12px; border-radius: 999px; cursor: pointer;
               border: 1px solid var(--yg-line); background: var(--yg-surface-2); color: var(--yg-tx2); }
.led-row .sw i { width: 9px; height: 9px; border-radius: 50%; background: #b6c0cd; flex: none; }
.led-row .sw.on { border-color: #d8a93a; background: #fffbeb; color: #7a6329; }
.led-row .sw.on i { background: #f0c651; box-shadow: 0 0 7px rgba(240, 198, 81, .85); }
.led-row .sw.pend { border-color: var(--yg-accent-2); color: var(--yg-accent-dp); background: var(--yg-accent-sf); }
.led-row .sw.pend i { background: var(--yg-accent); animation: ygLivePulse 1.1s ease-in-out infinite; }
.led-row .md, .led-row .ty { font: inherit; font-size: 10px; font-weight: 800; padding: 4px 9px;
                             cursor: pointer; border-radius: 999px; border: 1px solid var(--yg-line);
                             background: var(--yg-surface-2); color: var(--yg-tx3); }
.led-row .md.auto { border-color: var(--yg-accent-2); background: var(--yg-accent-sf); color: var(--yg-accent-dp); }
.led-row .ty:disabled { opacity: .45; cursor: not-allowed; }

/* 24시간 점등 띠 — 줄에서 가장 넓은 자리를 준다. 이 화면의 핵심 정보다. */
.ledstrip { flex: 1; min-width: 120px; display: flex; flex-direction: column; gap: 2px; }
.ledstrip .bar { position: relative; height: 16px; border-radius: 5px;
                 background: repeating-linear-gradient(90deg, #eef1f6 0 1px, #f6f8fb 1px 12.5%);
                 border: 1px solid var(--yg-line); overflow: hidden; }
.ledstrip i { position: absolute; top: 0; bottom: 0; display: block; }
.ledstrip i.on { background: linear-gradient(180deg, #f7cf6a, #e8b53c); }
.ledstrip i.rise { background: linear-gradient(180deg, #fbe7ad, #f4d78a); }
.ledstrip b.now { position: absolute; top: -2px; bottom: -2px; width: 2px; border-radius: 1px;
                  background: var(--yg-accent-dp); box-shadow: 0 0 0 1px #fff; }
.ledstrip .ax { position: relative; height: 10px; }
.ledstrip u { position: absolute; top: 0; font-size: 8.5px; font-weight: 700; color: var(--yg-tx3);
              text-decoration: none; transform: translateX(-50%); }
.ledstrip u:first-child { transform: none; }
.bigstrip .ledstrip .bar { height: 24px; }
.bigstrip .ledstrip u { font-size: 9.5px; }
.slg { display: flex; gap: 12px; margin-top: 6px; }
.slg span { display: inline-flex; align-items: center; gap: 4px;
            font-size: 9.5px; font-weight: 700; color: var(--yg-tx3); }
.slg i { width: 12px; height: 8px; border-radius: 2px; display: block; }
.slg i.on { background: linear-gradient(180deg, #f7cf6a, #e8b53c); }
.slg i.rise { background: linear-gradient(180deg, #fbe7ad, #f4d78a); }
.slg b { width: 2px; height: 10px; border-radius: 1px; background: var(--yg-accent-dp); display: block; }

.led-row .st { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
               min-width: 96px; }
.led-row .st .wt { font-size: 12px; font-weight: 800; color: var(--yg-tx2); }
.led-row .st .day { font-size: 10px; font-weight: 700; color: var(--yg-tx3); }
.led-row .st .rmp { font-size: 9.5px; font-weight: 800; color: var(--yg-accent-dp);
                    background: var(--yg-accent-sf); padding: 1px 7px; border-radius: 999px; }
.led-row .ex { flex: none; font: inherit; font-size: 10.5px; font-weight: 800; padding: 6px 11px;
               cursor: pointer; border-radius: var(--yg-r-sm); border: 1px solid var(--yg-line);
               background: var(--yg-surface-2); color: var(--yg-tx2); }
.led-row .ex:hover { border-color: var(--yg-accent-2); color: var(--yg-accent-dp); }

/* ── 펼침 — 줄 전체 폭을 쓴다 ─────────────────────────────────── */
.led-panel { display: grid; gap: 12px; padding: 13px 14px 15px;
             grid-template-columns: repeat(auto-fit, minmax(226px, 1fr));
             background: linear-gradient(180deg, #f8fafc, #fdfefe);
             border-top: 1px solid var(--yg-line); }
.led-panel .cell { display: flex; flex-direction: column; gap: 8px; min-width: 0;
                   background: var(--yg-surface); border: 1px solid var(--yg-line);
                   border-radius: var(--yg-r-sm); padding: 11px 12px; }
.led-panel .cell.wide { grid-column: span 2; }
.led-panel .ct { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3);
                 padding-bottom: 6px; border-bottom: 1px solid var(--yg-line-2); }
.led-panel .ct em { font-style: normal; color: var(--yg-accent-dp); }
.led-panel .hint { font-size: 10px; line-height: 1.55; color: var(--yg-tx3); margin-top: auto; }
.led-panel .hint b { color: var(--yg-tx2); font-weight: 800; }
.led-panel .two { display: flex; gap: 6px; }
.led-panel .two .yg-btn { flex: 1; }
.led-panel .lock .lockmsg { font-size: 10.5px; line-height: 1.6; color: var(--yg-tx3);
                            background: var(--yg-surface-2); border: 1px dashed var(--yg-line);
                            border-radius: var(--yg-r-sm); padding: 12px 10px; text-align: center; }
.led-panel .phs { display: flex; gap: 4px; flex-wrap: wrap; }
.led-panel .ph { font: inherit; font-size: 10.5px; font-weight: 800; padding: 4px 10px; cursor: pointer;
                 border-radius: 999px; border: 1px solid var(--yg-line);
                 background: var(--yg-surface-2); color: var(--yg-tx2); }
.led-panel .ph.on { background: var(--yg-accent-sf); border-color: var(--yg-accent-2); color: var(--yg-accent-dp); }
.led-panel .ph.add { color: var(--yg-accent-dp); font-size: 12px; line-height: 1; padding: 4px 11px; }
.led-panel .prow { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.led-panel .prow .k { font-size: 10px; font-weight: 800; color: var(--yg-tx3); }
.led-panel .tm { display: flex; align-items: center; gap: 6px; }
.led-panel .tm span { font-size: 10.5px; color: var(--yg-tx3); }
.led-panel .tm .yg-date { padding: 5px 8px; font-size: 11px; flex: 1; min-width: 0; }
.led-panel .yg-num { width: 66px; }
.led-panel .yg-btn.sm { padding: 4px 9px; font-size: 10.5px; }
.led-panel .act { gap: 6px; }
.led-panel .act .yg-btn { width: 100%; }

.led-panel .dim { display: flex; align-items: center; gap: 7px; }
.led-panel .dim .t { flex: none; width: 24px; font-size: 10px; font-weight: 800; color: var(--yg-tx3); }
.led-panel .dim .p { flex: none; min-width: 34px; text-align: right; font-size: 11.5px;
                     font-weight: 800; color: var(--yg-tx2); }
.led-panel .dim .cur { flex: none; font-size: 9.5px; font-weight: 700; color: var(--yg-tx3); }
.led-panel .dim.off { opacity: .45; }
.led-panel .dim .cy-range { flex: 1; min-width: 50px; }

.led-panel .dayline { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
                      background: var(--yg-accent-sf); border-radius: var(--yg-r-sm); padding: 7px 10px; }
.led-panel .dayline b { font-size: 15px; font-weight: 800; color: var(--yg-accent-dp); }
.led-panel .dayline span { font-size: 10px; font-weight: 700; color: #2f6b57; }
.led-panel .heat { display: flex; flex-direction: column; gap: 3px; }
.led-panel .hrow { display: flex; align-items: center; gap: 3px; }
.led-panel .hrow.now .hl { color: var(--yg-accent-dp); }
.led-panel .hl { flex: none; width: 66px; font-size: 9.5px; font-weight: 800; color: var(--yg-tx3); }
.led-panel .hl em { font-style: normal; font-weight: 700; margin-left: 3px; opacity: .8; }
/* 히트맵 칸 — 값이 클수록 진하다. 글자색 교차점(60%)을 CSS 램프와 JS 가 함께 지킨다. */
.led-panel .hc { flex: 1; text-align: center; font-size: 9.5px; font-weight: 800;
                 padding: 3px 0; border-radius: 4px; color: #5a4a1f;
                 background: rgba(240, 198, 81, calc(var(--v) / 130)); }
.led-panel .hc.dark { color: #fffbeb; background: rgba(140, 108, 24, calc(0.55 + var(--v) / 260)); }

/* ── 일괄 바 — 두 줄이 각자 무슨 일을 하는지 구분되게 ───────────── */
.led-bulk { padding: 0; overflow: hidden; }
.led-bulk .row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                 padding: 10px 14px; }
.led-bulk .row + .row { border-top: 1px solid var(--yg-line-2); background: var(--yg-surface-2); }
.led-bulk .lb { flex: none; width: 44px; font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); }
.led-bulk .k { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); }
.led-bulk .sep { width: 1px; height: 18px; background: var(--yg-line); margin: 0 2px; }
.led-bulk .yg-num { width: 58px; }
.led-bulk .yg-date { padding: 5px 8px; font-size: 11px; }
/* 넓을 땐 오른쪽 끝에 붙이고(flex:none), 좁아지면 줄을 바꿔 넘치지 않게 */
.led-bulk .note-inline { flex: 0 1 auto; min-width: 0; }

#led-summary b { color: var(--yg-tx); font-weight: 800; }
#led-summary b.ok { color: #87702e; }
#led-summary b.warn { color: var(--yg-warn-tx); }
#led-summary .none { color: var(--yg-tx3); font-weight: 700; }

@media (max-width: 1000px) {
  .led-bulk .row { row-gap: 6px; }
  .led-bulk .note-inline { flex-basis: 100%; }
  .led-row .hd { flex-wrap: wrap; }
  .led-row .rk { width: 100%; flex-direction: row; align-items: baseline; gap: 7px; }
  .ledstrip { min-width: 100%; order: 9; }
  .led-panel .cell.wide { grid-column: auto; }
}

.cy-modal-in.sm { width: min(420px, 100%); }
.md-body { padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.md-body .fld { display: flex; flex-direction: column; gap: 4px; }
.md-body .fld.sm { flex-direction: row; align-items: center; gap: 6px; }
.md-body .fld span { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); }
.md-body .hint { font-size: 10.5px; line-height: 1.6; color: var(--yg-tx3); }
.md-body .hint b { color: var(--yg-tx2); font-weight: 800; }
.md-ft { padding: 0 14px 14px; display: flex; justify-content: flex-end; gap: 7px; }
.md-body.guide { max-height: 68vh; overflow: auto; }
.md-body .grow { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.md-body .calst { font-size: 10.5px; font-weight: 800; color: var(--yg-accent-dp); }
.gwrap { max-height: 42vh; overflow: auto; border: 1px solid var(--yg-line); border-radius: var(--yg-r-sm); }
.gtbl { width: 100%; border-collapse: collapse; font-size: 11px; }
.gtbl th { position: sticky; top: 0; background: var(--yg-surface-2); color: var(--yg-tx2);
           font-weight: 800; padding: 6px 8px; border-bottom: 1px solid var(--yg-line); text-align: left; }
.gtbl td { padding: 5px 8px; border-bottom: 1px solid var(--yg-line-2); color: var(--yg-tx2); }
.gtbl td.fp { font-weight: 800; color: var(--yg-accent-dp); }
.led-bulk .sep { width: 1px; height: 18px; background: var(--yg-line); }

@media (max-width: 900px) {
  .led-row .hd { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════════════════
   설비 제어 공통 — 상단 컨트롤 바의 질서.

   컨트롤 카드가 흰 판 하나에 라벨·버튼·설명이 뒤섞여 "어디까지가 한 묶음인지"가
   안 보였다. 라벨 폭을 고정하고, 묶음 사이에 구분선을 두고, 설명은 오른쪽 끝으로
   민다 — 왼쪽에서 오른쪽으로 [무엇을] [고르고] [무엇이 되는지] 순서가 되게.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .yg-ctrl .lb { min-width: 30px; }
body.skin-yongin .nt-subs { gap: 9px; }
body.skin-yongin .nt-subs .lb { flex: none; font-size: 11px; font-weight: 900;
                                color: var(--yg-accent-dp); background: var(--yg-accent-sf);
                                padding: 3px 9px; border-radius: 999px; min-width: 0; }
body.skin-yongin .nt-subs .note-inline { flex: 1; min-width: 180px; }

/* 양액 — LED 와 같은 문법으로 맞춘다(둘이 다른 화면처럼 보이지 않게) */
.nt-card { border-radius: var(--yg-r); padding: 0; overflow: hidden; }
.nt-card .hd { padding: 10px 12px 8px; border-left: 4px solid var(--yg-line); }
.nt-card.bad .hd { border-left-color: var(--yg-warn); }
.nt-card.sel .hd { border-left-color: var(--yg-accent); }
.nt-card.sel::before { display: none; }
.nt-card .ms { padding: 0 12px; }
.nt-card .ft { margin: 8px 12px 9px; }
.nt-card .nodev { padding: 16px 12px 18px; }

/* 카드 그리드가 화면 폭을 다 못 쓰던 문제 — 최소폭을 낮추고 정렬을 맞춘다 */
.nt-grid { grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); align-items: start; }

/* ── 공급펌프 — LED 와 같은 뼈대를 쓰고 색만 바꾼다(물=시안, 빛=앰버) ────── */
.yg-pump .led-row.lit .hd { border-left-color: #38bdf8;
                            background: linear-gradient(90deg, #f5fcff, #fff 42%); }
.yg-pump .led-row .sw.on { border-color: #3aa3cc; background: #f0faff; color: #24657f; }
.yg-pump .led-row .sw.on i { background: #38bdf8; box-shadow: 0 0 7px rgba(56, 189, 248, .8); }
.pmstrip { flex: 1; min-width: 130px; position: relative; display: flex;
           flex-direction: column; gap: 2px; }
.pmstrip .bar { position: relative; height: 16px; border-radius: 5px; overflow: hidden;
                border: 1px solid var(--yg-line); background-color: #eef4f8; }
/* 사이클은 완전 주기라 **반복 그라디언트 한 줄**로 그린다 — 5분 조각을 576개
   만들면 랙 18개에 1만 개가 넘는다. --on 이 ON 비율, background-position 이 위상. */
.pmstrip .bar.cyc { background-image: linear-gradient(90deg,
                      #4cc3ec 0, #4cc3ec var(--on), #e2edf4 var(--on), #e2edf4 100%);
                    background-repeat: repeat-x; }
.pmstrip .bar.cont { background-image: linear-gradient(180deg, #6fd3f5, #3fb4e0); }
.pmstrip .bar.none { background-image: repeating-linear-gradient(45deg,
                       #eef2f6 0 6px, #e3e9ef 6px 12px); }
.pmstrip b.now { position: absolute; top: -2px; height: 20px; left: 50%; width: 2px;
                 border-radius: 1px; background: var(--yg-accent-dp); box-shadow: 0 0 0 1px #fff; }
.pmstrip .ax { position: relative; height: 10px; }
.pmstrip u { position: absolute; top: 0; font-size: 8.5px; font-weight: 700; color: var(--yg-tx3);
             text-decoration: none; transform: translateX(-50%); }
.pmstrip u:first-child { transform: none; }
.pmstrip u:last-child { transform: translateX(-100%); }
.bigstrip .pmstrip .bar { height: 24px; }
.bigstrip .pmstrip b.now { height: 28px; }
.bigstrip .pmstrip u { font-size: 9.5px; }
.slg i.off { background: #e2edf4; border: 1px solid var(--yg-line); }
.yg-pump .slg i.on { background: linear-gradient(180deg, #6fd3f5, #3fb4e0); }

.led-row .st .pmph { font-weight: 800; }
.led-row .st .pmph.on { color: #1f6f8c; }
.led-row .st .pmph.off { color: var(--yg-tx3); }

/* 시나리오 선택 — 두 카드 중 하나 */
.led-panel .scn { display: flex; flex-direction: column; gap: 6px; }
.led-panel .sc { text-align: left; font: inherit; cursor: pointer; padding: 8px 10px;
                 border-radius: var(--yg-r-sm); border: 1px solid var(--yg-line);
                 background: var(--yg-surface-2); display: flex; flex-direction: column; gap: 2px; }
.led-panel .sc b { font-size: 11.5px; font-weight: 800; color: var(--yg-tx); }
.led-panel .sc span { font-size: 10px; font-weight: 600; color: var(--yg-tx3); }
.led-panel .sc.on { border-color: #3aa3cc; background: #f0faff; }
.led-panel .sc.on b { color: #1f6f8c; }
.yg-pump .led-panel .dayline { background: #eff9fd; }
.yg-pump .led-panel .dayline b { color: #1f6f8c; }
.yg-pump .led-panel .dayline span { color: #35708a; }

/* ══════════════════════════════════════════════════════════════════════════
   2D 배치 미니맵 — 제어 화면의 위치 가이드.
   "RACK 03" 이 어느 자리인지 알려주지 않으면 룸마다 01 부터 다시 시작하는 구조에서
   엉뚱한 랙을 조작하게 된다. 도면 좌표는 3D 오버뷰와 **같은 소스**를 읽는다.
   ══════════════════════════════════════════════════════════════════════════ */
.yg-map { padding: 0; overflow: hidden; margin-bottom: 11px; }
.yg-map .mh { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 9px 14px; }
.yg-map.fold .mh { padding-bottom: 9px; }
.yg-map .mh .t { font-size: 11px; font-weight: 900; color: var(--yg-accent-dp);
                 background: var(--yg-accent-sf); padding: 3px 9px; border-radius: 999px; }
.yg-map .mh .s { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
.yg-map .mh .s b { color: var(--yg-tx2); font-weight: 800; }
.yg-map .mh .sp { flex: 1; }
.yg-map .mb { display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
              padding: 0 14px 13px; border-top: 1px solid var(--yg-line-2); padding-top: 12px; }
/* 높이로 크기를 잡는다 — 폭으로 잡으면 도면 비율(가로 1.39:1) 때문에 카드가 세로로
   길어져 목록을 밀어낸다. 가이드는 곁눈으로 보는 것이라 작아도 된다. */
.ygmap { flex: none; height: 200px; width: auto; max-width: 100%; display: block; }

.ygmap .bld { fill: #fbfcfe; stroke: var(--yg-tx3); stroke-width: 0.06; }
.ygmap .rm rect { fill: #f1f4f8; stroke: var(--yg-line); stroke-width: 0.03; }
.ygmap .rm.grow rect { fill: #eef6f1; cursor: pointer; }
.ygmap .rm.grow:hover rect { fill: #e2f2ea; }
.ygmap .rm.on rect { fill: #d9f0e5; stroke: var(--yg-accent); stroke-width: 0.07; }
.ygmap .rmn { font-size: 0.46px; font-weight: 800; fill: var(--yg-tx3); }
.ygmap .rm.on .rmn { fill: var(--yg-accent-dp); }
.ygmap .wl { stroke: var(--yg-tx3); stroke-width: 0.05; opacity: .55; }
/* 랙 — 번호가 이 지도의 요점이다. 거터 랙은 폭이 0.5m 뿐이라 글자를 90° 돌린다. */
.ygmap .rk rect { fill: #fff; stroke: #7d8896; stroke-width: 0.045; cursor: pointer; }
/* 번호가 이 지도의 요점이라 글자를 키운다. 거터 랙은 90° 돌아 있어 긴 변(1.2)을
   쓰므로 0.46 이어도 칸을 안 넘는다(측정으로 확인). */
.ygmap .rk text { font-size: 0.46px; font-weight: 800; fill: var(--yg-tx2);
                  text-anchor: middle; pointer-events: none; }
.ygmap .rk:hover rect { fill: var(--yg-accent-sf); stroke: var(--yg-accent-2); }
.ygmap .rk.on rect { fill: #fdefc9; stroke: #b8871f; stroke-width: 0.09; }
.ygmap .rk.on text { fill: #7a5c12; }
.ygmap .rk.dim { opacity: .38; }
.yg-pump .ygmap .rk.on rect { fill: #dff2fb; stroke: #2b88ad; }
.yg-pump .ygmap .rk.on text { fill: #1f6f8c; }

.yg-map .mlg { flex: 1; min-width: 170px; display: flex; flex-direction: column; gap: 6px; }
.yg-map .mlg span { display: inline-flex; align-items: center; gap: 6px;
                    font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
.yg-map .mlg i { width: 13px; height: 10px; border-radius: 3px; flex: none; border: 1px solid var(--yg-line); }
.yg-map .mlg i.sel { background: #d9f0e5; border-color: var(--yg-accent); }
.yg-map .mlg i.rk { background: #fff; border-color: #7d8896; }
.yg-map .mlg i.cur { background: #fdefc9; border-color: #b8871f; }
.yg-map .mlg .hint { color: var(--yg-tx3); font-weight: 600; line-height: 1.5; }

@media (max-width: 700px) {
  .ygmap { height: auto; width: 100%; }
  .yg-map .mb { gap: 10px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   설비 제어 › 공조기

   LED·펌프처럼 랙이 없다 — 시설에 한 대뿐이라 목록이 아니라 **도메인 상자 2개**다.
   운전모드와 급기 목표온도는 서로 다른 스케줄·다른 자동/수동을 가지므로, 화면에서도
   섞이지 않게 상자를 분리한다(둘을 한 표에 넣으면 "자동" 배지가 어느 쪽 것인지
   읽는 사람이 매번 헷갈린다).
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .yg-hvacctl { display: block; }

body.skin-yongin .hvbox { padding: 0; overflow: hidden; }   /* 세로 간격은 공통 규칙이 준다 */
body.skin-yongin .hvbox > .h {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 13px 16px; border-bottom: 1px solid var(--yg-line);
  background: var(--yg-surface-2);
}
body.skin-yongin .hvbox > .h .t { font-size: 14px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .hvbox > .h .s { font-size: 12px; color: var(--yg-tx3); font-weight: 600; }
body.skin-yongin .hvbox > .h .sp { flex: 1; }

/* 데이터 출처 — "지금 보는 값이 설비에서 직접 읽은 건지, 마지막 수집값인지"는
   제어 화면에서 반드시 구분돼야 한다. 수집값을 실시간으로 착각하면 이미 바뀐 설비를
   안 바뀐 줄 알고 다시 누르게 된다. */
body.skin-yongin .hvbox .src {
  font-size: 11px; font-weight: 800; padding: 3px 9px; border-radius: 999px;
  border: 1px solid; letter-spacing: .01em;
}
body.skin-yongin .hvbox .src.live        { color: #0b6b4f; background: #e8f8f1; border-color: #a7dcc7; }
body.skin-yongin .hvbox .src.telemetry   { color: #8a6100; background: #fdf4e0; border-color: #e6cf9a; }
body.skin-yongin .hvbox .src.unavailable { color: #7a4a44; background: #fbecea; border-color: #e6bfb9; }

/* 현재값 줄 — 명령 → 실제 */
body.skin-yongin .hvnow {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 16px; border-bottom: 1px solid var(--yg-line-2);
}
body.skin-yongin .hvnow .p { display: flex; flex-direction: column; gap: 3px; min-width: 92px; }
body.skin-yongin .hvnow .p span { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .hvnow .p b { font-size: 19px; font-weight: 800; color: var(--yg-tx); line-height: 1.1; }
body.skin-yongin .hvnow .ar { font-size: 16px; color: #69737f; font-weight: 700; }
body.skin-yongin .hvnow .sp { flex: 1; }
body.skin-yongin .hvnow .yg-num { width: 104px; }

/* 모드 버튼 — 색은 띠와 같은 것을 쓴다(같은 것을 두 색으로 보여주지 않는다).
   평시에는 테두리·점으로만 색을 쓰고, 선택된 것만 채운다. */
body.skin-yongin .hvbtns { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 16px 4px; }
body.skin-yongin .hvm {
  position: relative; padding: 9px 15px 9px 28px; border-radius: 10px; cursor: pointer;
  font-size: 13px; font-weight: 700; color: var(--yg-tx);
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  transition: background .12s, border-color .12s, transform .06s;
}
body.skin-yongin .hvm::before {
  content: ''; position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 9px; height: 9px; border-radius: 50%; background: var(--c);
}
body.skin-yongin .hvm:hover { background: var(--yg-surface-2); border-color: #cfd7e2; }
body.skin-yongin .hvm:active { transform: translateY(1px); }
/* 선택 시 채우는 색은 --ct(같은 색상의 어두운 톤)다. --c 로 채우면 흰 글자 대비가
   모드마다 달라진다 — 송풍 2.42:1, 자동 3.07:1 로 **어떤 모드일 때만 안 보이는** 화면이 된다. */
body.skin-yongin .hvm.on {
  color: #fff; background: var(--ct); border-color: var(--ct);
}
body.skin-yongin .hvm.on::before { background: rgba(255, 255, 255, .92); }
body.skin-yongin .hvm[disabled] { opacity: .45; cursor: default; }

body.skin-yongin .hvbox .hint {
  padding: 10px 16px 14px; font-size: 12px; line-height: 1.65;
  color: var(--yg-tx3); font-weight: 600;
}
body.skin-yongin .hvbox .hint b { color: var(--yg-tx2); font-weight: 800; }

/* 결과 배너 — 쓰기 결과는 **되읽어 확인한 값**이라 화면 폴링보다 먼저 믿을 수 있다.
   그래서 사라지는 토스트가 아니라 다음 조작까지 남는 줄로 둔다. */
body.skin-yongin .hvmsg {
  padding: 11px 15px; border-radius: var(--yg-r-sm); margin-bottom: 12px;
  font-size: 13px; font-weight: 700; border: 1px solid;
}
body.skin-yongin .hvmsg.ok   { color: #0b6b4f; background: #e8f8f1; border-color: #a7dcc7; }
body.skin-yongin .hvmsg.err  { color: #96332a; background: #fbecea; border-color: #e6bfb9; }
body.skin-yongin .hvmsg.wait { color: #4a5568; background: var(--yg-surface-2); border-color: var(--yg-line); }

/* ── 스케줄 ─────────────────────────────────────────────────────────────── */
body.skin-yongin .hvsched { border-top: 1px solid var(--yg-line); background: var(--yg-surface-2); }
body.skin-yongin .hvsched .sh {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 12px 16px 0;
}
body.skin-yongin .hvsched .sh .k { font-size: 12px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .hvsched .sh .sp { flex: 1; }
body.skin-yongin .hvsched .st {
  padding: 9px 16px 0; font-size: 12px; font-weight: 700; color: var(--yg-tx2);
}

/* 24시간 띠 — 구간이 맞닿으므로 경계가 보여야 한다(색 최소 ΔE 42.0 은 JS 쪽 주석). */
body.skin-yongin .hvband { padding: 10px 16px 4px; }
body.skin-yongin .hvband .bar {
  position: relative; height: 26px; border-radius: 7px; overflow: hidden;
  background: #eef1f6; border: 1px solid var(--yg-line);
}
body.skin-yongin .hvband .bar.empty {
  background: repeating-linear-gradient(45deg, #f2f4f8 0 7px, #e8ecf2 7px 14px);
}
body.skin-yongin .hvband .bar i { position: absolute; top: 0; bottom: 0; }
body.skin-yongin .hvband .bar i + i { box-shadow: -1px 0 0 rgba(255, 255, 255, .55); }
body.skin-yongin .hvband .bar .now {
  position: absolute; top: -2px; bottom: -2px; width: 2px; background: #0f172a;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .8);
}
body.skin-yongin .hvband .ax { position: relative; height: 15px; margin-top: 3px; }
body.skin-yongin .hvband .ax u {
  position: absolute; top: 0; font-size: 10px; font-weight: 700; font-style: normal;
  text-decoration: none; color: var(--yg-tx3); transform: translateX(-50%);
}

body.skin-yongin .hvsched .sgs {
  display: flex; flex-direction: column; gap: 7px; padding: 8px 16px 4px;
}
body.skin-yongin .hvsched .sgr {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 10px; border-radius: 10px;
  background: var(--yg-surface); border: 1px solid var(--yg-line);
}
body.skin-yongin .hvsched .sgr i {
  width: 10px; height: 10px; border-radius: 3px; flex: none;
  box-shadow: 0 0 0 1px rgba(15, 23, 42, .12) inset;
}
body.skin-yongin .hvsched .sgr .yg-date { width: 118px; }
body.skin-yongin .hvsched .sgr .yg-num { width: 92px; }
body.skin-yongin .hvsched .sgr .yg-select { min-width: 104px; }
body.skin-yongin .hvsched .sgr .yg-btn { margin-left: auto; }

/* ── 보조 지표 ──────────────────────────────────────────────────────────── */
body.skin-yongin .hvbox .svs {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 8px; padding: 14px 16px;
}
body.skin-yongin .hvbox .sv {
  display: flex; flex-direction: column; gap: 2px; padding: 9px 11px;
  border-radius: 10px; background: var(--yg-surface-2); border: 1px solid var(--yg-line-2);
}
body.skin-yongin .hvbox .sv span { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .hvbox .sv b { font-size: 15px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .hvbox .sv b u {
  font-size: 11px; font-weight: 700; color: var(--yg-tx3);
  text-decoration: none; margin-left: 1px;
}

@media (max-width: 700px) {
  body.skin-yongin .hvsched .sgr .yg-btn { margin-left: 0; }
  body.skin-yongin .hvbtns { padding-left: 12px; padding-right: 12px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   환경 지표 탐색기 (용인)

   구간 카드를 세로로 쌓는다. 카드 하나 = 하나의 질문("이 랙·이 기간이 목표대로
   유지됐나"). 차트는 **지표마다 하나씩** 쌓인다 — 축이 다른 값을 한 축에 얹으면
   비교가 아니라 뭉갬이 되고, 목표선은 단위가 섞인 축에서 의미를 잃는다.
   ══════════════════════════════════════════════════════════════════════════ */
/* 표시·세로 간격은 위 '목록형' 공통 규칙이 함께 맡는다 */
body.skin-yongin .ex-top { position: sticky; top: 0; z-index: 4; }

body.skin-yongin .ex-seg { padding: 0; overflow: hidden; }
body.skin-yongin .ex-seg > .sh {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 11px 14px; background: var(--yg-surface-2);
}
body.skin-yongin .ex-seg.open > .sh { border-bottom: 1px solid var(--yg-line); }
body.skin-yongin .ex-seg .sh .tw {
  font: inherit; font-size: 13px; line-height: 1; width: 24px; height: 24px; flex: none;
  border-radius: 7px; border: 1px solid var(--yg-line); background: var(--yg-surface);
  color: var(--yg-tx2); cursor: pointer;
}
body.skin-yongin .ex-seg .sh .tw:hover { border-color: #cfd7e2; }
body.skin-yongin .ex-seg .sh .nm {
  font: inherit; font-size: 13.5px; font-weight: 800; color: var(--yg-tx);
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  padding: 4px 7px; min-width: 150px; max-width: 300px;
}
body.skin-yongin .ex-seg .sh .nm:hover { border-color: var(--yg-line); background: var(--yg-surface); }
/* 작기에서 불러온 구간 — 목표선의 출처가 있다는 표시다 */
body.skin-yongin .ex-seg .sh .cr {
  font-size: 10.5px; font-weight: 800; padding: 3px 9px; border-radius: 999px;
  color: var(--yg-accent-dp); background: var(--yg-accent-sf); border: 1px solid #a7dcc7;
}
body.skin-yongin .ex-seg .sh .sp { flex: 1; }
body.skin-yongin .ex-seg .sh .cnt { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .ex-seg .sh .cnt.warn { color: var(--yg-warn-tx); }

body.skin-yongin .ex-seg .sb { padding: 11px 14px 12px; border-bottom: 1px solid var(--yg-line-2); }
body.skin-yongin .ex-seg .sb .row {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
body.skin-yongin .ex-seg .sb .row + .row { margin-top: 9px; }
body.skin-yongin .ex-seg .sb .k {
  font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em;
  width: 30px; flex: none;
}
body.skin-yongin .ex-seg .sb .tl { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .ex-seg .sb .sp { flex: 1; }
/* `.chips` 는 이 절 아래 **공통 규칙**이 맡는다 (예전엔 화면마다 따로 정의해서, 빠뜨린
   화면에서는 칩이 간격 없이 붙었다 — 재배 설계의 룸 버튼이 그랬다) */

/* 칩 — 룸·랙·단은 같은 문법으로 고른다(다르게 생기면 셋을 다른 조작으로 읽는다) */
body.skin-yongin .yg-chip {
  font: inherit; font-size: 11.5px; font-weight: 700; padding: 5px 11px;
  border-radius: 999px; cursor: pointer;
  color: var(--yg-tx2); background: var(--yg-surface); border: 1px solid var(--yg-line);
  transition: background .12s, border-color .12s, color .12s;
}
body.skin-yongin .yg-chip:hover { border-color: #cfd7e2; background: var(--yg-surface-2); }
body.skin-yongin .yg-chip.on {
  color: #fff; background: var(--yg-accent-dp); border-color: var(--yg-accent-dp);
}

body.skin-yongin .ex-seg .sc { padding: 12px 14px 4px; }
body.skin-yongin .ex-chart + .ex-chart { margin-top: 12px; padding-top: 12px;
                                         border-top: 1px solid var(--yg-line-2); }
body.skin-yongin .ex-chart .ch {
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; margin-bottom: 6px;
}
body.skin-yongin .ex-chart .ch b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .ex-chart .ch .u { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .ex-chart .ch .tg {
  margin-left: auto; font-size: 10.5px; font-weight: 800; color: var(--yg-tx2);
  background: var(--yg-line-2); padding: 2px 9px; border-radius: 999px;
}
body.skin-yongin .ex-chart .ch .tg.none { color: var(--yg-tx3); font-weight: 700; background: transparent; }
body.skin-yongin .ex-chart .cv { position: relative; height: 190px; }

body.skin-yongin .ex-wait { padding: 26px 14px; text-align: center;
                            font-size: 12px; font-weight: 700; color: var(--yg-tx3); }

/* ── 표 ─────────────────────────────────────────────────────────────────── */
body.skin-yongin .ex-seg .st { padding: 0 14px 13px; }
body.skin-yongin .ex-tblhead {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 10px 0 8px;
}
body.skin-yongin .ex-tblhead .k { font-size: 11.5px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .ex-tblhead .n { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .ex-tblhead .sp { flex: 1; }
/* 표는 넓어질 수 있다 — **자기 안에서** 가로 스크롤한다(페이지가 흔들리면 안 된다) */
body.skin-yongin .ex-tblwrap {
  overflow: auto; max-height: 340px; border: 1px solid var(--yg-line);
  border-radius: var(--yg-r-sm); background: var(--yg-surface);
}
body.skin-yongin .ex-tbl { border-collapse: collapse; width: 100%; font-size: 11.5px; }
body.skin-yongin .ex-tbl th {
  position: sticky; top: 0; z-index: 1; background: var(--yg-surface-2);
  color: var(--yg-tx2); font-weight: 800; text-align: right; white-space: nowrap;
  padding: 7px 10px; border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin .ex-tbl th:first-child { text-align: left; }
body.skin-yongin .ex-tbl th u {
  display: block; font-size: 9.5px; font-weight: 700; color: var(--yg-tx3);
  text-decoration: none; margin-top: 1px;
}
body.skin-yongin .ex-tbl td {
  padding: 5px 10px; text-align: right; white-space: nowrap;
  color: var(--yg-tx); border-bottom: 1px solid var(--yg-line-2);
  font-variant-numeric: tabular-nums;
}
body.skin-yongin .ex-tbl td.ts { text-align: left; color: var(--yg-tx3); font-weight: 700; }
/* 메꾼 값 — admin(원본) 뷰에서만 구분한다. 색만으로 말하지 않도록 기울임을 함께 준다. */
body.skin-yongin .ex-tbl td.fill { color: var(--yg-tx3); font-style: italic; }
body.skin-yongin .ex-tbl tbody tr:hover td { background: var(--yg-accent-sf); }

/* ── 작기 고르기 ────────────────────────────────────────────────────────── */
body.skin-yongin .ex-crops { display: grid; gap: 8px; margin-top: 10px;
                             grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }
body.skin-yongin .ex-crops .cw {
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
  font: inherit; text-align: left; cursor: pointer; padding: 10px 12px;
  border-radius: var(--yg-r-sm); background: var(--yg-surface);
  border: 1px solid var(--yg-line); box-shadow: var(--yg-shadow);
}
body.skin-yongin .ex-crops .cw:hover { border-color: var(--yg-accent-2); box-shadow: var(--yg-shadow-lg); }
body.skin-yongin .ex-crops .cw b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .ex-crops .cw .m { font-size: 11px; font-weight: 700; color: var(--yg-tx2); }
body.skin-yongin .ex-crops .cw .t {
  font-size: 10.5px; font-weight: 800; color: var(--yg-accent-dp);
  background: var(--yg-accent-sf); padding: 2px 8px; border-radius: 999px; margin-top: 3px;
}
body.skin-yongin .ex-crops .cw .t.none {
  color: var(--yg-tx3); background: var(--yg-line-2);
}

@media (max-width: 700px) {
  body.skin-yongin .ex-seg .sb .k { width: auto; }
  body.skin-yongin .ex-chart .cv { height: 170px; }
  body.skin-yongin .ex-chart .ch .tg { margin-left: 0; }
}

/* ══════════════════════════════════════════════════════════════════════════
   재배 설계 (용인)

   왼쪽에 랙 카드 판, 오른쪽에 편집 패널. 카드는 **현장 뷰의 재배 정보 팝업과 같은
   문법**(작물 타일 + 이름 + 진행바)이다 — 같은 것을 두 화면에서 다르게 보여주면
   같은 것인지 알아볼 수 없다. 그래서 `.yg-crop` · `.yg-prog` 를 그대로 쓴다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .cd-top .lb b { color: var(--yg-tx); font-size: 12px; }
body.skin-yongin .cd-top .lb b.warn { color: var(--yg-warn-tx); }

body.skin-yongin .cd-body { display: flex; gap: 12px; align-items: flex-start; }
body.skin-yongin .cd-grid {
  flex: 1; min-width: 0; display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(216px, 1fr));
}
body.skin-yongin .cd-panel { width: 396px; flex: none; position: sticky; top: 60px; }

/* ── 랙 카드 ────────────────────────────────────────────────────────────── */
body.skin-yongin .cd-card {
  font: inherit; text-align: left; cursor: pointer; display: block; width: 100%;
  padding: 11px 13px 12px; border-radius: var(--yg-r-sm);
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  box-shadow: var(--yg-shadow); transition: border-color .12s, box-shadow .12s;
}
body.skin-yongin .cd-card:hover { border-color: #cfd7e2; box-shadow: var(--yg-shadow-lg); }
body.skin-yongin .cd-card.on {
  border-color: var(--yg-accent-2); box-shadow: 0 0 0 3px var(--yg-ring), var(--yg-shadow);
}
/* 미등록 — 점선으로 그리지 않는다(윤곽이 깨져 보인다). 면과 글자로 말한다. */
body.skin-yongin .cd-card.none {
  background: var(--yg-surface-2); border-color: var(--yg-line-mute);
}
body.skin-yongin .cd-card .hd {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-bottom: 9px;
}
body.skin-yongin .cd-card .hd b { font-size: 12px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .cd-card .hd .rm { font-size: 10px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .cd-card .hd .exp {
  margin-left: auto; font-size: 9.5px; font-weight: 800; color: #5b21b6;
  background: #f5f3ff; border-radius: 6px; padding: 2px 7px; white-space: nowrap;
}
body.skin-yongin .cd-card .nodev {
  padding: 14px 0 10px; text-align: center;
  font-size: 11.5px; font-weight: 700; color: var(--yg-tx2);
}
body.skin-yongin .cd-card .yg-crop .stg {
  margin-left: 6px; font-size: 9.5px; font-weight: 800; color: var(--yg-tx2);
  background: var(--yg-line-2); border-radius: 999px; padding: 2px 7px;
}
body.skin-yongin .cd-card .cnd {
  margin-top: 9px; font-size: 10.5px; font-weight: 800;
  color: var(--yg-accent-dp); background: var(--yg-accent-sf);
  border-radius: 999px; padding: 3px 9px; display: inline-block;
}
/* 목표조건이 없으면 **경고가 아니라 상태**다 — 아직 안 정했을 뿐이다. */
body.skin-yongin .cd-card .cnd.none { color: var(--yg-tx3); background: var(--yg-line-2); }

/* ── 편집 패널 ──────────────────────────────────────────────────────────── */
body.skin-yongin .cd-panel { padding: 0; overflow: hidden; }
body.skin-yongin .cd-panel.empty { padding: 0; }
body.skin-yongin .cd-panel > .h {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 11px 14px; background: var(--yg-surface-2);
  border-bottom: 1px solid var(--yg-line); margin: 0;
}
body.skin-yongin .cd-panel > .h .leaf {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
body.skin-yongin .cd-panel > .h .t { font-size: 13.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .cd-panel > .h .t .rm {
  margin-left: 6px; font-size: 10.5px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .cd-panel > .h .sp { flex: 1; }

body.skin-yongin .cd-panel .sec {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 12px 14px 2px;
}
body.skin-yongin .cd-panel .sec .k { font-size: 11px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .cd-panel .sec .s { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .cd-panel .sec .s b { color: var(--yg-tx2); font-weight: 800; }

body.skin-yongin .cd-panel .grid {
  display: grid; gap: 8px; padding: 8px 14px 2px;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
}
body.skin-yongin .cd-panel .grid label { display: flex; flex-direction: column; gap: 3px; }
body.skin-yongin .cd-panel .grid label > span {
  font-size: 10px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .02em;
}
/* 단위는 라벨 안에서 한 단계 낮춘다 — 이름과 같은 무게면 무엇이 이름인지 흐려진다 */
/* 단위는 이름보다 한 단계 낮추되 **읽히는 선 아래로 내리지 않는다** —
   #7c8899 는 흰 배경에서 3.60:1 이라 미달이었다(실측). */
body.skin-yongin .cd-panel .grid label > span u {
  font-weight: 700; font-style: normal; text-decoration: none; opacity: 1;
  color: #69737f;
}
/* 필수 표시는 색만으로 말하지 않는다 — 글자로도 '필수' 라고 적혀 있다 */
body.skin-yongin .cd-panel .grid label > span i {
  font-style: normal; font-size: 9.5px; font-weight: 800; color: #9a3412;
  background: #fff2e8; border-radius: 5px; padding: 1px 5px; margin-left: 3px;
}
body.skin-yongin .cd-panel .grid .yg-select,
body.skin-yongin .cd-panel .grid .yg-num,
body.skin-yongin .cd-panel .grid .yg-date { width: 100%; min-width: 0; }

body.skin-yongin .cd-note {
  font: inherit; font-size: 12px; width: calc(100% - 28px); margin: 6px 14px 0;
  padding: 8px 10px; border-radius: 9px; resize: vertical;
  color: var(--yg-tx); background: var(--yg-surface);
  border: 1px solid var(--yg-line);
}

body.skin-yongin .cd-panel .ft {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 14px 13px; margin-top: 10px;
  border-top: 1px solid var(--yg-line); background: var(--yg-surface-2);
}
body.skin-yongin .cd-panel .ft .tl {
  flex: 1; min-width: 170px; font-size: 11px; font-weight: 700;
  color: var(--yg-tx3); line-height: 1.55;
}
body.skin-yongin .cd-panel .ft .tl b { color: var(--yg-tx2); font-weight: 800; }
body.skin-yongin .cd-panel .ft .sp { flex: 0; }

body.skin-yongin .cd-msg {
  margin: 11px 14px 0; padding: 9px 12px; border-radius: var(--yg-r-sm);
  font-size: 12px; font-weight: 700; border: 1px solid;
}
body.skin-yongin .cd-msg.ok { color: #0b6b4f; background: #e8f8f1; border-color: #a7dcc7; }
body.skin-yongin .cd-msg.err { color: #96332a; background: #fbecea; border-color: #e6bfb9; }
body.skin-yongin .cd-msg.wait { color: #4a5568; background: var(--yg-surface-2); border-color: var(--yg-line); }

body.skin-yongin .cd-endrow {
  display: flex; align-items: center; gap: 10px; margin: 12px 0 4px;
}
body.skin-yongin .cd-endrow > span { font-size: 11px; font-weight: 800; color: var(--yg-tx2); }

@media (max-width: 1100px) {
  body.skin-yongin .cd-body { flex-direction: column; }
  body.skin-yongin .cd-panel { width: 100%; position: static; }
}


/* ── 다른 랙에 적용 ─────────────────────────────────────────────────────────
   남의 랙을 덮어쓰는 모달이다. **무엇을·어디에** 두 질문이 눈에 나뉘어야 하고,
   대상 칩은 덮어쓰는지(덮) 새로 만드는지(새) 못 고르는지(–)를 스스로 말해야 한다. */
body.skin-yongin .cd-ap-src {
  display: flex; align-items: center; gap: 10px; padding: 11px 12px;
  border-radius: var(--yg-r-sm); background: var(--yg-surface-2);
  border: 1px solid var(--yg-line);
}
body.skin-yongin .cd-ap-src .leaf {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
body.skin-yongin .cd-ap-src b { font-size: 13px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .cd-ap-src i {
  display: block; font-style: normal; font-size: 11px; font-weight: 700;
  color: var(--yg-tx3); margin-top: 2px;
}

body.skin-yongin .cd-ap-fields {
  display: grid; gap: 7px; margin-top: 8px;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}
body.skin-yongin .cd-ap-f {
  display: flex; align-items: flex-start; gap: 8px; cursor: pointer;
  padding: 9px 11px; border-radius: 10px;
  background: var(--yg-surface); border: 1px solid var(--yg-line);
}
body.skin-yongin .cd-ap-f.on { border-color: var(--yg-accent-2); background: var(--yg-accent-sf); }
body.skin-yongin .cd-ap-f input { margin-top: 2px; flex: none; }
body.skin-yongin .cd-ap-f b { font-size: 12px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .cd-ap-f i {
  display: block; font-style: normal; font-size: 10.5px; font-weight: 700;
  color: var(--yg-tx3); margin-top: 2px; line-height: 1.45;
}

body.skin-yongin .cd-ap-rooms { display: grid; gap: 9px; margin-top: 8px; }
body.skin-yongin .cd-ap-room {
  padding: 9px 11px 10px; border-radius: 10px;
  background: var(--yg-surface); border: 1px solid var(--yg-line);
}
body.skin-yongin .cd-ap-room .rh {
  display: flex; align-items: center; gap: 9px; margin-bottom: 7px;
}
body.skin-yongin .cd-ap-room .rh b { font-size: 11.5px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .cd-ap-room .rh .yg-btn { margin-left: auto; }
body.skin-yongin .cd-ap-room .rk { display: flex; gap: 6px; flex-wrap: wrap; }

body.skin-yongin .cd-ap-r {
  display: flex; align-items: center; gap: 5px; cursor: pointer;
  font: inherit; font-size: 11.5px; font-weight: 700; padding: 5px 9px;
  border-radius: 999px; color: var(--yg-tx2);
  background: var(--yg-surface); border: 1px solid var(--yg-line);
}
body.skin-yongin .cd-ap-r:hover { border-color: #cfd7e2; background: var(--yg-surface-2); }
body.skin-yongin .cd-ap-r.on {
  color: #fff; background: var(--yg-accent-dp); border-color: var(--yg-accent-dp);
}
/* 덮/새/– 는 색이 아니라 **글자로** 말한다 — 칩이 작아서 색만으로는 안 읽힌다 */
body.skin-yongin .cd-ap-r i {
  font-style: normal; font-size: 9.5px; font-weight: 800;
  padding: 1px 5px; border-radius: 5px;
  color: var(--yg-tx3); background: var(--yg-line-2);
}
body.skin-yongin .cd-ap-r.on i { color: var(--yg-accent-dp); background: #eafaf3; }
body.skin-yongin .cd-ap-r.off {
  cursor: default; color: var(--yg-tx3); background: var(--yg-surface-2);
  border-color: var(--yg-line-mute);
}

body.skin-yongin .cd-ap-sum {
  margin-top: 11px; padding: 10px 12px; border-radius: var(--yg-r-sm);
  font-size: 12px; font-weight: 700; line-height: 1.6;
  color: var(--yg-tx2); background: var(--yg-surface-2); border: 1px solid var(--yg-line);
}
body.skin-yongin .cd-ap-sum b { color: var(--yg-tx); font-weight: 800; }
/* 덮어쓰는 랙이 있으면 요약 자체가 경고가 된다 */
body.skin-yongin .cd-ap-sum.warn {
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border-color: #e6cf9a;
}
body.skin-yongin .cd-ap-sum.warn b { color: #8a4b06; }

body.skin-yongin .cy-modal-in .md-ft .sp { flex: 1; }


/* 센서 미연동 랙의 재배 팝업 머리말 — 계획은 보여주되 **대조는 못 한다**는 사실을
   먼저 말한다. 이 줄이 없으면 표의 '—' 가 "값이 안 들어온다" 로 읽힌다. */
body.skin-yongin .yg-offnote {
  margin: 0 0 9px; padding: 8px 11px; border-radius: 9px;
  font-size: 11px; font-weight: 700; line-height: 1.5;
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin .yg-offnote b { color: #8a4b06; font-weight: 800; }

/* ══════════════════════════════════════════════════════════════════════════
   작기 벤치마킹 (용인)

   축이 달력이 아니라 **생육일차**다. 그래서 슬라이더가 화면 위쪽에 하나만 있고,
   그 아래 열들이 그 값에 함께 반응한다 — 열마다 슬라이더를 두면 "같은 날" 이라는
   전제가 깨진다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .vb-day {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap; padding: 11px 15px;
  position: sticky; top: 0; z-index: 4;
}
body.skin-yongin .vb-day .k {
  font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em;
}
body.skin-yongin .vb-day .d {
  font-size: 17px; font-weight: 800; color: var(--yg-tx); min-width: 62px;
  font-variant-numeric: tabular-nums;
}
body.skin-yongin .vb-day input[type="range"] {
  flex: 1; min-width: 180px; accent-color: var(--yg-accent-dp);
}
body.skin-yongin .vb-day .mx { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }

body.skin-yongin .vb-cols {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
}
body.skin-yongin .vb-col {
  border-radius: var(--yg-r); overflow: hidden;
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  box-shadow: var(--yg-shadow);
  /* 열 색은 차트 계열 색과 같다 — 위아래가 같은 작기임을 색으로 잇는다 */
  border-top: 3px solid var(--c);
}
body.skin-yongin .vb-col .hd {
  display: flex; align-items: center; gap: 9px; padding: 11px 13px 9px;
}
body.skin-yongin .vb-col .hd .leaf {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
body.skin-yongin .vb-col .hd .t { flex: 1; min-width: 0; }
body.skin-yongin .vb-col .hd b { font-size: 13.5px; font-weight: 800; }
body.skin-yongin .vb-col .hd .var {
  font-size: 11px; font-weight: 700; color: var(--yg-tx3); margin-left: 5px;
}
body.skin-yongin .vb-col .hd .rk {
  display: block; font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); margin-top: 2px;
}
body.skin-yongin .vb-col .rg {
  padding: 0 13px 9px; font-size: 11px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .vb-col .rg b { color: var(--yg-tx2); }
body.skin-yongin .vb-col .rg em { font-style: normal; font-weight: 800; color: var(--yg-warn-tx); }
body.skin-yongin .vb-col .cams { display: flex; gap: 5px; flex-wrap: wrap; padding: 0 13px 9px; }

/* 사진 — 16:9 로 자리를 고정한다. 없을 때 칸이 접히면 열끼리 높이가 어긋나
   "같은 D+n" 을 나란히 보는 의미가 사라진다. */
body.skin-yongin .vb-col .ph {
  position: relative; aspect-ratio: 16 / 9; background: #0e141c; overflow: hidden;
}
body.skin-yongin .vb-col .ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
body.skin-yongin .vb-col .ph .cap {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 6px 10px;
  font-size: 10.5px; font-weight: 700; color: #eef2f7;
  background: linear-gradient(180deg, rgba(6,10,16,0) 0%, rgba(6,10,16,.82) 60%);
}
body.skin-yongin .vb-col .ph .cap b { color: #fff; font-weight: 800; }
/* 며칠 차이인지 — 이걸 숨기면 "D+15 사진" 이라며 D+9 것을 보여주게 된다 */
body.skin-yongin .vb-col .ph .cap em { font-style: normal; font-weight: 800; color: #f3c969; }
body.skin-yongin .vb-col .ph.none {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; padding: 14px; text-align: center;
  background: var(--yg-surface-2);
  border-top: 1px solid var(--yg-line-2); border-bottom: 1px solid var(--yg-line-2);
  font-size: 11.5px; font-weight: 800; color: var(--yg-tx2);
}
body.skin-yongin .vb-col .ph.none span {
  font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); line-height: 1.55; max-width: 260px;
}

body.skin-yongin .vb-col .svs {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
  gap: 7px; padding: 11px 13px 13px;
}
body.skin-yongin .vb-col .sv {
  display: flex; flex-direction: column; gap: 1px; padding: 7px 9px;
  border-radius: 9px; background: var(--yg-surface-2); border: 1px solid var(--yg-line-2);
}
body.skin-yongin .vb-col .sv span { font-size: 10px; font-weight: 800; color: var(--yg-tx3); }
body.skin-yongin .vb-col .sv b { font-size: 14px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .vb-col .sv b u {
  font-size: 9.5px; font-weight: 700; color: var(--yg-tx3);
  text-decoration: none; margin-left: 1px;
}
/* 목표 대비 — 화살표와 숫자를 함께 준다(색만으로 말하지 않는다) */
body.skin-yongin .vb-col .sv i {
  font-style: normal; font-size: 10px; font-weight: 800; color: var(--yg-tx2); margin-top: 1px;
}
body.skin-yongin .vb-col .sv i.up { color: #a8531c; }
body.skin-yongin .vb-col .sv i.dn { color: #1f5f8b; }
body.skin-yongin .vb-col .sv i.na { color: var(--yg-tx3); font-weight: 700; }


/* 피복률 카드 — 이 화면의 주인공이라 환경 지표보다 크게, 사진 바로 밑에 붙인다 */
body.skin-yongin .vb-col .cvr {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 10px 13px 0;
}
body.skin-yongin .vb-col .cvr .k {
  font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em;
}
body.skin-yongin .vb-col .cvr b {
  font-size: 22px; font-weight: 800; color: var(--yg-tx); line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
body.skin-yongin .vb-col .cvr b u {
  font-size: 12px; font-weight: 700; color: var(--yg-tx3); text-decoration: none; margin-left: 2px;
}
body.skin-yongin .vb-col .cvr i {
  font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--yg-tx2);
  margin-left: auto; text-align: right;
}
body.skin-yongin .vb-col .cvr.none b { color: var(--yg-tx3); font-size: 18px; }
body.skin-yongin .vb-col .cvr.none i { color: var(--yg-tx3); font-weight: 700; }

body.skin-yongin .vb-day .sep {
  width: 1px; height: 20px; background: var(--yg-line); flex: none;
}
body.skin-yongin .vb-day .prog {
  font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); min-width: 108px;
}
body.skin-yongin .vb-chart .foot {
  padding: 0 15px 13px; font-size: 10.5px; font-weight: 600; line-height: 1.7;
  color: var(--yg-tx3);
}
body.skin-yongin .vb-chart .foot b { color: var(--yg-tx2); font-weight: 800; }

body.skin-yongin .vb-chart { padding: 0; }
body.skin-yongin .vb-chart > .h {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 15px; border-bottom: 1px solid var(--yg-line);
  background: var(--yg-surface-2); margin: 0;
}
body.skin-yongin .vb-chart > .h .t { font-size: 13.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .vb-chart > .h .s { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .vb-chart > .h .sp { flex: 1; }
body.skin-yongin .vb-chart .cv { position: relative; height: 250px; padding: 12px 14px 14px; }

body.skin-yongin .vb-wait {
  padding: 30px 14px; text-align: center; font-size: 12px; font-weight: 700; color: var(--yg-tx3);
}

/* 없는 지표를 왜 안 그리는지 — 화면이 스스로 말한다 */
body.skin-yongin .vb-note > .h { margin-bottom: 8px; }
body.skin-yongin .vb-note > .h .t { font-size: 13px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .vb-note .b {
  font-size: 11.5px; font-weight: 600; line-height: 1.75; color: var(--yg-tx3);
}
body.skin-yongin .vb-note .b b { color: var(--yg-tx2); font-weight: 800; }

body.skin-yongin .vb-picks {
  display: grid; gap: 8px; margin-top: 10px;
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
}
body.skin-yongin .vb-picks .pk {
  display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer;
  font: inherit; padding: 10px 12px; border-radius: var(--yg-r-sm);
  background: var(--yg-surface); border: 1px solid var(--yg-line); box-shadow: var(--yg-shadow);
}
body.skin-yongin .vb-picks .pk:hover { border-color: var(--yg-accent-2); }
body.skin-yongin .vb-picks .pk.on { border-color: var(--yg-accent-dp); background: var(--yg-accent-sf); }
body.skin-yongin .vb-picks .pk.off {
  cursor: default; background: var(--yg-surface-2); border-color: var(--yg-line-mute);
}
body.skin-yongin .vb-picks .pk .leaf {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
body.skin-yongin .vb-picks .pk b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .vb-picks .pk i {
  display: block; font-style: normal; font-size: 10.5px; font-weight: 700;
  color: var(--yg-tx2); margin-top: 2px;
}

@media (max-width: 700px) {
  body.skin-yongin .vb-day .d { min-width: 0; }
  body.skin-yongin .vb-chart .cv { height: 210px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   기간 히스토리 (용인)

   고르는 곳(종류 → 장비 → 기간 → 해상도)이 위에 한 덩어리로 있고, 결과가 아래에
   쌓인다. 해상도 안내는 **조회 전에** 보여야 한다 — 받고 나서 "사실 평균이었다" 를
   알면 이미 늦다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .hy-pick { padding: 12px 15px 13px; }
body.skin-yongin .hy-pick .row {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
body.skin-yongin .hy-pick .row + .row {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--yg-line-2);
}
body.skin-yongin .hy-pick .k {
  font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em;
  width: 38px; flex: none;
}
body.skin-yongin .hy-pick .tl { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .hy-pick .sp { flex: 1; }
body.skin-yongin .hy-pick .yg-select.wide { min-width: 260px; max-width: 420px; }
/* 종류 칩의 개수 배지 — 장비가 없는 종류는 눌러도 소용없으니 비활성으로 보인다 */
body.skin-yongin .yg-chip i {
  font-style: normal; font-size: 9.5px; font-weight: 800;
  padding: 1px 5px; margin-left: 3px; border-radius: 5px;
  color: var(--yg-tx3); background: var(--yg-line-2);
}
body.skin-yongin .yg-chip.on i { color: var(--yg-accent-dp); background: #eafaf3; }
body.skin-yongin .yg-chip.off {
  cursor: default; color: var(--yg-tx3); background: var(--yg-surface-2);
  border-color: var(--yg-line-mute);
}
/* 고른 장비가 어떤 지표를 갖는지 — 레지스트리의 capabilities 를 그대로 보여준다 */
body.skin-yongin .hy-pick .caps {
  font-size: 10.5px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .hy-raw {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 11.5px; font-weight: 700; color: var(--yg-tx2);
}
body.skin-yongin .hy-raw input { accent-color: var(--yg-accent-dp); }
body.skin-yongin .hy-pick .res {
  font-size: 11px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .hy-pick .res b { color: var(--yg-tx2); font-weight: 800; }
/* 줄여서 준다는 사실은 **경고색**으로 — 원본인 줄 알고 쓰면 판단이 틀어진다 */
body.skin-yongin .hy-pick .res.down {
  color: var(--yg-warn-tx); background: var(--yg-warn-sf);
  border: 1px solid #e6cf9a; border-radius: 999px; padding: 3px 10px;
}
body.skin-yongin .hy-pick .res.down b { color: #8a4b06; }

body.skin-yongin .hy-charts { padding: 13px 15px 14px; }
body.skin-yongin .hy-note {
  padding: 9px 12px; margin-bottom: 12px; border-radius: var(--yg-r-sm);
  font-size: 11.5px; font-weight: 700; line-height: 1.6;
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin .hy-note b { color: #8a4b06; font-weight: 800; }

body.skin-yongin .hy-chart + .hy-chart {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--yg-line-2);
}
body.skin-yongin .hy-chart .ch {
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; margin-bottom: 6px;
}
body.skin-yongin .hy-chart .ch b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .hy-chart .ch .u { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .hy-chart .ch .n {
  margin-left: auto; font-size: 10.5px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .hy-chart .cv { position: relative; height: 200px; }
/* 상태값(on/off)은 선으로 그리지 않는다 — 요약 한 줄로 대신한다 */
body.skin-yongin .hy-chart.state .st {
  padding: 10px 12px; border-radius: 9px; font-size: 11.5px; font-weight: 700;
  color: var(--yg-tx2); background: var(--yg-surface-2); border: 1px solid var(--yg-line-2);
}
body.skin-yongin .hy-chart.state .st em {
  display: block; font-style: normal; font-size: 10.5px; font-weight: 700;
  color: var(--yg-tx3); margin-top: 3px;
}

body.skin-yongin .hy-table { padding: 0 15px 14px; }
body.skin-yongin .hy-tblhead {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 12px 0 8px;
}
body.skin-yongin .hy-tblhead .k { font-size: 11.5px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .hy-tblhead .n { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .hy-tblhead .sp { flex: 1; }
body.skin-yongin .hy-table .hint {
  font-size: 11px; font-weight: 600; color: var(--yg-tx3); line-height: 1.6;
  margin-bottom: 8px;
}
body.skin-yongin .hy-table .hint b { color: var(--yg-tx2); font-weight: 800; }
body.skin-yongin .hy-tblwrap {
  overflow: auto; max-height: 330px; border: 1px solid var(--yg-line);
  border-radius: var(--yg-r-sm); background: var(--yg-surface);
}
body.skin-yongin .hy-tbl { border-collapse: collapse; width: 100%; font-size: 11.5px; }
body.skin-yongin .hy-tbl th {
  position: sticky; top: 0; z-index: 1; background: var(--yg-surface-2);
  color: var(--yg-tx2); font-weight: 800; text-align: right; white-space: nowrap;
  padding: 7px 10px; border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin .hy-tbl th:first-child { text-align: left; }
body.skin-yongin .hy-tbl th u {
  display: block; font-size: 9.5px; font-weight: 700; color: var(--yg-tx3);
  text-decoration: none; margin-top: 1px;
}
body.skin-yongin .hy-tbl td {
  padding: 5px 10px; text-align: right; white-space: nowrap; color: var(--yg-tx);
  border-bottom: 1px solid var(--yg-line-2); font-variant-numeric: tabular-nums;
}
body.skin-yongin .hy-tbl td.ts { text-align: left; color: var(--yg-tx3); font-weight: 700; }
body.skin-yongin .hy-tbl tbody tr:hover td { background: var(--yg-accent-sf); }

body.skin-yongin .hy-wait {
  padding: 30px 14px; text-align: center; font-size: 12px; font-weight: 700; color: var(--yg-tx3);
}

@media (max-width: 700px) {
  body.skin-yongin .hy-pick .k { width: auto; }
  body.skin-yongin .hy-pick .yg-select.wide { min-width: 0; width: 100%; }
  body.skin-yongin .hy-chart .cv { height: 175px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   운영일지 (용인)

   위에서 거르고, 가운데서 쓰고, 아래로 읽는다. 위치 태그를 **칩으로** 고르게 한 것이
   이 화면의 핵심이라, 쓰는 자리와 거르는 자리가 같은 칩 문법을 쓴다 — 같은 조작으로
   보이면 같은 것을 고른다는 게 저절로 이해된다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .lg-filter,
body.skin-yongin .lg-write { padding: 12px 15px 13px; }
body.skin-yongin .lg-filter .row,
body.skin-yongin .lg-tags .row {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
body.skin-yongin .lg-filter .row + .row,
body.skin-yongin .lg-tags .row + .row {
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--yg-line-2);
}
body.skin-yongin .lg-filter .k,
body.skin-yongin .lg-tags .k {
  font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em;
  width: 32px; flex: none;
}

body.skin-yongin .lg-filter .sp, body.skin-yongin .lg-tags .sp { flex: 1; }
body.skin-yongin .lg-tags .tl { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .lg-filter input[type="search"] { min-width: 200px; }

body.skin-yongin .lg-write > .h {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 10px;
}
body.skin-yongin .lg-write > .h .t { font-size: 13.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .lg-write > .h .s { font-size: 11px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .lg-write > .h .s b { color: var(--yg-tx2); font-weight: 800; }
body.skin-yongin .lg-write > .h .sp { flex: 1; }

/* 유형 버튼 — 점(고유색)과 채움(어두운 톤)을 나눈다. 밝은 색으로 채우면 흰 글자 대비가
   유형마다 달라진다(공조기 모드 버튼에서 겪은 것과 같은 문제다). */
body.skin-yongin .lg-types { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 9px; }
body.skin-yongin .lg-type {
  position: relative; font: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  padding: 6px 12px 6px 25px; border-radius: 999px;
  color: var(--yg-tx2); background: var(--yg-surface); border: 1px solid var(--yg-line);
}
body.skin-yongin .lg-type::before {
  content: ''; position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  width: 8px; height: 8px; border-radius: 50%; background: var(--c);
}
body.skin-yongin .lg-type:hover { border-color: #cfd7e2; background: var(--yg-surface-2); }
body.skin-yongin .lg-type.on { color: #fff; background: var(--ct); border-color: var(--ct); }
body.skin-yongin .lg-type.on::before { background: rgba(255, 255, 255, .9); }

body.skin-yongin .lg-input {
  font: inherit; font-size: 13px; width: 100%; box-sizing: border-box;
  padding: 10px 12px; border-radius: var(--yg-r-sm); resize: vertical;
  color: var(--yg-tx); background: var(--yg-surface); border: 1px solid var(--yg-line);
}
body.skin-yongin .lg-tags { margin-top: 10px; }
body.skin-yongin .lg-tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 800; padding: 3px 5px 3px 9px; border-radius: 999px;
  color: var(--yg-accent-dp); background: var(--yg-accent-sf); border: 1px solid #a7dcc7;
}
body.skin-yongin .lg-tag button {
  font: inherit; font-size: 10px; line-height: 1; cursor: pointer; padding: 2px 4px;
  border: none; border-radius: 999px; color: var(--yg-accent-dp); background: transparent;
}
body.skin-yongin .lg-tag button:hover { background: #d3f2e3; }
body.skin-yongin .lg-tag.ro {
  color: var(--yg-tx2); background: var(--yg-line-2); border-color: var(--yg-line);
}

body.skin-yongin .lg-ft {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 11px;
}
body.skin-yongin .lg-ft .tl {
  flex: 1; min-width: 200px; font-size: 11px; font-weight: 700;
  color: var(--yg-tx3); line-height: 1.55;
}
body.skin-yongin .lg-ft .tl b { color: var(--yg-tx2); font-weight: 800; }
body.skin-yongin .lg-ft .sp { flex: 0; }

body.skin-yongin .lg-msg {
  padding: 9px 12px; border-radius: var(--yg-r-sm); margin-bottom: 10px;
  font-size: 12px; font-weight: 700; border: 1px solid;
}
body.skin-yongin .lg-msg.ok { color: #0b6b4f; background: #e8f8f1; border-color: #a7dcc7; }
body.skin-yongin .lg-msg.err { color: #96332a; background: #fbecea; border-color: #e6bfb9; }

/* ── 피드 ────────────────────────────────────────────────────────────────── */
body.skin-yongin .lg-day { padding: 0; overflow: hidden; }
body.skin-yongin .lg-day .dh {
  display: flex; align-items: baseline; gap: 9px;
  padding: 10px 15px; background: var(--yg-surface-2);
  border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin .lg-day .dh b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .lg-day .dh span { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }

body.skin-yongin .lg-item { padding: 12px 15px 13px; border-left: 3px solid var(--c); }
body.skin-yongin .lg-item + .lg-item { border-top: 1px solid var(--yg-line-2); }
body.skin-yongin .lg-item.editing { background: var(--yg-surface-2); }
body.skin-yongin .lg-item .hd {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 7px;
}
body.skin-yongin .lg-item .hd b { font-size: 12px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .lg-item .ty {
  font-size: 10.5px; font-weight: 800; padding: 3px 9px; border-radius: 999px;
}
body.skin-yongin .lg-item .who { font-size: 11.5px; font-weight: 800; color: var(--yg-tx2); }
body.skin-yongin .lg-item .tm { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .lg-item .sp { flex: 1; }
body.skin-yongin .lg-item .bd {
  font-size: 13px; line-height: 1.7; color: var(--yg-tx); white-space: normal;
}
body.skin-yongin .lg-item .tg { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 8px; }
body.skin-yongin .lg-item .phs { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 9px; }
body.skin-yongin .lg-item .phs .ph {
  display: block; width: 108px; height: 76px; border-radius: 9px; overflow: hidden;
  border: 1px solid var(--yg-line); background: #0e141c;
}
body.skin-yongin .lg-item .phs .ph img { width: 100%; height: 100%; object-fit: cover; display: block; }

body.skin-yongin .lg-wait {
  padding: 30px 14px; text-align: center; font-size: 12px; font-weight: 700; color: var(--yg-tx3);
}

@media (max-width: 700px) {
  body.skin-yongin .lg-filter .k, body.skin-yongin .lg-tags .k { width: auto; }
  body.skin-yongin .lg-filter input[type="search"] { min-width: 0; width: 100%; }
}

/* ══════════════════════════════════════════════════════════════════════════
   디바이스 상태 (용인)

   축은 **랙**이다. 100줄짜리 장비 표가 아니라, 랙 한 줄에 그 랙의 장비가 점으로 달려
   있고 나쁜 것부터 눈에 띈다. 줄 왼쪽의 색띠가 그 랙의 최악 상태다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .hz-only {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 11.5px; font-weight: 700; color: var(--yg-tx2);
}
body.skin-yongin .hz-only input { accent-color: var(--yg-accent-dp); }

body.skin-yongin .hz-sum { padding: 13px 15px 14px; }
body.skin-yongin .hz-sum .cards {
  display: grid; gap: 9px; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
}
body.skin-yongin .hz-sum .c {
  display: flex; flex-direction: column; gap: 2px; padding: 10px 12px;
  border-radius: var(--yg-r-sm); background: var(--yg-surface-2);
  border: 1px solid var(--yg-line-2); border-left: 3px solid var(--c, var(--yg-line));
}
body.skin-yongin .hz-sum .c span { font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); }
body.skin-yongin .hz-sum .c b {
  font-size: 21px; font-weight: 800; color: var(--yg-tx); font-variant-numeric: tabular-nums;
}
body.skin-yongin .hz-sum .c.bat { border-left-color: var(--yg-line); }
body.skin-yongin .hz-sum .c.bat.on {
  border-left-color: var(--yg-warn); background: var(--yg-warn-sf);
}
body.skin-yongin .hz-sum .c.bat.on b { color: var(--yg-warn-tx); }
body.skin-yongin .hz-sum .hint {
  margin-top: 11px; font-size: 11px; font-weight: 600; line-height: 1.65; color: var(--yg-tx3);
}
body.skin-yongin .hz-sum .hint b { color: var(--yg-tx2); font-weight: 800; }
body.skin-yongin .hz-low {
  margin-top: 10px; padding: 9px 12px; border-radius: var(--yg-r-sm);
  font-size: 11.5px; font-weight: 700; line-height: 1.6;
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin .hz-low b { color: #8a4b06; font-weight: 800; }

body.skin-yongin .hz-rows { padding: 0; overflow: hidden; }
body.skin-yongin .hz-row { border-left: 3px solid var(--c); }
body.skin-yongin .hz-row + .hz-row { border-top: 1px solid var(--yg-line-2); }
body.skin-yongin .hz-row.open { background: var(--yg-surface-2); }
body.skin-yongin .hz-row .hd {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; width: 100%;
  font: inherit; text-align: left; cursor: pointer; padding: 10px 14px;
  background: transparent; border: none;
}
body.skin-yongin .hz-row .hd:hover { background: var(--yg-accent-sf); }
body.skin-yongin .hz-row .hd .tw { font-size: 11px; color: var(--yg-tx3); width: 12px; flex: none; }
body.skin-yongin .hz-row .hd b { font-size: 12.5px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .hz-row .hd .sp { flex: 1; }
/* 점 하나가 장비 하나 — 색이 상태, 글자가 종류다(색만으로 말하지 않는다) */
body.skin-yongin .dots { display: flex; gap: 4px; flex-wrap: wrap; }
body.skin-yongin .dots .dot {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 18px; padding: 0 4px; border-radius: 5px;
  font-size: 9.5px; font-weight: 800; font-style: normal;
  color: #fff; background: var(--c);
}
body.skin-yongin .hz-row .hd .bad {
  font-size: 11px; font-weight: 800; color: var(--yg-warn-tx);
  background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
  border-radius: 999px; padding: 2px 9px;
}
body.skin-yongin .hz-row .hd .nd {
  font-size: 11px; font-weight: 700; color: var(--yg-tx3);
  background: var(--yg-line-2); border-radius: 999px; padding: 2px 9px;
}
body.skin-yongin .hz-row .hd .ok {
  font-size: 11px; font-weight: 800; color: var(--yg-tx2);
  font-variant-numeric: tabular-nums;
}

body.skin-yongin .hz-row .tb { padding: 0 14px 12px; }
body.skin-yongin .hz-row .tb table {
  width: 100%; border-collapse: collapse; font-size: 11.5px;
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r-sm); overflow: hidden;
}
body.skin-yongin .hz-row .tb th {
  text-align: left; font-weight: 800; color: var(--yg-tx2); background: var(--yg-surface-2);
  padding: 7px 10px; border-bottom: 1px solid var(--yg-line); white-space: nowrap;
}
body.skin-yongin .hz-row .tb td {
  padding: 6px 10px; color: var(--yg-tx); border-bottom: 1px solid var(--yg-line-2);
}
body.skin-yongin .hz-row .tb tr:last-child td { border-bottom: none; }
body.skin-yongin .hz-row .tb td em {
  font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .hz-row .tb td.id { color: var(--yg-tx3); font-size: 10.5px; }
body.skin-yongin .hz-row .tb td.low { color: var(--yg-warn-tx); font-weight: 800; }
body.skin-yongin .hz-row .tb .badge {
  font-size: 10.5px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
}
body.skin-yongin .hz-wait {
  padding: 30px 14px; text-align: center; font-size: 12px; font-weight: 700; color: var(--yg-tx3);
}

/* ══════════════════════════════════════════════════════════════════════════
   시스템 상태 (용인)

   맨 위 한 칸이 "지금 수집이 살아 있나" 다. 서비스가 떠 있는 것과 값이 들어오는 것은
   다른 문제라, 그 답을 제일 큰 글자로 둔다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .sy-ing { padding: 15px 17px 16px; border-left: 4px solid var(--yg-line); }
body.skin-yongin .sy-ing .t { font-size: 11px; font-weight: 800; color: var(--yg-tx3); }
body.skin-yongin .sy-ing .v {
  font-size: 24px; font-weight: 800; color: var(--yg-tx); margin: 3px 0 5px; line-height: 1.1;
}
body.skin-yongin .sy-ing .s { font-size: 12px; font-weight: 700; color: var(--yg-tx2); line-height: 1.6; }
body.skin-yongin .sy-ing .s b { color: var(--yg-tx); font-weight: 800; }
body.skin-yongin .sy-ing.ok { border-left-color: #2f9e7e; }
body.skin-yongin .sy-ing.ok .v { color: #22725b; }
body.skin-yongin .sy-ing.warn { border-left-color: var(--yg-warn); background: var(--yg-warn-sf); }
body.skin-yongin .sy-ing.warn .v { color: var(--yg-warn-tx); }
body.skin-yongin .sy-ing.bad { border-left-color: #dd6a4a; background: #fbecea; }
body.skin-yongin .sy-ing.bad .v { color: #96332a; }
body.skin-yongin .sy-ing.na { border-left-color: var(--yg-line-mute); }
body.skin-yongin .sy-ing.na .v { color: var(--yg-tx3); }

body.skin-yongin .sy-card { padding: 0; overflow: hidden; }
body.skin-yongin .sy-card > .h {
  display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
  padding: 11px 15px; background: var(--yg-surface-2);
  border-bottom: 1px solid var(--yg-line); margin: 0;
}
body.skin-yongin .sy-card > .h .t { font-size: 13px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .sy-card > .h .s { font-size: 10.5px; font-weight: 700; color: var(--yg-tx3); }
body.skin-yongin .sy-card > .h .s b { color: var(--yg-tx2); font-weight: 800; }

body.skin-yongin .sy-card .svs {
  display: grid; gap: 8px; padding: 12px 15px 14px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
body.skin-yongin .sy-card .sv {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 11px; border-radius: 10px;
  background: var(--yg-surface-2); border: 1px solid var(--yg-line-2);
}
body.skin-yongin .sy-card .sv .k {
  font-size: 11.5px; font-weight: 800; color: var(--yg-tx2); flex: 1; min-width: 90px;
}
body.skin-yongin .sy-card .sv .v { font-size: 12px; font-weight: 700; color: var(--yg-tx2); }
body.skin-yongin .sy-card .sv .v.big { font-size: 16px; font-weight: 800; color: var(--yg-tx); }
body.skin-yongin .sy-card .sv em {
  flex-basis: 100%; font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin .sy-card .badge {
  font-size: 11px; font-weight: 800; padding: 3px 10px; border-radius: 999px; border: 1px solid;
}
body.skin-yongin .sy-card .badge.ok { color: #0b6b4f; background: #e8f8f1; border-color: #a7dcc7; }
body.skin-yongin .sy-card .badge.bad { color: #96332a; background: #fbecea; border-color: #e6bfb9; }
/* '미설치'·'확인 불가' 는 고장이 아니다 — 중립색으로 둔다 */
body.skin-yongin .sy-card .badge.na {
  color: var(--yg-tx3); background: var(--yg-line-2); border-color: var(--yg-line);
}

body.skin-yongin .sy-card .rows { padding: 12px 15px 14px; display: grid; gap: 10px; }
body.skin-yongin .sy-card .r { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
body.skin-yongin .sy-card .r .k {
  font-size: 11.5px; font-weight: 800; color: var(--yg-tx2); width: 74px; flex: none;
}
body.skin-yongin .sy-bar {
  flex: 1; min-width: 130px; height: 8px; border-radius: 20px;
  background: var(--yg-line-2); overflow: hidden;
}
body.skin-yongin .sy-bar i {
  display: block; height: 100%; border-radius: 20px; background: var(--yg-accent);
}
body.skin-yongin .sy-bar.warn i { background: var(--yg-warn); }
body.skin-yongin .sy-bar.bad i { background: #dd6a4a; }
body.skin-yongin .sy-card .pct {
  font-size: 11.5px; font-weight: 800; color: var(--yg-tx2);
  font-variant-numeric: tabular-nums; width: 48px; text-align: right;
}
body.skin-yongin .sy-wait {
  padding: 30px 14px; text-align: center; font-size: 12px; font-weight: 700; color: var(--yg-tx3);
}

@media (max-width: 700px) {
  body.skin-yongin .sy-card .r .k { width: auto; }
  body.skin-yongin .hz-row .hd { gap: 7px; }
}

/* ════════════════════════════════════════
   관리자 화면 4종 (사용자 · 접속 기록 · 계정별 IP · 설비 이력)

   이 넷은 **사이트 구조와 무관하다** — 계정과 감사 기록이라 룸·랙 개념이 없다.
   그래서 화면을 새로 만들지 않고 **톤만 맞춘다**. 다만 설비 이력의 랙 표기만은
   사이트를 타므로 그쪽은 화면 코드에서 고쳤다(`equipment_events.js` `_rackLabel`).

   ⚠ **선택자마다 `[data-page]` 가 붙어 있는 이유** — `renewal.css` 의
   `body.renewal[data-page="users"] .usr-card` 는 (0,3,1) 이고
   `body.skin-yongin .usr-card` 는 (0,2,1) 이라 **진다**. `[data-page]` 로 동률을
   만들고, skin_yongin.css 가 뒤에 실리는 것으로 이긴다. 명시도를 세지 않으면
   규칙이 **조용히 안 먹는다** — 전 화면의 남색 누수와 같은 함정이다.
   `tests/css_cascade.test.js` 의 '관리자 스킨이 renewal 을 이김' 이 이걸 지킨다.

   위험 동작(비활성·초기화)은 평소엔 조용하고 누를 때 붉다 — 목록에 붉은 버튼이
   줄줄이 있으면 경고가 배경이 되어 아무도 안 읽는다.
   ════════════════════════════════════════ */
body.skin-yongin[data-page="users"] .usr-card,
body.skin-yongin[data-page="login_events"] .usr-card,
body.skin-yongin[data-page="account_ips"] .usr-card,
body.skin-yongin[data-page="equipment_events"] .usr-card {
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r); box-shadow: var(--yg-shadow); padding: 15px 17px;
}
body.skin-yongin[data-page="users"] .usr-card-title,
body.skin-yongin[data-page="login_events"] .usr-card-title,
body.skin-yongin[data-page="account_ips"] .usr-card-title,
body.skin-yongin[data-page="equipment_events"] .usr-card-title {
  color: var(--yg-tx); font-weight: 800;
}
body.skin-yongin[data-page="users"] .usr-summary,
body.skin-yongin[data-page="login_events"] .usr-summary,
body.skin-yongin[data-page="account_ips"] .usr-summary,
body.skin-yongin[data-page="equipment_events"] .usr-summary {
  color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .usr-foot,
body.skin-yongin[data-page="login_events"] .usr-foot,
body.skin-yongin[data-page="account_ips"] .usr-foot,
body.skin-yongin[data-page="equipment_events"] .usr-foot {
  color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .usr-th,
body.skin-yongin[data-page="login_events"] .usr-th,
body.skin-yongin[data-page="account_ips"] .usr-th,
body.skin-yongin[data-page="equipment_events"] .usr-th {
  color: var(--yg-tx2); font-weight: 800; background: var(--yg-surface-2);
  border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin[data-page="users"] .usr-td,
body.skin-yongin[data-page="login_events"] .usr-td,
body.skin-yongin[data-page="account_ips"] .usr-td,
body.skin-yongin[data-page="equipment_events"] .usr-td {
  color: var(--yg-tx); border-bottom: 1px solid var(--yg-line-2);
}
body.skin-yongin[data-page="users"] .usr-td-dim,
body.skin-yongin[data-page="login_events"] .usr-td-dim,
body.skin-yongin[data-page="account_ips"] .usr-td-dim,
body.skin-yongin[data-page="equipment_events"] .usr-td-dim {
  color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .usr-input,
body.skin-yongin[data-page="login_events"] .usr-input,
body.skin-yongin[data-page="account_ips"] .usr-input,
body.skin-yongin[data-page="equipment_events"] .usr-input {
  font: inherit; font-size: 12.5px; color: var(--yg-tx); background: var(--yg-surface);
  border: 1px solid var(--yg-line); border-radius: 9px; padding: 7px 10px;
}
body.skin-yongin[data-page="users"] .usr-sel,
body.skin-yongin[data-page="login_events"] .usr-sel,
body.skin-yongin[data-page="account_ips"] .usr-sel,
body.skin-yongin[data-page="equipment_events"] .usr-sel {
  font: inherit; font-size: 12.5px; color: var(--yg-tx); background: var(--yg-surface);
  border: 1px solid var(--yg-line); border-radius: 9px; padding: 7px 10px;
}
body.skin-yongin[data-page="users"] .usr-input:focus,
body.skin-yongin[data-page="login_events"] .usr-input:focus,
body.skin-yongin[data-page="account_ips"] .usr-input:focus,
body.skin-yongin[data-page="equipment_events"] .usr-input:focus {
  outline: none; border-color: var(--yg-accent-2); box-shadow: 0 0 0 3px var(--yg-ring);
}
body.skin-yongin[data-page="users"] .usr-sel:focus,
body.skin-yongin[data-page="login_events"] .usr-sel:focus,
body.skin-yongin[data-page="account_ips"] .usr-sel:focus,
body.skin-yongin[data-page="equipment_events"] .usr-sel:focus {
  outline: none; border-color: var(--yg-accent-2); box-shadow: 0 0 0 3px var(--yg-ring);
}
body.skin-yongin[data-page="users"] .usr-new-form,
body.skin-yongin[data-page="login_events"] .usr-new-form,
body.skin-yongin[data-page="account_ips"] .usr-new-form,
body.skin-yongin[data-page="equipment_events"] .usr-new-form {
  background: var(--yg-surface-2); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r-sm);
}
body.skin-yongin[data-page="users"] .usr-btn,
body.skin-yongin[data-page="login_events"] .usr-btn,
body.skin-yongin[data-page="account_ips"] .usr-btn,
body.skin-yongin[data-page="equipment_events"] .usr-btn {
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; padding: 7px 13px;
  border-radius: 9px; color: var(--yg-tx2); background: var(--yg-surface);
  border: 1px solid var(--yg-line);
}
body.skin-yongin[data-page="users"] .usr-btn:hover,
body.skin-yongin[data-page="login_events"] .usr-btn:hover,
body.skin-yongin[data-page="account_ips"] .usr-btn:hover,
body.skin-yongin[data-page="equipment_events"] .usr-btn:hover {
  border-color: #cfd7e2; background: var(--yg-surface-2);
}
body.skin-yongin[data-page="users"] .usr-btn-primary,
body.skin-yongin[data-page="login_events"] .usr-btn-primary,
body.skin-yongin[data-page="account_ips"] .usr-btn-primary,
body.skin-yongin[data-page="equipment_events"] .usr-btn-primary {
  color: #fff; background: var(--yg-accent-dp); border-color: var(--yg-accent-dp);
}
body.skin-yongin[data-page="users"] .usr-btn-primary:hover,
body.skin-yongin[data-page="login_events"] .usr-btn-primary:hover,
body.skin-yongin[data-page="account_ips"] .usr-btn-primary:hover,
body.skin-yongin[data-page="equipment_events"] .usr-btn-primary:hover {
  background: #036c4f; border-color: #036c4f;
}
body.skin-yongin[data-page="users"] .usr-btn-danger,
body.skin-yongin[data-page="login_events"] .usr-btn-danger,
body.skin-yongin[data-page="account_ips"] .usr-btn-danger,
body.skin-yongin[data-page="equipment_events"] .usr-btn-danger {
  color: #96332a; border-color: #e6bfb9; background: #fbecea;
}
body.skin-yongin[data-page="users"] .usr-btn-danger:hover,
body.skin-yongin[data-page="login_events"] .usr-btn-danger:hover,
body.skin-yongin[data-page="account_ips"] .usr-btn-danger:hover,
body.skin-yongin[data-page="equipment_events"] .usr-btn-danger:hover {
  color: #fff; background: #a8402f; border-color: #a8402f;
}
body.skin-yongin[data-page="users"] .usr-badge,
body.skin-yongin[data-page="login_events"] .usr-badge,
body.skin-yongin[data-page="account_ips"] .usr-badge,
body.skin-yongin[data-page="equipment_events"] .usr-badge {
  font-size: 10.5px; font-weight: 800; padding: 2px 9px; border-radius: 999px;
  color: var(--yg-tx2); background: var(--yg-line-2);
}
body.skin-yongin[data-page="users"] .usr-badge.on,
body.skin-yongin[data-page="login_events"] .usr-badge.on,
body.skin-yongin[data-page="account_ips"] .usr-badge.on,
body.skin-yongin[data-page="equipment_events"] .usr-badge.on {
  color: #0b6b4f; background: #e8f8f1;
}
body.skin-yongin[data-page="users"] .usr-badge.off,
body.skin-yongin[data-page="login_events"] .usr-badge.off,
body.skin-yongin[data-page="account_ips"] .usr-badge.off,
body.skin-yongin[data-page="equipment_events"] .usr-badge.off {
  color: var(--yg-tx3); background: var(--yg-surface-2);
}
body.skin-yongin[data-page="users"] .usr-badge.warn,
body.skin-yongin[data-page="login_events"] .usr-badge.warn,
body.skin-yongin[data-page="account_ips"] .usr-badge.warn,
body.skin-yongin[data-page="equipment_events"] .usr-badge.warn {
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin[data-page="users"] .usr-temp,
body.skin-yongin[data-page="login_events"] .usr-temp,
body.skin-yongin[data-page="account_ips"] .usr-temp,
body.skin-yongin[data-page="equipment_events"] .usr-temp {
  background: var(--yg-accent-sf); border: 1px solid #a7dcc7;
}
body.skin-yongin[data-page="users"] .usr-temp-head,
body.skin-yongin[data-page="login_events"] .usr-temp-head,
body.skin-yongin[data-page="account_ips"] .usr-temp-head,
body.skin-yongin[data-page="equipment_events"] .usr-temp-head {
  color: var(--yg-accent-dp); font-weight: 800;
}
body.skin-yongin[data-page="users"] .usr-temp-id,
body.skin-yongin[data-page="login_events"] .usr-temp-id,
body.skin-yongin[data-page="account_ips"] .usr-temp-id,
body.skin-yongin[data-page="equipment_events"] .usr-temp-id {
  color: var(--yg-tx2);
}
body.skin-yongin[data-page="users"] .usr-temp-pw,
body.skin-yongin[data-page="login_events"] .usr-temp-pw,
body.skin-yongin[data-page="account_ips"] .usr-temp-pw,
body.skin-yongin[data-page="equipment_events"] .usr-temp-pw {
  color: var(--yg-tx); font-weight: 800;
}
body.skin-yongin[data-page="users"] .usr-temp-foot,
body.skin-yongin[data-page="login_events"] .usr-temp-foot,
body.skin-yongin[data-page="account_ips"] .usr-temp-foot,
body.skin-yongin[data-page="equipment_events"] .usr-temp-foot {
  color: var(--yg-tx3);
}
/* 이 상자는 **평소 비어 있다** — style.css 가 `min-height: 20px` 로 자리를 잡아 두고
   오류가 생길 때만 글자를 넣는다. 거기에 배경·테두리를 주면 **아무 문구도 없는
   분홍 막대**가 화면에 상주한다(실제로 그렇게 만들었다가 지적받았다).
   내용이 있을 때만 칠하고, 없으면 자리도 차지하지 않는다. */
body.skin-yongin[data-page="users"] .usr-card .login-error,
body.skin-yongin[data-page="login_events"] .usr-card .login-error,
body.skin-yongin[data-page="account_ips"] .usr-card .login-error,
body.skin-yongin[data-page="equipment_events"] .usr-card .login-error {
  min-height: 0; margin: 0; padding: 0;
  background: transparent; border: none; color: #96332a;
}
body.skin-yongin[data-page="users"] .usr-card .login-error:not(:empty),
body.skin-yongin[data-page="login_events"] .usr-card .login-error:not(:empty),
body.skin-yongin[data-page="account_ips"] .usr-card .login-error:not(:empty),
body.skin-yongin[data-page="equipment_events"] .usr-card .login-error:not(:empty) {
  margin: 0 0 8px; padding: 8px 11px; border-radius: var(--yg-r-sm);
  background: #fbecea; border: 1px solid #e6bfb9; font-weight: 700;
}
body.skin-yongin[data-page="users"] .lev-wrap,
body.skin-yongin[data-page="login_events"] .lev-wrap,
body.skin-yongin[data-page="account_ips"] .lev-wrap,
body.skin-yongin[data-page="equipment_events"] .lev-wrap {
  border: 1px solid var(--yg-line); border-radius: var(--yg-r-sm);
  background: var(--yg-surface); overflow: auto;
}
body.skin-yongin[data-page="users"] .lev-table,
body.skin-yongin[data-page="login_events"] .lev-table,
body.skin-yongin[data-page="account_ips"] .lev-table,
body.skin-yongin[data-page="equipment_events"] .lev-table {
  border-collapse: collapse; width: 100%; font-size: 11.5px;
}
body.skin-yongin[data-page="users"] .lev-th,
body.skin-yongin[data-page="login_events"] .lev-th,
body.skin-yongin[data-page="account_ips"] .lev-th,
body.skin-yongin[data-page="equipment_events"] .lev-th {
  position: sticky; top: 0; z-index: 1; text-align: left; white-space: nowrap;
  color: var(--yg-tx2); font-weight: 800; background: var(--yg-surface-2);
  padding: 8px 10px; border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin[data-page="users"] .lev-td,
body.skin-yongin[data-page="login_events"] .lev-td,
body.skin-yongin[data-page="account_ips"] .lev-td,
body.skin-yongin[data-page="equipment_events"] .lev-td {
  padding: 6px 10px; color: var(--yg-tx); border-bottom: 1px solid var(--yg-line-2);
}
body.skin-yongin[data-page="users"] .lev-row:hover .lev-td,
body.skin-yongin[data-page="login_events"] .lev-row:hover .lev-td,
body.skin-yongin[data-page="account_ips"] .lev-row:hover .lev-td,
body.skin-yongin[data-page="equipment_events"] .lev-row:hover .lev-td {
  background: var(--yg-accent-sf);
}
body.skin-yongin[data-page="users"] .lev-td-dim,
body.skin-yongin[data-page="login_events"] .lev-td-dim,
body.skin-yongin[data-page="account_ips"] .lev-td-dim,
body.skin-yongin[data-page="equipment_events"] .lev-td-dim {
  color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .lev-td-time,
body.skin-yongin[data-page="login_events"] .lev-td-time,
body.skin-yongin[data-page="account_ips"] .lev-td-time,
body.skin-yongin[data-page="equipment_events"] .lev-td-time {
  color: var(--yg-tx3); font-variant-numeric: tabular-nums; white-space: nowrap;
}
body.skin-yongin[data-page="users"] .lev-td-id,
body.skin-yongin[data-page="login_events"] .lev-td-id,
body.skin-yongin[data-page="account_ips"] .lev-td-id,
body.skin-yongin[data-page="equipment_events"] .lev-td-id {
  color: var(--yg-tx3); font-variant-numeric: tabular-nums; white-space: nowrap;
}
body.skin-yongin[data-page="users"] .lev-ctl .hvac-ctl-label,
body.skin-yongin[data-page="login_events"] .lev-ctl .hvac-ctl-label,
body.skin-yongin[data-page="account_ips"] .lev-ctl .hvac-ctl-label,
body.skin-yongin[data-page="equipment_events"] .lev-ctl .hvac-ctl-label {
  font-size: 10.5px; font-weight: 800; color: var(--yg-tx3); letter-spacing: .03em;
}
body.skin-yongin[data-page="users"] .lev-pager-info,
body.skin-yongin[data-page="login_events"] .lev-pager-info,
body.skin-yongin[data-page="account_ips"] .lev-pager-info,
body.skin-yongin[data-page="equipment_events"] .lev-pager-info {
  font-size: 11.5px; font-weight: 700; color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .lev-badge.ok,
body.skin-yongin[data-page="login_events"] .lev-badge.ok,
body.skin-yongin[data-page="account_ips"] .lev-badge.ok,
body.skin-yongin[data-page="equipment_events"] .lev-badge.ok {
  color: #0b6b4f; background: #e8f8f1; border: 1px solid #a7dcc7;
}
body.skin-yongin[data-page="users"] .lev-badge.warn,
body.skin-yongin[data-page="login_events"] .lev-badge.warn,
body.skin-yongin[data-page="account_ips"] .lev-badge.warn,
body.skin-yongin[data-page="equipment_events"] .lev-badge.warn {
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin[data-page="users"] .lev-badge.bad,
body.skin-yongin[data-page="login_events"] .lev-badge.bad,
body.skin-yongin[data-page="account_ips"] .lev-badge.bad,
body.skin-yongin[data-page="equipment_events"] .lev-badge.bad {
  color: #96332a; background: #fbecea; border: 1px solid #e6bfb9;
}
body.skin-yongin[data-page="users"] .lev-badge.dim,
body.skin-yongin[data-page="login_events"] .lev-badge.dim,
body.skin-yongin[data-page="account_ips"] .lev-badge.dim,
body.skin-yongin[data-page="equipment_events"] .lev-badge.dim {
  color: var(--yg-tx3); background: var(--yg-line-2); border: 1px solid var(--yg-line);
}
body.skin-yongin[data-page="users"] .aip-summary,
body.skin-yongin[data-page="login_events"] .aip-summary,
body.skin-yongin[data-page="account_ips"] .aip-summary,
body.skin-yongin[data-page="equipment_events"] .aip-summary {
  color: var(--yg-tx3); font-size: 11.5px; font-weight: 700;
}
body.skin-yongin[data-page="users"] .aip-acc,
body.skin-yongin[data-page="login_events"] .aip-acc,
body.skin-yongin[data-page="account_ips"] .aip-acc,
body.skin-yongin[data-page="equipment_events"] .aip-acc {
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r-sm); box-shadow: var(--yg-shadow);
}
body.skin-yongin[data-page="users"] .aip-acc-head,
body.skin-yongin[data-page="login_events"] .aip-acc-head,
body.skin-yongin[data-page="account_ips"] .aip-acc-head,
body.skin-yongin[data-page="equipment_events"] .aip-acc-head {
  background: var(--yg-surface-2); border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin[data-page="users"] .aip-acc-head:hover,
body.skin-yongin[data-page="login_events"] .aip-acc-head:hover,
body.skin-yongin[data-page="account_ips"] .aip-acc-head:hover,
body.skin-yongin[data-page="equipment_events"] .aip-acc-head:hover {
  background: var(--yg-accent-sf);
}
body.skin-yongin[data-page="users"] .aip-acc-name,
body.skin-yongin[data-page="login_events"] .aip-acc-name,
body.skin-yongin[data-page="account_ips"] .aip-acc-name,
body.skin-yongin[data-page="equipment_events"] .aip-acc-name {
  font-size: 12.5px; font-weight: 800; color: var(--yg-tx);
}
body.skin-yongin[data-page="users"] .aip-caret,
body.skin-yongin[data-page="login_events"] .aip-caret,
body.skin-yongin[data-page="account_ips"] .aip-caret,
body.skin-yongin[data-page="equipment_events"] .aip-caret {
  color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .aip-metric,
body.skin-yongin[data-page="login_events"] .aip-metric,
body.skin-yongin[data-page="account_ips"] .aip-metric,
body.skin-yongin[data-page="equipment_events"] .aip-metric {
  font-size: 11.5px; font-weight: 800; color: var(--yg-tx2);
}
body.skin-yongin[data-page="users"] .aip-metric.alt,
body.skin-yongin[data-page="login_events"] .aip-metric.alt,
body.skin-yongin[data-page="account_ips"] .aip-metric.alt,
body.skin-yongin[data-page="equipment_events"] .aip-metric.alt {
  color: var(--yg-accent-dp);
}
body.skin-yongin[data-page="users"] .aip-metric-dim,
body.skin-yongin[data-page="login_events"] .aip-metric-dim,
body.skin-yongin[data-page="account_ips"] .aip-metric-dim,
body.skin-yongin[data-page="equipment_events"] .aip-metric-dim {
  color: var(--yg-tx3); font-weight: 700;
}
body.skin-yongin[data-page="users"] .aip-dim,
body.skin-yongin[data-page="login_events"] .aip-dim,
body.skin-yongin[data-page="account_ips"] .aip-dim,
body.skin-yongin[data-page="equipment_events"] .aip-dim {
  color: var(--yg-tx3); font-weight: 700;
}
body.skin-yongin[data-page="users"] .aip-table,
body.skin-yongin[data-page="login_events"] .aip-table,
body.skin-yongin[data-page="account_ips"] .aip-table,
body.skin-yongin[data-page="equipment_events"] .aip-table {
  border-collapse: collapse; width: 100%; font-size: 11.5px;
}
body.skin-yongin[data-page="users"] .aip-th,
body.skin-yongin[data-page="login_events"] .aip-th,
body.skin-yongin[data-page="account_ips"] .aip-th,
body.skin-yongin[data-page="equipment_events"] .aip-th {
  text-align: left; color: var(--yg-tx2); font-weight: 800;
  background: var(--yg-surface-2); padding: 7px 10px; border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin[data-page="users"] .aip-td,
body.skin-yongin[data-page="login_events"] .aip-td,
body.skin-yongin[data-page="account_ips"] .aip-td,
body.skin-yongin[data-page="equipment_events"] .aip-td {
  padding: 6px 10px; color: var(--yg-tx); border-bottom: 1px solid var(--yg-line-2);
}
body.skin-yongin[data-page="users"] .aip-td-dim,
body.skin-yongin[data-page="login_events"] .aip-td-dim,
body.skin-yongin[data-page="account_ips"] .aip-td-dim,
body.skin-yongin[data-page="equipment_events"] .aip-td-dim {
  color: var(--yg-tx3);
}
body.skin-yongin[data-page="users"] .aip-uid,
body.skin-yongin[data-page="login_events"] .aip-uid,
body.skin-yongin[data-page="account_ips"] .aip-uid,
body.skin-yongin[data-page="equipment_events"] .aip-uid {
  color: var(--yg-tx3); font-variant-numeric: tabular-nums;
}
body.skin-yongin[data-page="users"] .aip-dev,
body.skin-yongin[data-page="login_events"] .aip-dev,
body.skin-yongin[data-page="account_ips"] .aip-dev,
body.skin-yongin[data-page="equipment_events"] .aip-dev {
  color: var(--yg-tx2);
}
body.skin-yongin[data-page="users"] .aip-dev b,
body.skin-yongin[data-page="login_events"] .aip-dev b,
body.skin-yongin[data-page="account_ips"] .aip-dev b,
body.skin-yongin[data-page="equipment_events"] .aip-dev b {
  color: var(--yg-tx); font-weight: 800;
}
body.skin-yongin[data-page="users"] .aip-dev.mobile,
body.skin-yongin[data-page="login_events"] .aip-dev.mobile,
body.skin-yongin[data-page="account_ips"] .aip-dev.mobile,
body.skin-yongin[data-page="equipment_events"] .aip-dev.mobile {
  color: var(--yg-accent-dp);
}
body.skin-yongin[data-page="users"] .aip-tag,
body.skin-yongin[data-page="login_events"] .aip-tag,
body.skin-yongin[data-page="account_ips"] .aip-tag,
body.skin-yongin[data-page="equipment_events"] .aip-tag {
  font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
  color: var(--yg-tx2); background: var(--yg-line-2);
}
body.skin-yongin[data-page="users"] .aip-tag.role,
body.skin-yongin[data-page="login_events"] .aip-tag.role,
body.skin-yongin[data-page="account_ips"] .aip-tag.role,
body.skin-yongin[data-page="equipment_events"] .aip-tag.role {
  color: var(--yg-accent-dp); background: var(--yg-accent-sf); border: 1px solid #a7dcc7;
}
body.skin-yongin[data-page="users"] .aip-tag.warn,
body.skin-yongin[data-page="login_events"] .aip-tag.warn,
body.skin-yongin[data-page="account_ips"] .aip-tag.warn,
body.skin-yongin[data-page="equipment_events"] .aip-tag.warn {
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin[data-page="users"] .aip-tag.off,
body.skin-yongin[data-page="login_events"] .aip-tag.off,
body.skin-yongin[data-page="account_ips"] .aip-tag.off,
body.skin-yongin[data-page="equipment_events"] .aip-tag.off {
  color: var(--yg-tx3); background: var(--yg-surface-2); border: 1px solid var(--yg-line-mute);
}
body.skin-yongin[data-page="users"] .aip-fail,
body.skin-yongin[data-page="login_events"] .aip-fail,
body.skin-yongin[data-page="account_ips"] .aip-fail,
body.skin-yongin[data-page="equipment_events"] .aip-fail {
  color: var(--yg-warn-tx); background: var(--yg-warn-sf); border: 1px solid #e6cf9a;
}
body.skin-yongin[data-page="users"] .aip-iprow-fail,
body.skin-yongin[data-page="login_events"] .aip-iprow-fail,
body.skin-yongin[data-page="account_ips"] .aip-iprow-fail,
body.skin-yongin[data-page="equipment_events"] .aip-iprow-fail {
  background: #fdf7ea;
}

/* ══════════════════════════════════════════════════════════════════════════
   작기 달력 (공용 — 환경 탐색기 · 비전 분석의 작기 선택)

   가로가 시간, 세로가 공간이다. 사람이 작기를 기억하는 두 축을 그대로 쓴다.
   랙 이름 열 폭(`--cc-rl`)은 머리·본문·오늘선이 **같은 값을 봐야** 눈금이 맞는다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .cc { --cc-rl: 96px; margin-top: 10px; }
body.skin-yongin .cc-head { display: flex; align-items: flex-end; }
body.skin-yongin .cc-head .cc-rl { width: var(--cc-rl); flex: none; }
body.skin-yongin .cc-mon { flex: 1; display: flex; min-width: 0; }
body.skin-yongin .cc-mon i {
  font-style: normal; font-size: 10px; font-weight: 800; color: var(--yg-tx3);
  text-align: left; padding-left: 4px; white-space: nowrap; overflow: hidden;
  border-left: 1px solid var(--yg-line);
}
body.skin-yongin .cc-body {
  position: relative; margin-top: 4px; padding: 4px 0;
  border-top: 1px solid var(--yg-line); border-bottom: 1px solid var(--yg-line);
}
body.skin-yongin .cc-row { display: flex; align-items: center; height: 30px; }
body.skin-yongin .cc-row + .cc-row { border-top: 1px solid var(--yg-line-2); }
body.skin-yongin .cc-rl {
  width: var(--cc-rl); flex: none; font-size: 11px; font-weight: 800;
  color: var(--yg-tx2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding-right: 8px;
}
/* 트랙 바닥에 달 눈금을 옅게 깔아 막대 위치를 눈으로 잴 수 있게 한다 */
body.skin-yongin .cc-track {
  position: relative; flex: 1; height: 100%; min-width: 0;
  background: repeating-linear-gradient(90deg,
    var(--yg-surface-2) 0 1px, transparent 1px 100%);
}

body.skin-yongin .cc-bar {
  position: absolute; top: 4px; bottom: 4px; display: flex; align-items: center; gap: 4px;
  font: inherit; font-size: 10.5px; font-weight: 800; cursor: pointer; overflow: hidden;
  padding: 0 6px; border-radius: 7px; white-space: nowrap;
  /* 채움은 옅게, 글자는 어두운 톤 — 막대가 좁을 때도 이름이 읽혀야 한다 */
  color: var(--ct); background: color-mix(in srgb, var(--c) 22%, #fff);
  /* 테두리는 **작물 색**이 아니라 **글자 톤**에서 뽑는다. 채움은 트랙 대비 1.2:1 밖에
     안 되서 막대를 도형으로 보이게 하는 건 테두리뿐이다. 작물 색을 썼더니 연둔 색의
     막대가 1.41:1 로 윤곽이 사라졌다 — 양액 카드에서 한 번 겪은 일이다. */
  border: 1px solid color-mix(in srgb, var(--ct) 68%, #fff);
  transition: transform .1s, box-shadow .12s;
}
body.skin-yongin .cc-bar:hover {
  box-shadow: 0 2px 10px rgba(16, 24, 40, .18); transform: translateY(-1px); z-index: 3;
}
/* 진행 중 — 테두리를 진하게. 색만으로 말하지 않도록 툴팁에도 '진행 중' 이 들어간다 */
body.skin-yongin .cc-bar.live { border-color: var(--ct); border-width: 2px; }
/* 고른 것 — 채워서 확실히 구분한다(비전 분석은 최대 3개를 고른다) */
body.skin-yongin .cc-bar.on {
  color: #fff; background: var(--ct); border-color: var(--ct);
  box-shadow: 0 0 0 2px var(--yg-ring);
}
body.skin-yongin .cc-bar .e { font-size: 11px; flex: none; }
body.skin-yongin .cc-bar .n { overflow: hidden; text-overflow: ellipsis; }
/* 목표조건이 있는 작기 — 누르기 전에 알 수 있어야 헛클릭이 없다 */
body.skin-yongin .cc-bar .t { margin-left: auto; font-size: 9px; flex: none; opacity: .8; }

body.skin-yongin .cc-now { position: absolute; top: 0; bottom: 0; pointer-events: none; z-index: 4; }
body.skin-yongin .cc-now i {
  position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px;
  background: var(--yg-accent-dp); opacity: .55;
}
body.skin-yongin .cc-now b {
  position: absolute; top: -2px; left: 3px; font-size: 9px; font-weight: 800;
  color: var(--yg-accent-dp); background: var(--yg-surface);
  padding: 0 3px; border-radius: 4px;
}

body.skin-yongin .cc-foot {
  margin-top: 8px; font-size: 10.5px; font-weight: 600; line-height: 1.6; color: var(--yg-tx3);
}
body.skin-yongin .cc-foot b { color: var(--yg-tx2); font-weight: 800; }

@media (max-width: 700px) {
  body.skin-yongin .cc { --cc-rl: 72px; }
  body.skin-yongin .cc-bar .n { display: none; }   /* 좁으면 이모지만 — 툴팁에 이름이 있다 */
}

/* ══════════════════════════════════════════════════════════════════════════
   정보 그룹 (과제·공고 / 마켓 / 영상 자료)

   기본 규칙(renewal.css .info-* / .vd-*)은 **어두운 그라디언트 위**를 전제로 한다 —
   머리글이 흰 글자다. 용인은 밝은 표면이라 그대로 두면 제목이 안 보인다.
   여기서는 **색만 옮긴다**(구조·간격은 기본을 그대로 쓴다).

   기본 규칙이 클래스 하나(0,1,0)라 `body.skin-yongin` 접두(0,2,0)만으로 이긴다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin .info-screen { max-width: 1180px; padding: 0 0 22px; }
body.skin-yongin .info-head { margin: 0 0 16px; }
body.skin-yongin .info-eyebrow { color: var(--yg-accent-dp); letter-spacing: .16em; }
body.skin-yongin .info-title { font-size: 22px; color: var(--yg-tx); }
body.skin-yongin .info-sub { font-size: 13px; color: var(--yg-tx2); }

body.skin-yongin .info-item {
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r); box-shadow: var(--yg-shadow);
}
body.skin-yongin .info-item:hover {
  border-color: var(--yg-accent-2); box-shadow: var(--yg-shadow-lg);
}
body.skin-yongin .info-item-icon {
  background: var(--yg-accent-sf); color: var(--yg-accent-dp); border-radius: var(--yg-r-sm);
}
body.skin-yongin .info-item-title { color: var(--yg-tx); }
body.skin-yongin .info-item-desc { color: var(--yg-tx2); }
body.skin-yongin .info-item-link { color: var(--yg-accent-dp); }

/* ── 영상 자료 ─────────────────────────────────────────────────────────── */
/* 검색칸은 카드 안이 아니라 **페이지 바닥 위에** 놓인다. 다른 화면의 입력칸은
   흰 상단바 안에 있어서 기본 --yg-line 으로 충분하지만, 여기서는 흰 면이 페이지색과
   1.13:1 이라 윤곽이 사라진다 — 그 자리에 쓰라고 만들어 둔 --yg-line-mute 를 쓴다. */
body.skin-yongin .vd-search {
  background: var(--yg-surface); border: 1px solid var(--yg-line-mute);
  border-radius: var(--yg-r-sm); color: var(--yg-tx3);
}
body.skin-yongin .vd-search input { color: var(--yg-tx); }
body.skin-yongin .vd-note { color: var(--yg-tx2); }

body.skin-yongin .vd-btn {
  background: var(--yg-accent-dp); border-radius: var(--yg-r-sm);
}
body.skin-yongin .vd-btn.ghost {
  background: var(--yg-surface-2); color: var(--yg-tx2); border: 1px solid var(--yg-line);
}

body.skin-yongin .vd-chip {
  background: var(--yg-surface); border: 1px solid var(--yg-line); color: var(--yg-tx2);
}
body.skin-yongin .vd-chip b { color: var(--yg-tx3); }
body.skin-yongin .vd-chip.on {
  background: var(--yg-accent-dp); border-color: var(--yg-accent-dp); color: #fff;
}
body.skin-yongin .vd-chip.on b { color: #d9f2e7; }

body.skin-yongin .vd-card {
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r); box-shadow: var(--yg-shadow);
}
body.skin-yongin .vd-card:hover {
  border-color: var(--yg-accent-2); box-shadow: var(--yg-shadow-lg);
}
body.skin-yongin .vd-thumb { background: var(--yg-surface-2); }
body.skin-yongin .vd-ph { color: var(--yg-tx3); }
body.skin-yongin .vd-title { color: var(--yg-tx); }
body.skin-yongin .vd-desc { color: var(--yg-tx2); }
body.skin-yongin .vd-tag { background: var(--yg-accent-sf); color: var(--yg-accent-dp); }
body.skin-yongin .vd-meta { color: var(--yg-tx3); }
body.skin-yongin .vd-host { color: var(--yg-tx2); }
body.skin-yongin .vd-mini {
  background: var(--yg-surface-2); border-color: var(--yg-line); color: var(--yg-tx2);
}

body.skin-yongin .vd-wait,
body.skin-yongin .vd-empty {
  background: var(--yg-surface); border: 1px solid var(--yg-line);
  border-radius: var(--yg-r); box-shadow: var(--yg-shadow); color: var(--yg-tx2);
}
body.skin-yongin .vd-empty span { color: var(--yg-tx3); }

body.skin-yongin .vd-modal-in { border-radius: var(--yg-r); }
body.skin-yongin .vd-modal-hd { border-bottom-color: var(--yg-line); }
body.skin-yongin .vd-modal-ft { border-top-color: var(--yg-line); }
body.skin-yongin .vd-modal-hd h3 { color: var(--yg-tx); }
body.skin-yongin .vd-f > span { color: var(--yg-tx2); }
body.skin-yongin .vd-f em,
body.skin-yongin .vd-f em.inline { color: var(--yg-tx3); }
body.skin-yongin .vd-f input,
body.skin-yongin .vd-f textarea,
body.skin-yongin .vd-tagadd input {
  border-color: var(--yg-line); color: var(--yg-tx); border-radius: var(--yg-r-sm);
}
/* 포커스는 파일 맨 아래 '포커스 링' 절이 전역으로 잡는다 — 여기서 파란 링을 만들지 않는다 */
body.skin-yongin .vd-f input:focus,
body.skin-yongin .vd-f textarea:focus {
  border-color: var(--yg-accent-2); box-shadow: 0 0 0 3px var(--yg-ring);
}

/* ══════════════════════════════════════════════════════════════════════════
   포커스 링 · 남색 누수 차단 — 전 화면 공통

   "전력·작물기록 페이지에만 남색 링이 있다"의 원인은 디자인이 아니라 **명시도**다.
   style.css 의 `input[type="date"]:focus, select:focus { border-color: #4f46e5 }` 는
   (0,2,1) 이고 내 `.yg-date:focus` 는 (0,2,0) 이라 기본 규칙이 이긴다. 입력 요소가
   있는 화면이 그 두 개뿐이라 거기서만 드러났을 뿐, 의도한 강조가 아니다.
   `.chart-zoom-reset` 도 같은 남색(#4f46e5)을 그대로 쓰고 있었다.

   그래서 링을 **없애는 대신 하나로 통일**한다 — 키보드 이동 시 지금 어디에 있는지
   보이는 건 접근성상 필요하다. 색은 로그인 화면과 같은 에메랄드로 맞춘다.
   접두 `body.skin-yongin` 은 장식이 아니라 **명시도를 되찾기 위한 것**이다.
   ══════════════════════════════════════════════════════════════════════════ */
body.skin-yongin {
  --yg-focus: 0 0 0 3px var(--yg-ring);
  --yg-focus-line: var(--yg-accent-dp);   /* 흰 배경 6.5:1 — 포커스 표시는 3:1 이상 */
}

/* ① 입력류 — 기본 스타일시트의 element 선택자에게 뺏긴 모양을 되찾는다 */
body.skin-yongin .yg-num,
body.skin-yongin .yg-date,
body.skin-yongin .yg-select {
  border: 1px solid var(--yg-line);
  background: var(--yg-surface);
  color: var(--yg-tx2);
  border-radius: var(--yg-r-sm);
}

/* ② 포커스 — 링 하나로 통일. :focus-visible 이라 마우스 클릭에는 안 뜨고
   키보드로 이동할 때만 뜬다(클릭할 때마다 링이 남는 성가심을 없앤다). */
body.skin-yongin .yg-seg-btn:focus-visible,
body.skin-yongin .yg-metric:focus-visible,
body.skin-yongin .yg-btn:focus-visible,
body.skin-yongin .yg-back:focus-visible,
body.skin-yongin .cy-play:focus-visible,
body.skin-yongin .cy-th:focus-visible,
body.skin-yongin .cy-nav:focus-visible,
body.skin-yongin .cy-livebtn:focus-visible,
body.skin-yongin .cy-zone:focus-visible,
body.skin-yongin .chart-zoom-reset:focus-visible {
  outline: 2px solid var(--yg-focus-line);
  outline-offset: 2px;
  box-shadow: var(--yg-focus);
}
/* 입력류는 클릭으로 들어가도 링이 보이는 편이 낫다(어디에 타이핑되는지) */
body.skin-yongin .yg-num:focus,
body.skin-yongin .yg-date:focus,
body.skin-yongin .yg-select:focus,
body.skin-yongin .yg-num:focus-visible,
body.skin-yongin .yg-date:focus-visible,
body.skin-yongin .yg-select:focus-visible {
  outline: none;
  border-color: var(--yg-accent-2);
  box-shadow: var(--yg-focus);
}
body.skin-yongin .cy-sw input:focus-visible + .tr {
  outline: 2px solid var(--yg-focus-line);
  outline-offset: 2px;
  box-shadow: var(--yg-focus);
}
body.skin-yongin .cy-range { accent-color: var(--yg-accent); }
body.skin-yongin .cy-range:focus-visible {
  outline: 2px solid var(--yg-focus-line);
  outline-offset: 3px;
}

/* ③ 줌 초기화 버튼 — 기본 남색(#4f46e5)을 그대로 쓰고 있었다. 차트 위에 얹히는
   작은 버튼이라 색이 다르면 제일 먼저 눈에 띈다. */
body.skin-yongin .chart-zoom-reset {
  color: var(--yg-accent-dp);
  background: var(--yg-surface);
  /* 경계선도 3:1 이상이어야 한다 — --yg-accent-2(#34d399)는 흰 배경에서 1.92:1 로
     차트 위에 얹히면 테두리가 안 보인다. 구 남색(#4f46e5)이 6.29:1 이었다. */
  border: 1px solid var(--yg-accent-dp);
  border-radius: 8px;
  font-weight: 700;
}
body.skin-yongin .chart-zoom-reset:hover {
  background: var(--yg-accent-sf);
  border-color: var(--yg-accent);
}

@media (prefers-reduced-motion: reduce) {
  body.skin-yongin *:focus-visible { transition: none; }
}

/* ── 브라우저가 그리는 파란색까지 막는다 ────────────────────────────────
   포커스 링을 초록으로 바꿔도 파란 링이 남는 자리가 있다. **우리 CSS 가 손대지
   않은 조각들을 브라우저가 시스템 강조색(파랑)으로 칠하기 때문**이고, 그 조각들은
   date/time/number 입력에 붙어 있다 — 그런 입력이 있는 화면이 전력·작물기록
   둘뿐이라 거기서만 보인다. 링을 하나 고치는 게 아니라 **표면을 전부 덮어야** 한다.

     accent-color            체크박스·라디오·range·progress (기본 파랑)
     ::selection             글자를 끌어 선택했을 때의 하이라이트 (기본 파랑)
     datetime-edit-*-field   date/time 입력에서 **지금 편집 중인 칸** (기본 파랑 블록)
     caret-color             입력 커서
   ─────────────────────────────────────────────────────────────────────── */
body.skin-yongin {
  accent-color: var(--yg-accent);
  caret-color: var(--yg-accent-dp);
}
body.skin-yongin ::selection {
  background: var(--yg-accent-sf);
  color: var(--yg-accent-dp);
}
/* date/time 입력의 편집 중인 칸 — 파란 블록이 나오는 자리. 초록 톤으로 덮는다.
   (:focus 없이도 칠해 두면 브라우저가 시스템 색으로 되돌리지 못한다) */
body.skin-yongin .yg-date::-webkit-datetime-edit-year-field:focus,
body.skin-yongin .yg-date::-webkit-datetime-edit-month-field:focus,
body.skin-yongin .yg-date::-webkit-datetime-edit-day-field:focus,
body.skin-yongin .yg-date::-webkit-datetime-edit-hour-field:focus,
body.skin-yongin .yg-date::-webkit-datetime-edit-minute-field:focus,
body.skin-yongin .yg-date::-webkit-datetime-edit-ampm-field:focus {
  background: var(--yg-accent-sf);
  color: var(--yg-accent-dp);
  border-radius: 4px;
  outline: none;
}
/* 달력·시계 아이콘도 톤을 맞춘다(기본은 회색 아이콘 + 파란 포커스 링) */
body.skin-yongin .yg-date::-webkit-calendar-picker-indicator:focus-visible {
  outline: 2px solid var(--yg-focus-line);
  outline-offset: 1px;
  border-radius: 3px;
}
/* number 입력의 증감 버튼 */
body.skin-yongin .yg-num::-webkit-inner-spin-button { accent-color: var(--yg-accent); }
