
  /* =================================================================
     색상 / 여백 등 공통 값 정의
     ------------------------------------------------------------
     :root 안에 넣어두면 --변수이름 형태로 어디서든 재사용할 수 있어요.
     예를 들어 빨간색을 바꾸고 싶으면 --cr-red 값 하나만 고치면
     로고, 버튼, 테두리 등 이 색을 쓰는 모든 곳이 한 번에 바뀝니다.
     ================================================================= */
  :root{
    --cr-red: #c8102e;       /* 조선내화 브랜드 레드 (제목 바, 버튼 등) */
    --cr-red-dark: #9c0c22;  /* 위 빨간색보다 어두운 톤 (hover 시 사용) */
    --ink: #1c1c1c;          /* 기본 글자색 (거의 검정) */
    --table-head: #3a3a3a;   /* Other Properties 표 헤더용 - 순검정보다 살짝 밝은 흑색 */
    --line: #d8d8d8;         /* 테두리선 색 */
    --paper: #ffffff;        /* 카드/문서 배경색 (흰색) */
    --band: #f4f4f4;         /* 표의 옅은 회색 줄무늬 배경 */
    --spec: #fdecec;         /* 연한 빨간 배경 (hover, 강조용) */
    --muted: #6b6b6b;        /* 부가 설명 글자색 (회색) */
    --ok: #1c7c4c;           /* 성공/완료 상태를 나타내는 녹색 */
  }

  /* 모든 요소의 박스 크기 계산 방식을 통일합니다.
     (padding, border를 width/height 안쪽에 포함해서 계산 → 레이아웃이 안 깨짐) */
  *{
    box-sizing: border-box;
  }

  body{
    margin: 0;
    font-family: 'Pretendard','Segoe UI',Arial,sans-serif;
    background: #e9e9e9;   /* 페이지 전체의 회색 배경 (카드가 도드라져 보이게) */
    color: var(--ink);
  }

  /* 전체 컨텐츠를 가운데 정렬하고 최대 너비를 제한하는 바깥 컨테이너 */
  .app{
    max-width: 1100px;
    margin: 0 auto;
    padding: 28px 20px 60px;
  }

  /* ---------------- 상단 로고/타이틀 영역 ---------------- */
  .masthead{
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 18px;
    flex-wrap: wrap;
    gap: 10px;
  }

  /* 내비게이션 바 - TDS 조회 / 재질 비교 / 재질 추가 전환용 탭.
     실제 화면 전환은 JS가 .view-pane에 active 클래스를 붙였다 뗐다 하는
     것으로 처리하고(페이지 이동 없음), 여기 탭은 그 트리거일 뿐입니다. */
  .nav-bar{
    display: flex;
    gap: 6px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--line);
  }
  .nav-tab{
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 700;
    color: var(--muted);
    cursor: pointer;
    margin-bottom: -1px;   /* .nav-bar의 border-bottom과 탭의 활성 밑줄이 겹치도록 */
  }
  .nav-tab:hover{
    color: var(--ink);
  }
  .nav-tab.active{
    color: var(--cr-red);
    border-bottom-color: var(--cr-red);
  }

  /* 화면 전환 - active가 없는 view-pane은 아예 렌더링 안 함(display:none),
     그래서 다른 화면의 요소 id가 겹쳐도 서로 간섭하지 않습니다. */
  .view-pane{
    display: none;
  }
  .view-pane.active{
    display: block;
  }

  .brand{
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .brand .mark{
    width: 38px;
    height: 38px;
    border-radius: 50%;         /* 동그란 배지 모양 */
    background: var(--cr-red);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 16px;
    flex-shrink: 0;              /* 화면이 좁아져도 찌그러들지 않게 */
    cursor: pointer;             /* 클릭하면 처음 화면으로 (홈 버튼) */
    transition: transform .12s ease, box-shadow .12s ease;
  }
  .brand .mark:hover{
    box-shadow: 0 2px 8px rgba(200,16,46,.35);
    transform: translateY(-1px);
  }
  .brand .mark:active{
    transform: translateY(0);
  }
  .brand .name{
    font-weight: 700;
    font-size: 16px;
    letter-spacing: .2px;
  }
  .brand .name small{
    display: block;
    font-weight: 400;
    color: var(--muted);
    font-size: 12px;
  }

  /* ---------------- 엑셀 업로드 영역 (드래그앤드롭 박스) ---------------- */
  /* 우측 상단의 작은 CSV 업로드 아이콘 버튼 - 자동 로드가 기본이라
     평소엔 안 쓰이고, 가끔 다른 CSV를 대신 보고 싶을 때만 누르는 보조 기능 */
  /* 업로드 아이콘 버튼 - 자동 로드가 기본이라 평소엔 안 쓰이고, 가끔
     다른 CSV를 대신 보고 싶을 때만 누르는 보조 기능. 툴바(Product/검색/
     표시항목선택) 맨 우측에 같이 있고, fields-btn과 같은 방식으로
     세로 정렬을 라벨이 아니라 input 줄에 맞춥니다(align-self: flex-end). */
  .upload-icon-btn{
    width: 38px;
    height: 38px;
    border-radius: 8px;
    background: var(--band);
    border: 1px solid var(--line);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
    align-self: flex-end;
    margin-left: auto;   /* 툴바 안에서 맨 우측으로 밀어냄 */
  }
  .upload-icon-btn:hover{
    background: var(--spec);
    border-color: var(--cr-red);
  }
  /* 실제 <input type=file>은 못생겨서 숨기고, 위의 아이콘 버튼으로 대신 클릭시킵니다 */
  #fileInput{
    display: none;
  }

  /* data/data.csv 자동 로드가 실패했을 때만(파일 없음 등) 보이는 안내 배너 */
  /* 사용자 지정 CSV를 보고 있을 때만 나타나는 상시 뱃지 */
  .user-data-badge{
    background: var(--spec);
    border: 1px solid var(--cr-red);
    border-radius: 8px;
    padding: 10px 14px;
    margin-bottom: 18px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    font-size: 13px;
    color: var(--cr-red-dark);
    font-weight: 600;
  }
  .user-data-badge button{
    background: #fff;
    color: var(--cr-red-dark);
    border: 1px solid var(--cr-red);
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    flex-shrink: 0;
  }
  .user-data-badge button:hover{
    background: var(--cr-red);
    color: #fff;
  }

  .uploader-fallback{
    background: var(--paper);
    border: 1px dashed var(--line);
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 18px;
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
  }
  /* 이 배너 안에서는 부모의 align-items:center를 따라야 자연스러워서,
     툴바용으로 넣어둔 align-self/margin-left:auto를 여기서만 되돌립니다. */
  .uploader-fallback .upload-icon-btn{
    align-self: center;
    margin-left: 0;
  }
  .uploader-fallback .icon{
    width: 38px;
    height: 38px;
    border-radius: 8px;
    background: var(--band);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
    flex-shrink: 0;
  }
  .uploader-fallback .text{
    font-size: 14px;
    color: var(--muted);
    flex: 1;
    min-width: 180px;
    line-height: 1.6;
  }
  .uploader-fallback .text b{
    color: var(--ink);
  }

  /* ---------------- 재질 추가 화면 ---------------- */

  /* 특수 필드(formulation/product_name/카테고리 등) 입력 영역 */
  .am-special-fields{
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 16px;
  }
  .am-field{
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .am-field label{
    font-size: 12.5px;
    font-weight: 700;
    color: var(--muted);
  }
  .am-field.required label::after{
    content: " *";
    color: var(--cr-red);
  }
  .am-field input,
  .am-field select{
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 7px 10px;
    font-size: 13.5px;
    font-family: inherit;
  }
  .am-field input:focus,
  .am-field select:focus{
    outline: none;
    border-color: var(--cr-red);
  }
  /* formulation 입력값이 기존/이미 추가한 재질과 중복될 때 실시간으로 표시 */
  .am-field input.am-duplicate{
    border-color: var(--cr-red);
    background: var(--spec);
  }
  .am-field-hint{
    font-size: 11.5px;
    color: var(--cr-red-dark);
    display: none;
  }
  .am-field-hint.show{
    display: block;
  }

  /* General/Other Properties - "표시 항목 선택" 패널과 비슷한 톤의
     그룹 카드로 표시. 항목이 175개나 되니 접었다 펼 수 있게 합니다. */
  .am-group{
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 8px;
    margin-bottom: 10px;
    overflow: hidden;
  }
  .am-group-head{
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--band);
    border: none;
    padding: 10px 16px;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--ink);
    cursor: pointer;
    text-align: left;
  }
  .am-group-head .am-group-arrow{
    font-size: 11px;
    color: var(--muted);
    transition: transform .15s ease;
  }
  /* 그룹 제목 옆의 규격 코드(예: ISO 12677) - 모바일에서는 숨깁니다 */
  .am-group-std{
    font-weight: 400;
    color: var(--muted);
    font-size: 12px;
  }
  .am-group.collapsed .am-group-arrow{
    transform: rotate(-90deg);
  }
  .am-group-body{
    padding: 14px 16px;
  }
  .am-group.collapsed .am-group-body{
    display: none;
  }
  /* General Properties 그룹만 값 하나짜리라 그리드로, Other Properties
     그룹들은 항목별로 값/Min/Max 세 칸짜리 표라서 별도 레이아웃(.am-prop-row) 사용 */
  .am-general-grid{
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
  }
  .am-prop-row{
    display: grid;
    grid-template-columns: 140px 1fr 90px 90px 90px;
    align-items: center;
    gap: 8px;
    padding: 5px 0;
    border-bottom: 1px solid var(--line);
  }
  .am-prop-row:last-child{
    border-bottom: none;
  }
  .am-prop-row .am-prop-item-label{
    font-size: 12.5px;
    color: var(--muted);
  }
  .am-prop-row input[type="text"]{
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 5px 8px;
    font-size: 13px;
    font-family: inherit;
    width: 100%;
    text-align: center;
  }
  .am-prop-row input[type="text"]:focus{
    outline: none;
    border-color: var(--cr-red);
  }
  .am-prop-col-label{
    font-size: 10.5px;
    color: var(--muted);
    text-align: center;
  }
  /* water_cooling 항목처럼 modifier(이하 < 표시) 체크박스가 붙는 경우 */
  .am-prop-modifier{
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--muted);
    white-space: nowrap;
  }

  /* 화면 하단에 고정 - 175개 항목을 다 스크롤하지 않아도 항상 눌러서
     추가할 수 있습니다. app 컨테이너가 아니라 뷰포트 기준으로 고정. */
  .add-material-actions-sticky{
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 16px;
    padding: 14px 18px;
    background: #fff;
    border-top: 1px solid var(--line);
    border-radius: 8px 8px 0 0;
    box-shadow: 0 -4px 12px rgba(0,0,0,0.06);
    z-index: 15;
  }
  .add-material-cancel-edit-btn{
    background: #fff;
    border: 1px solid var(--line);
    color: var(--muted);
    padding: 10px 18px;
    border-radius: 6px;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
  }
  .add-material-cancel-edit-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red-dark);
  }
  .add-material-error{
    font-size: 13px;
    color: var(--cr-red-dark);
    font-weight: 600;
  }
  .add-material-add-btn{
    background: var(--cr-red);
    color: #fff;
    border: none;
    padding: 10px 22px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
  }
  .add-material-add-btn:hover{
    background: var(--ink);
  }

  .add-material-staged{
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 16px;
  }
  .add-material-staged-head{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
  }
  /* "보고서 미리보기"의 rp-title-toggle과 완전히 같은 패턴 - 통일감을 위해 */
  .am-staged-title-toggle{
    display: flex;
    align-items: center;
    gap: 6px;
    border: none;
    background: transparent;
    padding: 0;
    cursor: pointer;
    color: var(--ink);
    font-size: 14px;
    font-weight: 700;
  }
  .am-staged-title-toggle .count{
    color: var(--cr-red);
  }
  .am-toggle-arrow{
    display: inline-block;
    font-size: 11px;
    color: var(--muted);
    transition: transform .15s ease;
  }
  .am-staged-title-toggle.collapsed .am-toggle-arrow{
    transform: rotate(-90deg);
  }
  .am-staged-list{
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 4px;
  }
  .am-staged-list.am-staged-list-collapsed{
    display: none;
  }

  .am-staged-head-actions{
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
  }
  /* rp-include-all-btn과 완전히 같은 톤의 작은 보조 버튼 - "전체 조회",
     "전체 보고서에 추가" 등 이 화면의 일괄 작업 버튼에 전부 재사용합니다. */
  .am-head-action-btn{
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 5px;
    font-size: 12.5px;
    padding: 5px 10px;
    cursor: pointer;
    color: var(--muted);
    font-weight: 600;
  }
  .am-head-action-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red-dark);
  }
  .am-head-action-btn.am-danger-btn:hover{
    border-color: #8a1c1c;
    color: #8a1c1c;
  }

  .am-staged-row{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 8px 12px;
    font-size: 13px;
    flex-wrap: wrap;
  }
  .am-staged-row-info{
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
  }
  /* 보고서 포함 여부를 보여주는 작은 초록 점 - 재질명 바로 왼쪽에 둡니다.
     기본은 회색(미포함), 포함되면 초록색으로 채워집니다. */
  .am-staged-report-dot{
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--line);
    flex-shrink: 0;
  }
  .am-staged-report-dot.active{
    background: #2e9e4f;
  }
  .am-staged-row .am-staged-name{
    font-weight: 700;
    color: var(--ink);
  }
  .am-staged-row .am-staged-formulation{
    color: var(--muted);
    font-size: 12px;
  }
  .am-staged-row-actions{
    display: flex;
    gap: 6px;
    flex-shrink: 0;
  }
  /* 보고서 추가/수정/조회/제거 버튼 - 톤을 통일하기 위해 하나의 베이스
     스타일을 공유하고, 색만 필요한 곳(추가/제거)만 다르게 얹습니다. */
  .am-staged-add-report-btn,
  .am-staged-edit-btn,
  .am-staged-preview-btn,
  .am-staged-remove-btn{
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 4px 10px;
    font-size: 12px;
    color: var(--ink);
    cursor: pointer;
    white-space: nowrap;
  }
  .am-staged-edit-btn:hover,
  .am-staged-preview-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red-dark);
  }
  .am-staged-add-report-btn{
    border-color: #2e9e4f;
    color: #1f7a3a;
  }
  .am-staged-add-report-btn:hover{
    background: #eafaf0;
  }
  .am-staged-add-report-btn.added{
    background: #eafaf0;
    border-color: #2e9e4f;
    color: #1f7a3a;
  }
  .am-staged-remove-btn{
    color: var(--cr-red-dark);
  }
  .am-staged-remove-btn:hover{
    background: var(--spec);
  }
  /* 지금 수정 중인 행을 시각적으로 강조 */
  .am-staged-row.editing{
    border-color: var(--cr-red);
    background: var(--spec);
  }
  .add-material-download-btn{
    width: 100%;
    background: var(--ink);
    color: #fff;
    border: none;
    padding: 12px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    margin-top: 10px;
  }
  .add-material-download-btn:hover{
    background: var(--cr-red);
  }

  /* ---------------- 상단 툴바 (재질 선택 드롭다운 + 검색창 + 항목선택 버튼) ---------------- */
  .toolbar{
    display: none;   /* 엑셀을 업로드하기 전에는 숨김, 업로드되면 JS가 flex로 바꿔줌 */
    gap: 10px;
    align-items: flex-start;
    flex-wrap: wrap;
    margin-bottom: 12px;
    background: var(--paper);
    border: 1px solid var(--line);
    padding: 12px 14px;
    border-radius: 8px;
  }
  .tb-group{
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .tb-group label{
    font-size: 12.5px;
    color: var(--muted);
    font-weight: 600;
  }
  select{
    font-family: inherit;
    padding: 7px 10px;
    border: 1px solid var(--line);
    border-radius: 6px;
    font-size: 14px;
    background: #fff;
    min-width: 220px;
  }

  /* ---------------- 재질명 검색창 + 실시간 미리보기 드롭다운 ---------------- */
  .search-wrap{
    position: relative;   /* 아래 .search-preview를 이 요소 기준으로 절대배치하기 위함 */
  }
  #searchInput{
    font-family: inherit;
    padding: 7px 30px 7px 10px;
    border: 1px solid var(--line);
    border-radius: 6px;
    font-size: 14px;
    width: 240px;
  }
  #searchInput:focus{
    outline: none;
    border-color: var(--cr-red);
  }
  .search-icon{
    position: absolute;
    right: 9px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 14px;
    color: var(--muted);
    pointer-events: none;  /* 돋보기 아이콘 클릭이 뒤의 입력창으로 그대로 전달되게 */
  }
  /* 타이핑할 때마다 아래로 펼쳐지는 검색 결과 목록 */
  .search-preview{
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 4px;
    width: 360px;
    max-height: 340px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0,0,0,.12);
    z-index: 150;   /* .sheet-top(51)보다 훨씬 위로 - 검색창 아래 카드와 겹쳐도 클릭이 항상 드롭다운으로 가도록 */
    display: none;   /* JS가 검색어 있을 때 open 클래스를 붙여서 보여줌 */
  }
  .search-preview.open{
    display: block;
  }
  .search-item{
    padding: 8px 10px;
    cursor: pointer;
    border-bottom: 1px solid var(--band);
    font-size: 13.8px;
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .search-item:last-child{
    border-bottom: none;
  }
  .search-item:hover,
  .search-item.active{
    background: var(--spec);
  }
  .search-item .si-main{
    flex: 1;
    min-width: 0;
    cursor: pointer;
  }
  .search-item .sn{
    font-weight: 700;   /* 재질명(제품명) */
  }
  .search-item .si-formulation{
    font-weight: 400;
    font-size: 12px;
    color: var(--muted);
  }
  .search-item .st{
    color: var(--muted);
    font-size: 12.3px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;  /* 너무 길면 "..." 으로 잘라줌 */
    display: block;
  }
  .search-empty{
    padding: 14px;
    font-size: 13.5px;
    color: var(--muted);
    text-align: center;
  }
  /* 검색 결과 목록 맨 위에 붙는, "전체 추가/전체 해제" 일괄 처리 바 */
  .search-bulk-bar{
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    background: var(--band);
    border-bottom: 1px solid var(--line);
    font-size: 11.5px;
    color: var(--muted);
    font-weight: 600;
    position: sticky;
    top: 0;
    z-index: 1;
  }
  .search-bulk-actions{
    display: flex;
    gap: 10px;
  }
  .search-bulk-actions button{
    border: none;
    background: transparent;
    color: var(--cr-red);
    font-size: 11.5px;
    font-weight: 700;
    cursor: pointer;
    text-decoration: underline;
    padding: 0;
  }
  /* 검색어와 일치하는 부분을 노란색으로 하이라이트할 때 쓰는 <mark> 태그 스타일 */
  mark{
    background: #ffe08a;
    border-radius: 2px;
    padding: 0 1px;
  }
  /* "+ 보고서에 추가" / "✓ 보고서에 있음" 작은 버튼 */
  .add-chip-btn{
    flex-shrink: 0;
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 5px;
    font-size: 12px;
    padding: 4px 8px;
    cursor: pointer;
    color: var(--ink);
    font-weight: 600;
  }
  .add-chip-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  /* 이미 보고서에 담겨 있으면 초록색으로 표시 */
  .add-chip-btn.added{
    background: var(--ok);
    border-color: var(--ok);
    color: #fff;
  }

  /* ---------------- "표시 항목 선택" 버튼 & 패널 ---------------- */
  .fields-btn{
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 8px 14px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    align-self: flex-end;
  }
  .fields-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .fields-btn.active{
    background: var(--ink);
    color: #fff;
    border-color: var(--ink);
  }

  /* 체크박스들이 펼쳐지는 패널 (General/Other Properties 항목 선택) */
  .fields-panel{
    display: none;   /* fields-btn 클릭 시 JS가 open 클래스 토글 */
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 16px 18px;
    margin-bottom: 20px;
  }
  /* 표시 항목 선택 패널 하단의 적용/확인 버튼 - fieldsPanel과 별개 요소라
     패널 내용이 다시 그려져도(buildFieldsPanelInto) 안 사라집니다. */
  .fields-panel-footer{
    display: none;   /* fieldsBtn 클릭 시 JS가 fieldsPanel과 함께 보임/숨김 전환 */
    align-items: center;
    gap: 10px;
    margin-top: -12px;
    margin-bottom: 20px;
    padding: 12px 18px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-top: none;
    border-radius: 0 0 8px 8px;
  }
  /* X(닫기) 버튼은 왼쪽에, 적용/확인은 오른쪽에 - 이 spacer가 가운데
     남는 공간을 다 차지해서 둘을 양 끝으로 밀어냅니다. */
  .fields-footer-spacer{
    flex: 1;
  }
  .fields-close-btn{
    border: none;
    background: transparent;
    color: var(--muted);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
  }
  .fields-close-btn:hover{
    background: var(--band-soft, #ececec);
    color: var(--ink);
  }
  .fields-apply-btn,
  .fields-confirm-btn{
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 6px;
    padding: 8px 18px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
  }
  .fields-confirm-btn{
    background: var(--cr-red);
    border-color: var(--cr-red);
    color: #fff;
  }
  .fields-apply-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .fields-confirm-btn:hover{
    background: var(--cr-red-dark);
    border-color: var(--cr-red-dark);
  }
  .fields-panel.open{
    display: block;
  }
  .fp-quick{
    display: flex;
    gap: 6px;
  }
  .fp-quick button{
    font-size: 12px;
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 5px;
    padding: 3px 9px;
    cursor: pointer;
    color: var(--muted);
  }
  .fp-quick button:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .fp-section{
    margin-bottom: 16px;
  }
  .fp-section:last-child{
    margin-bottom: 0;
  }
  .fp-section-title{
    font-size: 13px;
    font-weight: 700;
    color: var(--cr-red-dark);
    text-transform: uppercase;
    letter-spacing: .3px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--line);
    padding-bottom: 5px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .fp-chips{
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  /* 체크박스 + 라벨을 알약(pill) 모양으로 감싼 항목 하나 */
  .fp-chk{
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 4px 9px 4px 7px;
    font-size: 13px;
    cursor: pointer;
    user-select: none;   /* 클릭할 때 글자가 드래그 선택되는 것 방지 */
    background: #fafafa;
  }
  .fp-chk input{
    margin: 0;
    accent-color: var(--cr-red);  /* 체크박스 자체의 색상을 브랜드색으로 */
    cursor: pointer;
  }
  .fp-chk.checked{
    background: #fff;
    border-color: #c9c9c9;
  }
  .fp-group{
    margin-bottom: 10px;
  }
  .fp-group-head{
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.3px;
    font-weight: 700;
    margin-bottom: 6px;
    cursor: pointer;
  }
  .fp-group-head input{
    accent-color: var(--cr-red);
  }
  .fp-group-unit{
    font-weight: 400;
    color: var(--muted);
    font-size: 12px;
  }
  .fp-group-items{
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding-left: 20px;
  }

  /* =================================================================
     보고서(report) 관련 UI
     - 사용자가 "보고서에 추가"한 재질들의 목록/설정을 담는 패널입니다.
     ================================================================= */
  .report-panel{
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 14px 16px;
    margin-bottom: 20px;
    display: none;   /* 보고서에 담긴 재질이 1개 이상일 때만 JS가 보여줌 */
  }
  .report-panel.has-items{
    display: block;
  }
  .report-panel-head{
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
  }
  .report-panel-head .rp-title{
    font-size: 14px;
    font-weight: 700;
  }
  /* rp-title이 이제 버튼(접기/펼치기)이기도 해서 기본 버튼 스타일을 지웁니다 */
  .rp-title-toggle{
    display: flex;
    align-items: center;
    gap: 6px;
    border: none;
    background: transparent;
    padding: 0;
    cursor: pointer;
    color: var(--ink);
  }
  .rp-toggle-arrow{
    display: inline-block;
    font-size: 11px;
    color: var(--muted);
    transition: transform .15s ease;
  }
  .rp-title-toggle.collapsed .rp-toggle-arrow{
    transform: rotate(-90deg);   /* 접혔을 때 화살표가 옆을 향하게 */
  }
  .report-panel-head .rp-title .count{
    color: var(--cr-red);
  }
  .rp-list{
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
  }
  /* 접힌 상태 - 재질이 많아서 스크롤이 길어질 때 목록 전체를 숨깁니다.
     기본값은 펼침(이 클래스가 안 붙어있는 상태)입니다. */
  .rp-list.rp-list-collapsed{
    display: none;
  }

  /* 카테고리별 그룹화 켜기/끄기 체크박스 + 그룹 순서 조절 칩 */
  .rp-group-controls{
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 10px;
  }
  .rp-group-toggle{
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    user-select: none;
  }
  .rp-group-toggle input{
    accent-color: var(--cr-red);
    cursor: pointer;
  }
  .group-order-wrap{
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .group-order-chip{
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 4px 6px 4px 12px;
    font-size: 12px;
    font-weight: 700;
    color: var(--ink);
  }
  .group-order-chip button{
    border: none;
    background: var(--band);
    color: var(--muted);
    width: 20px;
    height: 20px;
    border-radius: 50%;
    font-size: 10px;
    cursor: pointer;
    line-height: 1;
  }
  .group-order-chip button:hover:not(:disabled){
    background: var(--cr-red);
    color: #fff;
  }
  .group-order-chip button:disabled{
    opacity: .3;
    cursor: not-allowed;
  }

  /* 보고서 목록 안에서 카테고리 구분선 (그룹화 켜져있을 때만 나타남) */
  .rp-group-header{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 11.5px;
    font-weight: 800;
    color: var(--cr-red);
    text-transform: uppercase;
    letter-spacing: .4px;
    padding: 10px 2px 2px;
    border-top: 1px dashed var(--line);
    margin-top: 4px;
  }
  .rp-group-header:first-child{
    border-top: none;
    margin-top: 0;
    padding-top: 0;
  }

  /* 보고서 목록에 있는 재질 한 줄 (이름 + 항목선택 버튼 + 제거 버튼) */
  .rp-row{
    display: flex;
    align-items: center;
    flex-wrap: wrap;   /* 요소가 많아져서 좁은 화면에 다 안 들어가면 줄바꿈되게 (숨거나 안 보이는 대신) */
    gap: 8px;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 7px 10px;
    background: #fafafa;
    transition: opacity .15s ease, border-color .15s ease;
  }
  /* "이번엔 제외" 체크를 끈 재질 - 목록엔 남아있지만 이번 출력에서는
     안 나간다는 걸 흐릿하게 표시해서 알 수 있게 합니다. */
  .rp-row.rp-excluded{
    opacity: .45;
  }
  .rp-include-label{
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    cursor: pointer;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 3px 9px 3px 7px;
  }
  .rp-include-label:hover{
    border-color: var(--cr-red);
  }
  .rp-include-text{
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    white-space: nowrap;
  }
  .rp-include-check{
    accent-color: var(--cr-red);
    cursor: pointer;
    width: 15px;
    height: 15px;
  }
  .rp-row.dragging{
    /* 흐려지는 대신, 살짝 진하게(테두리+배경) 강조해서 "이게 선택돼서
       움직이는 중"이라는 게 더 명확하게 보이도록 합니다. */
    background: var(--spec);
    border-color: var(--cr-red);
    box-shadow: 0 4px 12px rgba(0,0,0,.15);
    transform: scale(1.01);
    z-index: 5;
    position: relative;
  }
  .rp-row.drag-over{
    border-color: var(--cr-red);
    border-width: 2px;
    padding: 6px 9px;   /* 테두리 두꺼워진 만큼 안쪽 padding 살짝 줄여서 크기 안 튀게 */
  }
  .rp-drag-handle{
    cursor: grab;
    color: var(--muted);
    font-size: 15px;
    line-height: 1;
    padding: 0 2px;
    flex-shrink: 0;
    user-select: none;
    touch-action: none;   /* 터치 화면에서 드래그할 때 스크롤 제스처와 충돌하지 않도록 */
  }
  .rp-drag-handle:active{
    cursor: grabbing;
  }
  .rp-num{
    color: var(--cr-red);
    font-weight: 800;
    font-size: 12.5px;
    flex-shrink: 0;
  }
  .rp-row .rp-name{
    font-weight: 700;
    font-size: 13.8px;
    flex: 1;
  }
  .rp-row .rp-type{
    color: var(--muted);
    font-size: 12.5px;
    margin-right: 6px;
  }
  /* 이 재질에 "값 수정"이 하나라도 적용돼 있을 때 뜨는 작은 배지 */
  .rp-row .rp-edited-badge{
    background: var(--cr-red);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    border-radius: 999px;
    padding: 2px 7px;
    margin-right: 6px;
    flex-shrink: 0;
  }
  .rp-row button{
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 5px;
    font-size: 12px;
    padding: 4px 9px;
    cursor: pointer;
  }
  .rp-row button:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .rp-row button.rp-remove:hover{
    background: #fdecec;
    border-color: #e0a0a0;
    color: #8a1c1c;
  }

  /* 문서번호 / 설비명 / Revision 등을 입력하는 설정 영역 */
  .rp-docsettings{
    border-top: 1px solid var(--line);
    padding-top: 12px;
    margin-bottom: 12px;
  }
  .rp-docsettings-inputs{
    display: grid;
    /* 화면 너비에 맞춰 카드 개수가 자동으로 줄어드는 반응형 그리드 */
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px;
  }
  .rp-field{
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .rp-field label{
    font-size: 12px;
    color: var(--muted);
    font-weight: 600;
  }
  .rp-field input[type=text]{
    font-family: inherit;
    padding: 7px 9px;
    border: 1px solid var(--line);
    border-radius: 6px;
    font-size: 13.5px;
  }
  /* 입력칸 3개(문서번호/설비명/Revision) 바로 아래에, 체크박스 4개를
     하나의 묶음으로 따로 모아둡니다 - 입력칸이랑 안 섞이고 항상 그 아래에
     나란히 보이도록. */
  .rp-docsettings-checks{
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--line);
  }
  .checkrow{
    display: flex;
    align-items: center;
    gap: 7px;
    cursor: pointer;
  }
  .checkrow input{
    accent-color: var(--cr-red);
    width: 15px;
    height: 15px;
    cursor: pointer;
  }
  .checkrow span{
    font-size: 13.5px;
    color: var(--ink);
    font-weight: 600;
  }

  .rp-actions{
    display: flex;
    justify-content: flex-start;   /* PDF 내보내기 + 미리보기를 왼쪽 하단에 나란히 */
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
  }
  .pdf-btn{
    background: var(--cr-red);
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
  }
  .pdf-btn:hover{
    background: var(--cr-red-dark);
  }
  .pdf-btn:disabled{
    background: #c9a4a9;
    cursor: not-allowed;
  }
  .preview-btn{
    background: #fff;
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
  }
  .preview-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .pdf-status{
    font-size: 13px;
    color: var(--muted);
  }
  .clear-report-btn{
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 5px;
    font-size: 12.5px;
    padding: 5px 10px;
    cursor: pointer;
    color: var(--muted);
  }
  .clear-report-btn:hover{
    border-color: #8a1c1c;
    color: #8a1c1c;
  }
  .rp-head-actions{
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .rp-include-all-btn{
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 5px;
    font-size: 12.5px;
    padding: 5px 10px;
    cursor: pointer;
    color: var(--muted);
  }
  .rp-include-all-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  /* 카테고리 그룹 헤더 안에, 그 그룹만 전체 포함/제외 하는 작은 버튼 */
  .rp-group-header-actions{
    display: flex;
    gap: 4px;
    flex-shrink: 0;
  }
  .rp-group-header-actions button{
    border: none;
    background: transparent;
    color: var(--cr-red);
    font-size: 10.5px;
    font-weight: 700;
    cursor: pointer;
    padding: 2px 4px;
    text-decoration: underline;
  }

  /* "선택한 재질 미리보기" 영역 맨 위의 작은 타이틀 + 개수 배지 */
  .report-preview-head{
    font-size: 15px;
    font-weight: 800;
    color: var(--ink);
    margin: 8px 0 12px;
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .report-preview-head .badge{
    background: var(--cr-red);
    color: #fff;
    font-size: 12.5px;
    font-weight: 700;
    border-radius: 999px;
    padding: 2px 10px;
  }

  /* =================================================================
     재질별 "항목 선택"을 위한 팝업창(모달)
     ================================================================= */
  .modal-backdrop{
    display: none;   /* 열려있을 때만 JS가 open 클래스를 붙여서 보여줌 */
    position: fixed;
    inset: 0;                        /* top/right/bottom/left를 전부 0으로 = 화면 전체 덮기 */
    background: rgba(0,0,0,.45);     /* 어두운 반투명 배경 */
    z-index: 200;
    align-items: center;
    justify-content: center;
    padding: 20px;
  }
  .modal-backdrop.open{
    display: flex;
  }
  .modal-box{
    background: #fff;
    border-radius: 10px;
    max-width: 640px;
    width: 100%;
    max-height: 85vh;
    overflow-y: auto;
    overscroll-behavior: contain;   /* 스크롤이 끝(맨 위/아래)에 닿아도 배경 페이지로 스크롤이 안 새어나가게 함 */
    padding: 0;   /* 패딩은 modal-head/modal-body가 나눠 가집니다 - 그래야 sticky 헤더가
                     스크롤 영역의 진짜 맨 위 끝까지 닿아서, 스크롤할 때 그 틈으로
                     뒤 내용이 비쳐 보이는 문제가 없습니다. */
    box-shadow: 0 20px 50px rgba(0,0,0,.25);
  }
  .modal-body{
    padding: 0 22px 4px;   /* 아래쪽 여백은 이제 sticky 푸터가 자기 몫으로 가지므로 살짝만 */
  }
  /* 버튼(완료/적용)을 모달 맨 아래에 고정해서, 내용이 길어도 끝까지 스크롤
     안 해도 항상 보이게 합니다 (위쪽 modal-head를 sticky로 고정한 것과 동일한 방식). */
  .modal-footer-sticky{
    position: sticky;
    bottom: 0;
    background: #fff;
    padding: 10px 22px 20px;
    border-top: 1px solid var(--line);
    z-index: 20;
  }
  .modal-footer-sticky .modal-done{
    margin-top: 0;
  }
  .modal-head{
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 14px;   /* 텍스트가 줄바꿈돼도 ✕ 버튼과 최소 간격은 유지 */
    border-bottom: 1px solid var(--line);
    /* modal-box 자체엔 패딩이 없고(모달-body가 대신 가짐), 이 헤더가
       스크롤 영역의 진짜 맨 위/좌우 끝에 직접 붙어있기 때문에, 스크롤해도
       그 틈으로 뒤 내용이 비쳐 보이는 문제가 생기지 않습니다. */
    position: sticky;
    top: 0;
    margin-bottom: 14px;
    padding: 20px 22px 10px;
    background: #fff;
    border-radius: 10px 10px 0 0;   /* modal-box 위쪽 둥근 모서리와 어긋나지 않도록 */
    z-index: 20;
  }
  /* 제목+부제목을 감싸는 div - flex:1과 min-width:0이 없으면, 부제목이
     길어서 줄바꿈될 때 flex 아이템이 안 줄어들고 자기 원래 너비를
     고집해서 옆에 있는 ✕ 닫기 버튼과 겹쳐 보이는 문제가 생깁니다
     (좁은 모달일수록 잘 드러남). */
  .modal-head > div:not(.modal-head-actions){
    flex: 1;
    min-width: 0;
  }
  .modal-head h3{
    margin: 0;
    font-size: 16px;
  }
  .modal-head .modal-sub{
    font-size: 12.5px;
    color: var(--muted);
    margin-top: 2px;
  }
  /* 미리보기 모달 헤더 우측: PDF 내보내기 버튼 + 닫기 버튼을 나란히 */
  .modal-head-actions{
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
  }
  .preview-pdf-btn{
    background: var(--cr-red);
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
  }
  .preview-pdf-btn:hover{
    background: var(--cr-red-dark);
  }
  .preview-apply-btn{
    background: #fff;
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
  }
  .preview-apply-btn:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .modal-close{
    border: none;
    background: var(--band);
    border-radius: 6px;
    width: 30px;
    height: 30px;
    font-size: 16px;
    cursor: pointer;
    color: var(--muted);
  }
  .modal-close:hover{
    background: var(--spec);
    color: var(--cr-red-dark);
  }
  .modal-done{
    margin-top: 14px;
    width: 100%;
    padding: 10px;
    background: var(--ink);
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
  }
  .modal-done:hover{
    background: var(--cr-red);
  }

  /* 표시 항목 선택 모달보다 넓게 써야 하는 모달(값 수정, 미리보기)용 */
  .modal-box-wide{
    max-width: 900px;
  }
  /* 업로드 확인처럼 짧은 메시지 + 버튼 두 개만 있는 작은 모달용 */
  .modal-box-small{
    max-width: 420px;
  }
  /* 미리보기 모달은 실제 TDS 문서를 통째로 봐야 해서 훨씬 크게 씁니다 */
  .modal-box-preview{
    max-width: 1200px;
    width: 96vw;
    max-height: 94vh;
  }

  /* =================================================================
     "값 수정" 팝업창 - 이번 보고서 출력에만 일회성으로 반영되는 값 입력
     ================================================================= */
  .edit-fields{
    display: flex;
    flex-direction: column;
    gap: 18px;
  }
  .edit-fields-section-title{
    font-size: 13px;
    font-weight: 800;
    color: var(--cr-red);
    text-transform: uppercase;
    letter-spacing: .3px;
    margin-bottom: 8px;
  }
  .edit-fields-grid{
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 10px 14px;
  }
  .edit-field{
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .edit-field label{
    font-size: 11.5px;
    color: var(--muted);
    font-weight: 600;
  }
  .edit-field input{
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 7px 9px;
    font-size: 13px;
    color: var(--ink);
  }
  .edit-field input.edit-changed{
    border-color: var(--cr-red);
    background: var(--spec);
  }

  /* Other Properties용 Value/Min/Max 묶음 블록 - 한 줄에 깔끔하게 나란히 배치 */
  .edit-field-prop{
    grid-column: span 2;   /* 3칸짜리 입력이 들어가니 General 필드 블록보다 넓게 */
    min-width: 280px;
  }
  .edit-prop-inputs{
    display: flex;
    gap: 6px;
  }
  .epi-group{
    display: flex;
    flex-direction: column;
    gap: 3px;
  }
  .epi-group:first-child{
    flex: 2;   /* Value 칸을 Min/Max보다 넓게 */
  }
  .epi-group:not(:first-child){
    flex: 1;
  }
  .epi-tag{
    font-size: 10px;
    color: var(--muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .3px;
  }
  .epi-group input{
    width: 100%;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 12.5px;
    color: var(--ink);
  }
  .epi-group input.edit-changed{
    border-color: var(--cr-red);
    background: var(--spec);
  }
  .edit-field-label-row{
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
  }
  .edit-field-remove{
    border: none;
    background: none;
    color: var(--muted);
    font-size: 12px;
    cursor: pointer;
    padding: 0 2px;
    flex-shrink: 0;
  }
  .edit-field-remove:hover{
    color: #8a1c1c;
  }

  /* "+ 필드 추가" / "+ 항목 추가" 미니 입력 폼 (DB에 없는 항목을 직접 추가) */
  .edit-add-row{
    display: flex;
    gap: 8px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--line);
    flex-wrap: wrap;
  }
  .edit-add-row input{
    flex: 1;
    min-width: 110px;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 7px 9px;
    font-size: 13px;
  }
  .edit-add-row-prop input{
    flex: 1 1 120px;
  }
  .edit-add-row button{
    flex: 0 0 auto;
    padding: 7px 14px;
    background: #fff;
    color: var(--cr-red);
    border: 1px solid var(--cr-red);
    border-radius: 6px;
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
  }
  .edit-add-row button:hover{
    background: var(--cr-red);
    color: #fff;
  }
  .edit-modal-footer{
    display: flex;
    gap: 10px;
    margin-top: 0;   /* modal-footer-sticky가 이미 자기 패딩으로 여백을 주므로 중복 방지 */
  }
  /* 값 수정 모달처럼 넓은 모달에선 "초기화"(작게)+"적용"(꽉 채움)이
     자연스럽지만, 업로드 확인처럼 좁은 모달(.modal-box-small)에서는
     그렇게 꽉 채우면 버튼이 과하게 커 보여서, 우측 하단에 내용 크기만큼만
     차지하는 버튼 두 개를 나란히 배치합니다(흔한 확인창 스타일). */
  .modal-box-small .modal-head{
    margin-bottom: 7px;
  }

  .modal-box-small .edit-modal-footer{
    justify-content: flex-end;
    padding-bottom: 14px;
  }
  .modal-box-small .edit-modal-footer .edit-reset-btn{
    flex: 0 0 auto;
    padding: 10px 23px;
  }
  .modal-box-small .edit-modal-footer .modal-done{
    flex: 0 0 auto;
    width: auto;
    padding: 10px 24px;
    /* 기본은 사이트 테마의 빨간색, 호버 시에만 검정으로 - 다른 모달의
       "적용" 버튼(검정 고정)과는 다르게 이 확인창만 강조색을 씁니다. */
    background: var(--cr-red);
  }
  .modal-box-small .edit-modal-footer .modal-done:hover{
    background: var(--ink);
  }
  .edit-reset-btn{
    flex: 0 0 auto;
    padding: 10px 16px;
    background: #fff;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 6px;
    font-size: 13.5px;
    font-weight: 700;
    cursor: pointer;
  }
  .edit-reset-btn:hover{
    border-color: #8a1c1c;
    color: #8a1c1c;
  }
  .edit-modal-footer .modal-done{
    flex: 1;
    margin-top: 0;
  }
  .edit-apply-note{
    margin-top: 14px;
    padding: 10px 12px;
    background: #eaf6ee;
    border: 1px solid #b8e0c4;
    color: var(--ok);
    font-size: 12.5px;
    border-radius: 6px;
    line-height: 1.5;
  }

  /* =================================================================
     "보고서 미리보기" 팝업창
     ================================================================= */
  .preview-content{
    background: var(--band-soft, #ececec);
    max-height: 82vh;   /* 모달이 커진 만큼(.modal-box-preview) 미리보기 영역도 같이 키움 */
    overflow-y: auto;
    overscroll-behavior: contain;   /* 스크롤이 끝에 닿아도 배경 페이지로 스크롤이 안 새어나가게 함 */
  }
  /* 재질 이름 칩 바 - 스크롤해도 계속 위에 붙어있어서 언제든 다른 재질로 바로 이동 가능 */
  .preview-nav{
    position: sticky;
    top: 0;
    z-index: 100;   /* 시트 안의 요소(제목바 등)보다 확실히 위로 - 스크롤해도 내용이 안 비쳐 보이게 */
    background: #f5f5f5;
    border-bottom: 1px solid var(--line);
    padding: 10px 20px;
    box-shadow: 0 2px 6px rgba(0,0,0,.08);   /* 겹치는 경계가 또렷하게 보이도록 */
    display: flex;
    align-items: flex-start;
    gap: 12px;
  }
  .preview-nav-chips{
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    flex: 1;
    min-width: 0;
  }
  /* 기본은 접힌 상태 - 재질이 많아지면 칩이 여러 줄로 늘어나서 아래 보고서
     내용을 가리는 문제가 있었습니다. 접혔을 땐 한 줄 높이(약 34px)만큼만
     보여주고 나머지는 잘라둡니다 - "목록 펼치기" 버튼을 눌러야 다 보입니다. */
  .preview-nav-collapsed .preview-nav-chips{
    max-height: 34px;
    overflow: hidden;
  }
  /* 펼치기/접기 버튼을 칩들과 같은 줄, 맨 오른쪽에 고정합니다 - 줄바꿈되거나
     아래로 밀려나지 않게 flex-shrink:0 + white-space:nowrap을 둡니다. */
  .preview-nav-toggle{
    flex-shrink: 0;
    white-space: nowrap;
    border: none;
    background: transparent;
    color: var(--cr-red);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    padding: 6px 0;

  }
  .preview-nav-chip{
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid var(--line);
    background: #fff;
    border-radius: 999px;
    padding: 5px 12px;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    white-space: nowrap;
  }
  .preview-nav-chip:hover{
    border-color: var(--cr-red);
    color: var(--cr-red);
  }
  .preview-edited-dot{
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--cr-red);
    display: inline-block;
  }
  .preview-sheets{
    padding: 20px;
  }
  .preview-sheet-anchor{
    scroll-margin-top: 60px;   /* sticky nav에 안 가려지게 스크롤 위치 보정 */
  }

  /* =================================================================
     TDS 문서(재질 한 장) 카드 스타일
     - 실제 인쇄물처럼 보이도록 원본 PDF 디자인을 최대한 흉내냈습니다.
     - 화면 미리보기와 PDF 캡처(html2canvas) 모두 이 스타일을 그대로 씁니다.
     ================================================================= */
  .sheet{
    position: relative;   /* 안쪽의 워터마크(.watermark)를 이 카드 기준으로 배치하기 위함 */
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 2px;
    box-shadow: 0 1px 3px rgba(0,0,0,.06);
    overflow: hidden;      /* 워터마크 글자가 카드 밖으로 삐져나가지 않게 잘라줌 */
    margin-bottom: 22px;
  }
  /* 항상 떠있는 메인 브라우징 화면(.sheet-page가 안 붙는, 문서표 없는 카드)
     전용 - Other Properties 표가 끝나자마자 카드 테두리가 바로 나오면
     너무 딱 붙어 보여서, 카드 안쪽에 흰 여백을 살짝 추가합니다. PDF/미리보기
     (.sheet-page)는 여기 영향 안 받습니다 - 거긴 문서표 위치를 별도로 관리합니다. */
  .sheet:not(.sheet-page){
    padding-bottom: 10px;
  }

  /* PDF/미리보기 전용(!interactive일 때만 붙는 클래스) - 내용 높이만큼만
     페이지를 쓰고(generatePdf에서 페이지 크기를 내용에 맞춰 계산), 문서번호
     표/저작권 문구는 내용 바로 아래 작은 고정 간격만 두고 따라옵니다.
     flex-shrink:0을 모든 자식에 걸어두는 게 핵심입니다 - 이게 없으면 flex
     컨테이너가 자식들을 찌그러뜨려서 제목/표가 겹쳐 보이는 문제가 생깁니다. */
  .sheet-page{
    display: flex;
    flex-direction: column;
    /* PDF 캡처(pdfStage)가 항상 748px(=A4 내용 폭) 고정으로 렌더링하는데,
       미리보기는 이 폭 지정이 없어서 모달 폭(최대 1200px)에 맞춰 훨씬
       넓게 늘어나 있었습니다 - 그러면 글자 크기는 고정(px)인데 카드만
       넓어지니, 줄바꿈이 실제 PDF와 다르게 일어나고 압축 단계 판단도
       달라져서 미리보기와 PDF가 서로 다르게 보였습니다. 폭을 똑같이
       고정해서 미리보기가 실제 PDF와 항상 동일하게 보이도록 맞춥니다. */
    width: 748px;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
  }
  .sheet-page > *{
    flex-shrink: 0;
  }
  /* 표(General/Other Properties, 또는 목차 표)를 담는 영역만 예외적으로
     줄어들 수 있고(flex-shrink:1) 넘치는 부분을 잘라냅니다(overflow:hidden).
     그래서 항목이 너무 많아져서 페이지를 넘칠 때, "표만" 잘리고 문서표·
     카피라이트는 항상 온전하게 보입니다(둘 다 flex-shrink:0 그대로라 절대
     안 줄어들고, 잘리지도 않습니다). min-height:0은 flex item이 원래
     "내용물 크기 밑으로는 못 줄어드는" 기본 동작을 풀어주는 필수 설정입니다. */
  .sheet-page > .content-area{
    flex-shrink: 1;
    min-height: 0;
    overflow: hidden;
  }
  .sheet-page .doc-footer-wrap{
    margin-top: auto;   /* 문서표/카피라이트를 항상 컨테이너 맨 아래에 고정 (표가 짧으면 그 사이 간격이 벌어짐) */
  }

  /* 문서표를 안 보이게 설정했을 때(사용자가 체크박스로 끔) - 페이지는 여전히
     A4 한 장 비율만큼 최소 높이를 확보하고(JS의 fitSheetPageToOnePage 참고),
     그 남는 공간을 Other Properties 표가 늘어나서 채우도록 합니다 - 화면이
     허전해 보이지 않게 하기 위함입니다.
     ★ table.props 자체의 margin-bottom은 0으로 고정돼있어서(문서표가 있을
     땐 그 사이 간격을 .doc-footer-wrap의 margin-top이 전담하므로 문제 없음),
     문서표가 없을 때는 표가 카드 맨 아래까지 닿아버려 여백이 하나도 없이
     딱 붙어 보였습니다. 재질/목차 페이지 둘 다, 문서표를 꺼놨을 때는
     카드 자체(.sheet-page)에 하단 여백을 20px 고정으로 둡니다. */
  .no-footer-page{
    padding-bottom: 20px;
  }

  /* 표 셀 여백/글자 크기는 항상 고정값입니다 - 재질(또는 목차 항목) 개수에
     따라 계산해서 바뀌는 로직은 전부 없앴습니다. "Technical Data Sheet"
     표시줄, 제목바, 섹션 제목, 표, 문서표, 카피라이트 문구까지 모든 요소가
     몇 개를 선택했든 항상 똑같은 위치·크기를 유지합니다. 항목이 너무
     많아져서 페이지 한 장(A4)을 넘치면, 페이지 크기나 글자 크기를 바꾸는
     대신 그냥 넘치는 부분을 잘라냅니다 - .sheet의 overflow:hidden이
     이 역할을 합니다. */

  /* 카드 전체에 옅게 깔리는 회사 워터마크 이미지(assets/watermark.png를
     base64로 구운 것). background-image 대신 실제 <img> + opacity 조합을
     쓰는 이유: html2canvas로 PDF 캡처할 때 CSS background-image의 알파
     채널이 제대로 안 살아나서 훨씬 진하고 뭉개지게 나오는 문제가 있는데,
     <img> + opacity는 캡처 결과가 화면에서 보는 것과 동일하게 나옵니다. */
  .watermark{
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;   /* 워터마크가 마우스 클릭을 가로채지 않도록 */
    overflow: hidden;
    z-index: 50;   /* 표의 셀 배경색 밑에 깔리지 않고, 표 위로 겹쳐 보이도록 확실히 앞으로 */
  }
  .watermark img{
    width: 42%;
    height: auto;
    opacity: .55;
  }

  /* 카드 맨 위 줄: "Technical Data Sheet" 라벨 + (선택시) Revision/날짜 */
  .sheet-top{
    position: relative;
    z-index: 51;   /* 워터마크(z-index 50)보다 위에 오도록 */
    display: flex;
    justify-content: space-between;
    align-items: flex-end;   /* center → flex-end: 공간(패딩)은 그대로 두고, 글자만 바닥에 붙여서 덜 휑해 보이게 */
    padding: 6px 22px;   /* 14px → 6px, 별 내용도 없는데 공간을 너무 많이 차지해서 위아래로 줄임 */
    border-bottom: 2px solid var(--ink);
    font-size: 14px;
    font-weight: 700;
    gap: 10px;
    flex-wrap: wrap;
    min-height: 20px;
  }
  .sheet-top .st-left{
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .sheet-top .st-rev{
    font-weight: 400;
    color: var(--muted);
    font-size: 13px;
  }

  /* 빨간 배경의 제목 바 (제품명 + 제품 종류) */
  .titlebar{
    position: relative;
    z-index: 1;
    background: var(--cr-red);
    color: #fff;
    padding: 10px 22px;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 17px;
    flex-wrap: wrap;
    gap: 4px;
  }
  .titlebar .idx{
    font-weight: 800;
  }
  /* 목차 제목("INDEX") - 미리보기에서만 contenteditable로 바뀝니다.
     .idx의 흰 글씨/굵기는 그대로 물려받고, 편집 가능하다는 티만 살짝 냅니다. */
  .toc-title-input{
    display: inline-block;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: text;
    outline: none;
    border-bottom: 1px dashed rgba(255,255,255,.5);
  }
  .toc-title-input:focus{
    border-bottom-style: solid;
  }
  /* product_name 옆에 작게 붙는 formulation(고유 ID) 표시. 웹 화면에만 뜨고
     보고서(PDF)에는 안 나갑니다 - renderSheet에서 interactive일 때만 렌더링. */
  .titlebar .formulation-tag{
    font-weight: 400;
    font-size: 12.5px;
    opacity: .8;
    margin-left: 6px;
  }
  .titlebar .kind{
    font-weight: 600;
    font-size: 14px;
    opacity: .95;
  }

  /* major_category / minor_category 작게 표시 (필터링용, 웹 화면 전용 -
     보고서에는 안 나갑니다). 나중에 필터 기능을 붙일 걸 대비해 배지 형태로. */
  .category-tags{
    position: relative;
    z-index: 1;
    margin: 8px 22px 0;
    font-size: 12px;
    color: var(--muted);
    letter-spacing: .2px;
  }

  /* "General Properties" / "Other Properties" 섹션 제목 */
  .section-label{
    position: relative;
    z-index: 1;
    text-align: left;
    margin: 8px 22px 5px;   /* 14px 8px → 8px 5px: 압축 없이도 세로 공간을 더 확보하기 위해 기본값 자체를 줄임 */
  }
  .section-label span{
    display: inline-block;
    font-size: 18px;          /* 16px → 18px */
    font-weight: 800;
    letter-spacing: .4px;
    color: var(--ink);
    padding-bottom: 7px;
    border-bottom: 3px solid var(--cr-red);   /* 밑줄로 한 번 더 강조 */
  }

  /* 보고서 첫 페이지 목차 - 업로드해주신 참고 이미지 스타일(CATEGORY/NO/
     Product Name/Product Type/Remark 5열, CATEGORY는 같은 값이 연속되면
     병합)대로 구성합니다.
     ★ <table rowspan>도, CSS Grid(span 있는 버전/없는 버전 둘 다)도
     html2canvas에서 레이아웃이 깨졌습니다. 이 앱의 다른 모든 페이지
     (General/Other Properties)는 전부 순수 <table>이고 PDF에서 멀쩡했으므로,
     목차도 CSS Grid를 버리고 똑같은 순수 <table>(스팬 전혀 없음)로
     만듭니다. "병합"처럼 보이는 효과는 셀 사이 테두리만 지워서 냅니다. */
  table.toc-table{
    position: relative;
    z-index: 1;
    width: calc(100% - 44px);
    margin: 0 22px 0;   /* 30px → 0, 문서표까지 간격은 이제 .doc-footer-wrap의 margin-top이 전담 */
    border-collapse: collapse;
    font-size: 13.5px;
  }
  table.toc-table th,
  table.toc-table td{
    border: 1px solid var(--line);
    padding: 9px 10px;   /* 보기 좋은 고정값 - 재질 개수와 무관하게 항상 이 값 그대로 */
    text-align: center;
    vertical-align: middle;
    overflow-wrap: break-word;
    word-break: break-word;
  }
  table.toc-table thead th{
    background: var(--table-head);
    color: #fff;
    font-weight: 700;
    font-size: 13px;
  }
  table.toc-table .toc-td-category{ width: 15%; }
  table.toc-table .toc-td-no{ width: 8%; }
  table.toc-table .toc-td-name{ width: 20%; }
  table.toc-table .toc-td-type{ width: 37%; }
  table.toc-table .toc-td-remark{ width: 20%; }
  /* 카테고리 표시를 끄면 Category 열 자체를 안 그리는데(HTML에서 th/td를
     아예 뺌), 그만큼 나머지 열들이 원래 비율(8:20:37:20)을 유지한 채
     폭을 나눠 갖도록 다시 계산한 값입니다(15%를 뺀 85%를 기준으로 재분배). */
  table.toc-table.no-category-col .toc-td-no{ width: 9%; }
  table.toc-table.no-category-col .toc-td-name{ width: 24%; }
  table.toc-table.no-category-col .toc-td-type{ width: 44%; }
  table.toc-table.no-category-col .toc-td-remark{ width: 23%; }
  table.toc-table td.toc-category-merged{
    font-weight: 700;
    background: var(--band);
  }
  /* 병합된 그룹 텍스트를 담는 span - 평소엔 그냥 보통 흐름대로 표시되고,
     JS(centerMergedCategoryText)가 그룹이 2줄 이상일 때만 position:absolute로
     정확한 세로 중앙 위치를 계산해서 넣어줍니다. */
  .toc-category-text-inner{
    display: block;
    text-align: center;
  }
  /* border-collapse:collapse에서는 인접한 두 셀의 테두리가 충돌하면 "더
     진하게 그려지는 쪽"(실선)이 이겨버려서, border-bottom:none 하나만으론
     아래쪽 셀의 기본 border-top(실선)에 밀려 경계선이 계속 보였습니다.
     border-collapse 충돌 해석에서 항상 이기는 값인 hidden을 쓰고, 위/아래
     양쪽 다 지워야 확실하게 안 보입니다. */
  table.toc-table td.toc-no-bottom-border{
    border-bottom-style: hidden;
  }
  table.toc-table td.toc-no-top-border{
    border-top-style: hidden;
  }
  table.toc-table td.toc-zebra{
    background: var(--band);
  }
  /* Remark를 직접 입력한 줄은 살짝 색을 넣어서 "채워져 있다"는 걸 표시 */
  table.toc-table td.toc-remark-filled{
    background: var(--spec);
  }
  /* Remark 칸 - 사용자가 직접 타이핑해서 채우는 입력창 (테두리 없이 표 칸처럼 보이게) */
  .toc-remark-input{
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    background: transparent;
    font-size: 13.5px;
    font-family: inherit;
    letter-spacing: normal;
    color: var(--ink);
    text-align: center;
    padding: 0;
    margin: 0;
    line-height: 1.4;
    cursor: text;
    white-space: pre-wrap;   /* 아래 .toc-remark-text와 동일한 줄바꿈 방식 */
    overflow-wrap: break-word;
    word-break: break-word;
  }
  .toc-remark-input:focus{
    outline: 1px solid var(--cr-red);
    outline-offset: 2px;
    border-radius: 3px;
  }
  /* Category/NO/Product Name/Product Type 칸도 Remark와 똑같이 직접 고쳐
     쓸 수 있게 만든 공용 입력 스타일 (폰트굵기 등은 각 열의 기존 클래스가
     이어서 그대로 적용됨 - 예: toc-category-merged의 font-weight:700). */
  .toc-editable-input{
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    background: transparent;
    font: inherit;
    color: inherit;
    text-align: center;
    padding: 0;
    margin: 0;
    line-height: 1.4;
    cursor: text;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    word-break: break-word;
  }
  .toc-editable-input:focus{
    outline: 1px solid var(--cr-red);
    outline-offset: 2px;
    border-radius: 3px;
  }
  .toc-remark-text{
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    font-size: 13.5px;
    font-family: inherit;
    letter-spacing: normal;
    color: var(--ink);
    text-align: center;
    margin: 0;
    line-height: 1.4;
    white-space: pre-wrap;   /* textarea와 동일한 줄바꿈 방식 - 웹/PDF 줄바꿈 지점이 어긋나지 않도록 */
    overflow-wrap: break-word;
    word-break: break-word;
  }

  /* General Properties 표 (제품명, 원료, 성상 등 2열 표) */
  table.gp{
    position: relative;
    z-index: 1;
    width: calc(100% - 44px);
    margin: 0 22px 15px;   /* 아래쪽 15px - Other Properties 제목과 간격을 더 띄움 (마진 겹침 규칙상 .section-label의 margin-top 8px보다 커야 실제로 적용됨) */
    border-collapse: collapse;
    font-size: 14px;
  }
  table.gp td{
    padding: 5px 10px;   /* 보기 좋은 고정값 - 재질 개수와 무관하게 항상 이 값 그대로 */
    border-bottom: 1px solid var(--line);
    vertical-align: middle;   /* 우측 값 칸이 위쪽으로 붙지 않고 세로 가운데 정렬되도록 */
  }
  /* 메인 브라우징 화면(.sheet-page가 안 붙는 카드)은 A4 크기 제약이 없어서
     PDF처럼 빡빡하게 짤 필요는 없지만, 8px는 과했다는 피드백에 따라 살짝만 줍니다. */
  .sheet:not(.sheet-page) table.gp td{
    padding: 4px 12px;
  }
  .sheet:not(.sheet-page) table.props th,
  .sheet:not(.sheet-page) table.props td{
    padding: 3px 10px;
  }
  table.gp td.key{
    width: 220px;   /* Other Properties 표의 Product Properties 열(220px)과 폭을 맞췄습니다 */
    color: #333;
    font-weight: 600;
    background: var(--band);
  }
  table.gp td.pname{
    font-size: 16px;
    font-weight: 800;
  }

  /* Other Properties 표 (물성값들이 들어가는 4열 표) */
  table.props{
    position: relative;
    z-index: 1;
    width: calc(100% - 44px);
    margin-left: 22px;
    margin-right: 22px;
    margin-bottom: 10px;   /* 0 → 10px, 문서표와의 최소 간격 확보 */
    border-collapse: collapse;
    font-size: 13.8px;
    /* ★ table-layout:fixed 없이는 각 <th>에 %/px로 너비를 지정해도
       브라우저가 셀 내용 길이를 같이 고려해서 실제 렌더링 너비를 정하기
       때문에, 재질마다 값의 자릿수가 다르면 같은 CSS인데도 컬럼 너비가
       페이지마다 미묘하게 달라 보이는 문제가 있었습니다. fixed로 못박아서
       내용과 무관하게 항상 지정한 비율 그대로 나오게 합니다. */
    table-layout: fixed;
  }
  table.props th,
  table.props td{
    border: 1px solid var(--line);
    padding: 4px 10px;   /* 기본값 4px - Other Properties 데이터 셀은 JS가 항목 수에 맞춰 이 값을 늘리거나 줄임 (헤더는 항상 이 값 그대로 고정) */
    text-align: center;   /* 기본은 가운데 정렬 (Exp.Cond, Value, Unit 칸이 여기 해당) */
  }
  table.props thead th{
    background: var(--table-head);   /* 순검정 대신 살짝 밝은 흑색 - 보고서 톤과 부드럽게 어울리도록 */
    color: #fff;
    font-weight: 700;
    font-size: 13px;
  }
  /* Product Properties 헤더(첫 칸) 너비를 General Properties 표의 왼쪽
     라벨 열(table.gp td.key, 220px)과 동일하게 맞춥니다. */
  table.props th.propname-col{
    width: 220px;
  }
  /* 항목 이름(예: Chemical Analysis)이 들어가는 첫 칸만 왼쪽 정렬 */
  table.props td.propname{
    text-align: left;
    background: var(--band);
    font-weight: 600;
    max-width: 220px;
  }
  /* 항목명 밑에 붙는 규격 코드(예: ISO 12677) - 모바일에서는 공간이
     부족해서 숨깁니다(아래 @media 참고). */
  table.props td.propname .propname-std{
    font-weight: 400;
    color: #888;
    font-size: 11px;
  }
  /* Unit(단위) 칸: 항목 이름과 같은 배경이지만 가운데 정렬 */
  table.props td.unitcell{
    text-align: center;
    background: var(--band);
    font-weight: 600;
    color: #333;
  }
  table.props td.exp{
    color: var(--muted);
    white-space: nowrap;
  }
  table.props td.val{
    font-weight: 700;
  }
  /* Spec(Min/Max) 칸: 값 옆에 규격 하한/상한을 보여줍니다.
     min-max 사이는 시각적으로 "한 쌍"처럼 보이도록 경계선을 없앱니다.
     헤더(Min/Max)는 Spec과 같은 흰색(thead th 기본값 상속), 값도 흐리게
     죽이지 않고 일반 글자색 그대로 또렷하게 보이도록 합니다. */
  table.props th.spec-min,
  table.props th.spec-max{
    font-size: 12.5px;
  }
  table.props td.spec-min,
  table.props td.spec-max{
    font-size: 12.5px;
    color: var(--ink);
  }
  table.props td.spec-min{
    border-right: none;
  }
  table.props td.spec-max{
    border-left: none;
  }
  table.props th.spec-min{
    border-right: none;
  }
  table.props th.spec-max{
    border-left: none;
  }

  /* =================================================================
     문서 하단 정보 표 (문서번호 / 페이지 / TDS / 회사로고)
     ================================================================= */
  .doc-footer-wrap{
    position: relative;
    z-index: 1;
    margin-left: 22px;
    margin-right: 22px;
    /* margin-top은 여기서 아예 선언하지 않습니다 - .sheet-page .doc-footer-wrap이
       전담해서 정합니다. (margin shorthand로 0을 넣으면 그것도 하나의 선언이라
       나중에 캐스케이드 우선순위 계산에서 혼선을 줄 수 있어서, 아예 안 쓰는 쪽이 안전합니다.) */
  }
  table.doc-footer{
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;      /* 12px → 14px, 문서표 전체 글자 크기 통일 */
    letter-spacing: 1px;  /* 폰트 크기에 비해 칸이 커 보여서 자간을 넓힘 */
    table-layout: fixed;   /* 칸 너비를 아래 %값대로 고정 (내용 길이에 흔들리지 않게) */
  }
  table.doc-footer td{
    border: 1px solid var(--line);
    padding: 5px 8px;      /* 7px 10px → 5px 8px, 표를 좀 더 작게 */
    vertical-align: middle;
  }
  table.doc-footer td.df-docnum{     /* 1행 1열: 문서번호 - 셀을 꽉 채우도록 정렬 */
    font-weight: 700;
    width: 34%;
    vertical-align: middle;
    white-space: nowrap;   /* JS가 자간을 계산해서 셀 너비에 맞춰 늘려줍니다 */
    overflow: hidden;
  }
  /* 글자가 칸 너비에 비해 너무 짧으면(한글 몇 글자, 짧은 코드 등) 자간을
     억지로 늘리지 않고 그냥 가운데 정렬합니다 (justifyCellText가 판단) */
  table.doc-footer td.df-docnum.df-cell-centered,
  table.doc-footer td.df-plant.df-cell-centered{
    text-align: center;
  }
  table.doc-footer td.df-pagenum{    /* 1행 2열: "현재페이지/전체페이지" */
    font-weight: 700;
    text-align: center;
    width: 14%;
  }
  table.doc-footer td.df-tds{        /* 1행 3열: 고정 텍스트 "TDS" */
    font-weight: 700;
    text-align: center;
    width: 14%;
  }
  table.doc-footer td.df-plant{      /* 2행 1열: 설비명 - 셀을 꽉 채우도록 정렬 */
    font-weight: 700;
    vertical-align: middle;
    white-space: nowrap;   /* JS가 자간을 계산해서 셀 너비에 맞춰 늘려줍니다 */
    overflow: hidden;
  }
  table.doc-footer td.df-pagelabel{  /* 2행 2열: 고정 텍스트 "Page" */
    text-align: center;
    color: var(--muted);
    font-weight: 600;
  }
  table.doc-footer td.df-catlabel{   /* 2행 3열: 고정 텍스트 "Category" */
    text-align: center;
    color: var(--muted);
    font-weight: 600;
  }
  table.doc-footer td.df-logo{       /* 4열: 1~2행 병합, 회사 로고 이미지 */
    width: 20%;
    text-align: center;
    padding: 6px 12px;
  }
  table.doc-footer td.df-logo img{
    max-width: 100%;
    height: auto;
    display: block;
    margin: 0 auto;
  }

  /* 저작권 안내 문구 (아주 작고 흐린 회색 글씨, 2줄) */
  .copyright-note{
    position: relative;
    z-index: 1;
    margin: 6px 22px 12px;   /* 8px 18px → 6px 12px, 여백 살짝 줄임 */
    font-size: 9px;
    line-height: 1.4;
    color: #9a9a9a;
    text-align: left;
  }

  /* ---------------- 빈 화면 / 오류 화면 ---------------- */
  .empty-state{
    text-align: center;
    padding: 70px 20px;
    color: var(--muted);
    font-size: 14.5px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
  }
  .error-state{
    text-align: center;
    padding: 24px 20px;
    color: #8a1c1c;
    background: var(--spec);
    border: 1px solid #eab8b8;
    border-radius: 8px;
    font-size: 14px;
    margin-bottom: 20px;
  }

  /* PDF를 만들 때만 잠깐 쓰는 "숨겨진 작업 공간".
     화면 밖(왼쪽으로 아주 멀리)에 위치시켜서 사용자 눈에는 안 보이지만,
     html2canvas가 캡처할 수 있도록 실제로 DOM에는 존재하게 합니다. */
  #pdfStage{
    position: fixed;
    left: -99999px;
    top: 0;
    background: #ffffff;
  }

  /* ---------------- 좁은 화면(모바일)용 스타일 조정 ----------------
     데스크톱 스타일(위쪽 전부)은 절대 안 건드리고, 여기서 필요한 것만
     덮어씁니다. 앞으로 새 화면/컴포넌트를 만들 때도 이 블록에 맞춰
     모바일 대응을 같이 넣는 걸 기본으로 합니다. */
  @media (max-width: 640px){
    /* ===== 공통: 좌우 여백을 화면 전체적으로 살짝 줄임 ===== */
    .app{ padding: 14px 12px; }
    .masthead .name{ font-size: 15px; }
    .masthead .name small{ font-size: 11px; }

    /* ===== 내비게이션 바 ===== */
    .nav-tab{ padding: 9px 10px; font-size: 13px; }

    /* ===== 상단 툴바 (Product/검색/표시항목선택/업로드) ===== */
    .toolbar{ padding: 10px 10px; gap: 8px; }
    .upload-icon-btn{ margin-left: 0; }   /* 좁은 화면에서 flex-wrap될 때 오른쪽 끝에 억지로 안 붙게 */

    /* ===== TDS 조회: 재질 카드(General/Other Properties 표) =====
       표 자체 폭/글자는 최대한 줄이되, 그래도 다 못 담으면(항목명이나
       숫자가 유독 긴 경우) 잘려서 안 보이는 대신 가로 스크롤이 되도록
       안전장치를 겁니다. */
    table.gp td.key,
    table.props th.propname-col{ width: 92px; font-size: 11.5px; padding-left: 8px; padding-right: 8px; }
    .titlebar{ font-size: 14px; padding: 10px 14px; }
    .titlebar .no{ font-size: 12px; }
    .sheet-top{ padding: 10px 14px; font-size: 12px; }
    .content-area{ padding-left: 0; padding-right: 0; overflow-x: auto; }
    table.gp,
    table.props{
      margin-left: 12px;
      margin-right: 12px;
      width: calc(100% - 24px);
      font-size: 11.5px;
    }
    table.props th,
    table.props td{ padding: 4px 5px; }
    /* 위의 desktop 전용 규칙(.sheet:not(.sheet-page) table.props td)이
       선택자 우선순위가 더 높아서 방금 규칙을 덮어쓰기 때문에, 웹
       브라우징 화면(interactive)의 모바일 패딩은 여기서 따로 맞춥니다.
       세로 여백을 살짝 더 줘서 줄마다 너무 다닥다닥 붙지 않게 합니다. */
    .sheet:not(.sheet-page) table.props th,
    .sheet:not(.sheet-page) table.props td{ padding: 5px 5px; }
    table.props th.spec-min, table.props th.spec-max,
    table.props td.spec-min, table.props td.spec-max{ font-size: 10.5px; }
    /* ISO 규격 코드는 좁은 화면에서 공간 낭비가 커서 숨깁니다 (항목명은 그대로 유지) */
    table.props td.propname .propname-std{ display: none; }
    /* 그래도 한 줄에 다 안 들어가는 극단적인 경우를 위한 안전장치 -
       내용이 잘려서 안 보이는 대신 옆으로 스크롤해서 볼 수 있게 합니다.
       (padding 조정은 위 .content-area 규칙에서 같이 처리) */

    #searchInput{ width: 100%; }
    select{ min-width: 0; width: 100%; }
    .search-preview{ width: 100%; }
    .doc-footer-wrap{ margin-left: 12px; margin-right: 12px; }
    .copyright-note{ margin-left: 12px; margin-right: 12px; }

    /* ===== 목차(TOC) 표 ===== */
    table.toc-table{ font-size: 11.5px; }
    table.toc-table th, table.toc-table td{ padding: 4px 4px; }

    /* ===== 보고서 패널 (재질 목록/버튼들) ===== */
    .report-panel-head{ flex-wrap: wrap; gap: 8px; }
    .rp-head-actions{ flex-wrap: wrap; }
    .rp-docsettings-inputs{ grid-template-columns: 1fr; }

    /* ===== 재질 추가 화면 ===== */
    .am-special-fields,
    .am-general-grid{ grid-template-columns: 1fr; }   /* 한 줄에 하나씩, 라벨/입력칸이 안 눌리게 */
    /* Value가 잘 안 보일 정도로 Min/Max가 넓었던 문제 - 라벨/Min/Max를
       확 줄이고 Value(1fr)에 남는 공간을 몰아줍니다. */
    .am-prop-row{
      grid-template-columns: 66px 1fr 40px 40px;
      gap: 4px;
      font-size: 11px;
    }
    .am-prop-row .am-prop-item-label{ font-size: 10.5px; line-height: 1.3; }
    .am-prop-row input[type="text"]{ padding: 4px 3px; font-size: 11.5px; }
    .am-prop-col-label{ font-size: 9px; }
    .am-prop-modifier{ font-size: 9.5px; grid-column: 1 / -1; }   /* 체크박스 라벨이 길어서 다음 줄로 내려서 전체 폭 사용 */
    /* 그룹 제목의 규격 코드(예: ISO 12677)도 여기서는 숨깁니다 */
    .am-group-std{ display: none; }
    .am-group-head{ font-size: 12.5px; }
    .am-staged-row{ flex-direction: column; align-items: flex-start; }
    .am-staged-row-actions{ width: 100%; justify-content: flex-end; flex-wrap: wrap; }
    .add-material-staged-head{ flex-direction: column; align-items: flex-start; }
    .am-staged-head-actions{ width: 100%; }
    .am-staged-head-actions .am-head-action-btn{ flex: 1; text-align: center; }
    /* 하단 고정 액션바 - 버튼 문구가 잘리지 않게 폭을 넉넉히 확보 */
    .add-material-actions-sticky{ padding: 12px 14px; gap: 8px; }
    .add-material-add-btn{ padding: 10px 16px; font-size: 13px; }

    /* ===== 모달 ===== */
    .modal-box{ max-width: calc(100% - 20px); }
    .edit-fields-grid{ grid-template-columns: 1fr; }
  }

  /* 맨 위로 스크롤 버튼 - 화면 우측 하단에 떠있음 */
  .scroll-top-btn{
    position: fixed;
    right: 24px;
    bottom: 24px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: none;
    background: var(--cr-red);
    color: #fff;
    font-size: 20px;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 3px 10px rgba(0,0,0,.25);
    z-index: 300;
  }
  .scroll-top-btn:hover{
    background: var(--cr-red-dark);
  }

  /* 재질 추가 화면의 하단 고정 액션바와 겹치지 않도록 더 위로 띄웁니다
     (모바일 전용 - 다른 화면엔 그 고정바가 없어서 여기서 높게 띄워도
     문제 없습니다). base .scroll-top-btn 규칙보다 반드시 뒤에 와야
     같은 우선순위에서 이 값으로 덮어씁니다. */
  @media (max-width: 640px){
    .scroll-top-btn{ bottom: 110px; right: 16px; width: 40px; height: 40px; font-size: 17px; }
  }
