/* BulkJob 진행 패널 — common.loading 전면 차단 오버레이를 대신한다. */

/*
   ★ 딤은 작업을 시작한 탭의 본문만 덮는다.

   예전에는 inset:0 으로 화면 전체를 덮었다. 벌크가 도는 동안 좌측 메뉴도 상단 탭도
   못 눌러서, 5분짜리 작업 하나가 사람을 5분 묶어 두었다.

   탭 전환·새 탭 열기는 페이지를 다시 읽지 않는다(main.js 는 AMP_COMPONENT div 를
   추가하고 v-show 로 바꿔 끼운다). 즉 다른 탭으로 옮겨도 pagehide 가 뜨지 않아
   작업이 취소되지 않는다. 전체를 덮을 이유가 없었다.

   위치는 자바스크립트가 소유 탭의 사각형을 재서 넣는다. position 은 fixed 그대로다 —
   탭 본문 안에 넣으면 Vue 가 그 subtree 를 다시 그릴 때 노드가 날아간다.
*/
/*
   z-index 는 다이얼로그(#mainPopup 20000, 개별 다이얼로그 30000+) 아래에 둔다.

   예전에는 21억이었다. 화면 전체를 덮던 시절에는 그래도 됐지만, 이제 다른 탭에서
   일하게 열어 준 이상 그 탭에서 띄운 다이얼로그가 이 딤 밑에 깔리면 안 된다.
   딤은 자기 탭 본문만 가리면 충분하다.
*/
.bulkjob-backdrop{position:fixed;background:rgba(16,23,32,.55);z-index:19000;
  display:flex;align-items:center;justify-content:center;
  overscroll-behavior:contain;touch-action:none;-webkit-user-select:none;user-select:none;
  backdrop-filter:saturate(60%) blur(1px);}

/* 소유 탭을 찾지 못했을 때(로그인·팝업 레이아웃 등)는 예전처럼 전체를 덮는다.
   그때는 어차피 화면 전체를 묶는 것이 의도라 위에 있어야 한다. */
.bulkjob-backdrop.is-full{inset:0;z-index:2147483000;}

/* 다른 탭을 보고 있는 동안. 작업은 계속 돈다. */
.bulkjob-backdrop.is-away{display:none;}
.bulkjob-panel{-webkit-user-select:text;user-select:text;}   /* 패널 안 텍스트는 선택 가능 */
.bulkjob-panel{background:#fff;border-radius:8px;box-shadow:0 8px 32px -8px rgba(0,0,0,.35);
  width:min(680px,92vw);padding:20px 22px 16px;font-size:14px;color:#101720;}
.bulkjob-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:14px;}
.bulkjob-title{font-size:17px;font-weight:700;margin:0 0 4px;}
.bulkjob-sub{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;color:#78828f;margin:0;}
/* 남은 시간이 주인공이고 경과는 참고다 — 사용자가 알고 싶은 건 "언제 끝나나" 다. */
.bulkjob-clock{font-family:ui-monospace,Menlo,monospace;
  font-variant-numeric:tabular-nums;text-align:right;line-height:1.25;}
.bulkjob-eta{display:block;font-size:19px;font-weight:600;white-space:nowrap;}
.bulkjob-eta b{font-size:22px;}
.bulkjob-eta i{font-size:12px;font-weight:400;font-style:normal;color:#8a8f98;}
.bulkjob-elapsed{display:block;font-size:12px;font-weight:400;color:#8a8f98;}

.bulkjob-banner{padding:10px 12px;border-radius:5px;font-size:13.5px;margin-bottom:12px;}
.bulkjob-banner.ok  {background:#e4f3eb;border:1px solid #9dd3b6;}
.bulkjob-banner.warn{background:#fdf3e0;border:1px solid #e8c37a;}
.bulkjob-banner.bad {background:#fbeae8;border:1px solid #e5a49d;}

/* 전체 진행바가 곧 건별 구성비 */
.bulkjob-gauge{height:22px;border-radius:4px;overflow:hidden;display:flex;
  background:#dfe3e9;border:1px solid #cfd5dd;}
.bulkjob-gauge > i{display:block;height:100%;width:0;transition:width .35s ease;}
.bulkjob-gauge .g-ok{background:#127a4b;} .bulkjob-gauge .g-bad{background:#c0392f;}
.bulkjob-gauge .g-skip{background:#6b7683;} .bulkjob-gauge .g-run{background:#c77a00;}

.bulkjob-legend{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;}
/* 범례는 곧 필터다. 눌러서 실패·미실행만 골라 볼 수 있다는 걸 모양으로 알려야 한다. */
.bulkjob-legend .lg{font-size:12px;padding:4px 9px;border-radius:4px;background:#f1f3f7;
  border:1px solid #e4e7ec;cursor:pointer;user-select:none;transition:background .12s,border-color .12s;}
.bulkjob-legend .lg:hover{background:#e7ebf2;border-color:#c9d0da;}
/* 남음은 거를 대상(행)이 없다 — 누를 수 있는 것처럼 보이면 안 된다. */
.bulkjob-legend .lg.is-static{cursor:default;}
.bulkjob-legend .lg.is-static:hover{background:#f1f3f7;border-color:#e4e7ec;}
.bulkjob-legend .lg.is-on{background:#1f2d3d;border-color:#1f2d3d;color:#fff;}
.bulkjob-legend .lg.is-on b{color:#fff;}
.bulkjob-legend .lg b{font-family:ui-monospace,Menlo,monospace;font-size:13px;margin-left:4px;}
.bulkjob-legend .ok b{color:#127a4b;} .bulkjob-legend .bad b{color:#c0392f;}

.bulkjob-list{margin-top:14px;border:1px solid #dfe3e9;border-radius:5px;overflow:hidden;}
.bulkjob-rows{max-height:260px;overflow-y:auto;}
.bulkjob-row{display:grid;grid-template-columns:150px 1fr 96px 100px;gap:10px;
  padding:7px 12px;border-bottom:1px solid #eef0f3;align-items:center;font-size:13px;}
.bulkjob-row:last-child{border-bottom:0;}
/* 실패·건너뜀 사유. 상태 칩 안에 넣으면 잘려서 못 읽으므로 아래 줄에 전체 너비로 깐다. */
.bulkjob-row .rsn{grid-column:1/-1;font-size:12px;line-height:1.45;margin-top:3px;
  padding:4px 8px;border-radius:4px;word-break:break-all;}
.bulkjob-row .rsn.bad{background:#fdf0ef;color:#a3291f;border:1px solid #f5d9d6;}
.bulkjob-row .rsn.skip{background:#f6f7f9;color:#5b6472;border:1px solid #e6e9ee;}
.bulkjob-row.is-run{background:#fdf3e0;}
/* 업무키는 길다(주문일괄등록 27자). 넘침 제어가 없으면 옆 칸으로 흘러 표시명 위에 겹쳐
   그려진다 — 실측에서 "4110000/20260804/10003" 위에 "4110000 1000313318" 이 포개졌다.
   잘라 두고 전체 값은 title 로 본다. */
.bulkjob-row .k{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:#4a5563;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.bulkjob-row .n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bulkjob-row .s{font-size:11.5px;color:#78828f;}
.bulkjob-row .pill{font-size:11.5px;font-weight:600;padding:2px 8px;border-radius:99px;justify-self:start;}
.bulkjob-row .pill.wait{background:#f1f3f7;color:#78828f;}
.bulkjob-row .pill.run {background:#fdf3e0;color:#a86500;}
.bulkjob-row .pill.ok  {background:#e4f3eb;color:#127a4b;}
.bulkjob-row .pill.bad {background:#fbeae8;color:#c0392f;}
.bulkjob-row .pill.skip{background:#edeff2;color:#6b7683;}

.bulkjob-foot{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:14px;}
.bulkjob-note{font-size:12px;color:#78828f;margin:0;}
.bulkjob-foot button{font-size:13px;font-weight:600;padding:7px 15px;border-radius:5px;
  border:1px solid #dfe3e9;background:#fff;cursor:pointer;margin-left:6px;}
.bulkjob-foot .bulkjob-cancel{color:#c0392f;border-color:#c0392f;}
.bulkjob-foot .bulkjob-close{background:#1b54c7;border-color:#1b54c7;color:#fff;}

/* 준비 중 — 클릭 즉시 표시. jobId 를 받기 전 구간을 비워두지 않는다. */
.bulkjob-prep{display:flex;align-items:center;gap:10px;padding:14px 4px;color:#4a5563;font-size:13.5px;}
.bulkjob-prep i{width:16px;height:16px;border-radius:50%;flex:none;
  border:2px solid #dfe3e9;border-top-color:#1b54c7;animation:bulkjob-spin .8s linear infinite;}
@keyframes bulkjob-spin{to{transform:rotate(360deg)}}

/* 멈춤 후 결정 — 취소를 누르면 먼저 세우고 나서 묻는다.
   확인 후 멈추면 결정하는 동안에도 처리가 진행돼 시점이 어긋난다. */
.bulkjob-paused{background:#fdf3e0;border:1px solid #e8c37a;border-radius:5px;
  padding:13px 14px;margin-bottom:12px;}
.bulkjob-paused-msg{font-size:13.5px;line-height:1.6;color:#101720;}
.bulkjob-paused-btns{display:flex;justify-content:flex-end;gap:8px;margin-top:11px;}
.bulkjob-paused-btns button{font-size:13px;font-weight:600;padding:7px 15px;border-radius:5px;
  border:1px solid #dfe3e9;background:#fff;cursor:pointer;}
.bulkjob-paused-btns .bulkjob-resume{background:#1b54c7;border-color:#1b54c7;color:#fff;}
.bulkjob-paused-btns .bulkjob-stop{color:#c0392f;border-color:#c0392f;}
.bulkjob-paused-btns .bulkjob-stop:hover{background:#fbeae8;}

/* 멈춤 중 경과 시간 — 세고 있지 않다는 것을 보이게 한다. */
.bulkjob-clock.is-paused{color:#a86500;}
.bulkjob-clock.is-paused::after{content:' 멈춤';font-size:11px;font-weight:600;}

/* ── 엑셀 업로드 행 상태 ────────────────────────────────────────────
   오류행은 붉게, 저장 완료행은 회색으로 가른다. 둘은 상호 배타다(오류가 우선).
   common.css 는 index.html 이 로드하지 않는다(common.min.css 를 쓴다). 그래서 여기에 둔다.
   003.js 에 인라인 getRowStyle 로 회색을 칠하던 것이 있었는데, 인라인이라 CSS 로는
   이길 수 없어 !important 가 필요했다. 그쪽을 걷고 여기로 모았다. */
.ag-theme-balham .ag-row.row-excel-error,
.ag-theme-balham .ag-row-even.row-excel-error,
.ag-theme-balham .ag-row-odd.row-excel-error {
  background-color: #fdecea;
}
.ag-theme-balham .ag-row.row-excel-error.ag-row-hover,
.ag-theme-balham .ag-row-even.row-excel-error.ag-row-hover,
.ag-theme-balham .ag-row-odd.row-excel-error.ag-row-hover {
  background-color: #fbd9d3;
}

/* 저장이 끝난 행 — 더 손댈 것이 없다는 표시 */
.ag-theme-balham .ag-row.row-excel-saved,
.ag-theme-balham .ag-row-even.row-excel-saved,
.ag-theme-balham .ag-row-odd.row-excel-saved {
  background-color: #f2f2f2;
  color: #767676;
}

/* 엑셀을 끌어다 놓는 중 — 여기 놓으면 된다는 표시.
   테두리와 배경을 요소 자체에 주면 그리드 자식들이 덮어 보이지 않는다.
   그래서 ::before 를 전면 오버레이로 깔고, 그 위에 아이콘과 문구를 얹는다.
   문구만으로는 "끌어다 놓는 곳"이라는 느낌이 오지 않아 아이콘을 중심에 둔다. */
.excel-drop-over {
  position: relative;
}
.excel-drop-over::before {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  border: 2px dashed #1b7fd4;
  border-radius: 6px;
  /* ag-Grid 의 'No Rows To Show' 가 비쳐 글자가 겹치므로 흰 반투명으로 덮는다. */
  background-color: rgba(255,255,255,.93);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231b7fd4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 5 17 10'/%3E%3Cline x1='12' y1='5' x2='12' y2='16'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center calc(50% - 22px);
  background-size: 76px 76px;
  pointer-events: none;
  z-index: 20;
  animation: excel-drop-lift .9s ease-in-out infinite alternate;
}
.excel-drop-over::after {
  content: '여기에 놓으세요';
  position: absolute;
  top: 50%;
  left: 0; right: 0;
  margin-top: 30px;
  text-align: center;
  color: #14608f;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.2px;
  pointer-events: none;
  z-index: 21;
}

/* 아이콘이 살짝 떠오르며 "올린다"는 동작을 암시한다. */
@keyframes excel-drop-lift {
  from { background-position: center calc(50% - 20px); }
  to   { background-position: center calc(50% - 26px); }
}
@media (prefers-reduced-motion: reduce) {
  .excel-drop-over::before { animation: none; }
}

/* 작업이 끝난 뒤 — 딤을 걷고 클릭을 통과시킨다.
   패널 자체가 화면 전체를 덮는 요소(z-index 21억)라 그대로 두면 다음 버튼이 안 눌린다.
   카드만 남겨 결과는 계속 보이게 하고, 카드 밖을 누르면 닫는다. */
.bulkjob-backdrop.is-released{background:transparent;pointer-events:none;}
.bulkjob-backdrop.is-released > *{pointer-events:auto;}

/* ── 엑셀을 끌어다 놓을 수 있는 화면임을 쉴 때도 알린다 ────────────────────
 *
 * 드래그 중 표시(.excel-drop-over)만 있으면 그런 기능이 있는 줄 모르는 사람에게는
 * 없는 것과 같다. 빈 그리드의 'No Rows To Show' 자리를 빌려 안내한다.
 * 행이 생기면 ag-Grid 가 이 자리를 걷으므로 저절로 사라진다.
 */
.excel-droppable .ag-overlay-no-rows-wrapper {
  /* 기본 문구('No Rows To Show')를 감춘다. 한글 안내와 섞이면 지저분하다. */
  font-size: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a8b3bd' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 5 17 10'/%3E%3Cline x1='12' y1='5' x2='12' y2='16'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center calc(50% - 22px);
  background-size: 34px 34px;
}
.excel-droppable .ag-overlay-no-rows-wrapper::after {
  content: '엑셀 파일을 여기에 끌어다 놓거나  [엑셀 업로드] 를 누르세요';
  display: block;
  margin-top: 30px;
  font-size: 13px;
  line-height: 1.6;
  color: #8a949e;
  white-space: pre-line;
}
