/* ===================================================================
   app.css — 시안에 없던 화면을 위한 추가 스타일.
   퍼블리싱 산출물(reset.css / style.css / header.css)은 손대지 않고,
   글쓰기 모달·입점문의 폼·알림 같은 신규 UI만 여기에 둔다.
   색·라운드·그림자는 style.css의 톤(딥그린 #163d2c)을 그대로 따른다.
   =================================================================== */

:root {
  --nf-green: #163d2c;
  --nf-green-soft: #eaf2ed;
  --nf-line: #e3e8e5;
  --nf-text: #2a3b31;
  --nf-muted: #7a8896;
  --nf-danger: #c0392b;
}

/* ===== 모달 ===== */
.nf-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(20, 32, 26, 0.45);
}
.nf-modal-overlay.is-open {
  display: flex;
}

.nf-modal {
  width: 100%;
  max-width: 520px;
  max-height: 88vh;
  overflow-y: auto;
  padding: 24px;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.18);
}

.nf-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}
.nf-modal__title {
  font-size: 17px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-modal__desc {
  margin-bottom: 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--nf-muted);
}
.nf-modal__close {
  flex: none;
  width: 28px;
  height: 28px;
  font-size: 16px;
  color: var(--nf-muted);
  background: none;
  border: 0;
  cursor: pointer;
}

/* ===== 폼 ===== */
.nf-field {
  margin-bottom: 14px;
}
.nf-field-row {
  display: flex;
  gap: 12px;
}
.nf-field-row .nf-field {
  flex: 1;
  min-width: 0;
}

.nf-label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-text);
}

.nf-input,
.nf-select,
.nf-textarea {
  width: 100%;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 14px;
  color: var(--nf-text);
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 8px;
  outline: none;
}
.nf-input:focus,
.nf-select:focus,
.nf-textarea:focus {
  border-color: var(--nf-green);
}
.nf-textarea {
  min-height: 120px;
  line-height: 1.6;
  resize: vertical;
}

/*
 * 입력칸 아래 안내문.
 *
 * 한 줄로 끝나지 않는 문장이 많은데, 줄간격이 기본값(약 1.2)이면 두 줄이 서로 붙어
 * 읽기 어렵다. 게다가 한글은 어절 중간에서도 줄이 넘어가 글자가 흩어져 보인다.
 * 줄간격을 벌리고 어절 단위로만 넘기면 폭이 좁은 칸에서도 가지런히 놓인다.
 */
.nf-hint {
  margin-top: 6px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--nf-muted);
  word-break: keep-all;
  overflow-wrap: break-word;
}
.nf-hint--error {
  color: var(--nf-danger);
  font-weight: 600;
}

/* 입력칸 + 버튼을 한 줄에 두는 배치(이메일 인증번호 발송·확인). */
/* 입력칸 옆 버튼은 입력칸과 높이가 같아야 한 줄로 읽힌다.
   가운데 맞춤이면 padding 차이만큼(1~2px) 윗변이 어긋나 삐뚤어 보인다. */
.nf-inline {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.nf-inline .nf-input {
  flex: 1;
  min-width: 0;
}
.nf-inline .nf-btn,
/* 관리자 콘솔 안에서도 같은 배치를 쓴다(회원 수정의 '자동 생성' 버튼). */
.nf-inline .admin-btn {
  flex: none;
  white-space: nowrap;
}

/* 회원 유형. 내 정보 화면에서 지금 어떤 자격으로 쓰고 있는지 한 줄로 보여준다. */
.nf-membertype {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 16px;
  margin-bottom: 10px;
  background: #f4f8f5;
  border: 1px solid #cfe3d6;
  border-radius: 10px;
}
.nf-membertype__badge {
  flex: none;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 800;
  color: #fff;
  background: var(--nf-green);
  border-radius: 999px;
}
.nf-membertype__can {
  flex: 1;
  min-width: 200px;
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--nf-text);
}

/* 인증이 끝나면 버튼 자리에 결과를 남긴다. 버튼이 그대로 있으면 또 눌러도 되는 줄 안다. */
.nf-verified {
  flex: none;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--nf-green);
  background: #eef7f1;
  border: 1px solid #cfe3d6;
  border-radius: 8px;
  white-space: nowrap;
}

/* ===== 버튼 ===== */
.nf-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

.nf-btn {
  padding: 10px 18px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
}
/* 링크로 쓰는 버튼(알림 설정 등). a는 인라인이라 그냥 두면 위아래 여백이 어긋난다. */
a.nf-btn {
  display: inline-flex;
  align-items: center;
}

.nf-btn--primary {
  color: #fff;
  background: var(--nf-green);
}
.nf-btn--primary:disabled {
  background: #9db3a7;
  cursor: not-allowed;
}
.nf-btn--outline {
  color: var(--nf-text);
  background: #fff;
  border-color: var(--nf-line);
}
.nf-btn--danger {
  color: #fff;
  background: var(--nf-danger);
}
.nf-btn--danger:disabled {
  background: #d9b3ae;
  cursor: not-allowed;
}

/* ===== 알림 ===== */
.nf-alert {
  margin-bottom: 14px;
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.5;
  border-radius: 8px;
}
.nf-alert--error {
  color: #8c2b20;
  background: #fdecea;
}
.nf-alert--ok {
  color: var(--nf-green);
  background: var(--nf-green-soft);
}

/* ===== 단일 폼 페이지 (입점문의 / 로그인 실패 안내 등) ===== */
.nf-page {
  max-width: 640px;
  margin: 0 auto;
  padding: 32px 16px 64px;
}
.nf-page__title {
  margin-bottom: 8px;
  font-size: 22px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-page__desc {
  margin-bottom: 24px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--nf-muted);
}
.nf-card {
  padding: 24px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 14px;
}

/* ===== 댓글 작성 ===== */
.nf-comment-form {
  display: flex;
  gap: 8px;
  margin-top: 16px;
}
.nf-comment-form .nf-input {
  flex: 1;
}

/* ===== 관리자/공급업체에서 쓰는 인라인 저장 표시 ===== */
.nf-saving {
  margin-left: 8px;
  font-size: 12px;
  color: var(--nf-muted);
}
.nf-saved {
  margin-left: 8px;
  font-size: 12px;
  color: var(--nf-green);
}

@media (max-width: 540px) {
  .nf-field-row {
    flex-direction: column;
    gap: 0;
  }
}

/* ===== 게시판 사진 첨부 ===== */
.nf-hint-inline {
  font-weight: 500;
  color: var(--nf-muted);
}

.nf-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 22px 16px;
  text-align: center;
  background: #fafcfb;
  border: 1px dashed var(--nf-line);
  border-radius: 10px;
  cursor: pointer;
}
.nf-dropzone:hover {
  border-color: var(--nf-green);
  background: var(--nf-green-soft);
}
.nf-dropzone img {
  width: 24px;
  height: 24px;
  opacity: 0.6;
}
.nf-dropzone p {
  font-size: 12px;
  line-height: 1.5;
  color: var(--nf-muted);
}

.nf-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.nf-thumb {
  position: relative;
  width: 84px;
  height: 84px;
  overflow: hidden;
  border: 1px solid var(--nf-line);
  border-radius: 8px;
}
.nf-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.nf-thumb__remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 20px;
  height: 20px;
  font-size: 11px;
  line-height: 1;
  color: #fff;
  background: rgba(20, 32, 26, 0.65);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}

/* ===== 게시글 본문의 첨부 이미지 ===== */
.nf-post-images {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 18px;
}
.nf-post-images a {
  display: block;
}
.nf-post-images img {
  max-width: 100%;
  height: auto;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}

/* 목록에서 사진 있는 글 표시 */
.nf-photo-mark {
  margin-left: 4px;
  font-size: 11px;
  color: var(--nf-muted);
}

/* 사업자등록증처럼 내용을 읽어야 하는 첨부는 크게 보여준다 */
.nf-thumb--lg {
  width: 220px;
  height: 150px;
}
.nf-thumb--lg img {
  object-fit: contain;
  background: #f6f8f7;
}

/* 관리자 회원 관리 목록 */
.nf-member-license {
  width: 92px;
  height: 62px;
  object-fit: cover;
  border: 1px solid var(--nf-line);
  border-radius: 6px;
}

/* 이메일 인증 전에는 글쓰기 버튼 자리에 안내를 둔다 */
.board-write-btn--disabled {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* ===== 비교표 등락 화살표 깜빡임 =====
   값이 계속 움직이는 표라는 걸 한눈에 알리려고 오른 칸·내린 칸의 화살표만 깜빡인다.
   가격 숫자는 건드리지 않는다 — 읽는 중에 흐려지면 오히려 확인이 늦어진다.
   화살표는 배경 이미지라 흐려져도 자리를 지키므로 표가 출렁이지 않는다. */
.compare-table .cell-price .arrow_up,
.compare-table .cell-price .arrow_down {
  animation: nf-blink 1.1s ease-in-out infinite;
}

@keyframes nf-blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.15;
  }
}

/* 움직임을 줄여 달라고 설정한 사용자에게는 깜빡이지 않는다. */
@media (prefers-reduced-motion: reduce) {
  .compare-table .cell-price .arrow_up,
  .compare-table .cell-price .arrow_down {
    animation: none;
  }
}

/* ===== 전광판 → B2B 링크 직행 ===== */
/* 셀 전체가 클릭 대상이 되도록 a가 td를 꽉 채운다 */
.nf-cell-link {
  position: relative;
  display: block;
  padding: 2px;
  color: inherit;
  text-decoration: none;
  border-radius: 6px;
}
.nf-cell-linked {
  cursor: pointer;
}
.nf-cell-link:hover {
  background: var(--nf-green-soft);
  box-shadow: inset 0 0 0 1px rgba(22, 61, 44, 0.25);
}

/* 외부로 나간다는 표시. 평소엔 흐리게, 호버 시 또렷하게 */
.nf-ext {
  margin-left: 2px;
  font-size: 10px;
  color: var(--nf-muted);
  opacity: 0.5;
}
.nf-cell-link:hover .nf-ext,
.nf-b2b-name:hover .nf-ext {
  opacity: 1;
  color: var(--nf-green);
}
.nf-cell-link .nf-ext {
  position: absolute;
  top: 2px;
  right: 4px;
}

/* 업체명 = 업체 상세로 가는 링크 */
.nf-b2b-name {
  display: inline-block;
  padding: 2px 0;
  color: inherit;
  text-decoration: none;
}
.nf-b2b-name:hover {
  color: var(--nf-green);
  text-decoration: underline;
}

.nf-toolbar-hint {
  margin-left: 8px;
  font-size: 11px;
  font-weight: 500;
  color: var(--nf-muted);
}
@media (max-width: 768px) {
  .nf-toolbar-hint {
    display: block;
    margin: 4px 0 0;
  }
}

/* 업체 상세의 B2B 바로가기 버튼 */
.detail-order-btn--b2b {
  color: #fff;
  background: var(--nf-green);
}

/* 공급업체 상품 행의 상품 페이지 주소 입력 */
.nf-order-url {
  width: 100%;
  margin-top: 6px;
  padding: 5px 8px;
  font-size: 11px;
}
/* 주소 검색 창. 우편번호 서비스가 iframe으로 이 상자를 채운다 —
   높이를 주지 않으면 0px로 붙어 아무것도 보이지 않는다. */
/* 안내 토스트. 잠깐 떴다 사라지는 한 줄.
   이름을 nf-snack 으로 따로 쓴다 — 알림 팝업 카드(.nf-toast)와 이름이 같으면
   나중에 선언된 쪽이 이겨 position:fixed 가 relative 로 덮인다. 그러면 이 한 줄이
   전광판(.main-content, display:flex) 안의 flex 아이템이 되어 표를 밀어 좁힌다. */
.nf-snack {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%);
  z-index: 300;
  max-width: calc(100vw - 32px);
  padding: 12px 20px;
  font-size: 13.5px;
  font-weight: 700;
  color: #fff;
  background: rgba(28, 59, 46, 0.94);
  border-radius: 999px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22);
  animation: nf-snack-in 0.16s ease-out;
}

@keyframes nf-snack-in {
  from {
    opacity: 0;
    transform: translate(-50%, 8px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

.nf-postcode {
  width: 100%;
  height: 420px;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  overflow: hidden;
}

@media (max-width: 540px) {
  .nf-postcode {
    height: 60vh;
  }
}

.nf-inline-error {
  margin-top: 4px;
  font-size: 11px;
  color: var(--nf-danger);
}

/* ===== 관리자 상품·단가 관리 모달 ===== */
.nf-modal--wide {
  max-width: 760px;
}

.nf-prod-row {
  padding: 12px;
  margin-bottom: 10px;
  background: #fafcfb;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}
.nf-prod-row__name {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}
.nf-prod-row__name b {
  font-size: 14px;
  color: var(--nf-text);
}
.nf-prod-row__name span {
  font-size: 12px;
  color: var(--nf-muted);
}

.nf-prod-row__fields {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.nf-prod-row__fields label,
.nf-prod-row__url {
  display: block;
  font-size: 11px;
  font-weight: 700;
  color: var(--nf-muted);
}
.nf-prod-row__fields label .nf-input,
.nf-prod-row__fields label .nf-select,
.nf-prod-row__url .nf-input {
  margin-top: 4px;
  padding: 7px 9px;
  font-size: 13px;
  font-weight: 400;
}
.nf-prod-row__url {
  margin-top: 8px;
}
.nf-prod-row > .nf-btn {
  margin-top: 8px;
}

@media (max-width: 640px) {
  .nf-prod-row__fields {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ===== 가격 신선도 ===== */
/* 각 가격 아래에 붙는 마지막 확인 시각 */
.nf-fresh {
  margin-top: 2px;
  font-size: 10px;
  line-height: 1.3;
  letter-spacing: -0.2px;
}
.nf-fresh--fresh {
  color: #2f7d5a;
}
.nf-fresh--aging {
  color: var(--nf-muted);
}
.nf-fresh--stale {
  font-weight: 700;
  color: #b26a00;
}

/* 오래된 가격은 셀 자체를 눌러 보이게 해서, 훑어볼 때 자연히 걸러지도록 한다 */
.nf-cell-stale {
  background: #fffaf0;
}
.nf-cell-stale .cell-price {
  opacity: 0.55;
}
.nf-cell-stale .cell-status,
.nf-cell-stale .cell-time {
  opacity: 0.5;
}
.nf-cell-stale:hover .cell-price,
.nf-cell-stale:hover .cell-status,
.nf-cell-stale:hover .cell-time {
  opacity: 1;
}

/* 공급업체·관리자 화면에서 쓰는 신선도 뱃지 */
.nf-fresh-badge {
  display: inline-block;
  padding: 2px 7px;
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
}
.nf-fresh-badge--fresh {
  color: #1d6b4a;
  background: #e6f4ec;
}
.nf-fresh-badge--aging {
  color: #5c6b7a;
  background: #eef1f4;
}
.nf-fresh-badge--stale {
  color: #8a5200;
  background: #fdf0dc;
}

/* 공급업체 상단 '가격 확인' 안내 줄 */
.nf-confirm-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding: 12px 14px;
  background: #fdf0dc;
  border-radius: 10px;
}
.nf-confirm-bar p {
  flex: 1;
  min-width: 200px;
  font-size: 13px;
  line-height: 1.5;
  color: #8a5200;
}

/* ===== 유입 통계 ===== */
.nf-stats-title {
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 800;
  color: var(--nf-text);
}

/* 일별 막대 — 차트 라이브러리 없이 높이만으로 그린다 */
.nf-bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 140px;
  padding-top: 18px;
}
.nf-bars__col {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  min-width: 0;
}
.nf-bars__value {
  margin-bottom: 4px;
  font-size: 10px;
  color: var(--nf-muted);
}
.nf-bars__bar {
  width: 100%;
  min-height: 2px;
  background: var(--nf-green);
  border-radius: 3px 3px 0 0;
}
.nf-bars__date {
  margin-top: 6px;
  font-size: 9px;
  white-space: nowrap;
  color: var(--nf-muted);
}

.nf-rank-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.nf-rank-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}
.nf-rank-list__no {
  flex: none;
  width: 20px;
  height: 20px;
  font-size: 11px;
  font-weight: 700;
  line-height: 20px;
  color: #fff;
  text-align: center;
  background: var(--nf-green);
  border-radius: 50%;
}
.nf-rank-list__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--nf-text);
}
.nf-rank-list__count {
  font-weight: 700;
  color: var(--nf-green);
}

/* ===== 작업 내역 (/nf/report) ===== */
.nf-report {
  max-width: 860px;
  margin: 0 auto;
  padding: 32px 16px 80px;
}

.nf-report__tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin-bottom: 20px;
}
.nf-report__tab {
  display: flex;
  flex: none;
  flex-direction: column;
  gap: 2px;
  padding: 10px 16px;
  font-family: inherit;
  text-align: left;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  cursor: pointer;
}
.nf-report__tab.is-active {
  color: #fff;
  background: var(--nf-green);
  border-color: var(--nf-green);
}
.nf-report__tab-date {
  font-size: 13px;
  font-weight: 700;
}
.nf-report__tab-count {
  font-size: 11px;
  opacity: 0.7;
}

.nf-report__summary {
  padding: 14px 16px;
  margin-bottom: 24px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--nf-green);
  background: var(--nf-green-soft);
  border-radius: 10px;
}

.nf-report__list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  counter-reset: report;
}
.nf-report__item {
  padding: 20px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 12px;
}

.nf-report__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.nf-report__title {
  font-size: 16px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-report__body {
  margin-bottom: 8px;
  font-size: 14px;
  line-height: 1.75;
  color: #4a5a50;
}
.nf-report__body:last-of-type {
  margin-bottom: 0;
}

.nf-report__links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}
.nf-report__link {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-green);
  text-decoration: none;
  background: var(--nf-green-soft);
  border-radius: 999px;
}
.nf-report__link:hover {
  color: #fff;
  background: var(--nf-green);
}

@media (max-width: 540px) {
  .nf-report__title {
    font-size: 15px;
  }
  .nf-report__body {
    font-size: 13px;
  }
}

/* ===== 통합 검색 ===== */
.nf-search {
  position: relative;
}
.nf-search__input {
  width: 100%;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 13px;
  color: var(--nf-text);
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 8px;
  outline: none;
}
.nf-search__input:focus {
  border-color: var(--nf-green);
}

.nf-search__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  width: 100%;
  max-height: 320px;
  overflow-y: auto;
  padding: 8px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.12);
}
.nf-search__label {
  padding: 6px 8px 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--nf-muted);
}
.nf-search__row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 8px;
  font-family: inherit;
  text-align: left;
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.nf-search__row:hover {
  background: var(--nf-green-soft);
}
.nf-search__row b {
  font-size: 13px;
  color: var(--nf-text);
}
.nf-search__row span {
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-search__empty {
  padding: 12px 8px;
  font-size: 12px;
  color: var(--nf-muted);
}

/* ===== 즐겨찾기 ===== */
.nf-star {
  padding: 0 4px 0 0;
  font-size: 13px;
  line-height: 1;
  color: #c9d2cc;
  background: none;
  border: 0;
  cursor: pointer;
}
.nf-star.is-on {
  color: #e8a33d;
}
.nf-star:hover {
  color: #e8a33d;
}

.nf-fav-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nf-fav-list li {
  padding: 7px 10px;
  font-size: 13px;
  color: var(--nf-text);
  border-radius: 6px;
  cursor: pointer;
}
.nf-fav-list li:hover {
  background: var(--nf-green-soft);
}
.nf-fav-list li.active {
  font-weight: 700;
  color: #fff;
  background: var(--nf-green);
}

/* ===== 품목 시세 요약 ===== */
.nf-market {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding: 14px 18px;
  margin-bottom: 14px;
  background: linear-gradient(180deg, #f7fbf8 0%, #fff 100%);
  border: 1px solid var(--nf-line);
  border-radius: 12px;
}

.nf-market__main {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.nf-market__label {
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-muted);
}
.nf-market__avg {
  font-size: 22px;
  font-weight: 800;
  color: var(--nf-text);
  letter-spacing: -0.5px;
}
.nf-market__change {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 14px;
  font-weight: 800;
}
.nf-market__change em {
  font-size: 11px;
  font-style: normal;
  font-weight: 500;
  color: var(--nf-muted);
}
.nf-market__change.is-up {
  color: #c0392b;
}
.nf-market__change.is-down {
  color: #1d6b4a;
}
.nf-market__change.is-same {
  color: var(--nf-muted);
}

.nf-market__side {
  display: flex;
  gap: 16px;
  margin-left: auto;
  font-size: 12px;
  color: var(--nf-muted);
}
.nf-market__side b {
  font-weight: 700;
  color: var(--nf-text);
}

.nf-spark {
  display: block;
}

@media (max-width: 768px) {
  .nf-market {
    gap: 10px;
  }
  .nf-market__side {
    width: 100%;
    margin-left: 0;
  }
  .nf-market__avg {
    font-size: 19px;
  }
}

/* ===== 신고 ===== */
.nf-report-btn {
  padding: 2px 8px;
  font-family: inherit;
  font-size: 11px;
  color: var(--nf-muted);
  background: none;
  border: 1px solid var(--nf-line);
  border-radius: 999px;
  cursor: pointer;
}
.nf-report-btn:hover {
  color: var(--nf-danger);
  border-color: var(--nf-danger);
}

/* 목록 안에서는 자리를 적게 차지하도록 */
.comment-item__head .nf-report-btn,
.col-status .nf-report-btn {
  margin-left: 6px;
}

/* 게시글·댓글 옆 쪽지 버튼. 신고 버튼과 나란히 서므로 같은 크기·모양을 쓰되,
   색만 다르다 — 하나는 사람에게 말을 거는 일이고 하나는 운영자를 부르는 일이다. */
.nf-dm-btn {
  padding: 2px 8px;
  font-family: inherit;
  font-size: 11px;
  /* 신고는 <button>이라 reset의 line-height:1.15를 받는다. 쪽지는 <a>여서
     그냥 두면 본문 줄높이(1.5)를 물려받아 혼자 키가 커진다. 같은 값을 박아
     둘이 정확히 같은 높이로 서게 한다. */
  line-height: 1.15;
  color: var(--nf-muted);
  text-decoration: none;
  background: none;
  border: 1px solid var(--nf-line);
  border-radius: 999px;
  cursor: pointer;
}
.nf-dm-btn:hover {
  color: var(--nf-green, #15924c);
  border-color: var(--nf-green, #15924c);
}
.comment-item__head .nf-dm-btn,
.post-detail-card__meta .nf-dm-btn {
  margin-left: 6px;
}

/* 글쓴이·날짜·조회 뒤에 신고·쪽지·수정·삭제까지 한 줄에 서므로, 폰 폭에서는
   줄이 넘친다. 두 줄 다 flex인데 줄바꿈이 없어 넘친 만큼 오른쪽으로 밀려나고
   #wrapper의 overflow-x:clip에 잘려 나가 — 줄 끝의 쪽지 버튼이 아예 보이지
   않았다. 넘칠 때만 다음 줄로 내려보낸다(넓은 화면에서는 그대로 한 줄). */
.post-detail-card__meta,
.comment-item__head {
  flex-wrap: wrap;
  row-gap: 6px;
}

/* 다만 버튼들끼리는 흩어지면 안 된다. 넷을 한 덩어리로 묶어 flex 항목 하나로
   만들면, 줄이 넘칠 때 신고·쪽지가 갈라지지 않고 묶음째로 다음 줄로 내려간다. */
.nf-meta-actions {
  display: inline-flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 6px;
}
/* 묶음 안에서는 gap이 간격을 맡으므로 개별 margin은 지운다. */
.nf-meta-actions .nf-report-btn,
.nf-meta-actions .nf-dm-btn,
.nf-meta-actions .nf-post-actions,
.nf-meta-actions .nf-comment-actions {
  margin-left: 0;
}
.col-status .nf-report-btn {
  display: block;
  margin: 6px 0 0;
}

/* ===== 알림 ===== */
/*
 * 안 읽은 알림 수는 '알림' 글자 오른쪽에 나란히 붙인다.
 *
 * 처음에는 글자 위로 띄워 올렸는데(position: absolute), 대각선 허공에 뜬 숫자가
 * 무엇에 붙은 것인지 읽히지 않았다. 한 줄 안에 두면 '알림 3'으로 그냥 읽힌다.
 *
 * '알림' 링크에는 display를 주지 않는다. 헤더 버튼 줄(#header .hr_btns)이 flex라
 * 이 링크만 inline-flex로 만들면 그것만 세로 가운데로 내려가고, 옆의
 * 공지사항·자유게시판·내 정보(위에서부터 흐르는 보통 링크)보다 글자가 낮게 앉는다.
 * 다른 링크와 똑같은 보통 링크로 두고, 숫자만 글자 옆에 끼워 넣는다.
 */
.nf-bell__dot {
  display: inline-block;
  min-width: 17px;
  height: 17px;
  margin-left: 5px;
  padding: 0 5px;
  font-size: 11px;
  font-weight: 700;
  line-height: 17px;
  color: #fff;
  text-align: center;
  vertical-align: middle;
  background: #c0392b;
  border-radius: 999px;
}

/* 알림함 상단 줄. 왼쪽 전체 선택, 오른쪽 일괄 버튼. */
.nf-noti-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.nf-noti-bar__all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--nf-text);
  cursor: pointer;
}
.nf-noti-bar__all input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--nf-green);
}
.nf-noti-bar__count {
  font-weight: 800;
  color: var(--nf-green);
}
.nf-noti-bar__btns {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.nf-noti-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.nf-noti {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}
.nf-noti.is-unread {
  background: var(--nf-green-soft);
  border-color: #cfe1d3;
}
.nf-noti.is-picked {
  border-color: var(--nf-green);
  box-shadow: inset 0 0 0 1px var(--nf-green);
}
/* 체크 영역을 행 높이만큼 잡아둔다 — 칸이 좁으면 지우려다 알림이 열린다. */
.nf-noti__check {
  display: flex;
  align-items: center;
  align-self: stretch;
  padding-right: 2px;
  cursor: pointer;
}
.nf-noti__check input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--nf-green);
}
.nf-noti__main {
  display: block;
  flex: 1;
  min-width: 0;
  text-decoration: none;
}
.nf-noti__title {
  margin-bottom: 4px;
  font-size: 14px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-noti__body {
  font-size: 13px;
  line-height: 1.6;
  color: #4a5a50;
}
.nf-noti__date {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  color: var(--nf-muted);
}

.nf-alert-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  margin-bottom: 8px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}
.nf-alert-row__main {
  flex: 1;
  min-width: 180px;
}
.nf-alert-row__name {
  font-size: 14px;
  font-weight: 700;
  color: var(--nf-text);
}
.nf-alert-row__cond {
  font-size: 12px;
  color: var(--nf-muted);
}

/* ===== 단위당 단가 ===== */
/* 규격이 제각각이라 원가격만으로는 비교가 안 된다. 환산값을 가격 바로 아래 붙인다. */
.nf-unit-price {
  margin-top: 1px;
  font-size: 10px;
  font-weight: 700;
  color: #5c7a68;
  letter-spacing: -0.3px;
}

/* ===== 발주마감 상태 ===== */
.nf-dl--open {
  color: var(--nf-muted);
}
.nf-dl--soon {
  font-weight: 700;
  color: #b26a00;
}
.nf-dl--urgent {
  font-weight: 800;
  color: #c0392b;
}
.nf-dl--closed {
  font-weight: 700;
  color: #9aa5ad;
  text-decoration: line-through;
}

/* ===== 관심 시세 ===== */
.nf-page--wide {
  max-width: 1000px;
}
.nf-watch {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.nf-watch__card {
  padding: 16px 18px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 12px;
}
.nf-watch__head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 8px;
}
.nf-watch__cat {
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-watch__name {
  font-size: 15px;
  font-weight: 800;
  color: var(--nf-text);
  text-decoration: none;
}
.nf-watch__name:hover {
  color: var(--nf-green);
}
.nf-watch__change {
  margin-left: auto;
  font-size: 12px;
  font-weight: 800;
}
.nf-watch__change.is-up {
  color: #c0392b;
}
.nf-watch__change.is-down {
  color: #1d6b4a;
}
.nf-watch__change.is-same {
  color: var(--nf-muted);
}

.nf-watch__price {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 24px;
  font-weight: 800;
  color: var(--nf-text);
  letter-spacing: -0.6px;
}
.nf-watch__price em {
  font-size: 13px;
  font-style: normal;
  font-weight: 700;
}
.nf-watch__unit {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  color: #5c7a68;
}
.nf-watch__meta {
  margin-top: 4px;
  font-size: 12px;
  color: var(--nf-muted);
}
.nf-watch__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.nf-watch__tag {
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 700;
  color: var(--nf-muted);
  background: #f2f5f3;
  border-radius: 999px;
}
.nf-watch__actions {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}
.nf-watch__actions .nf-btn {
  flex: 1;
  padding: 8px 10px;
  font-size: 12px;
  text-align: center;
  text-decoration: none;
}
.nf-watch__foot {
  margin-top: 8px;
  font-size: 11px;
  color: var(--nf-muted);
}

/* ===== 업체 신뢰 지표 ===== */
.nf-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.nf-trust__badge {
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
}
.nf-trust__badge--green {
  color: #1d6b4a;
  background: #e6f4ec;
}
.nf-trust__badge--blue {
  color: #2a5d8f;
  background: #e8f0f8;
}
.nf-trust__badge--amber {
  color: #8a5200;
  background: #fdf0dc;
}
.nf-trust__sub {
  font-size: 11px;
  font-weight: 400;
  color: var(--nf-muted);
}

/* ===== 비교함 · 시세표 받기 ===== */
.nf-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.nf-download {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-green);
  text-decoration: none;
  white-space: nowrap;
  background: var(--nf-green-soft);
  border-radius: 8px;
}
.nf-download:hover {
  color: #fff;
  background: var(--nf-green);
}

.nf-compare-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px 5px 12px;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  white-space: nowrap;
  background: var(--nf-green);
  border-radius: 999px;
}
.nf-compare-chip button {
  padding: 0 2px;
  font-size: 12px;
  line-height: 1;
  color: #fff;
  background: none;
  border: 0;
  cursor: pointer;
  opacity: 0.8;
}
.nf-compare-chip button:hover {
  opacity: 1;
}

/* 업체 · 정렬 드롭다운 — 항목이 늘어도 필터 바 높이가 그대로다.
   업체 칩을 가로로 늘어놓던 방식은 업체가 늘수록 줄이 길어져 접었다. */
.nf-dropdown {
  position: relative;
}
.nf-dropdown__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  max-width: 200px;
  padding: 0 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--nf-text);
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 999px;
  cursor: pointer;
}
.nf-dropdown__btn:hover {
  border-color: var(--nf-green);
}
.nf-dropdown__btn.is-on {
  color: var(--nf-green);
  font-weight: 700;
  border-color: var(--nf-green);
  background: var(--nf-green-soft);
}
.nf-dropdown__text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nf-dropdown__caret {
  font-size: 10px;
  line-height: 1;
  opacity: 0.7;
}
.nf-dropdown__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 30;
  min-width: 200px;
  max-width: 280px;
  padding: 4px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  box-shadow: 0 8px 20px rgb(0 0 0 / 12%);
}
/* 업체가 100곳이어도 화면을 덮지 않게 목록만 스크롤한다. */
.nf-dropdown__list {
  max-height: 240px;
  overflow-y: auto;
  scrollbar-width: thin;
}
.nf-dropdown__opt {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 7px 8px;
  font-size: 12.5px;
  text-align: left;
  color: var(--nf-text);
  background: none;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}
.nf-dropdown__opt:hover {
  background: #f2f6f3;
}
.nf-dropdown__opt.is-on {
  font-weight: 700;
  color: var(--nf-green);
  background: var(--nf-green-soft);
}
.nf-dropdown__check {
  flex: 0 0 12px;
  font-size: 11px;
  color: var(--nf-green);
}
.nf-dropdown__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nf-chip__star {
  margin-right: 3px;
  color: #e8a33d;
}
.nf-chip.is-on .nf-chip__star {
  color: #ffd88a;
}

/* ===== 일괄 등록 미리보기 ===== */
.nf-bulk-list {
  max-height: 420px;
  overflow-y: auto;
  margin-top: 16px;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}
.nf-bulk-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid #f0f3f1;
}
.nf-bulk-row:last-child {
  border-bottom: 0;
}
.nf-bulk-row.is-error {
  background: #fdecea;
}
.nf-bulk-row.is-same {
  opacity: 0.6;
}
.nf-bulk-row__main {
  flex: 1;
  min-width: 0;
}
.nf-bulk-row__name {
  font-size: 13px;
  font-weight: 700;
  color: var(--nf-text);
}
.nf-bulk-row__name em {
  margin-left: 6px;
  font-size: 11px;
  font-style: normal;
  font-weight: 500;
  color: var(--nf-muted);
}
.nf-bulk-row__msg {
  margin-top: 2px;
  font-size: 12px;
  color: var(--nf-muted);
}
.nf-bulk-row__msg s {
  color: #b9c2bc;
}
.nf-bulk-row__msg b {
  color: var(--nf-text);
}

/* ===================================================================
   첫 화면 — 게시판 최근글
   =================================================================== */

/*
 * 공지 줄과 큰 배너 사이에 끼는 줄.
 *
 * 카드 모양(흰 바탕·둥근 모서리·옅은 그림자)은 공지 줄(.notice-bar)에 맞춰 두되,
 * 제목 앞 초록 막대와 옅은 머리 구분선으로 '여기부터 게시판'이라는 표시를 준다 —
 * 예전에는 공지 줄과 생김새가 완전히 같아서 위아래 두 덩어리가 한 덩어리로 읽혔고,
 * 게시판 글이 걸려 있다는 것 자체가 눈에 안 들어왔다.
 *
 * 높이는 두 줄로 고정한다. 아래에 있는 전광판이 이 화면의 본체라서,
 * 최근글이 세로로 길어지면 정작 보러 온 표가 접힌 아래로 밀린다.
 */
.home-posts {
  margin-bottom: 12px;
  padding: 8px 18px 6px;
  background: #fff;
  border-radius: 8px;
  box-shadow: rgba(18, 40, 28, 0.04) 0px 4px 14px;
}

.home-posts__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* 구분선을 넣느라 늘어난 만큼은 아래위 여백에서 도로 빼 온다 — 이 줄이 두꺼워지면
     그만큼 전광판이 아래로 밀린다. 전체 높이는 예전과 같게 맞춰 둔 값이다. */
  padding-bottom: 2px;
  margin-bottom: 2px;
  border-bottom: 1px solid #eef2ef;
}

/* 제목 앞의 짧은 초록 막대. 공지 줄의 '공지' 뱃지와 같은 색 계열을 쓰되
   덩치는 훨씬 작게 둔다 — 뱃지를 하나 더 세우면 두 줄이 서로 경쟁한다. */
.home-posts__title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 800;
  color: #1c3b2e;
}

.home-posts__title::before {
  width: 3px;
  height: 12px;
  background: #1c7c4a;
  border-radius: 2px;
  content: '';
}

/* 인디케이터와 더보기를 한 덩어리로 묶어 오른쪽 끝에 세운다. */
.home-posts__nav {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 10px;
}

/*
 * 묶음 인디케이터.
 *
 * 5초마다 저 혼자 바뀌는데 몇 개 중 몇 번째인지 알 길이 없어서, 읽던 글이 사라지면
 * 되돌릴 방법이 없었다. 점으로 개수를 드러내고 눌러서 바로 그 묶음으로 간다.
 */
.home-posts__dots {
  display: flex;
  align-items: center;
  gap: 4px;
}

.home-posts__dot {
  width: 5px;
  height: 5px;
  padding: 0;
  background: #d9e0db;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.2s, width 0.2s;
}

.home-posts__dot:hover {
  background: #a8b6ad;
}

/* 지금 보고 있는 묶음은 색과 함께 길이로도 구분한다 — 5px짜리 점 두 개는
   색만 다르면 어느 쪽이 켜진 것인지 멀리서 안 갈린다. */
.home-posts__dot.is-on {
  width: 14px;
  background: #1c7c4a;
  border-radius: 3px;
}

.home-posts__more {
  font-size: 12px;
  font-weight: 700;
  color: #6b7b72;
}

.home-posts__more:hover {
  color: #1c7c4a;
}

/* 두 글을 위아래로 쌓고, 한 글은 가로로 끝까지 뽑는다.
   5초마다 다음 두 글로 바뀌므로(HomePosts.tsx) 묶음이 바뀔 때 살짝 떠오르게 한다. */
.home-posts__list {
  display: block;
  animation: home-posts-in 0.35s ease;
}

@keyframes home-posts-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* 화면 움직임을 줄여 달라고 설정한 사람에게는 떠오르는 효과를 끈다.
   내용은 그대로 바뀌므로 잃는 정보가 없다. */
@media (prefers-reduced-motion: reduce) {
  .home-posts__list {
    animation: none;
  }
}

.home-posts__item a {
  display: flex;
  align-items: center;
  gap: 8px;
  /* 좌우 8px은 마우스를 올렸을 때 깔리는 바탕이 글자에 딱 붙지 않게 하는 여백이다.
     바깥 여백으로 도로 빼서 글자가 서는 자리는 예전 그대로 둔다. */
  padding: 4px 8px;
  margin: 0 -8px;
  color: #2a3b31;
  border-radius: 6px;
  border-bottom: 1px solid #f4f7f5;
  transition: background 0.15s;
}

.home-posts__item:last-child a {
  border-bottom: 0;
}

/* 한 줄 전체가 눌리는 자리라는 것을 바탕색으로 알린다 — 제목에만 밑줄이 그어지면
   제목 글자를 정확히 눌러야 하는 줄 알고 줄 끝을 눌렀다가 아무 일도 안 일어난다. */
.home-posts__item a:hover {
  background: #f4f9f6;
}

.home-posts__item a:hover .home-posts__subject {
  color: #14603a;
  text-decoration: underline;
}

/* 제목은 제 길이만큼 다 쓴다 — 절반에서 끊으면 '추석 앞 물량…'처럼 정작 무슨 글인지
   모르는 채로 잘린다. 자리가 모자라면 옆의 본문 첫머리가 먼저 줄어들고(아래 shrink),
   본문이 다 사라진 뒤에야 제목이 말줄임된다. */
.home-posts__subject {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 본문 첫머리. 남는 가로 자리를 채우고, 넘치면 말줄임으로 끊는다.
   제목보다 흐린 색·작은 글씨로 두어 어느 쪽이 제목인지 한눈에 갈린다.

   shrink를 크게 준 건 줄이 넘칠 때 누가 먼저 양보하느냐를 정하려는 것이다.
   flex의 줄임은 기준 너비 x shrink 값에 비례해 나뉘므로, 여기에 큰 수를 두면
   줄어드는 몫을 본문이 거의 다 가져가고 제목은 그대로 남는다. */
.home-posts__excerpt {
  flex: 1 9999 auto;
  min-width: 0;
  font-size: 12.5px;
  color: #7d8b83;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-posts__excerpt::before {
  margin-right: 6px;
  color: #cfd8d2;
  content: '|';
}

/*
 * 줄 끝의 작성자·시간·조회·댓글.
 *
 * 넷을 같은 색·같은 크기로 늘어놓으면 글자 덩어리 하나로 뭉쳐 아무것도 안 읽힌다.
 * 작성자만 조금 진하게 두고, 나머지는 흐린 회색에 가운뎃점으로 끊는다.
 */
.home-posts__meta {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  color: #9aa89f;
  font-variant-numeric: tabular-nums;
}

.home-posts__meta > * + *::before {
  margin-right: 8px;
  color: #dde4df;
  content: '·';
}

.home-posts__author {
  max-width: 90px;
  overflow: hidden;
  color: #6b7b72;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-posts__time {
  flex-shrink: 0;
}

/* 아이콘과 숫자를 한 덩어리로 붙인다. 아이콘은 글자보다 조금 흐리게 둬서
   숫자가 먼저 읽히게 한다 — 여기서 알고 싶은 건 그림이 아니라 수다. */
.home-posts__stat {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: 3px;
}

.home-posts__stat svg {
  color: #c2cec7;
}

/* 댓글이 달린 글은 들어가 볼 이유가 하나 더 있는 글이라 색으로 짚어 준다. */
.home-posts__stat--comment {
  color: #c8622f;
  font-weight: 700;
}

.home-posts__stat--comment svg {
  color: #e0a888;
}

/*
 * 자리가 좁아지면 뒤에서부터 하나씩 내린다: 본문 첫머리 → 작성자 → 조회·댓글.
 * 제목과 시간은 끝까지 남긴다 — 그 둘이 빠지면 최근글 줄일 이유가 없어진다.
 *
 * 본문을 900px에서 아예 접는 이유: 그보다 좁아지면 본문에 남는 자리가 한두 글자라
 * '|' 뒤에 말줄임만 찍힌다. 읽히지도 않는 토막을 두느니 통째로 내리고 제목에 자리를 준다.
 */
@media (max-width: 900px) {
  .home-posts__subject {
    flex: 1 1 auto;
  }
  .home-posts__excerpt {
    display: none;
  }
}

@media (max-width: 600px) {
  .home-posts__author {
    display: none;
  }
}

@media (max-width: 480px) {
  .home-posts {
    padding: 8px 14px 6px;
  }
  .home-posts__meta {
    font-size: 11px;
  }
  .home-posts__stat {
    display: none;
  }
}

/* ===================================================================
   신고 처리 — 신고된 쪽지 열어 보기
   =================================================================== */

/* 표 안에서 '바로가기 ↗' 링크와 같은 자리에 서는 버튼. 생김새를 링크에 맞춘다. */
.admin-link-btn {
  display: inline-block;
  padding: 0;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  color: #1c7c4a;
  text-decoration: underline;
  background: none;
  border: 0;
  cursor: pointer;
}

.admin-msg-meta {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: 6px 12px;
  font-size: 13px;
  color: var(--nf-text);
}

.admin-msg-meta dt {
  font-weight: 700;
  color: var(--nf-muted);
}

/*
 * 쪽지 본문.
 * 줄바꿈을 그대로 살린다(pre-wrap) — 신고 사유가 '줄을 채워 도배했다'인 경우가 있어
 * 한 덩어리로 이어 붙이면 무엇이 문제였는지가 사라진다.
 */
.admin-msg-body {
  margin-top: 6px;
  padding: 12px 14px;
  max-height: 320px;
  overflow-y: auto;
  font-size: 13.5px;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--nf-text);
  background: #f7faf8;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}

/* 바로가기로 들어왔을 때 그 댓글이 헤더에 가리지 않게 한다(#header는 fixed 64px). */
.comment-item[id] {
  scroll-margin-top: 84px;
}

/* ===================================================================
   아이디 찾기
   =================================================================== */

/* 찾는 방법 고르기(이메일 / 연락처). 한 줄에 둘, 고른 쪽만 진하게. */
.nf-method {
  display: flex;
  gap: 8px;
  margin-bottom: 18px;
}

.nf-method__btn {
  flex: 1;
  padding: 11px 12px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--nf-muted);
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  cursor: pointer;
}

.nf-method__btn.is-on {
  color: #fff;
  background: #1c3b2e;
  border-color: #1c3b2e;
}

/* 찾은 아이디. 옮겨 적을 대상이라 글자를 키우고 자간을 넓힌다 —
   가린 아이디의 별표 개수도 세어 보게 되므로 붙어 있으면 안 된다. */
.nf-found-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 4px 0 12px;
}

.nf-found {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  background: #f7faf8;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}

.nf-found__id {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--nf-text);
  /* 아이디에는 O/0, l/1이 섞인다. 옮겨 적을 때 헷갈리지 않게 고정폭으로 보여준다. */
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  user-select: all;
}

.nf-found__meta {
  font-size: 12px;
  color: var(--nf-muted);
}

/* 폼 맨 아래 제출 버튼. 링크(<a>)에도 붙으므로 inline-flex로 가운데를 맞춘다. */
.nf-btn--full {
  display: block;
  width: 100%;
  margin-top: 20px;
  text-align: center;
}

.nf-actions a.nf-btn {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* ===================================================================
   품목 노출 순서 — 분류별 순위
   =================================================================== */

/* 네 분류를 두 칸으로 눕힌다. 한 줄에 하나씩이면 스크롤이 길어져
   '과일 1순위'와 '수산 1순위'를 한눈에 견주지 못한다. */
.admin-rank-groups {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.admin-rank-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: #fafcfb;
  border: 1px solid var(--nf-line);
  border-radius: 12px;
}

.admin-rank-group__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.admin-rank-group__name {
  font-size: 14px;
  font-weight: 800;
  color: var(--nf-text);
}

.admin-rank-group__count {
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-muted);
}

/*
 * 통합 목록일 때는 칩이 옆으로 흐르는 편이 좋았지만, 분류 칸 안에서는
 * 순위가 위에서 아래로 읽혀야 한다 — ▲▼ 버튼의 방향과 목록의 방향이 같아야 한다.
 */
.admin-rank-group .admin-rank-list {
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 6px;
}

.admin-rank-group .admin-rank-item {
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  background: #fff;
  border: 1px solid var(--nf-line);
  /* 드래그가 아니라 버튼으로 옮기므로 손 모양 커서를 쓰지 않는다. */
  cursor: default;
}

/* 1순위만 눈에 띄게 — 접속했을 때 기본으로 열리는 품목이라 확인할 일이 잦다. */
.admin-rank-group .admin-rank-item:first-child {
  border-color: #1c3b2e;
}

.admin-rank-item--empty {
  justify-content: center;
  font-size: 12.5px;
  color: var(--nf-muted);
  background: transparent;
  border-style: dashed;
}

.admin-rank-saved {
  margin-right: 10px;
  align-self: center;
  font-size: 12.5px;
  font-weight: 700;
  color: #1c7c4a;
}

.admin-icon-btn:disabled {
  opacity: 0.3;
  cursor: default;
}

@media (max-width: 900px) {
  .admin-rank-groups {
    grid-template-columns: 1fr;
  }
}

/* 저장 완료 같은 짧은 알림 창. 기본 520px는 두 줄짜리 내용에 비해 휑하다. */
.nf-modal--sm {
  max-width: 400px;
}

.admin-rank-done {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--nf-text);
}

.admin-rank-done b {
  display: inline-block;
  min-width: 44px;
  font-weight: 800;
}

.admin-rank-done__note {
  margin-top: 12px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--nf-muted);
}

/* ===================================================================
   운영자 계정 — 기능 권한 고르기
   =================================================================== */

/* 계정 구분(직원 / 최고관리자) 라디오. 권한 체크와 같은 생김새로 맞춘다. */
.admin-kind {
  display: flex;
  gap: 10px;
}

.admin-kind__opt,
.admin-perm__item {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 11px 12px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  cursor: pointer;
}

/* 켜진 항목은 테두리 색만 바꾼다. 배경까지 칠하면 14개가 한꺼번에 켜졌을 때
   격자가 통째로 물들어 무엇이 꺼져 있는지가 오히려 안 보인다. */
.admin-kind__opt.is-on,
.admin-perm__item.is-on {
  border-color: #1c3b2e;
  box-shadow: inset 0 0 0 1px #1c3b2e;
}

.admin-kind__opt input,
.admin-perm__item input {
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: #1c3b2e;
}

.admin-perm {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--nf-line);
}

.admin-perm__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.admin-perm__bulk {
  display: flex;
  gap: 6px;
}

/* 14개를 한 줄에 하나씩 두면 모달이 스크롤 없이는 안 담긴다. 두 칸으로 눕힌다. */
.admin-perm__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.admin-perm__label,
.admin-perm__desc {
  display: block;
}

.admin-perm__label {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--nf-text);
}

.admin-perm__desc {
  margin-top: 2px;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--nf-muted);
}

.admin-perm__note {
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--nf-muted);
}

/* 목록의 권한 요약 — 배지와 기능 이름이 한 줄에 붙는다. */
.admin-perm-summary {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--nf-muted);
}

@media (max-width: 600px) {
  .admin-kind,
  .admin-perm__grid {
    grid-template-columns: 1fr;
    flex-direction: column;
  }
}

/* ===================================================================
   모바일 보정
   실제 기기 폭(360/375/390px)으로 확인하며 잡은 것들.
   퍼블리싱 산출물(header.css/style.css)은 건드리지 않고 여기서 덮어쓴다.
   =================================================================== */

/* [중요] 모바일 메뉴 패널이 화면 밖으로 나가 있는데(translateX(100%)) 잘리지 않아
   문서 전체 폭이 늘어나고 전광판에 가로 스크롤이 생겼다.
   고정 컨테이너에서 넘치는 부분을 잘라내면 해결된다. 열릴 때는 패널이
   translateX(0)으로 들어오므로 정상적으로 보인다. */
.hr_mobile-menu {
  overflow: hidden;
}

/* 혹시 다른 요소가 넘치더라도 가로 스크롤로 이어지지 않게 한 겹 더 막는다.

   hidden이 아니라 clip인 이유: overflow-x:hidden은 반대 축을 auto로 바꿔 그 요소를
   스크롤 컨테이너로 만든다. 그러면 안쪽의 position:sticky가 페이지가 아니라
   절대 스크롤되지 않는 #wrapper를 기준으로 삼아 아예 따라오지 않는다
   (우측 배너 .side-banner가 이것 때문에 멈춰 있었다).
   clip은 넘친 부분만 잘라낼 뿐 스크롤 컨테이너를 만들지 않아 sticky가 살아 있다. */
#wrapper {
  overflow-x: clip;
}

@media (max-width: 768px) {
  /* --- 터치 대상 키우기 ---
     손가락으로 누르는 화면에서 높이 20px짜리 링크는 정확히 누르기 어렵다. */
  .login-links a {
    display: inline-block;
    padding: 8px 6px;
  }

  .board-back,
  .detail-back {
    display: inline-block;
    padding: 8px 0;
  }

  .order-btn {
    padding: 7px 12px;
  }

  /* 즐겨찾기 별 — 표 안이라 여백을 크게 줄 수 없어
     보이는 크기는 두고 누를 수 있는 범위만 넓힌다. */
  .nf-star {
    padding: 6px 4px;
    font-size: 15px;
  }

  /* 손가락으로 누르는 화면이라 조금 키운다. */
  .nf-dropdown__btn {
    height: 32px;
    max-width: 150px;
  }
  .nf-dropdown__opt {
    padding: 9px 8px;
  }

  /* 폭이 좁아 오른쪽에 놓인 드롭다운은 펼치면 화면 밖으로 나간다.
     (#wrapper의 overflow-x:hidden 탓에 스크롤로도 닿을 수 없다)
     좁은 화면에서는 필터 줄 아래에 줄 너비 그대로 펼친다. */
  .nf-filter-bar {
    position: relative;
  }
  .nf-dropdown {
    position: static;
  }
  .nf-dropdown__panel {
    left: 0;
    right: 0;
    max-width: none;
  }

  .nf-report-btn,
  .nf-dm-btn {
    padding: 8px 10px;
  }

  .nf-download {
    padding: 8px 12px;
  }

  /* --- 표 안 글자 --- */
  /* 규격 라벨이 10px이라 폰에서 읽기 어렵다. 표가 좁아지지 않는 선에서 키운다. */
  .col-variety {
    font-size: 11px;
  }
  .nf-unit-price {
    font-size: 11px;
  }
}

@media (max-width: 540px) {
  /* 시세 요약이 세로로 길어지지 않도록 정리 */
  .nf-market {
    padding: 12px 14px;
  }
  .nf-market__side {
    gap: 12px;
    font-size: 11px;
  }

  /* 관심 시세 카드는 한 줄에 하나 */
  .nf-watch {
    grid-template-columns: 1fr;
  }
}

/* --- 모바일: 잘리던 것들 --- */
@media (max-width: 768px) {
  .table-toolbar {
    flex-wrap: wrap;
    gap: 8px;
  }
  .nf-toolbar-actions {
    margin-left: 0;
  }

  /* 표 안 상태 글자가 9px이라 폰에서 읽기 어렵다 */
  .cell-status,
  .cell-time,
  .nf-fresh {
    font-size: 11px;
  }

  /* 업체명·상품명 링크가 높이 14px이라 누르기 어렵다 */
  .nf-b2b-name {
    display: inline-block;
    padding: 5px 0;
  }
  .notice-bar__more {
    display: inline-block;
    padding: 6px 0;
  }
}

/* 좌측 프로모션·우측 배너 슬라이더가 화면 밖으로 삐져나온다.
   style.css에서 `.promo-swiper { overflow: visible }` 규칙이 1024px 미디어쿼리보다
   뒤에 있어 덮어써진 탓이다. 좁은 화면에서는 잘라낸다. */
@media (max-width: 1024px) {
  .promo-swiper,
  .banner-swiper {
    overflow: hidden;
  }
}

/* --- 모바일: 전광판 업체 칸 --- */
@media (max-width: 768px) {
  /* 업체 칸이 화면의 절반을 넘게 차지해 정작 가격 볼 자리가 없었다.
     이름과 버튼을 세로로 쌓아 폭을 줄인다. 첫 열은 sticky라 가로로 넘겨도
     어느 업체 가격인지 계속 보인다.

     폭(min/max-width)은 여기서 정하지 않는다 — 표가 table-layout:fixed라 그 선언은
     무시되고, 실제 폭은 PriceBoard의 COMPANY_MIN(모바일 122px)이 colgroup으로 넣는다.
     좌우 여백은 데스크톱과 같이 0이다 — 이 칸에서는 여백이 곧 폭이다. */
  .compare-table .col-company {
    padding: 8px 0;
  }
  /* 배치(별표+이름 줄 / 버튼 줄)는 데스크톱과 같다(style.css). 여기서는 글자만 키운다 —
     현장에서 폰으로 보는 화면이라 11px은 작다. 대신 칸이 8px 넓어진다(114 → 122). */
  .compare-table .col-company .company-name {
    margin: 2px 0;
    font-size: 12px;
    line-height: 1.3;
  }
}

/* ===== 글·댓글 수정·삭제 ===== */
.nf-post-actions {
  display: inline-flex;
  gap: 6px;
  margin-left: 8px;
}
.nf-comment-actions {
  display: inline-flex;
  gap: 4px;
  margin-left: 6px;
}
.nf-comment-actions .nf-report-btn,
.nf-post-actions .nf-report-btn {
  padding: 2px 8px;
  font-size: 11px;
}
/* 위 규칙은 선택자가 길어 모바일 확대(.nf-report-btn)를 이기고 수정·삭제만
   작게 남겨 놓는다. 신고·쪽지와 나란히 선 자리에서는 넷이 같아야 한다. */
@media (max-width: 768px) {
  .nf-meta-actions .nf-comment-actions .nf-report-btn,
  .nf-meta-actions .nf-post-actions .nf-report-btn {
    padding: 8px 10px;
  }
}

/* ===== 작업 내역: 다음에 할 일 ===== */
.nf-next {
  margin-top: 32px;
  padding: 24px;
  background: #f7fbf8;
  border: 1px solid var(--nf-line);
  border-radius: 14px;
}
.nf-next__title {
  margin-bottom: 6px;
  font-size: 17px;
  font-weight: 800;
  color: var(--nf-green);
}
.nf-next__desc {
  margin-bottom: 18px;
  font-size: 13px;
  color: var(--nf-muted);
}
.nf-next__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.nf-next__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}
.nf-next__level {
  flex: none;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 800;
  border-radius: 999px;
}
.nf-next__level--now {
  color: #fff;
  background: #c0392b;
}
.nf-next__level--soon {
  color: #8a5200;
  background: #fdf0dc;
}
.nf-next__level--later {
  color: var(--nf-muted);
  background: #eef1f4;
}
.nf-next__name {
  margin-bottom: 4px;
  font-size: 14px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-next__detail {
  font-size: 13px;
  line-height: 1.7;
  color: #4a5a50;
}

@media (max-width: 540px) {
  .nf-next {
    padding: 18px 14px;
  }
  .nf-next__item {
    flex-direction: column;
    gap: 8px;
  }
}

/* ===== 약관 · 방침 문서 ===== */
.nf-alert--warn {
  color: #8a6100;
  background: #fff6e0;
}
.nf-alert--warn a {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}

.legal-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}
.legal-tabs__item {
  padding: 7px 13px;
  font-size: 13px;
  font-weight: 600;
  color: var(--nf-muted);
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 999px;
}
.legal-tabs__item.is-active {
  color: #fff;
  background: var(--nf-green);
  border-color: var(--nf-green);
}

.legal-doc__meta {
  padding-bottom: 14px;
  margin-bottom: 18px;
  font-size: 12px;
  color: var(--nf-muted);
  border-bottom: 1px solid var(--nf-line);
}
/* 본문은 평문이다. 줄바꿈을 그대로 살리고 태그는 해석하지 않는다. */
.legal-doc__body {
  font-size: 14px;
  line-height: 1.9;
  color: #3c4c42;
  white-space: pre-wrap;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.legal-history {
  margin-top: 18px;
  padding: 16px 18px;
  background: #f7f9f8;
  border: 1px solid var(--nf-line);
  border-radius: 12px;
}
.legal-history__title {
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 800;
  color: var(--nf-text);
}
.legal-history li {
  font-size: 13px;
  line-height: 1.9;
}
.legal-history a {
  display: inline-block;
  padding: 7px 0;
  color: var(--nf-muted);
  text-decoration: underline;
}

/* ===== 동의 체크박스 (회원가입 / 입점문의) ===== */
.nf-consent {
  padding: 16px;
  margin-bottom: 20px;
  background: #f7f9f8;
  border: 1px solid var(--nf-line);
  border-radius: 12px;
}
.nf-consent__all {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 12px;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 800;
  color: var(--nf-text);
  cursor: pointer;
  border-bottom: 1px solid var(--nf-line);
}
.nf-consent__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  font-size: 13px;
  line-height: 1.5;
  color: #4a5a50;
}
.nf-consent__row label {
  flex: 1;
  cursor: pointer;
}
.nf-consent__row .nf-consent__req {
  font-weight: 700;
  color: var(--nf-danger);
}
.nf-consent__view {
  flex-shrink: 0;
  /* 손가락으로 누르는 링크다. 글자만 두면 18px이라 눌리지 않는다 (최소 32px). */
  padding: 8px 2px;
  font-size: 12px;
  color: var(--nf-muted);
  text-decoration: underline;
}
.nf-consent input[type='checkbox'] {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  accent-color: var(--nf-green);
}

/* ===== 공통 푸터 ===== */
.nf-footer {
  padding: 28px 16px 40px;
  margin-top: 40px;
  background: #f4f6f5;
  border-top: 1px solid var(--nf-line);
}
/* 관리자·공급업체 콘솔은 사이드바 전체화면 레이아웃이라 푸터를 붙이지 않는다. */
.admin-wrap + .nf-footer,
.supplier-wrap + .nf-footer {
  display: none;
}
.nf-footer__inner {
  max-width: 1400px;
  margin: 0 auto;
}
.nf-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 18px;
  margin-bottom: 8px;
  font-size: 13px;
}
.nf-footer__links a {
  display: inline-block;
  padding: 8px 0;
  color: #4a5a50;
}
.nf-footer__links a.is-strong {
  font-weight: 800;
  color: var(--nf-text);
}
.nf-footer__biz {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 14px;
  margin-bottom: 10px;
  font-size: 12px;
  line-height: 1.8;
  color: var(--nf-muted);
}
.nf-footer__biz--empty {
  color: var(--nf-danger);
}
.nf-footer__notice {
  max-width: 900px;
  margin-bottom: 12px;
  font-size: 12px;
  line-height: 1.8;
  color: var(--nf-muted);
  word-break: keep-all;
}
.nf-footer__notice b {
  color: #4a5a50;
}
.nf-footer__notice a {
  color: var(--nf-muted);
  text-decoration: underline;
}
/*
 * 저작권 경고 줄.
 *
 * 면책 고지(.nf-footer__notice)와 같은 크기로 두면 두 문단이 한 덩어리로 읽혀
 * 경고가 묻힌다. 위에 선을 하나 긋고 글자색을 한 단계 진하게 해서 따로 떼어 놓는다.
 */
.nf-footer__warn {
  max-width: 900px;
  margin-bottom: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--nf-line, #e3e8e5);
  font-size: 12px;
  line-height: 1.8;
  color: #6a7770;
  word-break: keep-all;
}

.nf-footer__copy {
  font-size: 12px;
  color: #9aa7a0;
}

@media (max-width: 540px) {
  .nf-footer {
    padding: 22px 14px 32px;
  }
  .legal-doc__body {
    font-size: 13px;
    line-height: 1.85;
  }
}

/* ===== 관리자 · 약관 · 정책 ===== */
.admin-legal-card {
  padding: 20px;
  margin-bottom: 18px;
  background: #fff;
  border-radius: 10px;
  box-shadow: rgba(18, 40, 28, 0.05) 0 6px 20px;
}
.admin-legal-card__head {
  margin-bottom: 16px;
}
.admin-legal-card__title {
  margin-bottom: 6px;
  font-size: 15px;
  font-weight: 800;
  color: #16271e;
}
.admin-legal-card__desc {
  font-size: 12.5px;
  line-height: 1.7;
  color: #7a8a80;
  word-break: keep-all;
}
.admin-legal-card__saved {
  margin-right: auto;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--nf-green);
}
.admin-legal-card .admin-table-card {
  box-shadow: none;
  border: 1px solid var(--nf-line);
}

.admin-biz-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 16px;
}

.admin-row--legal {
  grid-template-columns: 3fr 1fr 1.2fr 0.8fr 1.1fr;
}
.admin-row--consent {
  grid-template-columns: 1.6fr 1.6fr 0.6fr 0.7fr 1fr;
}
.admin-legal__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--nf-text);
}
.admin-legal__summary {
  margin-top: 3px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--nf-muted);
  word-break: keep-all;
}
.admin-legal__warn {
  color: var(--nf-danger);
}
.admin-empty {
  padding: 24px 0;
  font-size: 13px;
  color: var(--nf-muted);
  text-align: center;
}

/* 약관 본문은 길다. 편집창을 넉넉히 준다. */
.nf-textarea--doc {
  min-height: 340px;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.75;
}

@media (max-width: 900px) {
  .admin-biz-grid {
    grid-template-columns: 1fr;
  }
}

/* 시안의 관리자 표와 같은 767px 기준으로 한 줄씩 쌓고 항목명을 앞에 붙인다. */
@media (max-width: 767px) {
  .admin-row--legal,
  .admin-row--consent {
    grid-template-columns: 1fr;
  }
  .admin-row--legal > [data-label],
  .admin-row--consent > [data-label] {
    padding-top: 4px;
    text-align: left !important;
  }
  .admin-row--legal > [data-label]::before,
  .admin-row--consent > [data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 4px;
    font-size: 11px;
    font-weight: 700;
    color: #9aa89f;
  }
}

/* ===================================================================
   착지가 · 등급 · 산지            (2026-08-13)
   =================================================================== */

/* ===== 전광판 필터 바 ===== */
/* 수량 · 등급 · 산지. 정렬 버튼 줄 위에 붙는다. */
.nf-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  width: 100%;
  padding: 10px 0 4px;
  border-top: 1px solid var(--nf-line);
  margin-top: 8px;
}

.nf-qty {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--nf-text);
}
.nf-qty__label {
  font-weight: 700;
}
.nf-qty__input {
  width: 68px;
  height: 28px;
  padding: 0 8px;
  font-size: 12px;
  text-align: right;
  color: var(--nf-text);
  border: 1px solid var(--nf-line);
  border-radius: 6px;
  background: #fff;
}
.nf-qty__input:focus {
  outline: none;
  border-color: var(--nf-green);
}
.nf-qty__unit {
  color: var(--nf-muted);
}
.nf-qty__hint {
  font-size: 11px;
  color: var(--nf-muted);
  letter-spacing: -0.2px;
}

.nf-chip-group {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
}
.nf-chip-group__label {
  margin-right: 2px;
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-text);
}
.nf-chip {
  height: 26px;
  padding: 0 10px;
  font-size: 12px;
  color: var(--nf-muted);
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 999px;
  cursor: pointer;
}
.nf-chip:hover {
  border-color: var(--nf-green);
  color: var(--nf-green);
}
.nf-chip.is-on {
  color: #fff;
  background: var(--nf-green);
  border-color: var(--nf-green);
  font-weight: 700;
}

/* ===== 등급 뱃지 ===== */
/* 가격 바로 앞에 붙는다. 등급이 다르면 가격 차이는 비교 대상이 아니기 때문이다. */
.nf-grade {
  display: inline-block;
  margin-right: 4px;
  padding: 1px 5px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.5;
  vertical-align: middle;
  border-radius: 4px;
}
.nf-grade--green {
  color: #1d6b4a;
  background: #e6f4ec;
}
.nf-grade--blue {
  color: #245b8f;
  background: #e8f0f8;
}
.nf-grade--gray {
  color: #5c6b7a;
  background: #eef1f4;
}
.nf-grade--none {
  color: var(--nf-muted);
  background: #f4f6f5;
}

/* ===== 산지 ===== */
/* 수입산이 국내산처럼 보이면 안 되므로 색을 갈라 놓는다. */
.nf-origin {
  margin-top: 1px;
  font-size: 10px;
  letter-spacing: -0.3px;
}
.nf-origin--domestic {
  color: #5c7a68;
}
.nf-origin--import {
  font-weight: 700;
  color: #8a5200;
}
.nf-origin--unknown {
  color: var(--nf-muted);
}

/* ===== 착지 총액 ===== */
.nf-landed {
  margin-top: 2px;
  font-size: 10px;
  line-height: 1.35;
  color: var(--nf-text);
  letter-spacing: -0.3px;
}
.nf-landed b {
  font-weight: 700;
}
.nf-landed__detail {
  margin-left: 3px;
  color: var(--nf-muted);
}
.nf-landed__moq {
  display: block;
  font-style: normal;
  font-weight: 700;
  color: #8a5200;
}
/* 최소주문수량 때문에 수량이 올라간 칸은 총액이 커진다. 그 사실이 보여야 한다. */
.nf-landed--bumped {
  padding: 1px 4px;
  background: #fdf6e8;
  border-radius: 4px;
}

/* ===== 업체 배송비 정책 ===== */
/* 이건 숫자가 아니라 문장이다. 그런데 표 칸(.compare-table td)의
   white-space: nowrap을 물려받아 한 줄로 뻗고 있었다. 결과가 화면마다 달랐다:
     데스크톱 — 가장 긴 문장(280px)이 업체 칸을 293px까지 벌렸다.
                가격 칸이 113~155px인데 첫 칸만 두 배였다.
     모바일   — 칸 폭이 132px로 고정돼 있어 글자가 최대 154px 밖으로 삐져나갔다.
   줄바꿈을 허용하면 둘 다 사라진다. */
.nf-ship-policy {
  display: block;
  margin-top: 4px;
  font-size: 10px;
  line-height: 1.35;
  color: #5c7a68;
  letter-spacing: -0.3px;
  white-space: normal;
  /* 한국어는 단어 중간에서 끊으면 읽기 어렵다. 띄어쓰기에서만 넘긴다. */
  word-break: keep-all;
  overflow-wrap: anywhere;
}
/* '무료배송'과 '아직 안 넣음'은 정반대인데 둘 다 0원이다. 미입력은 미입력으로 보인다. */
.nf-ship-policy--unset {
  color: #b26a00;
  font-weight: 700;
}

/* ===== 공급업체 콘솔 — 상품 속성 줄 ===== */
.nf-attr-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
}
.nf-attr-select {
  height: 28px;
  padding: 0 6px;
  font-size: 11px;
  max-width: 118px;
}
.nf-attr-moq {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-attr-moq__input {
  width: 46px;
  height: 28px;
  padding: 0 6px;
  font-size: 11px;
  text-align: right;
}

.supplier-profile__biz {
  margin-top: 4px;
  font-size: 11px;
  color: var(--nf-muted);
  letter-spacing: -0.3px;
}
.supplier-profile__biz .admin-badge {
  margin-right: 4px;
}

/* ===== 공급업체 콘솔 — 가격 경쟁력 ===== */
.nf-rank-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.nf-rank-table {
  border-top: 1px solid var(--nf-line);
}
.nf-rank-table__row {
  display: grid;
  grid-template-columns: 2.2fr 1fr 1.1fr 1fr 1fr 1.3fr;
  gap: 10px;
  align-items: center;
  padding: 10px 4px;
  font-size: 13px;
  border-bottom: 1px solid var(--nf-line);
}
.nf-rank-table__row--head {
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-muted);
  background: #fafbfa;
}
.nf-rank-no {
  font-size: 15px;
  font-weight: 700;
  color: var(--nf-text);
}
.nf-rank-no.is-best {
  color: #1d6b4a;
}
.nf-rank-of {
  font-size: 11px;
  color: var(--nf-muted);
}
/* 공급가 순위와 착지가 순위가 다르면 배송비가 순위를 바꾸고 있다는 뜻이다. */
.nf-rank-landed {
  margin-top: 2px;
  font-size: 11px;
  font-weight: 700;
}
.nf-rank-landed.is-worse {
  color: var(--nf-danger);
}
.nf-rank-landed.is-better {
  color: #1d6b4a;
}
.nf-rank-gap {
  font-weight: 700;
  color: #8a5200;
}
.nf-rank-gap.is-best {
  color: #1d6b4a;
}
.nf-rank-gap em {
  font-style: normal;
  font-weight: 400;
  color: var(--nf-muted);
}
.nf-rank-warn {
  margin-top: 2px;
  font-size: 11px;
  color: var(--nf-danger);
}

/* ===== 모바일 ===== */
@media (max-width: 768px) {
  .nf-filter-bar {
    gap: 8px 12px;
  }
  .nf-qty__hint {
    display: none;
  }

  /* 표 형태를 유지하면 6열이 눌려 읽을 수 없다. 라벨을 붙인 목록으로 바꾼다. */
  .nf-rank-table__row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
  .nf-rank-table__row--head {
    display: none;
  }
  .nf-rank-table__row > div[data-label]::before {
    content: attr(data-label) ' ';
    margin-right: 6px;
    font-size: 11px;
    color: var(--nf-muted);
  }
}

@media (max-width: 540px) {
  /* 셀이 좁아 세 줄이 겹친다. 총액만 남기고 상세는 접는다. */
  .nf-landed__detail {
    display: block;
    margin-left: 0;
  }
  .nf-attr-select {
    max-width: 100%;
    flex: 1 1 100%;
  }
}

/* ===== 메인 상단 배너 배경 사진 =====
   퍼블리싱 산출물(style.css)의 .main-banner는 단색 그라데이션이다.
   그 파일을 고치지 않고 여기서 덮어쓴다 (app.css가 뒤에 로드된다).

   덮개는 초록이 아니라 중립 검정이다. 초록을 씌우면 사진 속 청과가
   전부 같은 색으로 물들어 무슨 사진인지 사라진다.
   좌→우 그라데이션도 쓰지 않는다. 한쪽만 진해지면 배너에 결이 생겨
   사진이 아니라 그 효과가 먼저 보인다. 전체를 고르게 덮고,
   흰 글자의 가독성은 글자 그림자로 따로 잡는다.
   마지막 단색은 사진을 못 받아왔을 때의 바탕이다. */
/* 사진 자체는 --hero-image로 뺐다.
   관리자가 올린 것이 있으면 app/page.tsx가 인라인으로 그 값을 얹고,
   없으면 여기 적힌 시안 사진이 쓰인다 — 지워도 첫 화면이 비지 않는다.
   움짤(GIF)이 올라와도 이 자리에 그대로 들어가 배경에서 재생된다. */
.main-banner {
  --hero-image: url('../images/main_banner_bg.jpg');
  background: linear-gradient(rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.42)),
    var(--hero-image) no-repeat center / cover,
    rgb(15, 43, 31);
  padding: 24px;
}

/* 고르게 덮은 만큼 밝은 과일 위에서는 덮개만으로 부족하다.
   글자 자체에 그림자를 줘서 어디에 얹히든 읽히게 한다. */
.main-banner__top,
.main-banner__title,
.main-banner__desc {
  text-shadow: rgba(0, 0, 0, 0.55) 0 1px 6px;
}

/* '오늘 · 실시간 갱신' 칸.
   시안의 11px는 사진 위에 얹히는 흰 글자치고 너무 작아서, 이 화면이 내세우는
   '지금 값'이라는 사실이 제일 작은 글자로 적혀 있었다. 그래서 한 번 키웠는데,
   이번에는 배지가 커진 만큼 아래 제목이 배너 가운데에서 밀려났다.

   배지가 글 위에 있는 한 묶음을 가운데에 놓아도 글은 배지 높이의 절반만큼 내려앉는다.
   묶음을 그 절반만큼 끌어올려도 봤지만, 이번에는 배지가 위 테두리에 붙어 버렸다 —
   가운데를 얻고 위 여백을 잃은 셈이다.

   그래서 배지를 도로 줄인다. 작아진 만큼 글이 밀리는 양도 줄어 가운데에 가까워지고,
   배너 높이도 위쪽 여백도 그대로다. 배지는 읽히기만 하면 되고 주인공은 제목이다.
   시안의 11px보다는 크게 둔다 — 사진 위 흰 글자라 그 아래로 내리면 다시 안 읽힌다. */
.main-banner__top {
  gap: 7px;
  padding: 6px 13px;
  font-size: 12.5px;
  border-radius: 8px;
  border-color: rgba(255, 255, 255, 0.34);
  /* 사진 위에서 테두리만으로는 칸의 경계가 흐리다. 어두운 판을 얇게 깐다. */
  background: rgba(0, 0, 0, 0.3);
  margin-bottom: 12px;
}

.main-banner__top::before {
  width: 7px;
  height: 7px;
}

/* 반투명 흰색(0.05)만으로는 사진 위에서 숫자가 묻힌다.
   어두운 판을 깔고 흐림을 더해 사진과 분리한다. */
.main-banner__right li {
  background: rgba(0, 0, 0, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}

/*
 * 카테고리 아이콘을 이모지로 넣었을 때.
 *
 * 그림(.category__icon)과 같은 자리를 차지해야 이모지를 쓰는 카테고리와 그림을 쓰는
 * 카테고리가 섞여도 이름 시작점이 어긋나지 않는다.
 */
.category__icon--emoji {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  line-height: 1;
}

/*
 * 히어로 제목·설명을 왼쪽에 세우고, 세로로는 배너 한가운데에 맞춘다.
 *
 * 격자로 칸을 나눠 보았지만 세로 가운데가 잡히지 않았다. 배지와 글이 각각 제 줄을
 * 차지하니 남는 높이가 두 줄에 나뉘어, 글은 '아래 줄의 가운데'에 설 뿐이었다.
 *
 * 그래서 배지와 글을 한 묶음(.main-banner__lead)으로 싸고, 배너는 그 묶음과 숫자
 * 두 덩이만 세운다. 덩이가 둘뿐이면 세로 가운데는 align-items: center 한 줄로 끝난다.
 * 왼쪽 정렬도 저절로 지켜진다 — 묶음 안에서 배지와 글이 같은 선에서 시작한다.
 */
.main-banner__lead {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

/* 859px 기준인 이유: 집계 숫자가 글 아래로 내려오기 시작하는 폭이 860px다
   (style.css의 글자 크기 분기인 768px가 아니다). */
@media (max-width: 859px) {
  .main-banner {
    padding: 20px 18px;
  }

  /*
   * 글은 좁은 화면에서도 왼쪽에 세운다                   (2026-09-01)
   *
   * 08-31에 배지·제목·설명까지 가운데로 모아 봤지만, 두세 줄로 접히는 문장은
   * 가운데 정렬하면 줄마다 시작점이 달라져 눈이 매 줄 새 자리를 찾아야 한다.
   * 왼쪽에 세워 두면 넓은 화면과 읽는 방식도 같아진다.
   *
   * 가운데로 모으는 것은 아래로 내려온 숫자 세 칸뿐이다 — 그건 문장이 아니라
   * 길이가 고른 칸이라, 모아 놓아야 한 줄로 읽힌다.
   */
  .main-banner {
    justify-content: flex-start;
    text-align: left;
  }

  .main-banner__lead {
    align-items: flex-start;
  }

  /* 숫자가 글 아래로 내려오면 그것만 가운데로 모은다. */
  .main-banner__right {
    justify-content: center;
    width: 100%;
  }
}

/* ===================================================================
   전광판 툴바 줄바꿈                (2026-08-14)
   =================================================================== */

/* .table-toolbar(style.css)는 시안에서 '제목 + 정렬 버튼' 둘만 한 줄에 놓는
   자리였다. 08-13에 '시세표 받기' · 주문 수량 · 등급 · 산지가 들어와 넣을 것이
   넷이 됐는데, 줄바꿈은 모바일(≤768px)에만 걸려 있었다. 그래서 데스크톱에서는
   넷이 한 줄에 눌려 제목이 세 줄로 쪼개지고 'kg·개당 낮은순' 같은 정렬 버튼이
   글자 단위로 접혔다.

   세 줄로 나눈다:
     [제목 ............ 시세표 받기]
     [주문 수량 · 등급 · 산지]
     [.................... 정렬] */
.table-toolbar {
  flex-wrap: wrap;
  align-items: flex-start;
  row-gap: 8px;
}

/* 제목이 첫 줄의 남는 폭을 가져간다. min-width:0이 없으면 flex 항목이
   글자 길이만큼 버텨 옆의 버튼을 밀어낸다. */
.table-toolbar__title {
  flex: 1 1 260px;
  min-width: 0;
  line-height: 1.5;
}

/* 안내 문장이 길어 제목과 같은 줄에 두면 제목이 쪼개진다. 아래로 내린다. */
.nf-toolbar-hint {
  display: block;
  margin: 3px 0 0;
}

/* '시세표 받기'는 첫 줄 오른쪽 끝. 줄어들지 않는다. */
.nf-toolbar-actions {
  flex: 0 0 auto;
}

/* 필터 줄은 한 줄을 통째로 쓴다(등급 · 산지 · 업체 · 정렬). */
.nf-filter-bar {
  flex: 1 1 100%;
}

/* 규격 헤더의 체크박스를 뺐다. 라벨만 남아도 가운데로 오게 한다. */
.col-label {
  align-items: center;
}

/* ===================================================================
   기획전(관)  /nf/hall/[slug]                        (2026-08-14)
   업체가 주인공인 화면이라 전광판의 표가 아니라 카드로 늘어놓는다.
   =================================================================== */

.nf-hall__head {
  margin: 6px 0 18px;
}

.nf-hall__title {
  font-size: 22px;
  font-weight: bold;
  color: #1c3b2e;
}

.nf-hall__sub {
  margin-top: 6px;
  font-size: 14px;
  color: #5b6b62;
}

.nf-hall__meta {
  margin-top: 8px;
  font-size: 12px;
  color: #9aa89f;
}

.nf-hall__empty {
  padding: 40px 0;
  text-align: center;
  font-size: 14px;
  color: #9aa89f;
}

.nf-hall__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
}

.nf-hall-card {
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 14px;
  padding: 16px;
  box-shadow: rgba(18, 40, 28, 0.05) 0px 6px 20px;
}

.nf-hall-card__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nf-hall-card__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: 12px;
  font-size: 16px;
  font-weight: bold;
  color: #1c3b2e;
  background-color: #eef3ea;
}

.nf-hall-card__name {
  font-size: 15px;
  font-weight: bold;
  color: #1c3b2e;
}

.nf-hall-card__region {
  margin-top: 2px;
  font-size: 12px;
  color: #9aa89f;
}

.nf-hall-card__items {
  margin-top: 10px;
  font-size: 12px;
  color: #5b6b62;
}

.nf-hall-card__products {
  margin-top: 12px;
  border-top: 1px solid #f2f4ef;
}

.nf-hall-card__products li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid #f2f4ef;
}

.nf-hall-card__products li.is-soldout {
  opacity: 0.55;
}

.nf-hall-card__none {
  justify-content: center !important;
  font-size: 12px;
  color: #9aa89f;
}

.nf-hall-card__pname {
  min-width: 0;
  font-size: 13px;
  color: #1c3b2e;
}

.nf-hall-card__pname span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nf-hall-card__pname em {
  font-size: 11px;
  font-style: normal;
  color: #9aa89f;
}

.nf-hall-card__pprice {
  flex-shrink: 0;
  text-align: right;
  font-size: 13px;
  font-weight: bold;
  color: #1c3b2e;
}

.nf-hall-card__pprice a {
  color: #15924c;
}

.nf-hall-card__pprice em {
  display: block;
  font-size: 11px;
  font-weight: normal;
  font-style: normal;
  color: #9aa89f;
}

.nf-hall-card__more {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  margin-top: 14px;
  border: 1px solid #d9dcd3;
  border-radius: 9px;
  font-size: 13px;
  font-weight: bold;
  color: #1c3b2e;
}

@media (max-width: 600px) {
  .nf-hall__grid {
    grid-template-columns: 1fr;
  }
}

/* ===== 알림 배지 (모바일 드로어) =====
   데스크톱 배지(.nf-bell__dot)와 같은 모양·같은 자리다. 목록 글꼴이 조금 커서
   크기만 맞춰 둔다. */
.nf-drawer__badge {
  display: inline-block;
  min-width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0 5px;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  color: #fff;
  text-align: center;
  vertical-align: middle;
  background: #c0392b;
  border-radius: 999px;
}

/* ===== 실시간 알림 팝업 =====
   목표가에 닿았다는 소식은 몇 분이면 값이 달라진다. 알림함을 열어봐야 아는 대신
   보고 있는 화면 오른쪽 아래로 바로 띄운다. */
.nf-toasts {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 9000;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 320px;
  max-width: calc(100vw - 32px);
}

.nf-toasts__bar {
  display: flex;
  justify-content: flex-end;
}

.nf-toasts__sound {
  padding: 4px 10px;
  font-size: 11px;
  color: #4a5a50;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid #d9dcd3;
  border-radius: 999px;
  cursor: pointer;
}

.nf-toast {
  position: relative;
  padding: 14px 34px 14px 16px;
  background: #fff;
  border: 1px solid #d9dcd3;
  border-left: 4px solid #15924c;
  border-radius: 10px;
  box-shadow: 0 10px 24px rgba(28, 59, 46, 0.18);
  animation: nf-toast-in 0.22s ease-out;
}

@keyframes nf-toast-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 팝업이 뜰 때마다 미끄러져 들어오는 것을 불편해하는 사람이 있다. 설정을 따른다. */
@media (prefers-reduced-motion: reduce) {
  .nf-toast,
  .nf-snack {
    animation: none;
  }
}

.nf-toast__close {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 24px;
  height: 24px;
  font-size: 18px;
  line-height: 1;
  color: #9aa89f;
  background: none;
  border: 0;
  cursor: pointer;
}

.nf-toast__tag {
  margin-bottom: 4px;
  font-size: 11px;
  font-weight: bold;
  color: #15924c;
}

.nf-toast__title {
  font-size: 15px;
  font-weight: bold;
  color: #1c3b2e;
}

.nf-toast__body {
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.5;
  color: #4a5a50;
}

.nf-toast__go {
  margin-top: 10px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: bold;
  color: #fff;
  background: #15924c;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}

@media (max-width: 600px) {
  .nf-toasts {
    right: 12px;
    left: 12px;
    bottom: 12px;
    width: auto;
  }
}

/* ===== 전광판 실시간 변동 팝업 =====
   값이 바뀌는 순간을 화면 왼쪽 아래로 흘려보낸다.
   알림 팝업(.nf-toasts)이 오른쪽 아래를 쓰고 있어 반대편에 세운다 — 겹치면 둘 다 못 읽는다.
   여기 뜨는 것은 '읽고 판단할 내용'이 아니라 '지금 움직였다'는 신호라서,
   알림 팝업보다 작고 낮은 대비로 둔다. 시선을 뺏으면 정작 표를 못 본다. */
.live-toasts {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 8900;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 292px;
  max-width: calc(100vw - 32px);
  pointer-events: none;
}

.live-toasts > * {
  pointer-events: auto;
}

.live-toasts__bar {
  display: flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  padding: 3px 10px 3px 8px;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid #d9dcd3;
  border-radius: 999px;
}

/* 켜져 있다는 것 자체를 보이는 점. 값이 안 바뀌는 시간에도 화면이 살아 있음을 알린다. */
.live-toasts__pulse {
  width: 7px;
  height: 7px;
  background: #e0392b;
  border-radius: 50%;
  animation: live-pulse 1.4s ease-in-out infinite;
}

@keyframes live-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.35;
    transform: scale(0.7);
  }
}

.live-toasts__label {
  font-size: 11px;
  font-weight: bold;
  color: #4a5a50;
  letter-spacing: 0.02em;
}

.live-toasts__sound {
  padding: 0 2px;
  font-size: 12px;
  line-height: 1;
  background: none;
  border: 0;
  cursor: pointer;
}

.live-toast {
  display: block;
  width: 100%;
  padding: 9px 12px;
  text-align: left;
  background: #fff;
  border: 1px solid #d9dcd3;
  border-left: 3px solid #9aa89f;
  border-radius: 9px;
  box-shadow: 0 8px 20px rgba(28, 59, 46, 0.16);
  cursor: pointer;
  animation: live-toast-in 0.24s ease-out;
}

@keyframes live-toast-in {
  from {
    opacity: 0;
    transform: translateX(-12px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* 왼쪽 선 색으로 무슨 일인지 가른다. 글자를 읽기 전에 눈에 먼저 들어오는 정보다.
   내림이 파랑인 것은 표의 등락 표시(.is-down)와 같은 약속이다. */
.live-toast--down {
  border-left-color: #1f6fd0;
}
.live-toast--up {
  border-left-color: #c0392b;
}
.live-toast--new {
  border-left-color: #15924c;
}
.live-toast--ship,
.live-toast--deadline {
  border-left-color: #d08a1f;
}

.live-toast__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 3px;
}

.live-toast__tag {
  font-size: 10px;
  font-weight: bold;
  color: #6a7770;
}

.live-toast__at {
  font-size: 10px;
  color: #9aa89f;
}

.live-toast__title {
  display: block;
  font-size: 12px;
  color: #4a5a50;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-toast__text {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  font-weight: bold;
  color: #1c3b2e;
}

/* 방금 값이 바뀐 칸.
   팝업은 화면 구석에 뜨므로 '어느 칸인지'까지는 말해주지 못한다.
   표가 조용히 갱신되기만 하면 새로고침한 것과 구분이 안 되므로, 그 칸만 잠깐 물들인다.
   시간(2.6초)은 components/PriceBoard.tsx의 FLASH_MS와 맞춰 둔다. */
.is-live-flash {
  animation: live-flash 2.6s ease-out;
}

@keyframes live-flash {
  0% {
    background-color: rgba(255, 214, 102, 0.85);
  }
  35% {
    background-color: rgba(255, 214, 102, 0.55);
  }
  100% {
    background-color: transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .live-toast {
    animation: none;
  }
  .live-toasts__pulse {
    animation: none;
  }
  /* 반짝임 자체는 남긴다 — 어느 칸이 바뀌었는지 알리는 유일한 표시다.
     대신 번쩍이지 않고 한 번 물들었다 빠지게 한다. */
  .is-live-flash {
    animation: live-flash 2.6s linear;
  }
}

/* 배너 '실시간 갱신' 옆의 점.
   시각(components/LiveClock.tsx)은 30초마다 움직이지만, 분이 안 바뀌면 화면은 그대로다.
   점이 뛰고 있으면 그 사이에도 화면이 값을 확인하고 있다는 것이 보인다.
   위 .live-toasts__pulse와 같은 동작을 쓴다 — 한 화면 안에서 '살아 있음'의 표시는 하나여야 한다. */
.main-banner__top::before {
  animation: live-pulse 1.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .main-banner__top::before {
    animation: none;
  }
}

@media (max-width: 600px) {
  .live-toasts {
    right: 12px;
    left: 12px;
    /* 알림 팝업과 같은 구석에 몰리지 않도록 한 층 위로 올린다. */
    bottom: 96px;
    width: auto;
  }
}

/* ===================================================================
   쪽지함 (/messages)
   왼쪽이 대화 목록(받은 것·보낸 것을 함께), 오른쪽이 대화창이다.
   =================================================================== */
.nf-msg {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 16px;
  align-items: start;
  margin-top: 18px;
}

.nf-msg__side {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 14px;
}
.nf-msg__side-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.nf-msg__blocklink {
  padding: 6px 10px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--nf-muted);
  background: none;
  border: 1px solid var(--nf-line);
  border-radius: 999px;
  cursor: pointer;
}
.nf-msg__blocklink:hover {
  color: var(--nf-text);
}

.nf-msg__blocks {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  background: #f7faf8;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}
.nf-msg__block-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.nf-msg__block-row b {
  display: block;
  font-size: 13px;
  color: var(--nf-text);
}
.nf-msg__block-row span {
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-msg__block-row .nf-btn {
  flex: none;
  padding: 6px 10px;
  font-size: 12px;
}

.nf-msg__list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 62vh;
  overflow-y: auto;
}
/* 갈래를 바꿨는데 비어 있을 때의 한 줄. 목록 자리를 그대로 지킨다. */
.nf-msg__list > .nf-hint {
  margin-top: 0;
  padding: 24px 8px;
  text-align: center;
}

.nf-msg__conv {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  padding: 10px 12px;
  font-family: inherit;
  text-align: left;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
  cursor: pointer;
}
.nf-msg__conv:hover {
  background: #f7faf8;
}
.nf-msg__conv.is-active {
  border-color: var(--nf-green);
  background: var(--nf-green-soft);
}
.nf-msg__conv.is-unread .nf-msg__conv-name {
  color: var(--nf-green);
}
.nf-msg__conv-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.nf-msg__conv-name {
  font-size: 13px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-msg__conv-date {
  flex: none;
  font-size: 11px;
  color: var(--nf-muted);
}
/* 마지막 한 줄만 보인다. 길이가 제각각이면 목록의 리듬이 무너진다. */
.nf-msg__conv-body {
  overflow: hidden;
  font-size: 12px;
  line-height: 1.5;
  color: #4a5a50;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nf-msg__conv-body em {
  font-style: normal;
  color: var(--nf-muted);
}
.nf-msg__conv-foot {
  display: flex;
  align-items: center;
  gap: 6px;
}
.nf-msg__conv-role {
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-msg__blocked-tag {
  display: inline-block;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 700;
  color: var(--nf-danger);
  vertical-align: 2px;
  background: #fdf3f2;
  border: 1px solid #eccac5;
  border-radius: 999px;
}
/* 대화창 머리에서는 이름 옆에 붙는다. */
.nf-msg__head-name .nf-msg__blocked-tag {
  margin-left: 6px;
  font-size: 11px;
}
.nf-msg__conv-badge {
  min-width: 18px;
  margin-left: auto;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 800;
  color: #fff;
  text-align: center;
  background: var(--nf-danger);
  border-radius: 999px;
}

/* ===== 오른쪽: 대화창 ===== */
.nf-msg__main {
  display: flex;
  flex-direction: column;
  min-height: 520px;
  background: #fff;
  border: 1px solid var(--nf-line);
  border-radius: 14px;
}
.nf-msg__empty {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  font-size: 13px;
  color: var(--nf-muted);
  text-align: center;
}

.nf-msg__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--nf-line);
}
/* 목록으로 돌아가는 화살표는 좁은 화면에서만 쓸모가 있다(넓으면 목록이 옆에 있다). */
.nf-msg__back {
  display: none;
  padding: 0 6px;
  font-size: 22px;
  line-height: 1;
  color: var(--nf-text);
  background: none;
  border: 0;
  cursor: pointer;
}
.nf-msg__head-name {
  min-width: 0;
}
.nf-msg__head-name b {
  display: block;
  font-size: 15px;
  font-weight: 800;
  color: var(--nf-text);
}
.nf-msg__head-name span {
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-msg__head-actions {
  display: flex;
  gap: 6px;
  margin-left: auto;
}
.nf-msg__head-actions .nf-btn {
  padding: 6px 10px;
  font-size: 12px;
}

.nf-msg__blocked-note {
  padding: 12px 14px;
  font-size: 12px;
  line-height: 1.6;
  color: #7a4a44;
  background: #fdf3f2;
  border: 1px solid #eccac5;
  border-radius: 10px;
}
.nf-msg__blocked-note b {
  color: var(--nf-danger);
}

.nf-msg__thread {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 10px;
  max-height: 52vh;
  padding: 16px;
  overflow-y: auto;
}

.nf-bubble {
  max-width: 78%;
  padding: 10px 12px;
  background: #f2f5f3;
  border-radius: 12px;
}
/* 내가 쓴 것은 오른쪽에 붙여 딥그린으로. 누가 한 말인지 색만 보고 알 수 있어야 한다. */
.nf-bubble.is-mine {
  align-self: flex-end;
  color: #fff;
  background: var(--nf-green);
}
.nf-bubble__body {
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.nf-bubble__foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  font-size: 11px;
  color: var(--nf-muted);
}
.nf-bubble.is-mine .nf-bubble__foot {
  justify-content: flex-end;
  color: rgba(255, 255, 255, 0.72);
}
.nf-bubble__read {
  font-weight: 700;
}

.nf-msg__form {
  padding: 14px 16px;
  border-top: 1px solid var(--nf-line);
}
.nf-msg__form .nf-textarea {
  min-height: 72px;
}
.nf-msg__form-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 8px;
}
.nf-msg__form-foot .nf-hint {
  margin-top: 0;
}

/* ===== 새 쪽지 모달의 검색 결과 ===== */
.nf-msg__picker-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* 결과가 없을 때도 자리를 비워둔다 — 한 줄 나올 때마다 모달이 커졌다 작아지면
     고르려던 줄이 그 사이에 움직인다. */
  min-height: 168px;
  max-height: 320px;
  margin-top: 12px;
  overflow-y: auto;
}
/* 검색 결과가 맨텍스트로 놓이면 누를 수 있는 것인지 읽히지 않는다. */
.nf-msg__picker-list .nf-search__row {
  flex: none;
  padding: 10px 12px;
  border: 1px solid var(--nf-line);
  border-radius: 10px;
}

@media (max-width: 900px) {
  /*
   * 한 화면에 하나씩. 평소에는 목록만 보이고,
   * .is-thread(대화를 열었을 때)면 대화창으로 바뀐다.
   * 좁은 화면에서 300px 목록과 대화창을 나란히 두면 둘 다 못 쓴다.
   */
  .nf-msg {
    grid-template-columns: 1fr;
  }
  .nf-msg.is-thread .nf-msg__side {
    display: none;
  }
  .nf-msg:not(.is-thread) .nf-msg__main {
    display: none;
  }
  /* 목록으로 돌아갈 길이 이때만 필요하다(넓은 화면에서는 목록이 옆에 그대로 있다). */
  .nf-msg__back {
    display: block;
  }
  .nf-msg__main {
    min-height: 420px;
  }
  .nf-msg__list {
    max-height: none;
  }
  .nf-msg__thread {
    max-height: 60vh;
  }
  .nf-bubble {
    max-width: 88%;
  }
}

/* ===================================================================
   메인 히어로 배경 교체            (사이트 설정)
   ===================================================================
   시안 사진이 CSS에 박혀 있어서 제철·행사 때마다 배포가 필요했다.
   설정 화면에서 갈아끼울 수 있게 하면서, 지금 무엇이 걸려 있는지도 같이 보인다 —
   목록에 '설정됨'이라고만 적혀 있으면 결국 첫 화면을 열어 확인하게 된다. */
.admin-hero {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 20px;
  margin-bottom: 16px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: rgba(18, 40, 28, 0.05) 0 6px 20px;
}

.admin-hero__label {
  margin-bottom: 4px;
  font-size: 14px;
  font-weight: 800;
  color: #14241c;
}

.admin-hero__desc {
  font-size: 12.5px;
  line-height: 1.55;
  color: #6b7785;
  word-break: keep-all;
}

.admin-hero__err {
  margin-top: 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: #c0392b;
}

.admin-hero__side {
  flex-shrink: 0;
  width: 220px;
  text-align: center;
}

/* 첫 화면과 같은 가로세로비로 보여준다. 정사각형으로 줄이면 실제로 어디가 잘리는지
   가늠할 수 없어서, 걸어보고 나서야 인물이 잘린 것을 알게 된다. */
.admin-hero__thumb {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 5;
  object-fit: cover;
  background-color: #eef0f2;
  border: 1px solid #e3e8e5;
  border-radius: 8px;
}

.admin-hero__state {
  margin-top: 6px;
  font-size: 11.5px;
  color: #7a8896;
}

.admin-hero__actions {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
}

/* 파일 고르기는 <label>이라 버튼 모양을 따로 맞춘다. */
.admin-hero__actions label {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

.admin-hero__actions .is-busy {
  opacity: 0.6;
  cursor: default;
}

@media (max-width: 700px) {
  .admin-hero {
    flex-direction: column;
  }
  .admin-hero__side {
    width: 100%;
  }
}

/* ===================================================================
   공급업체 — 가격 확인 버튼
   ===================================================================
   값이 그대로여도 '오늘도 이 가격이 맞다'를 남기는 버튼이다.
   신선도 뱃지('3일 전 확인') 바로 옆에 붙여, 오래됐다는 것을 본 그 자리에서
   바로 고칠 수 있게 한다.

   버튼처럼 크게 만들지 않는 이유: 이 줄에서 중요한 것은 공급가·출고상태이고
   이것은 그 옆의 거드는 동작이다. 뱃지와 같은 높이의 작은 글씨로 둔다. */
.supplier-confirm-btn {
  margin-left: 5px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 700;
  color: #4a5a50;
  background: #fff;
  border: 1px solid #d9dcd3;
  border-radius: 999px;
  cursor: pointer;
  vertical-align: middle;
}

.supplier-confirm-btn:hover {
  color: #15924c;
  border-color: #15924c;
}

/* 비활성 버튼이 눌리는 것처럼 보이지 않게 한다(전체 가격 확인). */
.supplier-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

/* 닫을 수 있는 안내줄.
   일괄 등록 결과처럼 '다 보고 나면 치우고 싶은' 안내에 쓴다.
   ✕를 글 흐름 안에 두면 줄이 바뀔 때 따라 움직이므로 오른쪽 끝에 붙여 고정한다. */
.nf-alert--closable {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.nf-alert__close {
  flex-shrink: 0;
  padding: 0 2px;
  font-size: 14px;
  line-height: 1.4;
  color: inherit;
  background: none;
  border: 0;
  opacity: 0.65;
  cursor: pointer;
}

.nf-alert__close:hover {
  opacity: 1;
}

/* 예약 모달의 항목 켜기.
   '무엇을 바꿀지'를 항목마다 고르므로 체크와 이름표가 한 줄로 붙어야 한다. */
.nf-check {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  cursor: pointer;
}

.nf-check input {
  width: 15px;
  height: 15px;
  cursor: pointer;
}

/* 끈 항목은 값이 남아 있어도 지금은 쓰이지 않는다는 것을 보인다. */
.nf-input:disabled,
.nf-select:disabled {
  color: #9aa89f;
  background: #f4f6f4;
  cursor: default;
}

/* 판매상태 열의 예약 버튼.
   가격 칸의 것과 같은 시계 아이콘이지만, 이쪽은 두 버튼(판매중·품절) 뒤에 붙으므로
   왼쪽 여백만 두어 한 묶음으로 보이게 한다. */
.supplier-schedule-btn--status {
  margin-left: 4px;
}

/* 일괄 등록 미리보기의 예약 줄.
   지금 값과 섞이면 '지금 이 가격'으로 읽히므로 한 단 낮춰 따로 보이게 한다. */
.nf-bulk-row__sched {
  margin-top: 2px;
  font-size: 12px;
  color: #8a6d1f;
}

/* ===================================================================
   내 상품 관리 표 — 판매상태 칸 넓히기
   ===================================================================
   판매상태 칸에 예약(시계) 버튼이 하나 늘면서, 140px짜리 칸에 네 개
   (판매중 · 품절 · 예약 · 삭제)가 들어가게 됐다. 칸을 넘친 버튼이 옆의 발주마감을
   덮어 07:40 같은 값이 가려지고 삭제 버튼은 오른쪽에서 잘렸다.

   칸을 넓히고, 그래도 모자라면 옆으로 삐져나가는 대신 아래로 접히게 한다 —
   좁은 화면에서 다시 같은 일이 생기지 않게 하는 쪽이 폭을 한 번 더 키우는 것보다 낫다.
   212px = 판매중(56) + 품절(46) + 예약(36) + 삭제(47) + 사이 간격 — 실제로 재서 맞춘 값이다.

   미디어쿼리 안에 두는 이유: 이 파일은 style.css보다 나중에 읽힌다.
   그냥 .supplier-row로 쓰면 style.css의 @media (max-width: 720px)까지 덮어써서,
   폰에서 한 줄에 하나씩 쌓이던 배치가 다시 다섯 칸 가로 배치로 돌아간다.
   (기본 격자는 style.css의 .supplier-row) */
@media (min-width: 721px) {
  .supplier-row {
    grid-template-columns:
      minmax(220px, 4.4fr)
      minmax(170px, 1.75fr)
      minmax(130px, 1.3fr)
      minmax(92px, 0.8fr)
      minmax(212px, 1.8fr);
  }
}

.supplier-col-status {
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 4px;
}

/* 판매중·품절은 한 덩어리로 붙어 있어야 '둘 중 하나'로 읽힌다. 접힐 때도 같이 접힌다. */
.supplier-status-set {
  flex-shrink: 0;
}

/* 좁은 화면에서 표가 잘리지 않게.
   칸이 다섯이라 폭이 모자라면 오른쪽(판매상태·삭제)부터 카드 밖으로 밀려나 잘렸다.
   720px 아래로는 원래 한 줄에 하나씩 쌓이므로(style.css) 그 위 구간만 다룬다.
   잘라내는 대신 옆으로 밀어 볼 수 있게 한다 — 삭제 버튼이 안 보이는 것보다는
   한 번 미는 편이 낫다.
   912px = 각 칸의 최소폭 합(824) + 칸 사이 간격(48) + 좌우 안쪽 여백(40). */
@media (min-width: 721px) {
  .supplier-table-card {
    overflow-x: auto;
  }

  .supplier-row {
    min-width: 912px;
  }
}

/* 서버가 알아들은 시각을 사람 말로 되읽어 주는 줄.
   맞게 읽혔으면 초록, 지난 시각이거나 못 읽으면 빨강 — 색만 봐도 판단이 된다. */
.nf-when-echo {
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: #1d6b4a;
}

.nf-when-echo.is-bad {
  color: #c0392b;
}

/* ===================================================================
   날짜 · 시각 고르기 (components/DateTimePicker.tsx)
   ===================================================================
   브라우저 기본 달력은 닫는 버튼이 없어서, 다 고르고 나면 어떻게 끝내는지
   화면에 아무것도 없었다. 확인 · 취소가 있는 달력을 직접 그린다. */
.nf-dtp {
  position: relative;
}

.nf-dtp__field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 10px 12px;
  font-size: 14px;
  color: #1b2a22;
  text-align: left;
  background: #fff;
  border: 1px solid var(--nf-line, #e3e8e5);
  border-radius: 8px;
  cursor: pointer;
}

.nf-dtp__field:hover {
  border-color: #15924c;
}

.nf-dtp__placeholder {
  color: #9aa89f;
}

.nf-dtp__icon {
  flex-shrink: 0;
  font-size: 14px;
}

/*
 * 달력은 칸 바로 아래에 '펼쳐진다'. 떠 있는 팝오버가 아니다.
 *
 * 모달(.nf-modal)이 max-height + overflow-y:auto라, 그 안에서 절대배치로 띄우면
 * 스크롤 상자에 잘려 달력의 아래쪽 절반과 확인 버튼이 보이지 않았다.
 * 흐름 안에 두면 모달이 그만큼 늘고, 넘치면 모달이 스크롤된다 — 잘릴 일이 없다.
 */
.nf-dtp__panel {
  margin-top: 6px;
  padding: 12px;
  background: #fbfcfb;
  border: 1px solid var(--nf-line, #e3e8e5);
  border-radius: 10px;
}

.nf-dtp__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.nf-dtp__month {
  font-size: 14px;
  font-weight: 800;
  color: #14241c;
}

.nf-dtp__nav {
  width: 28px;
  height: 28px;
  font-size: 18px;
  line-height: 1;
  color: #4a5a50;
  background: none;
  border: 1px solid var(--nf-line, #e3e8e5);
  border-radius: 7px;
  cursor: pointer;
}

.nf-dtp__nav:hover {
  border-color: #15924c;
  color: #15924c;
}

.nf-dtp__week,
.nf-dtp__days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.nf-dtp__wd {
  padding: 4px 0;
  font-size: 11px;
  font-weight: 700;
  color: #9aa89f;
  text-align: center;
}

.nf-dtp__day {
  padding: 6px 0;
  font-size: 13px;
  color: #1b2a22;
  background: none;
  border: 1px solid transparent;
  border-radius: 7px;
  cursor: pointer;
}

.nf-dtp__day:hover {
  background: #eef4f0;
}

/* 오늘은 테두리로만 표시한다. 고른 날(진한 바탕)과 헷갈리면 안 된다. */
.nf-dtp__day.is-today {
  border-color: #b9d6c6;
}

.nf-dtp__day.is-on {
  color: #fff;
  font-weight: 700;
  background: #15924c;
  border-color: #15924c;
}

.nf-dtp__time {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}

.nf-dtp__time-label {
  font-size: 12px;
  font-weight: 700;
  color: #4a5a50;
}

.nf-dtp__time .nf-select {
  flex: 1;
  min-width: 0;
  padding: 6px 8px;
  font-size: 13px;
}

.nf-dtp__echo {
  margin-top: 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: #1d6b4a;
  text-align: center;
}

.nf-dtp__actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 10px;
}

/* ===================================================================
   상품 등록/수정 모달 — '이미 등록하신 규격입니다' 안내
   ===================================================================
   규격 칸(행의 절반, 300px 남짓) 안에서는 이 한 문장이 네댓 줄로 접히고
   옆 공급가 입력칸과 밑줄이 어긋나 뒤죽박죽으로 읽혔다.
   행 아래 전폭 한 줄로 빼고, 현재 공급가는 오른쪽에 떼어 붙인다.
   좁은 화면에서는 아래로 접히되 문장·숫자 각각은 통째로 유지된다. */
.supplier-exists-note {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  margin: 8px 0 4px;
  padding: 10px 12px;
  border: 1px solid #dbe7df;
  border-left: 3px solid #2f7d5c;
  border-radius: 8px;
  background: #f4f9f6;
  font-size: 12.5px;
  line-height: 1.6;
  color: #43584c;
  word-break: keep-all;
  overflow-wrap: break-word;
}

.supplier-exists-note b {
  font-weight: 700;
  color: #1f5d43;
}

/* 숫자는 문장에 섞이지 않게 한 덩어리로 둔다. */
.supplier-exists-note__price {
  flex-shrink: 0;
  font-weight: 700;
  color: #1b2a22;
  white-space: nowrap;
}

/* ===================================================================
   유입 통계 — 제품별 방문자 · 조회수
   =================================================================== */
.nf-stats-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-bottom: 4px;
}

.nf-stats-head .nf-stats-title {
  margin: 0;
}

/* 순위 손잡이. 지금 무엇으로 줄을 세웠는지 눌린 칸으로 보인다. */
.nf-stats-sort {
  display: inline-flex;
  flex-shrink: 0;
  padding: 3px;
  border: 1px solid #dce6e0;
  border-radius: 10px;
  background: #f4f6f5;
}

.nf-stats-sort__btn {
  padding: 6px 12px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  font-size: 12.5px;
  font-weight: 700;
  color: #6a7a71;
  cursor: pointer;
}

.nf-stats-sort__btn:hover {
  color: #1f5d43;
}

.nf-stats-sort__btn.is-on {
  background: #fff;
  color: #1f5d43;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.nf-stats-legend {
  margin-bottom: 12px;
}

.nf-stats-legend b {
  font-weight: 700;
  color: #1f5d43;
}

/* 표. 줄 수가 수십이라 실제 <table> 대신 격자 한 줄씩 그린다 —
   숫자 칸 폭을 고정해 두면 어느 줄이 큰지 눈으로 바로 비교된다. */
.nf-stat-table {
  border-top: 1px solid #e5ebe8;
}

.nf-stat-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 92px 92px;
  align-items: center;
  gap: 8px;
  padding: 10px 4px;
  border-bottom: 1px solid #eef2f0;
  font-size: 13px;
}

.nf-stat-row--head {
  padding: 8px 4px;
  font-size: 12px;
  font-weight: 700;
  color: #6a7a71;
  background: #fafcfb;
}

.nf-stat-row--foot {
  border-bottom: 0;
  font-weight: 700;
  color: #1b2a22;
  background: #fafcfb;
}

.nf-stat-col-no {
  text-align: center;
  font-size: 12.5px;
  font-weight: 700;
  color: #8c9a93;
}

/* 순위로 세웠을 때 위 세 줄만 표시를 준다. 1등이 어디인지 세지 않아도 보이게. */
.nf-stat-col-no.is-top {
  color: #fff;
  background: #2f7d5c;
  border-radius: 999px;
  padding: 2px 0;
}

.nf-stat-col-name {
  min-width: 0;
  color: #1b2a22;
  word-break: keep-all;
  overflow-wrap: break-word;
}

.nf-stat-col-name b {
  font-weight: 700;
}

/* 품목과 고유번호는 제품명 밑으로 내린다. 한 줄에 다 넣으면 이름이 밀린다. */
.nf-stat-code {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  font-style: normal;
  color: #8c9a93;
}

.nf-stat-col-num {
  text-align: right;
  font-size: 14px;
  font-weight: 700;
  color: #1b2a22;
  font-variant-numeric: tabular-nums;
}

.nf-stat-row--head .nf-stat-col-num {
  font-size: 12px;
  color: #6a7a71;
}

/* 사람 수 옆의 '몇 회'. 같은 크기로 두면 어느 쪽이 사람인지 헷갈린다. */
.nf-stat-col-num em {
  display: block;
  font-size: 11px;
  font-style: normal;
  font-weight: 600;
  color: #8c9a93;
}

@media (max-width: 640px) {
  .nf-stat-row {
    grid-template-columns: 34px minmax(0, 1fr) 66px 66px;
    gap: 6px;
    font-size: 12.5px;
  }
  .nf-stat-col-num {
    font-size: 13px;
  }
}

/* ===================================================================
   정렬 기준 줄 옆으로 밀기            (2026-08-31)
   ===================================================================

   규격 칩은 지금까지 줄바꿈(flex-wrap)으로 쌓였다. 규격이 셋뿐인 품목에서는
   한 줄이지만, 복숭아처럼 열여덟인 품목을 폰에서 열면 다섯 줄이 되어 정작
   봐야 할 시세표가 화면 밖으로 밀려났다.

   좁은 화면에서는 쌓지 않고 옆으로 민다 — 사이드바 카테고리(style.css의
   .category-list @540)와 같은 방식이라, 이 화면에서 가로로 미는 손짓이
   한 가지로 통일된다.

   이름표('정렬 기준')는 밀리지 않고 제자리에 남는다. 같이 흘러가면 무엇을
   고르는 줄인지 알 수 없게 된다. */

.unit-picker__chips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  /* 남는 폭을 다 쓰되 줄어들 수도 있어야 한다. min-width:0이 없으면 칩들이
     내용 길이만큼 버텨 이름표를 밖으로 밀어낸다. */
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 540px) {
  .unit-picker {
    flex-wrap: nowrap;
    align-items: center;
  }

  .unit-picker__label {
    flex: 0 0 auto;
  }

  .unit-picker__chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* 스크롤바가 칩 밑에 겹쳐 보이지 않도록 자리를 둔다. */
    padding-bottom: 6px;
  }

  /* 밀리는 줄 안에서는 어느 것도 눌려 찌그러지지 않는다. */
  .unit-picker__chips > * {
    flex-shrink: 0;
  }
}

/* ===================================================================
   정렬 버튼 한 줄로                  (2026-08-31)
   ===================================================================

   정렬 넷과 단가 알림은 폰에서 두 줄로 접혀 있었다(style.css @540의 flex-wrap).
   접힌 줄은 '가격 낮은순 / 가격 높은순'과 '배송 빠른순 / 배송 늦은순 / 단가 알림'을
   서로 다른 묶음처럼 보이게 한다 — 다섯은 나란한 선택지이지 두 무리가 아니다.

   바로 위 정렬 기준 줄과 같이 옆으로 밀어 본다. 다섯을 다 줄여 넣을 수도 있지만
   그러면 글자가 10px 아래로 내려가고, 폰에서 누를 수 있는 크기도 함께 줄어든다. */
@media (max-width: 540px) {
  .sort-buttons {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* 툴바가 줄바꿈된 뒤 이 줄이 한 줄을 통째로 쓴다. 폭이 정해져야 넘치는 만큼을
       스크롤로 넘길 수 있다 — min-width:0이 없으면 내용 길이대로 벌어져 툴바를 밀어낸다. */
    flex: 1 1 100%;
    min-width: 0;
    padding-bottom: 6px;
  }

  .sort-buttons button {
    flex-shrink: 0;
    white-space: nowrap;
  }
}

/* ===================================================================
   안내 문장은 제목 아래로            (2026-08-31)
   ===================================================================

   '업체별 공급가 비교' 옆에 붙어 있던 안내(.unit-filter-note)를 아랫줄로 내린다.
   문장이 길어져 제목과 한 줄에 두면 제목이 밀려 쪼개지고, 굵은 제목과 회색 안내가
   한 줄에 이어 붙어 어디까지가 제목인지 읽히지 않았다.

   style.css의 margin-left:8px는 옆에 붙어 있을 때의 간격이라 함께 지운다. */
.unit-filter-note {
  display: block;
  margin-left: 0;
  margin-top: 4px;
  line-height: 1.5;
  /* 어절 단위로 끊는 것(word-break:keep-all)은 reset.css의 body에서 이미 물려받는다.
     그런데도 폰에서 볼썽사나웠던 건 끊는 자리 때문이다 — 앞줄을 끝까지 채우고 남은
     '있습니다.' 한 어절만 뒷줄에 홀로 떨어졌다.
     balance는 줄 길이를 고르게 맞춰 어절 경계에서 나눈다:
       규격 선택 후 정렬을 누르면 업체별 공급가를
       비교하여 가격순으로 확인할 수 있습니다.
     지원하지 않는 브라우저는 이 줄만 무시하므로 지금 모습 그대로다. */
  text-wrap: balance;
}

/* ===================================================================
   로그인 화면 하단 겹침                (2026-08-31)
   ===================================================================

   style.css의 .login-page는 height:75vh 로 잠겨 있었다. 시안에는 입력 두 칸과
   버튼뿐이라 그 안에 들어갔지만, 지금은 회원 유형 두 카드 · 찾기 줄 · 회원가입
   안내까지 들어와 내용이 그 높이를 넘는다.

   align-items:center 로 세운 칸은 내용이 넘칠 때 위아래 양쪽으로 삐져나온다.
   칸의 높이는 여전히 75vh 라 그 아래 푸터는 원래 자리에 그려지고, 넘친 로그인
   내용이 그 위에 겹쳐 앉는다 — 폰에서 화면 아래쪽이 뭉개져 보이던 이유다.

   높이를 최소 높이로 바꾼다. 내용이 짧은 넓은 화면에서는 지금처럼 75vh 안에서
   세로 가운데에 서고, 넘치면 칸이 함께 늘어나 푸터를 밀어낸다. */
.login-page {
  height: auto;
  min-height: 75vh;
  padding: 40px 20px 28px;
  box-sizing: border-box;
}

/* ===================================================================
   게시판 검색 줄 · 글쓰기 버튼         (2026-08-31)
   ===================================================================

   폰에서 이 두 곳이 덩치로 화면을 먹고 있었다.

   1) 검색 줄
      style.css @560 은 검색어 칸을 아래로 내리고(order:3) 남은 첫 줄을
      '검색하기'가 flex:1 로 통째로 채우게 해 두었다. 그래서 무엇을 넣을지
      적기도 전에 시커먼 버튼부터 눈에 들어오고, 정작 입력칸은 그 아래에 있어
      읽는 순서가 거꾸로였다.

      셋을 한 줄에 세운다. 검색어 칸이 남는 폭을 갖고, 분류와 버튼은 글자 폭만큼만
      차지한다. min-width:0 이 있어야 검색어 칸이 줄어들 수 있다 —
      style.css의 min-width:160px 이 남아 있으면 셋이 한 줄에 못 들어간다.

   2) 글쓰기 버튼
      제목 줄(.board-panel__header)이 안내 문구와 버튼을 양끝으로 미는 칸이라,
      좁은 화면에서 '로그인 후 글쓰기'가 두 줄로 접혀 버튼만 사각형 덩어리가 됐다.
      글자를 한 줄로 묶고 버튼은 제 글자 폭만 갖게 한다. 남는 폭은 안내 문구가
      가져가 거기서 접힌다 — 접혀도 되는 쪽은 버튼이 아니라 설명이다. */

@media (max-width: 560px) {
  .board-find__input {
    /* style.css가 아래 줄로 내려보내던 것을 제자리로 되돌린다. */
    order: 0;
    /* 기준 폭 0. auto로 두면 입력칸이 제 기본 폭(글자 20자쯤)을 주장해
       줄바꿈 계산에서 먼저 밀려나고, 셋이 세 줄로 흩어진다. */
    flex: 1 1 0;
    min-width: 0;
  }

  .board-find__select {
    flex: 0 0 auto;
    padding: 0 28px 0 10px;
    background-position: calc(100% - 15px) 19px, calc(100% - 10px) 19px;
  }

  .board-find__btn {
    flex: 0 0 auto;
    padding: 0 13px;
    white-space: nowrap;
  }

  .board-find__reset {
    flex: 0 0 auto;
    padding: 0 12px;
    white-space: nowrap;
  }

  .board-panel__header {
    align-items: center;
    gap: 10px;
  }

  .board-panel__desc {
    flex: 1 1 auto;
    min-width: 0;
  }

  .board-write-btn {
    flex: 0 0 auto;
    padding: 11px 14px;
    white-space: nowrap;
  }
}

/* ===================================================================
   제휴목록 — 버튼을 오른쪽 끝으로       (2026-08-31)
   ===================================================================

   넓은 화면에서는 업체 이름이 왼쪽, 상품 수와 버튼이 오른쪽 끝에 선다
   (.partner-row의 space-between). 좁은 화면에서는 두 줄로 나뉘면서
   아랫줄 전체가 왼쪽에 붙어(justify-content:flex-start) 상품 수·상품 보기·문의하기가
   한 덩어리로 뭉쳐 있었다.

   버튼만 오른쪽 끝으로 보낸다. 상품 수는 업체를 설명하는 값이라 이름 아래,
   즉 왼쪽에 남는 편이 읽힌다 — 자동 여백(margin-right:auto)이 그 사이를 벌린다. */
@media (max-width: 640px) {
  .partner-row__side {
    justify-content: flex-end;
  }

  .partner-row__stat {
    margin-right: auto;
  }
}

/* ===================================================================
   약관 탭 한 줄로                      (2026-08-31)
   ===================================================================

   다섯 탭(이용약관 · 개인정보처리방침 · 통신판매중개자 면책 고지 · 이메일 무단수집
   거부 · 광고성 정보 수신 동의)을 다 펴면 740px쯤 된다. 그래서 폰에서는 세 줄로
   쌓여 문서 제목보다 탭 줄이 더 커 보였다.

   쌓지 않고 옆으로 민다 — 전광판의 카테고리·정렬 기준 줄과 같은 방식이다.
   지금 보고 있는 탭이 오른쪽 밖에 있으면 그쪽으로 밀어 둔다
   (components/LegalTabsScroll.tsx). */
@media (max-width: 768px) {
  .legal-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 6px;
  }

  .legal-tabs__item {
    flex: 0 0 auto;
    white-space: nowrap;
  }
}

/* ===================================================================
   콘솔(관리자 · B2B 사업자) — 좁은 화면 메뉴     (2026-08-31)
   ===================================================================

   두 콘솔 다 사이드바에 메뉴를 세로로 세운다. 화면이 좁아 사이드바가 본문 위로
   올라오면 메뉴가 본문을 밀어내려, 탭을 옮기는 일이 매번 '펼치고 → 고르고 →
   다시 내려가기'가 됐다(접기 버튼이 있었지만 펼치면 결국 같은 자리에 쌓였다).

   메뉴 문은 헤더 자리에 단다. 콘솔 화면에는 공통 헤더가 없지만 그 자리(64px)는
   #wrapper의 위 여백으로 이미 비워져 있다 — 화면 맨 위에 가로로 꽉 찬 띠가 놓일
   자리다. 본문 안에 띠를 하나 더 만들면 좌우 여백만큼 안으로 들어가 앉아,
   헤더도 본문도 아닌 것이 하나 끼어든 꼴이 된다.

   두 콘솔이 같은 옷을 입도록 클래스를 공유한다(console-*). 운영자와 공급업체가
   같은 서버의 두 얼굴이라, 문 여는 법이 화면마다 다르면 설명할 것이 두 배가 된다.

   기준선 1024px: 사이드바가 본문 옆자리를 잃고 위아래로 쌓이기 시작하는 폭이다
   (style.css @1024). 옆에 설 수 없게 된 메뉴는 옆에서 불러내는 편이 낫다. */

.console-topbar {
  display: none;
}

.console-close {
  display: none;
}

@media (max-width: 1024px) {
  /* 헤더 자리에 그대로 얹는다. #wrapper가 이미 위로 64px을 비워 두었으므로
     자리를 새로 만들지 않고, 좌우로도 화면 끝까지 간다. */
  .console-topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 300;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 64px;
    padding: 0 16px;
    background: #ffffff;
    border-bottom: 1px solid #eceee8;
  }

  .console-topbar__logo {
    flex: 0 0 auto;
    display: flex;
  }

  .console-topbar__logo img {
    display: block;
    height: 22px;
    width: auto;
  }

  /* 지금 어느 탭인지. 로고와 삼선 사이의 남는 폭만 쓰고, 길면 줄인다. */
  .console-topbar__title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 14px;
    font-weight: 800;
    color: #14241c;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .console-topbar__burger {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 32px;
    height: 32px;
    padding: 0 3px;
  }

  .console-topbar__burger span {
    display: block;
    width: 100%;
    height: 2px;
    border-radius: 999px;
    background-color: #1c3b2e;
  }

  /* ---- 옆에서 들어오는 메뉴 ---- */
  .console-scrim {
    position: fixed;
    inset: 0;
    z-index: 310;
    background-color: rgba(20, 36, 28, 0.5);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease;
  }

  .console-scrim.is-open {
    opacity: 1;
    visibility: visible;
  }

  .admin-sidebar,
  .supplier-sidebar {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 320;
    width: 280px;
    max-width: 86%;
    height: 100%;
    border-radius: 0;
    padding: 14px 14px 24px;
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform 0.28s ease;
  }

  .admin-sidebar.is-open,
  .supplier-sidebar.is-open {
    transform: translateX(0);
  }

  /* 접기 버튼은 이제 할 일이 없다. 문이 둘이면 어느 것이 메뉴인지 흐려진다. */
  .admin-sidebar__toggle,
  .supplier-sidebar__toggle {
    display: none;
  }

  /* 서랍 안에서는 세로 한 줄씩. 공급업체 쪽은 좁은 화면에서 가로로 흐르게
     되어 있었는데(style.css @1024), 서랍은 폭이 좁아 그대로 두면 두 칸씩 끊긴다. */
  .admin-nav,
  .supplier-nav {
    display: flex;
    flex-direction: column;
  }

  .console-close {
    display: block;
    margin-left: auto;
    width: 30px;
    height: 30px;
    font-size: 20px;
    line-height: 1;
    background: none;
  }

  /* 닫기 글자색은 사이드바 바탕을 따른다 — 관리자는 짙은 초록, 공급업체는 흰색. */
  .admin-sidebar .console-close {
    color: rgba(255, 255, 255, 0.7);
  }

  .supplier-sidebar .console-close {
    color: #7a8a80;
  }

  /* 손가락으로 고르는 목록이라 한 줄을 키운다(기존 12.5px · 높이 36px). */
  .admin-nav__item,
  .supplier-nav__item {
    padding: 13px 12px;
    font-size: 13.5px;
  }

  .admin-sidebar__back,
  .supplier-sidebar__logout {
    padding: 12px 10px;
    font-size: 13.5px;
  }
}

/* ===================================================================
   관리자 표 — 좁은 화면에서는 한 줄이 한 장     (2026-08-31)
   ===================================================================

   표를 세로로 쌓는 것까지는 style.css @767이 하고 있었지만, 쌓기만 해서
   생긴 문제가 셋이었다.

   1) 어디까지가 한 업체인지 알 수 없다. 줄과 줄 사이가 실선 하나뿐이라
      값이 예닐곱 개씩 이어지면 다음 업체의 값과 섞여 읽힌다.
   2) 라벨과 값이 위아래로 놓여 한 업체가 화면 한 장을 넘긴다.
   3) '신청서'·'상태'처럼 표에서 가운데로 맞춰 둔 칸(인라인 style)만
      혼자 가운데에 떠 있어 줄이 들쭉날쭉했다.

   그래서 좁은 화면에서는 한 줄을 한 장의 카드로 만든다. 값은 [라벨 | 값] 두 칸으로
   나란히 놓아 세로 길이를 줄이고, 가운데 정렬은 전부 왼쪽으로 되돌린다.
   처리 버튼은 카드 아래에 가름선을 두고 모아 둔다 — 읽는 곳과 누르는 곳을 나눈다. */
@media (max-width: 767px) {
  /* 바깥 상자는 배경을 내려놓는다. 카드가 겹쳐 흰 판이 두 겹이 되지 않게. */
  .admin-table-card {
    background-color: transparent;
    box-shadow: none;
    border-radius: 0;
    overflow: visible;
  }

  .admin-table-card .admin-row:not(.admin-row--head) {
    display: block;
    background-color: #fff;
    border: 1px solid #eceee8;
    border-radius: 12px;
    padding: 14px;
    margin-bottom: 10px;
    box-shadow: rgba(18, 40, 28, 0.05) 0 4px 14px;
  }

  /*
   * 라벨을 값 왼쪽에 세운다.
   *
   * 칸을 격자(grid)로 나눠 [라벨 | 값] 두 칸을 만드는 방법은 여기서 통하지 않는다.
   * 값 칸에는 글자 한 줄과 보조 줄(.admin-row__sub)이 함께 들어 있는데, 격자는 그
   * 안의 것들을 저마다 하나의 칸으로 집어가 보조 줄이 다음 줄 왼쪽 칸으로 떨어진다
   * ('buy@example.com'이 라벨 자리로 내려앉던 것).
   *
   * 그래서 라벨만 자리를 띄워 왼쪽에 붙이고(absolute), 값은 그만큼 안으로 들여
   * 원래대로 흐르게 둔다. 몇 줄이 오든 라벨 오른쪽에 가지런히 쌓인다.
   */
  .admin-row:not(.admin-row--head) > [data-label] {
    position: relative;
    padding-left: 94px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #f4f6f5;
  }

  .admin-row:not(.admin-row--head) > [data-label]::before {
    position: absolute;
    left: 0;
    top: 9px;
    width: 84px;
    margin-bottom: 0;
  }

  /* 표에서 가운데로 맞춰 둔 칸들(인라인 style 포함)을 왼쪽으로 되돌린다. */
  .admin-row:not(.admin-row--head) > div {
    text-align: left !important;
  }

  /* 처리 버튼. 읽는 값과 섞이지 않게 가름선 아래로 내리고, 손가락 크기로 키운다. */
  .admin-row:not(.admin-row--head) > .admin-col-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid #f4f6f5;
  }

  .admin-row:not(.admin-row--head) > .admin-col-actions .admin-btn {
    flex: 1 1 auto;
    min-height: 38px;
  }
}

/* 색을 정하지 않은 버튼(.admin-btn 만 붙은 것 — '신청서 보기' 등)은 바탕도 테두리도
   없어 굵은 글자처럼 보였다. 옆의 상담·반려·승인과 나란히 서면서 저것만 버튼이
   아닌 것처럼 읽힌다. 기본값을 외곽선 버튼과 같게 준다.               (2026-08-31) */
.admin-btn:not(.admin-btn--primary):not(.admin-btn--outline):not(.admin-btn--danger) {
  background-color: #fff;
  border: 1px solid #dce6e0;
  color: #5b6b62;
}

/* 모달 제목 줄은 위에 붙여 둔다                     (2026-08-31)

   신청서·업체 상세는 폰에서 한 화면을 훌쩍 넘긴다. 제목 줄이 같이 흘러가면 닫는 ✕가
   위로 사라져, 닫으려면 읽던 자리에서 맨 위까지 되감아 올라가야 했다.
   흰 바탕을 깔아 두지 않으면 밑을 지나는 글자가 제목에 겹쳐 보인다. */
@media (max-width: 767px) {
  .nf-modal__head {
    position: sticky;
    top: -24px; /* .nf-modal의 위 padding 만큼 끌어올려 천장에 붙인다 */
    z-index: 1;
    padding: 24px 0 10px;
    margin-top: -24px;
    background: #fff;
  }

  /* 손가락으로 누르는 닫기. 글자 하나짜리 버튼은 눌리는 자리가 너무 좁다. */
  .nf-modal__close {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    margin: -6px -6px 0 0;
    font-size: 18px;
  }
}

/* 모달은 헤더 위로 올린다                          (2026-08-31)

   덮개(.nf-modal-overlay)가 z-index 200인데 헤더는 300이라, 창을 띄워도 헤더만
   덮이지 않고 밝게 떠 있었다. 창이 길면 그 아래로 창의 제목이 들어가 헤더에 눌린 것처럼
   보이고, 뒤가 잠긴 상태인데 헤더의 삼선은 눌려 다른 화면으로 나가진다.

   창이 떠 있는 동안은 화면에서 가장 앞이어야 한다. 전광판 헤더(#header 300),
   콘솔 띠(.console-topbar 300)와 그 서랍(320)보다 위로 올린다.
   알림 팝업(.nf-toasts 9000)은 그대로 위에 남는다 — 값이 바뀌었다는 소식은
   창을 띄워 둔 동안에도 닿아야 한다. */
.nf-modal-overlay {
  z-index: 400;
}

/* 전광판의 '방문하기' 주문 창도 같은 사정이다(z-index 100이라 헤더 아래였다).
   두 덮개가 같은 높이여야 어느 화면에서 띄우든 창이 앞에 온다. */
.order-modal-overlay {
  z-index: 400;
}

/* 히어로 아래 한 줄 안내 — 택배비 포함가             (2026-08-31)

   설명글(.main-banner__desc)보다 한 단계 작게 두되 색은 오히려 밝게 한다.
   더 흐리게 하면 사진 위에서 먼저 사라지는 줄이 되는데, 이건 값을 어떻게 읽어야
   하는지 알려주는 줄이라 설명글보다 늦게 읽혀서는 안 된다.

   별표는 뺐다(2026-09-01). 눈이 걸리라고 붙인 표시였지만, 별표가 붙는 순간
   이 줄은 '본문 밖의 각주'로 읽혀 오히려 나중에 보게 된다. 설명글 바로 아래에
   붙여 두는 편이 같은 일을 더 조용히 한다 — 그래서 위 여백도 거의 두지 않는다. */
.main-banner__note {
  margin-top: 3px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.5;
  color: #e4efe8;
  text-shadow: rgba(0, 0, 0, 0.55) 0 1px 6px;
}

/* 제목과 설명글 사이 여백(style.css의 8px)이 넓어, 제목·설명·안내 세 줄이
   한 덩어리로 읽히지 않았다. 퍼블리싱 파일은 두고 여기서만 좁힌다. */
.main-banner__title {
  margin-bottom: 4px;
}

/* 공급업체 가격 연동 화면의 '상품 짝짓기' 구역.
   연동 폼 아래에 이어 붙는 자리라, 위로 여백을 두고 세로로 쌓는다.
   (supplier-status-set 을 빌려 쓰면 그 클래스가 가로 배치라 문구가 좌우로 쪼개진다) */
.supplier-feed-map {
  margin-top: 28px;
  padding-top: 24px;
  border-top: 1px solid #e5eae7;
}
.supplier-feed-map .nf-stats-title {
  margin-bottom: 8px;
}
.supplier-feed-map .supplier-panel__desc {
  margin-bottom: 10px;
}
.supplier-feed-map .supplier-btn {
  margin-top: 6px;
}

/* ===== 전광판 '변동 없음' 자리 =====
   오름·내림은 12×14 화살표 아이콘인데 변동 없음만 글자 '-'였다. .cell-price가
   gap 2px인 flex라 그 글자가 숫자에 붙어 '- 41,800'이 음수처럼 읽혔다.
   값이 안 움직인 날에는 표의 대부분이 그렇게 보인다.

   대신 그릴 만한 짧은 선도 결국 빼기 기호와 같은 모양이라, **아무것도 그리지 않는다.**
   움직인 칸에만 화살표가 붙는 것으로 충분하고, 변동 없음은 화살표가 없는 것이 곧 표시다.

   그래도 자리는 남긴다. 폭을 0으로 두면 값이 움직여 화살표가 생기는 순간 숫자가
   옆으로 밀린다 — 몇 초에 한 번 저 혼자 갱신되는 표에서 숫자가 흔들리면 읽기 어렵다. */
.arrow_same {
  width: 12px;
  height: 14px;
  flex: 0 0 12px;
}
