/* 소싱풀 — 「웜 그레이 미니멀」 단일 스타일시트
   토큰·규칙 출처: .planning/DESIGN-SYSTEM.md (LOCKED). 새 색·서체·크기를 추가하지 않는다. */

:root {
  --bg: #fbfaf9; /* 지면 — 웜 화이트 */
  --surface: #ffffff; /* 입력창 등 떠 있는 표면 */
  --ink: #232120; /* 본문 텍스트 */
  --sub: #6f6a64; /* 보조 텍스트 */
  --faint: #aaa49d; /* 장식성 요소 전용 (텍스트 금지) */
  --line: #eceae6; /* 헤어라인 보더 */
  --hover: #f5f4f1; /* 행/메뉴 hover 배경 */
  --fill: #f0efeb; /* 세그먼트 트랙, 중립 아바타 배경 */
  --green: #357a5b; /* 포인트 — 유일한 유채색 */
  --green-hover: #2c674c;
  --green-soft: #ebf3ee; /* 활성 메뉴 배경, 선택 행 배경 */
  --batch-bg: #26241f; /* 플로팅 배치바 */
  --batch-accent: #8fd0ae;
  --danger: #c0392b; /* 삭제·오류 전용 */
}

/* ---------- 리셋 ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  caret-color: var(--green);
}

h1,
h2,
p,
figure {
  margin: 0;
}

/* ---------- 브라우저 표면 ---------- */

::selection {
  background: rgba(53, 122, 91, 0.18);
}

:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}

/* ---------- 타이포 (3단계 고정) ---------- */

.page-title {
  font-size: 22px;
  font-weight: 750;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.meta {
  font-size: 12px;
  color: var(--sub);
}

.num {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.wordmark {
  display: inline-block;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: var(--ink);
  text-decoration: none;
}

/* ---------- 폼 ---------- */

.field + .field {
  margin-top: 16px;
}

.field label {
  display: block;
  margin-bottom: 4px;
  font-size: 12px;
  color: var(--sub);
}

input[type='email'],
input[type='password'],
input[type='text'] {
  width: 100%;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input[type='email']:focus,
input[type='password']:focus,
input[type='text']:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(53, 122, 91, 0.1);
}

.form-actions {
  margin-top: 24px;
}

.form-message {
  margin-bottom: 16px;
  font-size: 14px;
}

.form-message.is-error {
  color: var(--danger);
}

.form-message.is-neutral {
  color: var(--sub);
}

.form-message.is-success {
  color: var(--green);
}

/* ---------- 버튼 ---------- */

.btn {
  font-family: inherit;
  font-size: 14px;
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.btn-primary {
  padding: 8px 16px;
  background: var(--green);
  color: #fff;
  border: none;
  font-weight: 600;
}

.btn-primary:hover {
  background: var(--green-hover);
}

.btn-primary:disabled {
  background: var(--green);
  opacity: 0.55;
  cursor: default;
}

.btn-block {
  display: block;
  width: 100%;
}

.btn-ghost {
  padding: 4px 0;
  background: transparent;
  border: none;
  color: var(--sub);
  font-size: 12px;
}

.btn-ghost:hover {
  color: var(--ink);
}

/* ---------- L-1 인증 레이아웃 ---------- */

.auth-shell {
  width: 360px;
  margin: 0 auto;
  padding-top: 20vh;
  padding-bottom: 64px;
}

.auth-title {
  margin-top: 32px;
}

.auth-form {
  margin-top: 32px;
}

.auth-links {
  margin-top: 24px;
}

.auth-links a {
  font-size: 12px;
  color: var(--green);
  text-decoration: none;
}

.auth-links a:hover {
  color: var(--green-hover);
  text-decoration: underline;
}

.auth-hint {
  margin-top: 8px;
  font-size: 12px;
  color: var(--sub);
}

/* ---------- L-2 앱 레이아웃 ---------- */

.app-shell {
  display: flex;
  min-height: 100vh;
  align-items: stretch;
}

.sidebar {
  /* 화면 높이에 sticky 고정 — 본문이 길어도 사이드바(특히 하단 계정·로그아웃)가
     항상 화면 안에 남는다. 메뉴가 화면보다 길어지는 예외 상황만 내부 스크롤. */
  position: sticky;
  top: 0;
  display: flex;
  flex: 0 0 224px;
  width: 224px;
  height: 100vh;
  flex-direction: column;
  padding: 36px 16px 24px;
  border-right: 1px solid var(--line);
  overflow-y: auto;
}

.sidebar-menu {
  flex: 1;
  margin-top: 32px;
}

.menu-item {
  display: block;
  padding: 8px 12px;
  border-radius: 7px;
  color: var(--ink);
  font-size: 14px;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.menu-item:hover {
  background: var(--hover);
}

.menu-item.is-active {
  background: var(--green-soft);
  color: var(--green);
  font-weight: 600;
}

.sidebar-footer {
  padding-top: 16px;
}

.sidebar-user {
  display: flex;
  align-items: center;
  gap: 8px;
}

.avatar {
  display: flex;
  flex: 0 0 26px;
  width: 26px;
  height: 26px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
}

.sidebar-email {
  overflow: hidden;
  font-size: 12px;
  color: var(--sub);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logout-form {
  margin: 4px 0 0;
}

.content {
  flex: 1;
  max-width: 1200px;
  padding: 36px 40px;
}

.page-body {
  margin-top: 24px;
  font-size: 14px;
  color: var(--sub);
}

/* ---------- 다중선택 (UI-SPEC S-1) ---------- */

/* 체크박스는 native input 그대로 두고 accent-color만 준다 — 커스텀 체크 마크를
   그리면 포커스 링·키보드 조작·indeterminate 표시를 전부 다시 만들어야 한다. */
.row-check {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--green);
  cursor: pointer;
  vertical-align: middle;
}

/* 선택 행은 hover보다 우선해야 한다 — 마우스를 얹었다고 선택 표시가 사라지면
   "무엇을 골랐나"가 흔들린다. 클래스 하나를 더 물려 명시도로 이긴다
   (.products-table tbody tr:hover 는 페이지 스타일 블록에 있다). */
.products-table tbody tr.product-row.is-selected,
.products-table tbody tr.product-row.is-selected:hover {
  background: var(--green-soft);
}

/* ---------- 플로팅 배치바 (DESIGN-SYSTEM 배치 작업 바) ---------- */

.batch-bar {
  position: fixed;
  z-index: 40; /* sticky 툴바(z-index auto)·필터 패널(20) 위 */
  bottom: 24px;
  left: 50%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--batch-bg);
  box-shadow: 0 16px 40px rgba(35, 33, 32, 0.25);
  transform: translateX(-50%);
}

.batch-count {
  color: #fff;
  font-size: 13px;
}

.batch-num {
  margin-right: 2px;
  color: var(--batch-accent);
  font-weight: 600;
}

.btn-batch {
  padding: 8px 16px;
}

/* 요청 중 표시. hx-disabled-elt가 붙인 disabled는 .btn-primary:disabled가 이미
   opacity .55로 다루고, htmx-request 클래스는 그 지원 여부와 무관하게 같은 상태를
   보장한다 (연타로 같은 이동이 두 번 나가는 것을 막는 것이 목적). */
.btn-batch.htmx-request {
  opacity: 0.55;
  pointer-events: none;
}

.btn-batch-clear {
  padding: 8px 4px;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.7);
  font-size: 13px;
}

.btn-batch-clear:hover {
  color: #fff;
}

/* 등장/퇴장은 transform·opacity만 (레이아웃 속성 트랜지션 금지).
   translateX(-50%)는 배치바의 중앙 정렬 자체라 두 상태 모두에 살아 있어야 한다. */
.batch-anim {
  transition: transform 0.22s ease, opacity 0.22s ease;
}

.batch-off {
  opacity: 0;
  transform: translateX(-50%) translateY(8px);
}

.batch-on {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ---------- 토스트 (DESIGN-SYSTEM 토스트 규격) ---------- */

/* 호스트는 항상 비어 있는 채로 떠 있다 — 클릭을 가로채지 않도록 pointer-events를
   끈다. 성공·실패를 색으로 구분하지 않는다(유채색은 그린 하나뿐). */
.toast-host {
  position: fixed;
  z-index: 60;
  top: 24px;
  left: 50%;
  display: flex;
  justify-content: center;
  pointer-events: none;
  transform: translateX(-50%);
}

.toast {
  padding: 10px 16px;
  border-radius: 8px;
  background: var(--batch-bg);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  transform: translateY(-6px);
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.toast.is-shown {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- 상세보기 모달 (UI-SPEC S-3, D-11) ---------- */

/* 이 블록이 페이지가 아니라 app.css에 있는 것이 계약이다 — /pool과 /products가
   **같은 파셜**(partials/product_detail.html)을 쓰므로 규격이 한 곳에 있어야
   두 화면의 상세가 갈라지지 않는다. 새 색·서체·크기는 만들지 않는다: 토큰과
   기확립 radius(12px 모달 / 8px 썸네일)만 쓰고, hex는 S-3이 수치까지 명시한
   그림자·백드롭 rgba 두 개가 전부다. */

/* 상품명 셀의 트리거. 버튼이지만 표에서는 텍스트처럼 보여야 하므로 서체·색을
   셀에서 그대로 물려받고, hover에서만 밑줄로 "누를 수 있다"를 알린다. */
.detail-trigger {
  display: block;
  max-width: 100%;
  overflow: hidden;
  padding: 0;
  border: none;
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.detail-trigger:hover {
  text-decoration: underline;
}

/* 배치바(40) 위, 토스트(60) 아래 — 모달이 떠 있어도 결과 알림은 보여야 한다. */
.detail-backdrop {
  position: fixed;
  z-index: 50;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(35, 33, 32, 0.35);
}

.detail-modal {
  position: relative;
  width: min(720px, calc(100vw - 48px));
  max-height: 85vh;
  padding: 24px;
  border-radius: 12px;
  background: var(--surface);
  box-shadow: 0 16px 40px rgba(35, 33, 32, 0.25);
  overflow-y: auto;
}

/* 등장은 opacity만 (S-3). 레이아웃·transform 트랜지션 금지 — 모달이 튀어오르면
   "정보를 보러 왔다"는 조용한 동작에 과한 연출이 된다. */
.detail-fade {
  transition: opacity 0.15s ease;
}

.detail-out {
  opacity: 0;
}

.detail-in {
  opacity: 1;
}

/* 우상단 고스트 텍스트 버튼 (아이콘 금지). 내용이 스크롤돼도 항상 같은 자리에
   있도록 모달 기준으로 절대 배치한다. */
.detail-close {
  position: absolute;
  top: 24px;
  right: 24px;
  padding: 0;
}

/* 섹션 간격 24px — 제목은 새 타이포 단계를 만들지 않고 테이블 헤더와 동급이다. */
.detail-section {
  margin-top: 24px;
}

.detail-section-title {
  margin: 0 0 8px;
  color: var(--sub);
  font-size: 12px;
  font-weight: 500;
}

.detail-title {
  /* 닫기 버튼과 겹치지 않도록 제목 줄만 오른쪽을 비워 둔다. */
  padding-right: 48px;
  font-size: 14px;
  font-weight: 620;
}

.detail-meta {
  margin-top: 4px;
  color: var(--sub);
  font-size: 12px;
}

/* 키-값 2열 + 옵션 표 공용. 행 구분은 헤어라인 하나뿐이다 (보더 박스 금지). */
.detail-table {
  width: 100%;
  border-collapse: collapse;
}

.detail-table th,
.detail-table td {
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.detail-key {
  width: 140px;
  color: var(--sub);
  font-size: 12px;
  font-weight: 400;
}

.detail-value {
  color: var(--ink);
  font-size: 14px;
  word-break: break-all;
}

.detail-link {
  color: var(--green);
  text-decoration: none;
}

.detail-link:hover {
  text-decoration: underline;
}

/* 옵션(SKU) 표는 목록 테이블의 축약 규격 — 열이 많아 12px로 낮춘다. */
.detail-sku-table th,
.detail-sku-table td {
  padding: 8px;
  font-size: 12px;
}

.detail-sku-table thead th {
  color: var(--sub);
  font-weight: 500;
}

.detail-sku-table td.num,
.detail-sku-table th.num {
  text-align: right;
}

/* 대표 옵션 표시는 텍스트뿐이다 — 배지 배경을 쓰지 않는다. */
.detail-sku-main {
  width: 36px;
  color: var(--sub);
}

.detail-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.detail-thumb {
  width: 72px;
  height: 72px;
  border-radius: 8px;
  background: var(--fill);
  object-fit: cover;
}

.detail-json-summary {
  color: var(--sub);
  font-size: 12px;
  cursor: pointer;
}

/* **<pre>의 기본 서체를 되돌리는 것이 이 규칙의 존재 이유다.** 브라우저 기본값은
   monospace인데 DESIGN-SYSTEM은 Pretendard 단일 서체를 못박고 모노 도입을
   금지한다 — 원본 JSON도 본문 서체로 본다. */
.detail-json-body {
  margin: 8px 0 0;
  font-family: inherit;
  font-size: 12px;
  white-space: pre-wrap;
  word-break: break-all;
}

.detail-empty {
  color: var(--sub);
  font-size: 12px;
}

/* ---------- Phase 5 신규 규격 (05-UI-SPEC 「신규 CSS 규격」) ---------- */
/* 새 토큰·새 크기를 만들지 않는다 — 전부 기존 토큰과 기확립 수치의 조합이다.
   페이지 <style>이 아니라 여기 두는 이유: 진행 바는 진행 화면과 전역 스트립 두 곳이
   쓰고, 스트립은 base_app.html이 쓴다. 한 곳에 있어야 두 화면이 갈라지지 않는다. */

/* 세그먼트 컨트롤 — DESIGN-SYSTEM 「필터」 규격의 첫 구현. */
.seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border-radius: 8px;
  background: var(--fill);
}

.seg-item {
  padding: 8px 12px;
  border-radius: 7px;
  color: var(--sub);
  font-size: 14px;
  text-decoration: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.seg-item:hover {
  color: var(--ink);
}

/* 활성 항목은 흰 배경 + 얕은 그림자 + 600이다. 그린을 쓰지 않는다. */
.seg-item.is-active {
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(35, 33, 32, 0.08);
}

/* 진행 바 — 수치는 Phase 3 .collect-bar와 같다. */
.progress-bar {
  margin-top: 8px;
  height: 6px;
  border-radius: 3px;
  background: var(--fill);
  overflow: hidden;
}

/* width에 트랜지션을 걸지 않는다 — 폴링 주기마다 즉시 갱신되는 레이아웃 값이라
   애니메이션이 오히려 지연으로 보인다. */
.progress-bar-fill {
  height: 100%;
  border-radius: 3px;
  background: var(--green);
}

/* 좁은 모달 — .detail-modal에 함께 붙인다 (새 백드롭·새 그림자·새 radius 없음). */
.modal-narrow {
  width: min(420px, calc(100vw - 48px));
}

/* SC-6 고지 카드 (S-4). 지면 위에 흰 면 하나가 떠 있는 것이 주목 장치의 전부다 —
   유채색·아이콘·배지·테두리 색 없음. 위계는 색이 아니라 웨이트가 만든다. */
.notice-card {
  margin-top: 24px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}

/* 이 화면에서 620은 여기 하나뿐이다. */
.notice-title {
  font-size: 14px;
  font-weight: 620;
}

.notice-item {
  margin-top: 16px;
}

.notice-item-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--sub);
}

.notice-item-body {
  margin-top: 4px;
  font-size: 14px;
}

/* 10종 나열 — 목록 태그·불릿·번호 없이 한 문단에 ' · ' 구분자로 흘린다. */
.notice-values {
  margin-top: 4px;
  font-size: 14px;
}

.notice-hint {
  margin-top: 4px;
  font-size: 12px;
  color: var(--sub);
}

/* 전역 진행 스트립 (S-5) — base_app.html이 쓴다. 활성 작업이 있을 때만 렌더된다. */
.import-strip {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  font-size: 12px;
}

/* ---------- 시작 모달 필드 (S-2) ---------- */
/* 파셜은 자기 <style>을 가질 수 없어(스왑 대상) 여기 둔다. 규격은 import.html의
   .quantity-select 및 위 input 규칙과 같은 값이다 — 새 크기를 만들지 않는다. */

.modal-title {
  font-size: 14px;
  font-weight: 620;
}

.modal-meta {
  margin-top: 4px;
  color: var(--sub);
  font-size: 12px;
}

.modal-field {
  margin-top: 24px;
}

.modal-label {
  display: block;
  margin-bottom: 4px;
  color: var(--sub);
  font-size: 12px;
}

.modal-hint {
  margin-top: 4px;
  color: var(--sub);
  font-size: 12px;
}

.modal-control {
  width: 100%;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.modal-control:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(53, 122, 91, 0.1);
}

.modal-control:disabled {
  opacity: 0.55;
  cursor: default;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  margin-top: 24px;
}

/* 제출 실패 사유 — 배경을 칠하지 않는다 (텍스트 색만). */
.modal-error {
  margin-top: 16px;
  font-size: 14px;
  color: var(--danger);
}

/* 필드를 렌더하지 않는 분기(토큰 미등록·이미 작업 중·대상 0건)의 안내 문구. */
.modal-blocked {
  margin-top: 16px;
  font-size: 14px;
  color: var(--sub);
}

/* ---------- 접근성 ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}
