#robotMapMainPage {
  display: flex;
  position: relative;
  height: auto; /* 높이 자동으로 조절 */
  /*width: auto;   너비도 자동으로 조절 */
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
}

#robotMapContainerIndexPage {
  display: flex;
  flex-direction: row;
  align-items: flex-start !important; /* ✅ 맵과 Y축 높이 동일하게 */
  background-color: #f5f5f5;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  min-width: max-content; /* 내부가 커지면 그대로 유지 */
}

#yAxisIndexPage {
  display: grid !important; /* ✅ flex 제거 */
  /* grid-template-rows: repeat(20, 1fr) !important; */
  grid-auto-rows: 1fr;
  /* height: 100%; */
  margin-right: 4px;
  font-size: 12px;
  align-items: stretch;
  color: gray;
  text-align: center;
}

.map-grid-wrapper {
  display: flex;
  flex-direction: column;
}

#mapIndexPage {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  /* width: 1500px; */
    width: 1300px;   /* 40px * 20칸 */
  height: 800px;  /* 40px * 20칸 */
  border: 1px solid #ccc;
  /* background-color: #f8f8f8; */
  grid-auto-rows: 1fr;
}

#xAxisIndexPage {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  height: 20px;
  font-size: 12px;
  color: gray;
  margin-top: 4px;
  text-align: center; /* ✅ 가운데 정렬 */
}

.grid-cell {
  border: 1px solid #ddd;
  box-sizing: border-box;
}
.axis-label.y-axis {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: gray;
  /* border-top: 1px solid rgba(0,0,0,0.1);  
  border-bottom: 1px solid rgba(0,0,0,0.1); */
}
/* ✅ Y축 라벨 위쪽 정렬 강제 */
#yAxisIndexPage .axis-label.y-axis {
  display: flex !important;
  align-items: flex-start !important;
  justify-content: flex-start !important;
  padding-top: 0 !important;
  line-height: 1 !important;
}

.obstacle-cell {
  background-color: rgba(128, 128, 128, 0.5);
}
.cell {
  width: 40px;
  height: 80px;
  border: 1px solid #ccc;
  box-sizing: border-box;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}

.obstacle {
  background-color: rgba(128, 128, 128, 0.5);
}

.device-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;        /* 셀 전체 너비 사용 */
  height: 100%;       /* 셀 전체 높이 사용 */
}
.device-icon {
  width: auto;
  height: 60%; /* 또는 40px 등 적당한 크기로 제한 */
  object-fit: contain;
  display: block;
}

.device-id-overlay {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  font-size: 14px;
  font-weight: bold;
  color: black;
  background: rgba(255, 255, 255, 0.6); /* 반투명 배경 */
  padding: 2px 6px;
  border-radius: 4px;
  pointer-events: none;
}
/* ===== 지도만 보기 모드 ===== */
body.map-only #sidebar {
  display: none !important;
}

/* 지도 카드의 오른쪽 제어패널 숨기기 (robotMapMainPage 바로 옆 div) */
body.map-only #robotMapMainPage + div {
  display: none !important;
}

/* 지도 영역을 크게 */
body.map-only #robotMapMainPage {
  width: 100% !important;
}

/* 스크롤/여백 최소화 (원하면 추가 조정) */
body.map-only .card {
  height: calc(100vh - 20px);
}

body.map-only .card-body {
  height: calc(100vh - 70px);
}

/* 전체화면(Fullscreen)일 때: 검은 여백 제거 + 가운데 정렬 */
#robotMapMainPage:fullscreen {
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden; /* 남는 부분 스크롤 대신 맞춤 확대 */
}

/* Safari 대응 */
#robotMapMainPage:-webkit-full-screen {
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* 모달 */
/* =========================
   Device modal - 최종 정리본
   ========================= */
body.modal-open{
  overflow: auto !important;
  padding-right: 0 !important; /* 스크롤바 보정 제거 */
}
.modal-backdrop{
  pointer-events: none !important;
}
/* 기본적으로 숨김 (클릭 차단 방지) */
body #deviceModal{ display: none !important; }

/* 보일 때: 화면 전체 고정 + 가장 위 z-index */
body #deviceModal.show{
  position: fixed !important;
  inset: 0 !important;              /* top/right/bottom/left: 0 */
  display: block !important;
  z-index: 2000 !important;         /* backdrop(1050)보다 확실히 높게 */
}

/* 모달 대화상자를 뷰포트 정중앙으로 강제 */
body #deviceModal .modal-dialog{
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  width: min(1280px, 96vw);
  max-height: 92vh;
}

#farmSettingsModal { 
  display: none;              /* Bootstrap 기본과 일치 */
}

#farmSettingsModal.show{
  position: fixed !important;
  inset: 0 !important;
  z-index: 1055 !important;
}


#farmSettingsModal .modal-dialog{
  position: fixed !important;
  top: 50% !important; left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  width: clamp(560px, 56vw, 820px);
  max-width: calc(100vw - 72px);
  max-height: 92vh;
}
.farm-card__drag{
  cursor: move;
  user-select: none;
  background: #f8fafc;
  border-bottom: 1px solid #e9ecef;
  border-top-left-radius: 12px;
  border-top-right-radius: 12px;
  padding: 12px 16px;
}
/* 투명해 보이는 문제 방지: 내용은 확실한 배경 */
#farmSettingsModal .modal-content{
  /* 배경/글자색: 디바이스 모달과 톤 매칭 */
  background: #262a30;                  /* 본문 */
  color: #e8edf3;
  border: 1px solid #3a3f47;
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,.45);
  overflow: auto;
  padding: 0;                           /* 섹션별로 패딩 부여 */
}

/* 입력 컨트롤 위에서는 커서/선택 정상 동작 */
#farmSettingsModal input,
#farmSettingsModal select,
#farmSettingsModal textarea,
#farmSettingsModal button {
  cursor: auto;
  user-select: text;
}
/* 드래그 헤더(카드 상단) */
#farmSettingsModal .farm-card__drag{
  background: #2d323a;
  border-bottom: 1px solid #3a3f47;
  border-top-left-radius: 12px;
  border-top-right-radius: 12px;
  padding: 14px 18px;
  display: flex; 
  flex-direction: row; gap: 6px;
  cursor: move; user-select: none;
  align-items: center;   
  justify-content: space-between; 
}
#farmSettingsModal .farm-card__title{
  margin: 0; font-weight: 700; color: #fff; font-size: 18px;
}
#farmSettingsModal .farm-card__sub{
  margin: 0; color: #b8c2cc; font-size: 12px;
}

/* 본문 섹션 */
/* #farmSettingsModal .farm-card__body{
  padding: 16px 18px 8px;
}
#farmSettingsModal .farm-card__body > * + *{ margin-top: 12px; } */

/* 폼 컨트롤 — 다크 스타일 */
#farmSettingsModal .form-label{ color: #c9d1da; font-weight: 600; }
#farmSettingsModal .form-text{ color: #9aa5b1; }

#farmSettingsModal .form-control,
#farmSettingsModal .form-select{
  background: #1f2430;
  color: #e8edf3;
  border: 1px solid #3a3f47;
}
#farmSettingsModal .form-control::placeholder{ color: #9aa5b1; }
#farmSettingsModal .form-control:focus,
#farmSettingsModal .form-select:focus{
  border-color: #5b9cff;
  box-shadow: 0 0 0 .15rem rgba(91,156,255,.25);
  background: #202632;
  color: #e8edf3;
}

/* 불러오기/삭제 라인 */
#farmSettingsModal .d-flex.gap-2.mt-3{ margin-top: 12px !important; }

/* 하단 액션 바 */
#farmSettingsModal .farm-card__actions{
  display: flex; gap: 10px;
  padding: 12px 18px 16px;
  background: #1f2430;
  border-top: 1px solid #2c3342;
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
}
#farmSettingsModal .btn-light{
  background: #343a46; color: #e8edf3; border: 1px solid #434a58;
}
#farmSettingsModal .btn-light:hover{ background: #3b4250; }

#farmSettingsModal .btn-primary{
  background: #3b82f6; border-color: #3b82f6;
}
#farmSettingsModal .btn-primary:hover{ background: #2563eb; border-color: #2563eb; }

/* 백드롭 톤을 디바이스 모달과 맞춤 */
.modal-backdrop{ background: #000 !important; }
.modal-backdrop.show{ opacity: .6 !important; }

/* 아주 작은 화면에서도 가장자리 여백 확보 */
@media (max-width: 576px){
  #farmSettingsModal .modal-dialog{ max-width: calc(100vw - 56px); }
}

/* Farm Settings modal buttons */
#farmSettingsModal #fsLoad{
  background: #f59e0b !important;   /* 주황 */
  color: #fff !important;
  border-color: #f59e0b !important;
}
#farmSettingsModal #fsLoad:hover{
  background: #d97706 !important;    /* 살짝 진하게 */
  border-color: #d97706 !important;
}

#farmSettingsModal #fsDelete{
  background: #ef4444 !important;    /* 빨강 */
  color: #fff !important;
  border-color: #ef4444 !important;
}
#farmSettingsModal #fsDelete:hover{
  background: #dc2626 !important;    /* 살짝 진하게 */
  border-color: #dc2626 !important;
}

/* 포커스/키보드 접근성 */
#farmSettingsModal #fsLoad:focus,
#farmSettingsModal #fsDelete:focus{
  box-shadow: 0 0 0 .15rem rgba(255,255,255,.15), 
              0 0 0 .35rem rgba(59,130,246,.25) !important;
  outline: none !important;
}

/* disabled일 때 */
#farmSettingsModal #fsLoad:disabled,
#farmSettingsModal #fsDelete:disabled{
  opacity: .65; filter: grayscale(.1);
}
#farmSettingsModal .farm-card__drag .btn-close{
  margin-left: auto;          /* 오른쪽으로 밀기 */
  filter: invert(1) brightness(200%);
  opacity: 1;
  width: .9rem; height: .9rem;
}



/* 백드롭(뒤 어둡게) — 선택 */
.modal-backdrop { background:#000; }
.modal-backdrop.show { opacity: .6; }
/* 내용 패널: 다크 카드 + 내부 스크롤 */
body #deviceModal .modal-content{
  background: #262a30 !important;
  color: #e8edf3 !important;
  border: 1px solid #3a3f47;
  border-radius: 12px;
  max-height: 92vh;
  overflow-y: auto;
  overflow-x: hidden;
}

/* 헤더도 다크 톤(선택) */

/* 헤더: 다크톤 + 오른쪽 정렬 */
#deviceModal .modal-header{
  background:#2d323a !important;
  border-bottom:1px solid #3a3f47 !important;
  display:flex !important;
  align-items:center !important;
  justify-content:flex-end !important;  /* 제목+닫기 우측 정렬 */
  gap:12px;                              /* 두 요소 간격 */
  padding:10px 16px;                     /* 가장자리 여백 */
  cursor: move;
  user-select: none;
}
/* 드래그 중에는 가운데 정렬 transform 끄기 */
#deviceModal.dragging .modal-dialog{
  transform: none !important;
}
/* 제목: 선명한 흰색, 오른쪽 정렬 */
#deviceModal .modal-title{
  color:#fff !important;
  font-weight:700;
  margin:0;                 /* gap으로만 간격 제어 */
  text-align:right;
  order:1;                  /* 닫기 버튼 오른쪽 끝, 제목은 그 왼쪽 */
}

/* 로봇 이미지 패널만 투명하게 */
#deviceModal .robot-image-panel{
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  /* 필요하면 여백도 제거
  padding: 0 !important;
  */
}

/* === Device modal: 중앙 배치 + 다크 스킨 === */

/* Bootstrap 기본 흐름을 존중: .modal.fade 가 알아서 숨김 처리 */
#deviceModal { display: none; }

/* .show 때는 block 만 — 전체화면 inset 고정은 제거 */
#deviceModal.show { display: block; }

/* 다이얼로그를 고정 중앙 배치 (드래그 대비 fixed 사용) */
#deviceModal .modal-dialog{
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  width: min(1280px, 96vw);
  max-height: 92vh;
}

/* 내용 스크롤 */
#deviceModal .modal-content{
  background: #262a30;
  color: #e8edf3;
  border: 1px solid #3a3f47;
  border-radius: 12px;
  max-height: 92vh;
  overflow-y: auto;
  overflow-x: hidden;
}

/* 헤더 */
#deviceModal .modal-header{
  background:#2d323a;
  border-bottom:1px solid #3a3f47;
  display:flex; align-items:center; justify-content:flex-end;
  gap:12px; padding:10px 16px;
  cursor: move; user-select: none;
}
#deviceModal .modal-title{ color:#fff; font-weight:700; margin:0; text-align:right; order:1; }

/* 드래그 중에는 중앙 transform 해제 (JS에서 .dragging 토글) */
#deviceModal.dragging .modal-dialog{ transform: none !important; }

/* 이미지 패널 투명 */
#deviceModal .robot-image-panel{ background: transparent; border:none; box-shadow:none; }

/* (선택) 백드롭 톤 */
.modal-backdrop{ background:#000; }
.modal-backdrop.show{ opacity:.6; }
/* == 모달 폭을 키우고, 화면 가장자리와 안전 여백 확보 ================== */
/* 데스크탑에서는 넓게, 작은 화면에서는 가장자리와 36~48px 여백 유지 */
.farm-card-dialog{
  /* 이전: width: min(420px, calc(100vw - 32px)); */
  width: clamp(520px, 58vw, 760px);            /* 기본 폭 확대 */
  max-width: calc(100vw - 72px);              /* 좌우 안전 여백(≈36px씩) */
}

/* == 카드 내부 패딩/섹션 간격 늘리기 =================================== */
.farm-card{
  /* 이전: padding: 18px 18px 14px; */
  padding: 24px 28px 18px;                    /* 좌우/상단 여백 확장 */
  border-radius: 16px;
}

.farm-card__body{
  /* 이전: padding: 0 6px 8px; */
  padding: 4px 6px 10px;
}

/* 입력 그룹 사이 간격을 일정하게 */
.farm-card__body > * + *{ margin-top: 12px; }

/* label과 컨트롤 간격 조금 더 */
.form-label-sm{ margin-bottom: .35rem; }

/* 하단 버튼 영역도 여백/간격 확장 */
.farm-card__actions{
  padding: 12px 6px 4px;
  gap: 10px;
}

/* 아주 작은 화면일 때(≤576px)도 가장자리와 붙지 않게 */
@media (max-width: 576px){
  .farm-card-dialog{ max-width: calc(100vw - 56px); }  /* 좌우 28px 여백 */
  .farm-card{ padding: 20px 22px 16px; }
}











/* 로봇 ID 글씨는 그대로 보이도록 */
#deviceModal .robot-image-panel .robot-id{
  color:#e8edf3 !important;
}

/* 닫기 버튼: 선명한 흰색 */
#deviceModal .btn-close{
  order:2;
  opacity:1 !important;
  filter: invert(1) brightness(200%) !important;
  width:.9rem; height:.9rem;
}
/* 백드롭: 진하게 */
.modal-backdrop{ background:#000 !important; }
.modal-backdrop.show{ opacity:.6 !important; }

/* 모달 열렸을 때 페이지 스크롤 잠금 */
/* body.modal-open{ overflow: hidden !important; } */

/* ===== 아래는 당신의 디자인(패널/그리드/게이지/배터리) ===== */

.device-modal-dark{ background:#262a30; color:#e8edf3; border:1px solid #3a3f47; }
.device-modal-dark .modal-header{ background:#2d323a; border-bottom:1px solid #3a3f47; }
.device-modal-footer{ background:#1f2430; border-top:1px solid #2c3342; }


.robot-detail-grid{
  display:grid;
  grid-template-columns: 1.1fr 1fr 1fr 1fr;  /* 좌측 이미지 + 3열 */
  grid-auto-rows: minmax(120px, auto);
  gap:16px;
}
.panel{
  background:#30353d;
  border:1px solid #3f4650;
  border-radius:8px;
  padding:14px;
  display:flex; flex-direction:column; justify-content:center;
}
.panel { overflow: hidden; }
.panel-title{ font-weight:600; color:#c9d1da; margin-bottom:8px; }
.panel-wide{ grid-column: span 3; }

.robot-image-panel{ align-items:center; justify-content:flex-start; }
.robot-image-panel img{ width:100%; height:auto; max-width:380px; object-fit:contain; }
.robot-id{ font-size:24px; font-weight:700; margin-bottom:8px; color:#e8edf3; }

.big-number{ font-size:38px; font-weight:800; letter-spacing:1px; }
.big-number small{ font-size:18px; opacity:.9; margin-left:6px; }

.state-badge{ font-size:40px; font-weight:900; color:#4caf50; text-align:center; }

.chart-placeholder{
  height:140px; border:1px dashed #555; display:flex; align-items:center; justify-content:center; color:#9aa5b1;
}
.panel .gauge { margin-top: 8px; }

/* 반원 게이지 */
/* 반도넛(두께 있는) 게이지 */
.gauge{
  --value:50;          /* 0~100 */
  --thickness:26px;    /* 호 두께 */
  width:180px; height:90px;
  position:relative; align-self:center;
}
.gauge-arc{
  position:absolute;
  top:-21%;           /* 원의 중심을 게이지 상변에 정확히 맞춤 */
  left:0; right:0;
  height:200%;        /* 완전한 원 크기 확보 */
  border-radius:50%;
  background: conic-gradient(
    from 180deg,
    #4caf50 calc(var(--value)*1%),
    #3f4650 0
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--thickness)), #000 0);
          mask: radial-gradient(farthest-side, transparent calc(100% - var(--thickness)), #000 0);
}
/* 아랫반원 가리기(반원만 보이도록) */
.gauge::after{
  content:""; 
  position:absolute; 
  inset:auto 0 0 0; 
  /* height:50%;  */
  background:#30353d;
}
.gauge-label{ position:absolute; inset:auto 0 8px 0; text-align:center; font-weight:700; }



/* 스피드게이지 */
/* 패널 배경색을 변수로 공유(없으면 기본 색 사용) */
.panel { --panel-bg: #30353d; }

/* ── SPEED: 반원 바늘 게이지(단순 버전) ───────────────── */
.speed-gauge{
  --angle: -90deg;         /* JS에서 setSpeedNeedle로 갱신 */
  --thickness: 22px;       /* 도넛 두께 */
  /* 바늘/허브 색상 변수 */
  --needle-color: #ff4d4f; /* 빨간 바늘 */
  --hub-fill: #111;        /* 허브 내부색 */
  --hub-stroke: #fff;      /* 허브 테두리 */

  width: 240px;
  aspect-ratio: 2 / 1;
  position: relative;
  margin: 8px auto 0;
}

.speed-gauge .speed-arc{
  position:absolute; inset:0;
  border-top-left-radius:1000px;
  border-top-right-radius:1000px;
  overflow:hidden;                 /* 하단 절반 자동 클리핑 */
  z-index: 1;
}
.speed-gauge .speed-arc::before{
  content:"";
  position:absolute; inset:0;
  background: conic-gradient(
    from 180deg,
    #2ecc71 0      0.25turn,  /* 25% */
    #f1c40f 0.25turn 0.50turn,/* 25% */
    #e67e22 0.50turn 0.75turn,/* 25% */
    #e74c3c 0.75turn 1turn    /* 25% */
  );
}
.speed-gauge .speed-arc::after{
  content:"";
  position:absolute;
  inset: var(--thickness) var(--thickness) 0 var(--thickness);
  background: var(--panel-bg, #30353d);
  border-top-left-radius:1000px;
  border-top-right-radius:1000px;
}

/* ── 바늘(빨간 삼각형) ───────────────── */
.speed-gauge .needle{
  position:absolute;
  left:50%;
  bottom: calc(var(--thickness) - 2px);   /* 축이 반원 경계선에 걸리도록 */
  width:0; height:0;                      /* 삼각형은 border로 그림 */
  transform-origin: 50% 100%;
  transform: rotate(var(--angle));
  z-index: 3;
  transition: transform .25s cubic-bezier(.2,.8,.2,1);
  pointer-events:none;
}
/* 삼각 바늘 */
.speed-gauge .needle::before{
  content:"";
  position:absolute;
  left:50%; bottom:0;
  transform: translateX(-50%);
  width:0; height:0;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-bottom: 72px solid var(--needle-color);
  filter: drop-shadow(0 0 1px rgba(0,0,0,.35));
}
/* 허브(동그란 축) */
.speed-gauge .needle::after{
  content:"";
  position:absolute;
  left:50%; bottom:-10px;
  transform: translateX(-50%);
  width:18px; height:18px;
  background: var(--hub-fill);
  border:2px solid var(--hub-stroke);
  border-radius:50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,.35);
}

/* 숫자 라벨(바늘 위에 겹치지 않게) */
.speed-gauge .speed-value{
  position:absolute;
  left:50%;
  bottom: calc(var(--thickness) + 14px);  /* 도넛 안쪽 위에 배치 */
  transform: translateX(-50%);
  font-weight:700;
  z-index: 4;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
  bottom: -15px;
}
/* .speed-value{
  bottom: -15px;
} */

/* 배터리 */
.battery{
  --pct:50; width:48px; height:84px; border:3px solid #dfe5ec; margin:8px auto 0;
  border-radius:8px; position:relative; background:#1f2329;
}
.battery::after{ content:""; position:absolute; top:-10px; left:50%; transform:translateX(-50%); width:16px; height:8px; background:#dfe5ec; border-radius:2px; }
.battery-level{ position:absolute; left:3px; right:3px; bottom:3px; height:calc(var(--pct)*1%); background:#4caf50; border-radius:4px; transition:height .3s ease; }
#m-battery-text{ font-weight:800; font-size:22px; }





/* 카드 클릭시 손가락 커서 */
.card[data-robot-id]{ cursor:pointer; }
.card[data-robot-id] * {
    pointer-events: none;
}


/* === Mini Map === */
/* #trendMiniMap.mini-map{
  display:flex; gap:12px; height:160px;
  border:1px dashed #555; border-radius:8px;
  padding:10px; background:transparent;
}
#trendMiniMap .mini-col{
  flex:1; position:relative;
  background:#262a30; border:1px solid #3f4650;
  border-radius:8px;
}
#trendMiniMap .mini-label{
  position:absolute; top:8px; left:10px;
  color:#c9d1da; font-weight:700;
}
#trendMiniMap .mini-track{
  position:absolute; left:50%; top:12%;
  transform:translateX(-50%);
  width:6px; height:76%; background:#3a3f47; border-radius:3px;
}
#trendMiniMap .mini-dot{
  position:absolute; left:50%; transform:translate(-50%,-50%);
  width:12px; height:12px; border-radius:50%;
  background:#ffd54f; box-shadow:0 0 8px #ffd54f;
  animation: miniBlink 1s infinite;
}
@keyframes miniBlink { 0%,100%{opacity:.35} 50%{opacity:1} } */

/* === Mini map: vertical === */
#trendMiniMap.mini-map{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: center;
  gap: 16px;
  height: 140px;           /* 필요시 높이 조절 */
}

.mini-col{
  height: 100%;
  display: flex;
  flex-direction: column;  /* 위: 트랙, 아래: 라벨 */
  align-items: center;
}

.mini-track{
  position: relative;
  width: 4px;              /* 세로 라인 두께 */
  height: calc(100% - 28px); /* 라벨 높이 만큼 빼기 */
  background: #3a424b;
  border-radius: 2px;
}

.mini-label{
  margin-top: 8px;
  font-weight: 600;
  opacity: 0.9;
}

/* 점(깜빡임) */
.mini-dot{
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ffd166;
  box-shadow: 0 0 10px #ffd166;
  animation: miniDotBlink 1s infinite;
}

@keyframes miniDotBlink{
  0%,100%{ opacity: .35; box-shadow: 0 0 0 #ffd166; }
  50%{    opacity: 1;   box-shadow: 0 0 14px #ffd166; }
}



/* === Robot hover card === */
/* === Robot hover card === */
#robotHoverCard{
  --card-bg: rgba(24, 28, 33, 0.78); /* ← 0.92 → 0.78 로 살짝 더 투명 */
  position: fixed;
  z-index: 5000;
  display: none;
  pointer-events: none;
  background: var(--card-bg);
  color:#fff;
  font-size:12px;
  line-height:1.35;
  border:1px solid rgba(255,255,255,.15);
  border-radius:8px;
  padding:8px 10px;
  box-shadow:0 8px 24px rgba(0,0,0,.35);
  min-width:160px;
  max-width:240px;
  transform: translateX(-50%);
}
#robotHoverCard .title{font-weight:700;margin-bottom:4px}
#robotHoverCard b{color:#fff}

/* 꼬리 */
#robotHoverCard::after{
  content:"";
  position:absolute;
  left:50%;
  transform:translateX(-50%);
  width:0;height:0;
  border:8px solid transparent;
}

/* 위로 뜰 때 */
#robotHoverCard.top::after{
  top:100%;
  border-top-color: var(--card-bg);   /* 꼬리 색도 동일 */
}
/* 아래로 뜰 때 */
#robotHoverCard.bottom::after{
  bottom:100%;
  border-bottom-color: var(--card-bg);/* 꼬리 색도 동일 */
}



/* 이동 로그 카드: 라이트 스타일 */
#logCard .card-body{
  height: 260px;            /* 필요 시 조절 */
  overflow-y: auto;
  background: #ffffff;
  color: #111111;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  line-height: 1.5;
  padding: 12px 14px;
  border-top: 1px solid #e9ecef; /* 헤더와 구분 */
}

#logCard #logList li{
  padding: 2px 0;
  white-space: pre-wrap;    /* 길면 줄바꿈 */
}

/* 카드 자체 여백은 기본 유지, 가장 넓게 보이도록 */
#logCard.card{
  width: 100%;
}

/* 공통 로그 패널 스타일 */
.log-pane{
  height: 280px;          /* ← 원하는 값(예: 240~320px)로 통일 */
  overflow: auto;
  background: #fff;
  color: #111;
  border-radius: .35rem;
}
#logList li,
#mqttList li{
  padding: .25rem .5rem;
  border-bottom: 1px dashed rgba(0,0,0,.08);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: .92rem;
  line-height: 1.3;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
#logList li:last-child,
#mqttList li:last-child{ border-bottom: 0; }

/* 메시지 타입별 색상(옵션) */
.mqtt-ok    { color:#2e7d32; }  /* green */
.mqtt-warn  { color:#ef6c00; }  /* orange */
.mqtt-err   { color:#c62828; }  /* red */
.mqtt-muted { color:#555; }
/* 카드 높이 강제 동일화(부트스트랩 컬럼 안에서) */
.equal-logs > [class*="col-"] { display: flex; }
.equal-logs .card { flex: 1 1 auto; display: flex; flex-direction: column; }
.equal-logs .card .card-body { flex: 1 1 auto; }

#mqttList .mqtt-row{padding:.5rem .75rem;border-bottom:1px solid #eef2f7}
#mqttList .topic-badge{display:inline-block;background:#eef5ff;color:#0b5ed7;
  border-radius:6px;padding:2px 6px;font-size:.75rem;margin-left:.25rem}
#mqttList .ts{color:#6c757d;font-size:.8rem;margin-right:.5rem}
#mqttList pre.mqtt-json{margin:.25rem 0 0 0;white-space:pre-wrap;word-break:break-word}



/* 가로 그리드 */
.mqtt-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(280px, 1fr));
  gap:8px;
  max-height:320px;            /* 카드 높이는 기존 로그 반 높이 기준 */
  overflow:auto;               /* 스크롤 */
  padding-right:4px;
}

/* 개별 메시지 카드 */
.mqtt-card{
  border:1px solid #eef2f7;
  border-radius:10px;
  padding:.5rem .6rem;
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.03);
}

/* 헤더(시간/토픽/버튼) */
.mqtt-head{
  display:flex; align-items:center; gap:.5rem;
  font-size:.84rem; margin-bottom:.25rem;
}
.mqtt-ts{ color:#6c757d; }
.mqtt-topic{ background:#eef5ff; color:#0b5ed7; border-radius:6px; padding:2px 6px; }
.mqtt-mini{ margin-left:auto; display:flex; gap:6px; }
.mqtt-mini button{ border:none; background:#f3f4f6; padding:2px 6px; border-radius:6px; font-size:.75rem; cursor:pointer }

/* 요약 라인 */
.mqtt-summary{
  font-size:.86rem; color:#2b2f33;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* 접히는 JSON 본문 */
.mqtt-json{ display:none; margin:.35rem 0 0 0; font-size:.8rem; white-space:pre-wrap; word-break:break-word }
.mqtt-card.expanded .mqtt-json{ display:block; }


/* ============================================================================== */
/* 시뮬레이션 버튼 */
.sim-btn{
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              box-shadow .2s ease, transform .05s ease;
}
.sim-btn:active{ transform: translateY(1px); }

/* 실행 중: 시작 버튼을 초록, 강조 */
#btnSimStart.running{
  background-color:#28a745;
  color:#fff;
  border-color:transparent;
  box-shadow:0 0 16px rgba(40,167,69,.35);
}

/* 실행 중: 중지 버튼을 ‘무장(armed)’ 상태로 빨강 */
#btnSimStop.armed{
  background-color:#dc3545;
  color:#fff;
  border-color:transparent;
  box-shadow:0 0 16px rgba(220,53,69,.35);
}

/* 실행 중 표시 점 깜빡임(시작 버튼 텍스트 앞에) */
body.sim-running #btnSimStart::before{
  content:"●";
  margin-right:6px;
  color:#ff5252;
  animation:sim-blink 1s step-end infinite;
}
@keyframes sim-blink{ 50%{ opacity:.3; } }
/* ============================================================================== */


/* ===== MQTT Settings Modal: device/farm 모달과 동일한 규칙 적용 ===== */
/* #mqttSettingsModal { 
  display: none;                    
}
#mqttSettingsModal.show{
  position: fixed !important;      
  inset: 0 !important;              
  z-index: 1055 !important;
  display: block !important;
}
#mqttSettingsModal .modal-dialog{
  position: fixed !important;
  top: 50% !important; 
  left: 50% !important;
  transform: translate(-50%, -50%) !important; 
  margin: 0 !important;
  width: clamp(480px, 46vw, 720px);            
  max-width: calc(100vw - 72px);              
  max-height: 92vh;
}
#mqttSettingsModal .modal-content{
  background: #262a30;               
  color: #e8edf3;
  border: 1px solid #3a3f47;
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,.45);
  overflow: auto;
}
#mqttSettingsModal .modal-header{
  background:#2d323a;
  border-bottom:1px solid #3a3f47;
}
#mqttSettingsModal .btn-close{
  filter: invert(1) brightness(200%);
  opacity: 1;
} */



/* ===== MQTT 모달: 라이트 테마 & 중앙 고정 ===== */
#mqttSettingsModal.show {
  position: fixed !important;
  inset: 0 !important;
  display: block !important;
  z-index: 1055 !important;
}

#mqttSettingsModal .modal-dialog {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;

  /* ✅ 폭을 여유 있게 조정 */
  width: clamp(640px, 60vw, 880px);
  max-width: calc(100vw - 120px);
  max-height: 90vh;

  margin: 0 !important;
}

#mqttSettingsModal .modal-content.mqtt-light {
  background: #ffffff;
  color: #1c2128;
  border: 1px solid #e2e6eb;
  border-radius: 16px;
  box-shadow: 0 22px 60px rgba(0,0,0,.25);
  padding: 10px 16px 16px 16px; /* ✅ 내부 여백 추가 */
}

/* 헤더: X는 오른쪽, 살짝 강조 */
#mqttSettingsModal .modal-header {
  background: #f9fafb;
  border-bottom: 1px solid #e6e9ef;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
#mqttSettingsModal .modal-title {
  font-weight: 700;
  font-size: 1.05rem;
}
#mqttSettingsModal .btn-close {
  opacity: 0.8;
  margin-left: auto;
}
#mqttSettingsModal .btn-close:hover { opacity: 1; }

/* 폼 영역 */
#mqttSettingsModal .form-label { font-weight: 600; margin-top: 0.4rem; }
#mqttSettingsModal .form-control {
  height: 44px;
  border-radius: 10px;
  border: 1px solid #d6d9e0;
  background: #fff;
  color: #1c2128;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.95rem;
}
#mqttSettingsModal .form-text { color: #7d8798; }

/* 상태 표시 */
#mqttSettingsModal .mqtt-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
  background: #f3f6fb;
  color: #273047;
  border: 1px dashed #cfd6e3;
}
#mqttSettingsModal .mqtt-badge.ok {
  background: #e9f8ef;
  color: #165f35;
  border-color: #bfe6cf;
}
#mqttSettingsModal .mqtt-badge.err {
  background: #fce8ea;
  color: #842029;
  border-color: #f5c2c7;
}
#mqttSettingsModal .mqtt-badge .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #28a745;
}

/* 푸터 버튼 */
#mqttSettingsModal .modal-footer {
  border-top: 1px solid #e6e9ef;
  padding-top: 12px;
  gap: 0.6rem;
}

/* 드래그 핸들 */
#mqttSettingsModal .mqtt-drag-handle {
  cursor: move;
}





/* TCP 로그 전체 스타일 */
#tcpGrid {
  font-size: 1rem;          /* 전체 로그 글씨 크기 */
  line-height: 1.4;         /* 가독성 향상 */
}

/* 로그 한 줄 컨테이너 */
.tcp-item {
  padding: 10px 12px;
  margin-bottom: 10px;
  border-radius: 6px;
  background: #fafafa;
  border: 1px solid #e6e6e6;
}

/* 상단 제목 "TCP MESSAGE" */
.tcp-topic {
  font-size: 1.1rem;
  font-weight: 600;
  color: #333;
}

/* 날짜 */
.tcp-time {
  font-size: 0.95rem;
  color: #555;
}

/* JSON 내용 */
.tcp-json {
  font-size: 1rem;        /* JSON 글자 크게 */
  white-space: pre-wrap;  /* 줄바꿈 자동 */
  word-break: break-all;  /* 너무 길면 강제 개행 */
  margin-top: 6px;
}

/* LED 스타일 */
/* LTE Status Style */
.m-lte-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

/* LED 점 스타일 */
.lte-led {
  display: inline-block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  margin-right: 8px;
  flex-shrink: 0;
  box-shadow: 0 0 6px rgba(255,255,255,0.4);
}

/* 상태 Text 스타일 */
.lte-text {
  font-size: 24px;
  font-weight: 600;
  line-height: 1;
  color: #e6e6e6;
  user-select: none;
}

/* 상태별 색상 */
.lte-online { background: #27c93f; }
.lte-delay {
  background: #ffee00;
}
.lte-attached { background: #ff822efb; }
.lte-offline { background: #ff605c; }


/* ✅ MQTT 모달이 'show'가 아닐 때는 화면을 절대 덮지 않게 */
#mqttSettingsModal:not(.show){
  display: none !important;
  pointer-events: none !important;
}

/* ✅ show일 때만 overlay 동작 */
#mqttSettingsModal.show{
  pointer-events: auto !important;
}
#gpsCard .card-header{
  position: relative;
  z-index: 50;
}

#gpsMap{
  position: relative;
  z-index: 1;
}

/* ===== TagPick Modal: 중앙 고정 + 작은 카드형 ===== */
/* Tag pick grid */
#tagPickGrid {
  display: grid;
  gap: 2px;
  user-select: none;
  justify-content: center;
}

.tp-cell {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: #ffffff;
  border: 1px solid #364055;
  cursor: pointer;
  box-sizing: border-box;
}

.tp-cell:hover { outline: 2px solid rgba(255, 193, 7, 0.35); }
.tp-cell.tp-obstacle { background:#3a3f48; border-color:#3a3f48; cursor:not-allowed; opacity:.9; }
.tp-cell.tp-selected { background:#ffc107; border-color:#ffc107; outline:2px solid rgba(255,193,7,.55); }
.tp-cell.tp-startline { box-shadow: inset 0 0 0 2px rgba(0, 200, 255, 0.35); }

/* ===== TagPick Modal: 중앙 고정 + 작은 카드형 ===== */
#tagPickModal { display: none; }  /* 기본 숨김 */

#tagPickModal.show{
  position: fixed !important;
  inset: 0 !important;
  display: block !important;
  z-index: 1065 !important;
}

#tagPickModal .modal-dialog{
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  width: clamp(520px, 48vw, 760px);
  max-width: calc(100vw - 72px);
  max-height: 88vh;
}

#tagPickModal .modal-content{
  background: #ffffff !important;
  color: #080808 !important;
  border: 1px solid #ffffff !important;
  border-radius: 12px;
  box-shadow: 0 12px 36px rgb(255 255 255 / 45%);
  overflow: hidden;
}

#tagPickModal .modal-body{
  max-height: calc(88vh - 120px);
  overflow: auto;
}


/* 태그 아코디언 헤더를 "버튼"이 아니라 "섹션 타이틀"처럼 보이게 */
#farmSettingsModal #fsTagAccordion .accordion-item {
  background: transparent;
  border: 1px solid #2c3342;
  border-radius: 10px;
  overflow: hidden;
}

#farmSettingsModal #fsTagAccordion .accordion-button {
  background: #ad6b86;           /* 모달 톤과 통일 */
  color: #e8edf3;
  font-weight: 700;
  padding: 10px 12px;
  box-shadow: none;
}

/* hover도 "버튼"처럼 튀지 않게 */
#farmSettingsModal #fsTagAccordion .accordion-button:hover {
  background: #ad4989;
}

/* 포커스 파란 링(버튼 느낌) 줄이기 */
#farmSettingsModal #fsTagAccordion .accordion-button:focus {
  box-shadow: none;
  border-color: #92378e;
}

/* 펼쳐졌을 때(=not collapsed)도 톤 유지 */
#farmSettingsModal #fsTagAccordion .accordion-button:not(.collapsed) {
  background: #ad4989;
  color: #ffffff;
}

/* 펼침/접힘 화살표도 너무 버튼같으면 톤다운 */
#farmSettingsModal #fsTagAccordion .accordion-button::after {
  filter: brightness(0.9);
  opacity: 0.7;
}
/* 태그 등록/관리 헤더 → 클릭 가능 표시 */
#farmSettingsModal .tag-section-header,
#farmSettingsModal .accordion-button,
#farmSettingsModal .tag-title {
  cursor: pointer;
}
/* ✅ 태그가 열렸을 때(= farmSettingsModal.tag-open) 모달 가로 확장 */
#farmSettingsModal.tag-open .modal-dialog{
  width: clamp(980px, 86vw, 1400px);
  max-width: calc(100vw - 48px);
}

/* ✅ 태그가 열렸을 때만 2컬럼 레이아웃 */


/* 기본(태그 닫힘)은 오른쪽 패널을 아래로 내리거나 숨김 */
/* #farmSettingsModal .fs-right{ margin-top: 12px; } 그냥 보기용 */
#farmSettingsModal.tag-open .fs-right{ margin-top: 0; }

/* ✅ 기본부터 2컬럼 유지 (헤더는 항상 보이게) */
#farmSettingsModal .farm-card__body{
  display: grid;
  grid-template-columns: minmax(640px, 1fr) 520px;
  gap: 14px;
  align-items: start;
}


/* ✅ 오른쪽 패널 숨김 제거 (헤더 클릭 가능해야 함) */
#farmSettingsModal .fs-right{
  position: sticky;
  top: 12px;
  align-self: start;
  margin-top: 0; /* ✅ 아래로 내려가는 효과 제거 */
}


#farmSettingsModal.tag-open .farm-card__body{
  grid-template-columns: 1fr 460px;  
}

#farmSettingsModal.tag-open #fsTagAccordion{
  position: sticky;
  top: 0;
}

#farmSettingsModal.tag-open .fs-right{
  opacity: 1;
  pointer-events: auto;
}

/* ✅ tag-open일 때 모달 자체도 가로로 확장 */
#farmSettingsModal.tag-open .modal-dialog{
  width: clamp(980px, 86vw, 1400px);
  max-width: calc(100vw - 48px);
}

#farmSettingsModal .fs-tag-table{
  max-height: 320px;
  overflow-y: auto;
}
