/* factory1_ipgo_style.css — 1공장 입고 스타일 정의
   (3공장 재고 종합 페이지 '입출고 대장' 좌측 패널(factory3_io.css의 .f3io-*)과
    동일한 레이아웃/색상 규격을 따릅니다) */

/* ================================================
   [옵션 설정] 글로벌 CSS 변수
   ================================================ */
:root {
    /*
      [제목 좌측 여백 옵션]
      '입고 대장' 제목의 좌측 여백입니다. 원하는 간격으로 px 값을 변경해 사용하세요.
    */
    --panel-title-left-offset: 12px;

    /*
      [날짜 열 너비 옵션]
      좌측 고정(sticky) 날짜 열의 너비입니다.
    */
    --ipgo-date-col-width: 72px;

    /*
      [표 높이 옵션]
      입고/별쇄 스크롤 영역의 높이입니다. 우측 영역은 여기에 맞춰 늘어납니다.
      계산식: 헤더 2줄(44px × 2 = 88px) + 행 높이 44px × 보고 싶은 일수
              7일  → 88 + 44 × 7  = 396px (이전 값)
              11일 → 88 + 44 × 11 = 572px
    */
    --ipgo-scroll-height: 572px;

    /*
      [우측 1층 카드 기본 높이]
      입고 현황(총무국 / 공무국) 카드의 '평소' 높이입니다.
      내용이 적은 날에도 이 높이 아래로는 줄지 않으므로, 총무국·공무국을
      오가도 아래 메모 카드의 윗선이 흔들리지 않습니다.
      내용이 이 높이를 넘는 날(총무국 블록 5개 + 48.8g)에는 카드가 아래로
      늘어나고, 그만큼 메모 카드가 줄어듭니다. 그래서 이 카드에는
      스크롤바가 생기지 않습니다.

      좌우 카드의 아래끝이 나란히 서도록 좌측 카드 높이에 맞춰 둡니다.
        좌측 카드 656px = 안쪽 여백 36 + 제목줄 32 + 제목 아래 여백 14 + 표 574
        우측 열   656px = 이 값 459 + 간격 14 + 메모 카드 183
      좌측 표 높이(--ipgo-scroll-height)를 바꾸면 이 값도 함께 맞춰 주세요.
      (표를 44px = 하루치 늘리면 이 값도 44px 늘리면 됩니다)
    */
    --ipgo-side-card-height: 459px;

    /*
      [우측 하단 메모 카드 높이]
      좌측 표가 길어지면서 남는 우측 공간에 들어가는 작은 카드입니다.
      (테두리·안쪽 여백을 포함한 전체 높이입니다)
      데스크톱에서는 우측 열의 남는 높이를 그대로 가져가므로 평소에는
      이 값과 같아지고, 위 카드가 늘어난 날에는 그만큼 줄어듭니다.
      화면이 좁아 카드가 세로로 쌓일 때는 이 값이 그대로 높이가 됩니다.
      메모 목록 한 줄은 약 17px 입니다. 여기서 17px 을 덜면 목록이 한 줄
      덜 보이고, 그만큼 --ipgo-side-card-height 를 늘려 주면 됩니다.
    */
    --ipgo-memo-height: 183px;

    /*
      [우측 하단 메모 카드 최소 높이]
      위 카드가 늘어난 날 메모 카드가 더 이상 줄지 않는 바닥선입니다.
      한 줄 약 17px 이라 110px 이면 4줄 남짓 보입니다.
      ※ 이 값을 올리면 위 카드가 늘어날 수 있는 여유(현재 최대 532px)가
        그만큼 줄어듭니다.
    */
    --ipgo-memo-min-height: 110px;

    /*
      [우측 열 전체 높이] = 좌측 카드 높이
      좌측 카드 656px = 안쪽 여백 36 + 제목줄 32 + 제목 아래 여백 14 + 표 574
      이므로 표 높이에 84px 을 더한 값입니다. 표 높이를 바꾸면 따라옵니다.
      우측 두 카드가 이 높이를 넘지 않게 잡아 두는 용도입니다. 넘어가면
      좌측 카드까지 같이 늘어나(align-items: stretch) 표 아래가 빕니다.
      ※ --ipgo-side-card-height 459 + 간격 14 + --ipgo-memo-height 183
        = 이 값 656 이 되도록 맞춰져 있습니다.
    */
    --ipgo-side-column-height: calc(var(--ipgo-scroll-height) + 84px);

    /*
      [좌우 레이아웃 비율 옵션]
      좌측(입고 및 별쇄 계획표) : 우측(추가 영역) 비율입니다.
      비율을 바꾸려면 두 값의 합이 100%가 되도록 함께 수정하세요.
      ※ 별관(3공장) 2열이 늘어난 만큼 좌측을 70% → 75% 로 넓혔습니다.
    */
    --ipgo-main-width: 75%;
    --ipgo-side-width: 25%;
    --ipgo-grid-gap: 14px;

    /*
      [데이터 열 개수]
      좌측 입고 대장의 품목 열 수입니다. 열을 추가/삭제하면 HTML 의
      colgroup span 과 이 값을 함께 맞춰 주세요.
    */
    --ipgo-data-col-count: 14;
}

.f1ip-wrapper {
    gap: 14px;
}

/* 1층 좌우 분할 — 좌측 입고/별쇄(7) : 우측 추가 영역(3) */
.f1ip-top-grid {
    display: flex;
    gap: var(--ipgo-grid-gap);
    align-items: stretch;
}

/* 내부 콘텐츠의 min-content 폭에 밀리지 않도록 비율을 flex-basis로 고정 */
.f1ip-main-card {
    flex: 0 0 calc(var(--ipgo-main-width) - var(--ipgo-grid-gap) / 2);
    min-width: 0;
}
/* 우측 열 — 입고 현황 카드 + 그 아래 메모 카드를 세로로 쌓습니다 */
.f1ip-side-column {
    flex: 0 0 calc(var(--ipgo-side-width) - var(--ipgo-grid-gap) / 2);
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--ipgo-grid-gap);
}

/* 입고 현황 카드는 기본 높이를 바닥으로 두고 내용만큼 늘어납니다.
   - 내용이 적은 날: min-height 에 걸려 기본 높이 그대로입니다. 총무국·
     공무국을 오가도 카드가 줄지 않아 아래 메모 카드의 윗선이 안 흔들립니다.
   - 총무국이 꽉 찬 날(블록 5개 + 48.8g): 필요한 만큼 아래로 늘어나고
     그만큼 메모 카드가 줄어듭니다. 메모는 원래 스크롤이 있는 목록이라
     손해가 없고, 입고 현황에는 스크롤바가 생기지 않습니다.
   그래도 감당이 안 되는 양이면 max-height 에 걸려 예전처럼 목록이
   스크롤됩니다(메모 카드를 바닥선 아래로 밀지 않기 위해서입니다).

   메모 카드는 우측 열에서 남는 높이를 전부 가져갑니다.
   height: 0 + min-height 조합이 핵심입니다. 메모가 많은 날 메모 카드가
   내용만큼 길어져 우측 열이 좌측보다 커지고, align-items: stretch 때문에
   좌측 카드까지 늘어나 표 아래가 비는 문제가 있었습니다. 높이 계산에
   쓰이는 값을 0(= 바닥선 110px)으로 묶어 두면 우측 열이 좌측 높이를
   넘겨 잡는 일이 없고, 실제 높이는 flex-grow 로 남는 만큼 채워집니다.

   box-sizing 을 지정해야 변수 값이 안쪽 여백을 포함한 전체 높이가 됩니다. */
.f1ip-side-card {
    flex: 0 0 auto;
    min-height: var(--ipgo-side-card-height);
    max-height: calc(var(--ipgo-side-column-height) - var(--ipgo-memo-min-height) - var(--ipgo-grid-gap));
    box-sizing: border-box;
}
.f1ip-memo-card {
    flex: 1 1 auto;
    height: 0;
    min-height: var(--ipgo-memo-min-height);
    box-sizing: border-box;
}

/* ================================================
   우측 영역: 지종별 재고 블록
   (제목 없이 블록만 세로로 균등 배치)
   ================================================ */
.f1ip-side-card {
    display: flex;
    flex-direction: column;
}

/* 카드 상단 — 총무국/공무국 전환 (기준 날짜는 아래 블록 위로 내렸습니다) */
.f1ip-side-head {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    padding-bottom: 9px;
    margin-bottom: 12px;
    border-bottom: 1px solid #ebebeb;
}

/* ── 입고 확인 칩 ────────────────────────────────────────────
   확인(초록 채움) / 미확인(회색 외곽선) 두 상태.
   master 는 버튼이라 눌러서 전환하고, 그 외 계정은 같은 모양의
   <span> 으로 보기만 합니다. (그리는 곳: render.js 의 renderCheckChip) */
.f1ip-check-slot {
    margin-right: auto;   /* 머리줄이 flex-end 라 이 칸만 왼쪽에 붙입니다 */
}

.f1ip-check-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 26px;
    padding: 0 10px;
    border-radius: 13px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: -0.2px;
    border: 1px solid #d2d2d7;
    background: #f5f5f7;
    color: #6e6e73;
    white-space: nowrap;
}

/* 확인 표시(✓) — 아이콘 글꼴을 쓰지 않습니다. 이 저장소의 아이콘 글꼴은
   쓰는 아이콘만 추린 사본이라, 목록에 없는 아이콘은 이름이 글자로 노출됩니다. */
.f1ip-check-mark {
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
}

.f1ip-check-chip.is-checked {
    border-color: #b7dfc3;
    background: #eaf7ee;
    color: #1e7e3e;
}

button.f1ip-check-chip { cursor: pointer; }
button.f1ip-check-chip:disabled { opacity: 0.55; cursor: default; }

/* 기준 날짜 — 맨 위에 고정하고 아래로 한 줄(약 19px)을 비웁니다.
   "날짜 / 빈 줄 / 대한제지 본관" 순서가 날짜와 무관하게 항상 같습니다.
   목록 바깥에 두었으므로 블록이 숨겨져도 이 위치는 움직이지 않습니다. */
.f1ip-side-date {
    flex: none;
    text-align: center;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.5;
    color: #1d1d1f;
    letter-spacing: -0.2px;
    white-space: nowrap;
    margin-bottom: 19px;
}

/* 총무국 / 공무국 전환 — factory1_ft_io 의 R/L·Kg 스위처와 같은 형태 */
.unit-switcher {
    position: relative;
    display: flex;
    flex: none;
    background: #eef0f4;
    border-radius: 14px;
    padding: 2px;
    width: 108px;
    height: 24px;
    align-items: center;
    border: 1px solid #d1d1d6;
    overflow: hidden;
    cursor: pointer;
}
.selection-bg {
    position: absolute;
    top: 2px; left: 2px;
    width: calc(50% - 2px); height: calc(100% - 4px);
    background-color: #000000;
    border-radius: 12px;
    transition: transform 0.25s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    will-change: transform;
    z-index: 1;
}
.selection-bg.mode-left  { transform: translateX(0); }
.selection-bg.mode-right { transform: translateX(100%); }
.unit-btn {
    position: relative; z-index: 2; flex: 1; border: none;
    background: transparent !important;
    font-size: 11px; font-weight: 600; color: #55555d;
    display: flex; align-items: center; justify-content: center;
    height: 100%;
    white-space: nowrap;
    cursor: pointer; outline: none;
    transition: color 0.2s ease;
}
.unit-btn.active { color: #ffffff !important; }

.f1ip-side-list {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* 위에서부터 채웁니다. 그 날 입고가 없어 블록이 빠지면 아래쪽이 비고,
       남은 블록들의 위치는 그대로 유지됩니다. */
    justify-content: flex-start;
    gap: 12px;
    /* 카드 높이가 고정이라 입고가 많은 날(블록 5개)에는 넘칠 수 있습니다.
       잘린 채 숨지 않도록 메모 카드와 같은 얇은 스크롤바를 띄웁니다. */
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: #c7c7cc transparent;
}
.f1ip-side-list::-webkit-scrollbar { width: 6px; }
.f1ip-side-list::-webkit-scrollbar-track { background: transparent; }
.f1ip-side-list::-webkit-scrollbar-thumb {
    background-color: #c7c7cc;
    border-radius: 8px;
}
.f1ip-side-list::-webkit-scrollbar-thumb:hover { background-color: #a1a1a6; }

/* ── 블록 안의 글자는 크기·굵기·색을 전부 동일하게 씁니다 ──────
   제목/지폭/kg 을 구분하지 않고 한 가지 서식으로만 표시합니다. */
.f1ip-side-block {
    text-align: center;
    line-height: 1.5;
    font-size: 12.5px;
    font-weight: 500;
    color: #1d1d1f;
    letter-spacing: -0.2px;
}

/* 지폭별 "지폭 - N롤" 한 줄 */
.f1ip-side-specs {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 2px 12px;
    white-space: nowrap;
}

.f1ip-side-roll {
    display: inline-block;
    min-width: 14px;
    text-align: right;
}

.f1ip-side-kg { white-space: nowrap; }

.f1ip-side-kg-val { display: inline-block; }

/* 한 블록 안의 두 번째 줄(대한제지 본관의 48.8g)만 앞 줄과 살짝 띄웁니다 */
.f1ip-side-kg + .f1ip-side-specs { margin-top: 6px; }

/* ================================================
   우측 하단: 메모 요약 카드
   화면에 불러온 구간의 셀 메모를 최근 날짜부터 한 줄씩 정리합니다.
   ================================================ */
.f1ip-memo-card {
    display: flex;
    flex-direction: column;
}

.f1ip-memo-head {
    flex: none;
    font-size: 12.5px;
    font-weight: 600;
    color: #1d1d1f;
    letter-spacing: -0.2px;
    padding-bottom: 9px;
    margin-bottom: 10px;
    border-bottom: 1px solid #ebebeb;
}

/* 목록 — 우측에 얇은 스크롤바를 띄워 위아래로 훑을 수 있게 합니다.
   (다른 영역은 스크롤바를 숨기지만, 여기는 내용이 더 있다는 걸
    알려 주는 편이 낫습니다) */
.f1ip-memo-list {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-right: 8px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: #c7c7cc transparent;
}
.f1ip-memo-list::-webkit-scrollbar { width: 6px; }
.f1ip-memo-list::-webkit-scrollbar-track { background: transparent; }
.f1ip-memo-list::-webkit-scrollbar-thumb {
    background-color: #c7c7cc;
    border-radius: 8px;
}
.f1ip-memo-list::-webkit-scrollbar-thumb:hover { background-color: #a1a1a6; }

/* 같은 날짜 메모 묶음 — 날짜는 묶음 머리에 한 번만 적습니다 */
.f1ip-memo-group {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.f1ip-memo-day {
    display: flex;
    align-items: baseline;
    gap: 5px;
    font-size: 11px;
    font-weight: 700;
    color: #8e8e93;
    letter-spacing: -0.2px;
}

/* 어느 공장 메모인지 — 날짜 옆 작은 배지 */
.f1ip-memo-factory {
    flex: none;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: -0.2px;
    padding: 1px 5px;
    border-radius: 4px;
}
.f1ip-memo-factory-1 { color: #1c6ec4; background: #e8f1fb; }
.f1ip-memo-factory-3 { color: #9a5b00; background: #fdf0dd; }

/* 한 항목 = 열 이름 + 메모 내용 (날짜는 묶음 머리에 있습니다).
   내용은 자르지 않습니다. 길면 다음 줄로 넘어가고, 카드를 넘치면
   목록이 스크롤됩니다. 줄 수를 제한하면 글자가 잘려 읽을 수 없습니다. */
.f1ip-memo-item {
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.45;
    color: #1d1d1f;
    letter-spacing: -0.2px;
    word-break: break-word;
    padding-left: 8px;
}

.f1ip-memo-label {
    color: #636366;
    font-weight: 700;
    margin-right: 5px;
}

.f1ip-memo-empty {
    margin: auto;
    text-align: center;
    font-size: 12.5px;
    font-weight: 500;
    color: #a1a1a8;
}

/* ================================================
   공무국 — 지종 묶음별 kg 합계
   이름은 오른쪽, 값은 왼쪽으로 맞춘 두 칸 배치입니다.
   줄 수가 날마다 달라져도(48.8g 유무) 콜론과 괄호가 세로로 나란히
   서서, 총무국의 가운데 정렬보다 값을 비교해 읽기 좋습니다.
   글자 서식은 총무국 블록과 동일하게 맞췄습니다.
   ================================================ */
.f1ip-gongmu-grid {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: center;
    align-content: start;
    column-gap: 12px;
    row-gap: 10px;

    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.5;
    color: #1d1d1f;
    letter-spacing: -0.2px;
}

.f1ip-gongmu-label {
    text-align: right;
    white-space: nowrap;
}

.f1ip-gongmu-val {
    text-align: left;
    white-space: nowrap;
}

/* 내용이 아직 정해지지 않은 화면 (공무국) */
.f1ip-side-pending {
    margin: auto;
    text-align: center;
    font-size: 12.5px;
    font-weight: 500;
    color: #a1a1a8;
}

/* 층(레이아웃) 외곽 프레임 — 이 안에 개별 패널(레이아웃 안의 레이아웃)이 들어갑니다 */
.f1ip-floor-container {
    background: #f7f8fa;
    border-radius: 16px;
    padding: 18px 20px;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.04);
    border: 1px solid #dcdce4;
    margin-bottom: 0;
}

/* ================================================
   패널 헤더 그리드 — 제목은 좌측 상단 고정
   ================================================ */
.panel-header-grid {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: stretch;
    padding-bottom: 6px;
    margin-bottom: 14px;
}

.panel-header-grid .header-left,
.panel-header-grid .header-center,
.panel-header-grid .header-right {
    display: flex;
    align-items: center;
    height: 100%;
}

.panel-header-grid .header-left {
    justify-content: flex-start;
    padding-left: var(--panel-title-left-offset);
}

.panel-header-grid .header-center {
    justify-content: center;
}

.panel-header-grid .header-right {
    justify-content: flex-end;
    gap: 8px;
}

.panel-title {
    font-size: 18px;
    font-weight: 700;
    color: #000000 !important;
    letter-spacing: -0.3px;
    margin: 0;
}

/* ================================================
   유틸리티
   ================================================ */
.d-flex { display: flex; }
.justify-content-end { justify-content: flex-end; }
.align-items-center { align-items: center; }
.gap-1 { gap: 4px; }
.gap-2 { gap: 8px; }
.fw-bold { font-weight: 700; }
.text-dark { color: #000000 !important; }
.text-muted { color: #8e8e93; }
.text-center { text-align: center; }
.small { font-size: 12px; }
.py-4 { padding-top: 16px; padding-bottom: 16px; }
.m-0 { margin: 0; }
.me-1 { margin-right: 4px; }
.mb-3 { margin-bottom: 14px; }

/* ================================================
   패널 바깥 컨테이너 / 개별 패널 (독립된 박스)
   ================================================ */
.f1ip-panels-outer {
    display: flex;
    gap: 16px;
    align-items: stretch;
    background: transparent;
    overflow: visible;
}

.f1ip-panel {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 0;
    background: #f7f8fa;
    border: 1px solid #e5e5ea;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.03);
}

/* 패널 비율 — 좌측 입고 대장(12열) : 우측 별쇄 계획표(3열)
   입력값이 두 자리 숫자 기준이라 열 폭을 좁게 잡고, 두 패널의 열 폭이
   비슷해지도록 12열 : 3열 비율에 맞췄습니다. */
.f1ip-panel-ledger { flex: 4.3; }
.f1ip-panel-plan   { flex: 1; }

/* ================================================
   스크롤 영역
   ================================================ */
.f1ip-scroll-area {
    position: relative;
    height: var(--ipgo-scroll-height);
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.f1ip-scroll-area::-webkit-scrollbar { display: none; }

/* 스크롤 잠금 시 시각적 반응 및 마우스 커서 제어 */
/* 내부 스크롤만 막고, 휠/터치는 페이지 전체 스크롤로 넘어가도록 둡니다 */
.f1ip-scroll-area.locked {
    touch-action: pan-y;
    overflow-y: hidden !important;
}

/* ================================================
   글래스 커서
   ================================================ */
.f1ip-cursor {
    position: absolute;
    pointer-events: none;
    background: rgba(255, 255, 255, 0.35);
    /* 바깥 그림자는 뺐습니다 — 고른 칸 주변이 단차 진 것처럼 허옇게
       보였습니다 (2026-08-10, 유리 커서를 쓰는 6개 페이지 공통 수정) */
    box-shadow: inset 0 0 8px rgba(255,255,255,0.5);
    border-radius: 6px;
    z-index: 8;
    opacity: 0;
    transition:
        top 0.12s cubic-bezier(0.23, 1, 0.32, 1),
        left 0.12s cubic-bezier(0.23, 1, 0.32, 1),
        width 0.10s ease-out,
        height 0.10s ease-out,
        opacity 0.10s ease-out;
}
.f1ip-cursor.active { opacity: 1; }

/* ================================================
   테이블
   ================================================ */
.f1ip-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    table-layout: fixed;
}

/* 열 너비 — 날짜는 고정, 품목 열은 남은 폭을 균등 분할 */
.f1ip-table col.f1ip-col-date { width: var(--ipgo-date-col-width); }
.f1ip-table col.f1ip-col-data { width: calc((100% - var(--ipgo-date-col-width)) / var(--ipgo-data-col-count)); }

/* 별쇄 계획표(우측 패널) — 3개 열이 남은 폭을 균등 분할 (colgroup 없이 colspan으로 자동 분배) */
.f1ip-plan-table { table-layout: fixed; }

/* 우측 패널의 날짜 열 — 데스크톱에서는 숨김 (좌측 패널과 행이 동기화되므로 불필요) */
.f1ip-responsive-date { display: none; }

.f1ip-table thead {
    position: sticky;
    top: 0;
    z-index: 20;
    background: #f7f8fa;
}

/* ─ 1레벨 헤더 행 ─ (좁은 열 폭에 맞춰 축소) */
.f1ip-thead-lv1 th {
    padding: 8px 2px 5px;
    font-size: 11.5px;
    font-weight: 800;
    color: #1d1d1f;
    text-align: center;
    border-bottom: 1px solid #e0e0e0;
    background: #f7f8fa;
    white-space: nowrap;
    height: 44px;
    box-sizing: border-box;
}

/* ─ 그룹 헤더 (1레벨) ─ */
.f1ip-group-th {
    font-size: 11.5px;
    font-weight: 800;
    color: #1d1d1f;
    padding: 8px 2px 5px;
    background: #f7f8fa;
    letter-spacing: -0.3px;
}

/* ─ 하위 구분이 없어 두 행을 병합한 1레벨 헤더 (예: 페이퍼 코리아) ─ */
.f1ip-single-th {
    vertical-align: middle;
    white-space: normal !important;
    line-height: 1.2;
    font-size: 10.5px;
    letter-spacing: -0.4px;
    padding: 4px 1px !important;
}

/* ─ 2레벨 헤더 행 ─ (좁은 열 폭에 맞춰 축소) */
.f1ip-thead-lv2 th {
    padding: 6px 1px 7px;
    font-size: 10.5px;
    font-weight: 700;
    color: #636366;
    text-align: center;
    border-bottom: 1px solid #e0e0e0;
    background: #f7f8fa;
    white-space: nowrap;
    height: 44px;
    box-sizing: border-box;
}

.f1ip-leaf-th {
    font-size: 10.5px;
    font-weight: 700;
    color: #636366 !important;
    text-align: center;
    letter-spacing: -0.3px;
}

/* ─ 그룹 구분선 ─ */
.f1ip-sep {
    border-left: 1px solid #e0e0e0 !important;
}

/* ─ 데이터 셀 ─ (두 자리 숫자 기준으로 좁게) */
.f1ip-table td {
    padding: 9px 1px;
    font-size: 12px;
    font-weight: 600;
    text-align: center;
    border-bottom: 1px solid #ebebeb;
    color: #1d1d1f;
    transition: background 0.12s;
    height: 44px;
    box-sizing: border-box;
}

/* ─ 날짜 헤더 & 셀 (좌측 고정) ─ */
.f1ip-date-th {
    position: sticky;
    left: 0;
    background: #f7f8fa !important;
    z-index: 21;
    text-align: center;
    min-width: var(--ipgo-date-col-width) !important;
    width: var(--ipgo-date-col-width) !important;
    border-right: 1px solid #e0e0e0 !important;
    border-bottom: 1px solid #e0e0e0 !important;
    font-size: 12px;
    font-weight: 800;
    color: #1d1d1f;
    box-sizing: border-box;
    white-space: nowrap;
    vertical-align: middle;
}

/* 날짜 셀 — .f1ip-table td 보다 우선하도록 선택자를 함께 지정 */
.f1ip-table td.f1ip-date-td,
.f1ip-date-td {
    position: sticky;
    left: 0;
    background: #f7f8fa;
    z-index: 12;
    text-align: center;
    white-space: nowrap;
    border-right: 1px solid #e0e0e0 !important;
    font-size: 11.5px;
    font-weight: 700;
    min-width: var(--ipgo-date-col-width) !important;
    width: var(--ipgo-date-col-width) !important;
    box-sizing: border-box;
    cursor: pointer;
    padding-left: 2px;
    padding-right: 2px;
}

/* ================================================
   오늘 / 선택 행 강조
   ================================================ */
.f1ip-row-today td { background: #e8f4fd !important; }
.f1ip-row-today .f1ip-date-td { background: #bbdefb !important; }
.f1ip-selected-row td { background: #f4f4f8 !important; }
.f1ip-selected-row .f1ip-date-td { background: #ebebf0 !important; }
.f1ip-row-today.f1ip-selected-row td { background: #daedf9 !important; }
.f1ip-row-today.f1ip-selected-row .f1ip-date-td { background: #bbd8f0 !important; }

/* 활성화된 헤더 — 선택한 그룹(1레벨) + 선택한 열(2레벨) 두 칸만 강조 */
.f1ip-thead-lv1 th.f1ip-header-active,
.f1ip-thead-lv2 th.f1ip-header-active,
.f1ip-group-th.f1ip-header-active {
    background-color: rgba(255, 160, 50, 0.18) !important;
    color: #c05a00 !important;
}

/* 겹침 순서(낮은 값이 아래)
     유리 커서 8 · 본문 강조 9 · 날짜칸 12 · thead 20 · 날짜 헤더 21

   [2026-08-06] 날짜칸이 5 였습니다. 1100px 이하에서는 표가 가로로 굴러가는데
   (아래 @media), 그때 밀려 온 본문 강조(9)와 유리 커서(8)가 붙박이 날짜 열
   **위로** 비쳐 나왔습니다. 왼쪽 붙박이는 본문보다 위, 머리글보다는 아래여야
   합니다 — 그래야 세로로 굴릴 때 날짜가 머리글 뒤로 들어갑니다.

   본문 칸(선택 강조 등)은 반드시 thead 보다 낮게 둡니다. 값이 같으면 문서
   순서상 뒤에 오는 tbody 가 이기고, 스크롤할 때 칸이 헤더 위로 비쳐 보입니다. */
.f1ip-selected-cell {
    position: relative;
    z-index: 9;
    font-weight: 900 !important;
    color: #000000 !important;
}

/* ─ 색상 / 호버 ─ */
.f1ip-sat { color: #007aff !important; }
.f1ip-sun { color: #ff3b30 !important; }
.f1ip-empty { color: #c7c7cc; font-weight: 400; }
/* 모바일 표(.f1ip-mobile-table)는 이 호버 배경에서 뺍니다 (2026-08-12).
   터치 화면에서는 탭한 자리에 :hover 가 계속 남는데, 이 선택자가 선택 열
   강조(.f1ip-mcol-active, 아래)보다 우선순위가 높아 방금 고른 칸의 배경이
   회색으로 덮여 "선택이 풀린 것처럼" 보였습니다. */
.f1ip-table:not(.f1ip-mobile-table) tbody tr:not(.f1ip-selected-row):hover td { background: #f7f7fa; }
.f1ip-data-cell { cursor: pointer; }

/* ================================================
   셀 메모 — 우측 상단 빨간 삼각형 (factory3_io 와 동일한 표기)
   더블클릭으로 입력하고 마우스를 올리면 내용이 툴팁으로 뜹니다.
   ================================================ */
/* z-index 를 준 셀은 자체 쌓임 맥락이 되어, 안쪽 삼각형이 아무리 높은 값을
   가져도 셀 밖(= thead 위)으로 튀어나오지 못합니다. 9 는 유리 커서(8) 위,
   thead(10) 아래입니다. */
.f1ip-table td.f1ip-has-memo {
    position: relative;
    z-index: 9;
    background-color: rgba(255, 59, 48, 0.05) !important;
}

.f1ip-table td.f1ip-has-memo::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    border-top: 8px solid #ff3b30;
    border-left: 8px solid transparent;
    z-index: 1;
    pointer-events: none;
}

/* ================================================
   편집 모드 — 수정 가능 구간(오늘 기준 ±7일)의 셀 입력
   ================================================ */

/* 입력칸이 들어간 셀
   input 을 absolute 로 띄워 레이아웃 흐름에서 완전히 빼냅니다.
   그래야 편집 모드에 들어가도 행 높이(44px)가 1px도 변하지 않아
   표가 위아래로 밀리지 않습니다. */
.f1ip-table td.f1ip-edit-cell {
    position: relative;
    padding: 0 !important;
    background: #fffdf7;
}

.f1ip-input {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    width: 100%;
    height: 100%;
    border: 0;
    outline: 0;
    background: transparent;
    text-align: center;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    color: #1d1d1f;
    box-sizing: border-box;
    /* 스피너(위아래 화살표)는 두 자리 숫자 칸에서 자리만 차지하므로 제거 */
    -moz-appearance: textfield;
}

.f1ip-input::-webkit-outer-spin-button,
.f1ip-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* 원본과 달라진 셀 — 저장 전까지 유지되며, 되돌리면 자동으로 해제됩니다 */
.f1ip-input.f1ip-dirty {
    background: #fff3cd;
    font-weight: 800;
    color: #8a6d00;
}

/* 편집 모드를 빠져나가도 미저장 변경분은 계속 표시 */
.f1ip-table td.f1ip-dirty-cell {
    background: #fff3cd !important;
    font-weight: 800 !important;
    color: #8a6d00 !important;
}

/* 별쇄 계획표 — 뒤 칸(수정1·수정2)에 값이 생긴 이전 계획.
   지우지 않고 취소선으로 남깁니다. (규칙 계산은 render.js) */
.f1ip-table td.f1ip-plan-strike {
    /* 한 줄 회색 선은 눈에 잘 안 띄어 두 줄 붉은 선으로 긋습니다 —
       "이 값은 바뀌었다"가 확실히 보여야 합니다. */
    text-decoration: line-through double #d64545;
    color: #a0a0a8;
}

/* 별관(3공장) 참조 열(.f1ip-mirror-cell)은 별도 배경 없이 일반 셀과
   똑같이 보여 줍니다. 편집 모드에서 입력칸(연노랑 배경)이 생기지 않는
   것만으로 읽기 전용이라는 게 구분됩니다. */

/* 수정 구간 밖(±7일 초과) — 편집 모드에서만 잠긴 것으로 표시 */
.f1ip-wrapper.edit-mode .f1ip-row-locked td.f1ip-data-cell {
    background: #f2f2f5 !important;
    color: #b0b0b8 !important;
    cursor: not-allowed;
}

/* ================================================
   반응형
   ================================================ */
@media (max-width: 1100px) {
    /* 좌우 레이아웃과 두 패널을 모두 세로로 쌓고, 우측 패널에도 날짜 열을 표시 */
    .f1ip-top-grid { flex-direction: column; }
    .f1ip-main-card, .f1ip-side-column { flex: none; width: 100%; }

    /* 세로로 쌓이면 우측 열의 높이가 좌측에 매이지 않습니다. 그래서
       "남는 높이를 메모가 가져가는" 규칙 대신 예전처럼 높이를 못박습니다.
       (입고 현황은 여기서도 내용만큼 늘어납니다) */
    .f1ip-side-card { max-height: none; }
    .f1ip-memo-card { flex: none; height: var(--ipgo-memo-height); }

    .f1ip-panels-outer { flex-direction: column; }
    .f1ip-panel-ledger, .f1ip-panel-plan { flex: none; width: 100%; }
    .f1ip-responsive-date { display: table-cell !important; }

    .f1ip-scroll-area { overflow-x: auto; }
    .f1ip-table { table-layout: auto; min-width: 620px; }
    .f1ip-plan-table { min-width: 0; }

    /* 세로로 쌓일 때는 위에서부터 채우되 간격은 동일하게 유지 */
    .f1ip-side-list { justify-content: flex-start; gap: 12px; }
}

@media (max-width: 640px) {
    .f1ip-floor-container { padding: 14px; border-radius: 14px; }
    .panel-title { font-size: 16px; }

    .f1ip-date-th,
    .f1ip-date-td {
        min-width: 62px !important;
        width: 62px !important;
        font-size: 11px;
    }

    .f1ip-table td {
        font-size: 11.5px;
        height: 38px;
    }

    .f1ip-input {
        font-size: 11.5px;
    }

    .f1ip-thead-lv1 th,
    .f1ip-thead-lv2 th,
    .f1ip-group-th,
    .f1ip-leaf-th {
        font-size: 10px !important;
    }
}

/* ════════════════════════════════════════════════════════════════
   모바일(≤640px) 전용 표 — 두 패널을 합쳐 행/열을 뒤집은 판 (2026-08-12)
   ────────────────────────────────────────────────────────────────
   폰에서는 위의 두 패널(입고 대장 · 별쇄 계획표)을 감추고 이 표 하나만
   보여 줍니다. 두 패널은 픽셀 단위로 스크롤을 맞추는 구조라, 세로로
   쌓이면(두 표의 행 높이가 어긋나면) 같은 스크롤 값이 서로 다른 날짜를
   가리켜 — 칸을 누르는 순간 표가 엉뚱한 날짜 구간으로 굴러갔습니다.
   행=품목 · 열=날짜(오늘 -2 ~ +4, constant.js 의 MOBILE_*_DAYS)라
   스크롤 창 자체가 없습니다. 그리는 곳은 render.js 의 renderMobileTable. */
.f1ip-mobile-area { display: none; }

/* min-width: 0 — 위 1100px 분기의 .f1ip-table { min-width: 620px } 이
   이 표에도 걸리면 폰 화면(약 390px)을 넘어 가로 스크롤이 생깁니다.
   이 표는 열이 7개뿐이라 화면 폭 안에 다 들어갑니다. */
.f1ip-mobile-table { width: 100%; min-width: 0; table-layout: fixed; }

/* 행 머리(품목 이름) 열 — 폭 고정, 날짜 7열은 남은 폭을 균등 분할 */
.f1ip-mobile-table .f1ip-mrow-th {
    width: 86px;
    padding: 4px 6px;
    font-size: 10.5px;
    font-weight: 700;
    color: #3c3c43;
    text-align: center;
    background: #f7f8fa;
    border-bottom: 1px solid #ebebeb;
    border-right: 1px solid #e0e0e0;
    white-space: normal;      /* '대한제지 48.8g' 같은 긴 이름은 두 줄로 */
    line-height: 1.25;
    box-sizing: border-box;
    vertical-align: middle;
}

/* 날짜 머리글 — 눌러서 그 날짜 열을 고를 수 있습니다 */
.f1ip-mobile-table .f1ip-mdate-th { cursor: pointer; }

/* 같은 구역 안에서 거래처가 바뀌는 행 — 굵은 구분선 */
.f1ip-mobile-table tr.f1ip-mgroup-start th,
.f1ip-mobile-table tr.f1ip-mgroup-start td { border-top: 2px solid #e0e0e0; }

/* ── 구역 상자 (2026-08-12) ─────────────────────────────────────
   표를 공장 단위 네 구역(1공장 · F.T · 별관 · 별쇄)으로 나눠, 구역마다
   1px 얇은 테두리를 두르고 사이를 빈 줄로 띄웁니다. 행에 구역 표시
   (f1ip-msec-first/last)와 빈 줄(f1ip-msec-gap)을 붙이는 곳은
   render.js 의 renderMobileTable 입니다. */
.f1ip-mobile-table tr.f1ip-msec-gap td {
    height: 8px;
    padding: 0;
    border: none;
    background: transparent;
}

/* 상자 좌우 세로선 — 빈 줄을 뺀 모든 행의 양 끝 칸에 긋습니다 */
.f1ip-mobile-table tbody tr:not(.f1ip-msec-gap) th { border-left: 1px solid #d1d1d6; }
.f1ip-mobile-table tbody tr:not(.f1ip-msec-gap) td:last-child { border-right: 1px solid #d1d1d6; }

/* 상자 위·아래 가로선 — 구역의 첫 행과 마지막 행에 긋습니다 */
.f1ip-mobile-table tr.f1ip-msec-first th,
.f1ip-mobile-table tr.f1ip-msec-first td { border-top: 1px solid #d1d1d6; }
.f1ip-mobile-table tr.f1ip-msec-last th,
.f1ip-mobile-table tr.f1ip-msec-last td { border-bottom: 1px solid #d1d1d6; }

/* 머리글(구분 + 날짜) 줄도 같은 상자로 두릅니다 — 아래 구역들과 같은
   1px 선입니다. 몸통 첫 구역과는 빈 줄로 띄우므로(renderMobileTable 이
   맨 위에도 f1ip-msec-gap 을 넣습니다) 선이 겹쳐 굵어 보이지 않습니다. */
.f1ip-mobile-table thead th {
    border-top: 1px solid #d1d1d6;
    border-bottom: 1px solid #d1d1d6;
}
.f1ip-mobile-table thead th:first-child { border-left: 1px solid #d1d1d6; }
.f1ip-mobile-table thead th:last-child { border-right: 1px solid #d1d1d6; }

/* 오늘 열 — 패널 표의 오늘 행과 같은 파란 바탕 */
.f1ip-mobile-table td.f1ip-mcol-today,
.f1ip-mobile-table th.f1ip-mcol-today { background: #e8f4fd; }

/* 고른 날짜 열 — 패널 표의 선택 행 강조에 해당합니다.
   오늘 열을 골랐을 때도 반응이 보이도록 겹칠 때는 톤을 한 단계 누릅니다. */
.f1ip-mobile-table td.f1ip-mcol-active,
.f1ip-mobile-table th.f1ip-mcol-active { background: #ebebf0; }
.f1ip-mobile-table td.f1ip-mcol-today.f1ip-mcol-active,
.f1ip-mobile-table th.f1ip-mcol-today.f1ip-mcol-active { background: #daedf9; }

@media (max-width: 640px) {
    .f1ip-mobile-area { display: block; }

    /* 두 패널과, 그 패널을 펴는 [최근 1개월 보기]는 폰에서 감춥니다 */
    .f1ip-panels-outer { display: none; }
    .f1ip-main-card .mk-expand-btn { display: none; }

    /* [ERP 대조]도 폰에서는 뺍니다 — 팝업이 14열짜리 가로 표라 폰 폭에서는
       읽을 수 없습니다. 옆의 DB 갱신 시각(.erpct-backup)은 이미 같은 폭에서
       숨겨집니다(css/common/common_erp_contrast.css). 대조는 PC 에서 봅니다. */
    #f1ipErpBtn { display: none; }
}

/* ── 불러오는 중 ────────────────────────────────────────────────
   날짜를 옮기는 동안 표의 값만 옅게 덮습니다. 표를 지우지는 않습니다 —
   이 표는 값이 올 때까지 옛 행을 그대로 두고 한 번에 갈아 끼우므로
   깜빡임은 없었지만, 그 사이 헤더 날짜만 새것이고 숫자는 이전 날짜의
   것이라 조용히 틀린 화면이 됩니다.

   열 머리글은 같은 표 안에 있으므로 tbody 의 칸만 골라 덮습니다.
   opacity 가 아니라 color 인 이유는 재고실사 페이지와 같습니다 — 칸에
   걸린 테두리까지 옅어지면 표 선이 중간에서 끊긴 것처럼 보입니다.
   스크롤로 더 불러오는 구간(prev/next)에는 걸지 않습니다. */
.f1ip-scroll-area tbody td { transition: color 0.14s ease-out; }

.f1ip-wrapper.is-loading .f1ip-scroll-area tbody td,
.f1ip-panels-outer.is-loading .f1ip-scroll-area tbody td { color: #c7c7cc !important; }

/* ════════════════════════════════════════════════════════════════
   최근 1개월 보기 (2026-08-05 · 머리글 고정 2026-08-10)
   ────────────────────────────────────────────────────────────────
   버튼 모양은 공통(css/common/common_expand_btn.css 의 .mk-expand-btn)이고,
   여기서는 '무엇이 얼마나 펴지는지'만 정합니다 — 패널 안의 창을 풀어
   기준을 페이지 스크롤로 옮깁니다.
   (예전 '스크롤 ON/OFF' 스위치를 대신하는 부품입니다)

   머리글은 펼쳐도 붙박이(sticky)를 유지합니다 — 한 달치를 내리다 보면
   어느 열이 어느 항목인지 알 수 없게 되기 때문입니다(사용량 페이지와
   같은 수정, 2026-08-10). 그러려면 머리글과 화면 사이의 '자르는 조상'을
   전부 풀어야 합니다(붙박이는 가장 가까운 자르는 조상까지만 올라갑니다).
     · 스크롤 창 — 한 축이 hidden 이면 다른 축 visible 이 auto 로 승격돼
       창이 여전히 '스크롤 상자'로 남습니다. 그래서 양쪽 다 풉니다.
       .locked 의 hidden 이 !important 라 여기도 !important 가 필요합니다.
     · 패널 카드 — 둥근 모서리에 표를 맞춰 자르던 overflow: hidden.
       머리글 배경이 카드 배경과 같은 색이라 풀어도 티가 안 납니다.
   2026-08-05 에 붙박이를 뗐던 것("머리글이 떠 버립니다")은 이 조상들을
   안 풀어 붙박이가 조용히 죽어 있던 현상입니다. */
.f1ip-floor-container.is-expanded .f1ip-scroll-area,
.f1ip-floor-container.is-expanded .f1ip-scroll-area.locked {
    height: auto;
    overflow-x: visible;
    overflow-y: visible !important;
}

.f1ip-floor-container.is-expanded .f1ip-panel {
    overflow: visible;
}

/* 펼친 동안의 우측 열(입고 현황 + 메모) — 예상 사용량 페이지의 우측 결과
   카드와 같은 붙박이(sticky)로 바꿉니다 (2026-08-12).
   · 평소에는 좌우 카드가 같은 높이(stretch)라 문제가 없지만, 한 달치를
     펴면 좌측이 길어진 만큼 우측 열도 따라 늘어나 메모 카드가 한 달치
     높이로 부풀었습니다. align-self 로 stretch 를 풀고 높이를 평소
     값(--ipgo-side-column-height = 656px)에 못박아 그 늘어남을 막습니다.
   · 대신 sticky 로 스크롤을 따라 내려옵니다. top: 0 은 표 머리글(thead,
     top: 0 붙박이)과 같은 값 — 화면을 내리면 우측 카드 윗선이 붙어 있는
     머리글 윗선과 나란히 서서 같이 따라옵니다. 표 끝(.f1ip-top-grid 의
     바닥)에 닿으면 예상 사용량 페이지처럼 같이 밀려 올라갑니다.
   · 높이에 메모 기본값의 절반(0.5 × 183px)을 더 얹습니다 — 남는 높이는
     전부 메모 카드가 가져가므로, 펼친 동안 메모만 평소의 1.5배(약 274px)로
     길어집니다. 한 달치를 훑는 화면이라 메모도 그만큼 더 보여 줍니다. */
.f1ip-main-card.is-expanded + .f1ip-side-column {
    align-self: flex-start;
    height: calc(var(--ipgo-side-column-height) + var(--ipgo-memo-height) * 0.5);
    position: sticky;
    top: 0;
}

/* 펼친 동안의 [접기] 버튼 — 화면 아래 끝에 붙어 스크롤을 따라옵니다
   (2026-08-12). 펼치면 접기 버튼이 표 맨 아래에 있어, 접으려면 한 달치를
   끝까지 내려가야 했습니다. sticky bottom 이면 버튼이 화면 아래 끝단에
   떠서 따라다니다, 맨 아래에 닿으면 제자리(표 아래)에 내려앉습니다 —
   언제든 접을 수 있습니다. 버튼은 불투명 배경이라 표 위에 떠도 잘 읽힙니다.
   z-index 22 는 이 페이지 겹침 순서(날짜 헤더 21)의 바로 위 — 떠 있는 동안
   버튼이 표의 붙박이 날짜 열(12) 위로 지나가기 때문입니다. */
.f1ip-floor-container.is-expanded .mk-expand-btn {
    position: sticky;
    bottom: 12px;
    z-index: 22;
}

/* 폰(≤640px)에서는 공통 하단 독(common_header.css 의 .mkm-dock, z 1500)이
   화면 아래에 떠 있어 붙박이 버튼이 그 뒤에 가려집니다. 붙박이를 풀어
   예전대로 표 아래에 둡니다. */
@media (max-width: 640px) {
    .f1ip-floor-container.is-expanded .mk-expand-btn { position: static; }
}

/* 좁은 화면(위 1100px 구간)은 표가 가로로 굴러야 해서 이 방식이 통하지
   않습니다 — 가로 스크롤을 되살리면 창이 다시 스크롤 상자가 되어,
   머리글은 예전처럼 페이지와 함께 흘러갑니다. (재선언이 여기 있는 이유:
   1100px 규칙이 이 블록보다 앞에 있어 위 규칙이 이겨 버립니다) */
@media (max-width: 1100px) {
    .f1ip-floor-container.is-expanded .f1ip-scroll-area,
    .f1ip-floor-container.is-expanded .f1ip-scroll-area.locked {
        overflow-x: auto;
    }

    /* 좁은 화면에서는 카드가 세로로 쌓이므로 붙박이·높이 고정을 되돌립니다
       — 위 1100px 규칙(내용만큼 늘어나는 카드)이 그대로 살아야 합니다. */
    .f1ip-main-card.is-expanded + .f1ip-side-column {
        position: static;
        height: auto;
        align-self: auto;
    }
}
