/* ═══════════════════════════════════════════════════════════════════════════
   JT Design System — Utilities  v1.0 (DRAFT · v5.0 토큰 필요)
   노코드·바이브코딩 사용자용 선택 레이어 — 클래스만 붙이면 되는 층

   사용법: jt-tokens.css를 먼저 로드한 뒤 이 파일을 로드합니다.
     <link rel="stylesheet" href="jt-tokens.css">
     <link rel="stylesheet" href="jt-utilities.css">

   설계 규칙 (DS §8 텍스트 팽창 규칙 내장):
   - 모든 컨트롤은 고정 width/height가 아니라 min-width/min-height
   - 값은 전부 토큰(var)만 참조 — 라이트/다크/밀도 전환 자동
   - 전역 리셋·body 스타일 없음 — 기존 앱에 얹어도 안전
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══ 컴포넌트 계약 (Component Contract) — 반드시 지켜주세요 ═══════════════
   앱이 늘어나도 시스템이 갈라지지 않게 하는 규칙입니다.

   1. 컴포넌트는 **Alias 토큰만** 참조합니다 (--color-text 등).
      원시 팔레트(--blue-500)를 직접 쓰면 라이트/다크 전환이 깨집니다.
   2. 앱이 모양을 바꿔야 하면 **이 파일을 수정하지 말고**, 컴포넌트가 노출한
      `--jt-{컴포넌트}-*` 변수만 덮어씁니다.

        .my-danger-btn{ --jt-btn-bg: var(--color-error); }   ← 이렇게
        .jt-btn{ background: red; }                          ← 이러지 마세요

   3. z-index 숫자를 직접 쓰지 않습니다. --z-* 이름만 씁니다.
   4. 새 값이 필요하면 먼저 토큰에 추가하고 → 컴포넌트에서 씁니다 (역순 금지).
   ═══════════════════════════════════════════════════════════════════════ */

/* ── box-sizing: jt- 클래스에만 한정 적용 — 전역 리셋 없이 안전.
   (width:100% + 패딩 조합이 컨테이너를 뚫는 것을 방지) ── */
[class^="jt-"],[class*=" jt-"]{ box-sizing:border-box; }

/* ── 포커스 링 — 전 컴포넌트 공통. 한 곳에서 관리합니다.
   :focus-visible = 키보드 탐색 시에만 표시(마우스 클릭 시엔 안 보임) ── */
.jt-scope :where(a,button,input,select,textarea,[tabindex]):focus-visible,
[class^="jt-"]:focus-visible,[class*=" jt-"]:focus-visible{
  outline:var(--focus-ring-width) solid var(--color-focus);
  outline-offset:var(--focus-ring-offset);
}

/* ── 범위 지정: 기존 앱에서는 이 클래스 안쪽에만 적용 ── */
.jt-scope{
  font-family:var(--font-base);
  font-size:var(--density-fs-base);
  line-height:var(--density-lh);
  color:var(--color-text);
}

/* ── 컨테이너 4종 — 좁은 화면에서는 자동으로 100% + 좌우 패딩 ── */
.jt-container,
.jt-container-narrow,
.jt-container-wide,
.jt-container-full{
  width:100%;
  margin-inline:auto;
  padding-inline:var(--space-4);            /* mobile 16px */
}
.jt-container{ max-width:var(--container-max); }
.jt-container-narrow{ max-width:var(--container-narrow); }
.jt-container-wide{ max-width:var(--container-wide); }
.jt-container-full{ max-width:none; }
@media (min-width:640px){
  .jt-container,.jt-container-narrow,.jt-container-wide,.jt-container-full{
    padding-inline:var(--space-6);          /* tablet 24px */
  }
}
@media (min-width:1024px){
  .jt-container,.jt-container-narrow,.jt-container-wide,.jt-container-full{
    padding-inline:var(--space-8);          /* desktop 40px */
  }
}

/* ── 타이포 유틸 ──
   .jt-display-* : Expressive 크기를 개별 요소에만 쓰고 싶을 때
   .jt-num       : 숫자 — Figtree + 자릿수 정렬 (표·가격·문서번호)
   .jt-lat-display: 영문 대형 제목·태그라인 — Figtree (브랜드 인상) */
.jt-display-lg{ font-size:var(--fs-display-lg); line-height:var(--lh-display); letter-spacing:var(--ls-display); font-weight:700; }
.jt-display-md{ font-size:var(--fs-display-md); line-height:var(--lh-display); letter-spacing:var(--ls-display); font-weight:700; }
.jt-display-sm{ font-size:var(--fs-display-sm); line-height:var(--lh-display); letter-spacing:var(--ls-display); font-weight:600; }
@media (max-width:639px){
  .jt-display-lg{ font-size:var(--fs-display-sm); }
  .jt-display-md{ font-size:var(--fs-4xl); }
  .jt-display-sm{ font-size:var(--fs-3xl); }
}
.jt-num{ font-family:var(--font-num); font-variant-numeric:tabular-nums; }
.jt-lat-display{ font-family:var(--font-display); }

/* ── 배치 유틸 ── */
.jt-stack-2{ display:flex; flex-direction:column; gap:var(--space-2); }
.jt-stack-3{ display:flex; flex-direction:column; gap:var(--space-3); }
.jt-stack-4{ display:flex; flex-direction:column; gap:var(--space-4); }
.jt-stack-6{ display:flex; flex-direction:column; gap:var(--space-6); }
.jt-row{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-3); }
.jt-grid-cards{
  --jt-grid-min:220px;
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(var(--jt-grid-min),1fr));
  gap:var(--space-4);
}

/* ── 카드 ── */
.jt-card{
  background:var(--color-bg-container);
  border:1px solid var(--color-border);
  border-radius:var(--r-lg);
  box-shadow:var(--elev-card);
  padding:var(--space-5);
}

/* ── 버튼 — 2톤 규칙: 주 버튼은 Charcoal. 파란 주 버튼 금지 ── */
.jt-btn,
.jt-btn-ghost,
.jt-btn-danger{
  /* ↓ 앱이 덮어쓸 수 있는 지점 (계약 규칙 2) */
  --jt-btn-bg:var(--color-primary);
  --jt-btn-fg:var(--color-on-primary);
  --jt-btn-border:var(--color-primary);
  --jt-btn-bg-hover:var(--color-primary-hover);
  --jt-btn-bg-active:var(--color-primary-active);
  --jt-btn-min-w:64px;

  display:inline-flex; align-items:center; justify-content:center;
  gap:var(--space-2);
  min-height:var(--control-height);         /* height 아님 — 팽창 규칙 */
  min-width:var(--jt-btn-min-w);             /* width 고정 금지 */
  padding:0 var(--space-4);
  border-radius:var(--r-md);
  font-family:inherit; font-size:var(--density-fs-base); font-weight:600;
  line-height:1.2; cursor:pointer;
  text-decoration:none;
  background:var(--jt-btn-bg); color:var(--jt-btn-fg);
  border:1px solid var(--jt-btn-border);
  transition:background var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard);
}
.jt-btn:hover,.jt-btn-danger:hover{ background:var(--jt-btn-bg-hover); border-color:var(--jt-btn-bg-hover); }
.jt-btn:active,.jt-btn-danger:active{ background:var(--jt-btn-bg-active); border-color:var(--jt-btn-bg-active); }

/* 보조 버튼 — 같은 구조에 변수만 교체 (CSS 중복 없음) */
.jt-btn-ghost{
  --jt-btn-bg:var(--color-bg-container);
  --jt-btn-fg:var(--color-text);
  --jt-btn-border:var(--color-border);
  --jt-btn-bg-hover:var(--color-fill-hover);
  --jt-btn-bg-active:var(--color-fill-active);
}
.jt-btn-ghost:hover{ background:var(--jt-btn-bg-hover); }
.jt-btn-ghost:active{ background:var(--jt-btn-bg-active); }

/* 위험 동작(삭제·폐기) — 되돌릴 수 없는 액션에만 */
.jt-btn-danger{
  --jt-btn-bg:var(--color-error);
  --jt-btn-fg:var(--neutral-0);
  --jt-btn-border:var(--color-error);
  --jt-btn-bg-hover:var(--red-700);
  --jt-btn-bg-active:var(--red-900);
}
/* 크기 — 종류(3) × 크기(3) = 9조합으로 제한 */
.jt-btn-sm{ min-height:var(--control-height-sm); padding:0 var(--space-3); font-size:var(--density-fs-sm); }
.jt-btn-lg{ min-height:var(--control-height-lg); padding:0 var(--space-5); }

.jt-btn[disabled],.jt-btn-ghost[disabled],.jt-btn-danger[disabled]{
  background:var(--color-fill-disabled); color:var(--color-text-disabled);
  border-color:var(--color-border); cursor:not-allowed;
}

/* ── 링크 — 클릭 가능 = Blue ── */
.jt-link{ color:var(--color-link); text-decoration:none; }
.jt-link:hover{ color:var(--color-link-hover); text-decoration:underline; }

/* ── 입력 ── */
.jt-input{
  display:block; width:100%;
  min-height:var(--control-height);
  padding:0 var(--space-3);
  font-family:inherit; font-size:var(--density-fs-base); color:var(--color-text);
  background:var(--color-bg-container);
  border:1px solid var(--color-border-strong);   /* 폼 컨트롤 — WCAG 3:1 */
  border-radius:var(--r-md);
}
.jt-input::placeholder{ color:var(--color-text-secondary); }  /* placeholder도 텍스트 — 4.5:1 필요 */
.jt-input:focus{ border-color:var(--color-focus); outline:none;
  box-shadow:0 0 0 3px var(--color-accent-bg); }
.jt-input[disabled],.jt-input[readonly]{
  background:var(--color-fill-disabled); color:var(--color-text-disabled); cursor:not-allowed; }
/* 검증 실패 — 색만으로 알리지 않고 .jt-error 메시지를 함께 표시하세요 */
.jt-input[aria-invalid="true"]{ border-color:var(--color-error); }
.jt-input[aria-invalid="true"]:focus{ box-shadow:0 0 0 3px var(--color-error-bg); }
textarea.jt-input{ min-height:calc(var(--control-height) * 2); padding:var(--space-2) var(--space-3); }
select.jt-input{ cursor:pointer; }

/* ── 라벨·도움말·오류 ── */
.jt-label{ display:block; font-size:var(--density-fs-sm); font-weight:600;
  color:var(--color-text-secondary); margin-bottom:var(--space-1); }
.jt-label[data-required]::after{ content:" *"; color:var(--color-error); }
.jt-help{ font-size:var(--density-fs-sm); color:var(--color-text-secondary); }
.jt-error{ font-size:var(--density-fs-sm); color:var(--color-error-text); margin-top:var(--space-1); }

/* ── 표 — 말줄임은 표 셀에서만 허용(§8) ── */
.jt-table-wrap{ overflow-x:auto; border:1px solid var(--color-border);
  border-radius:var(--r-md); background:var(--color-bg-container); }
.jt-table{ width:100%; border-collapse:collapse;
  font-size:var(--density-fs-base); line-height:var(--density-lh); }
.jt-table th{
  text-align:left; font-weight:600; font-size:var(--density-fs-sm);
  color:var(--color-text-secondary);
  background:var(--neutral-50);
  padding:var(--cell-pad-y) var(--cell-pad-x);
  border-bottom:1px solid var(--color-border);
}
[data-theme="dark"] .jt-table th{ background:var(--color-bg-elevated); }
.jt-table td{
  padding:var(--cell-pad-y) var(--cell-pad-x);
  border-bottom:1px solid var(--color-split);
}
.jt-table tr:last-child td{ border-bottom:none; }
.jt-table td.jt-num{ text-align:right; }
.jt-table td.jt-ellipsis{ max-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* ── 배지 ── */
.jt-badge{
  --jt-badge-h:22px;
  display:inline-flex; align-items:center; gap:var(--space-1);
  flex:none;                    /* 좁은 화면에서 눌리지 않게 */
  white-space:nowrap;           /* ⚠️ 판정·상태는 절대 줄바꿈 금지 */
  min-height:var(--jt-badge-h); padding:0 var(--space-2);
  border-radius:var(--r-full);
  font-size:var(--fs-xs); font-weight:600; line-height:1;
  border:1px solid var(--color-border);
  color:var(--color-text-secondary); background:var(--color-bg-container);
}
.jt-badge-info{    color:var(--color-info-text);    background:var(--color-info-bg);    border-color:var(--color-info-border); }
.jt-badge-success{ color:var(--color-success-text); background:var(--color-success-bg); border-color:var(--color-success-border); }
.jt-badge-warning{ color:var(--color-warning-text); background:var(--color-warning-bg); border-color:var(--color-warning-border); }
.jt-badge-error{   color:var(--color-error-text);   background:var(--color-error-bg);   border-color:var(--color-error-border); }

/* 품질 판정 배지 — 화장품 제조 도메인 전용
   ⚠️ 반드시 글자(적합/부적합/보류)를 함께 넣으세요. 색만으로 판정을 전달하면
      색맹 사용자와 흑백 인쇄된 COA·시험성적서에서 정보가 사라집니다. */
.jt-badge-pass{ color:var(--color-pass-text); background:var(--color-pass-bg); border-color:var(--color-pass-border); }
.jt-badge-fail{ color:var(--color-fail-text); background:var(--color-fail-bg); border-color:var(--color-fail-border); }
.jt-badge-hold{ color:var(--color-hold-text); background:var(--color-hold-bg); border-color:var(--color-hold-border); }
.jt-badge-oos{  color:var(--color-oos-text);  background:var(--color-oos-bg);  border-color:var(--color-oos-border); }

/* ── 알림 박스 — border-inline-start = RTL 자동 대응(논리 방향 속성) ── */
.jt-note{
  --jt-note-accent:var(--color-accent);
  padding:var(--space-4); border-radius:var(--r-md);
  border:1px solid var(--color-border);
  border-inline-start:3px solid var(--jt-note-accent);
  background:var(--color-bg-container);
  font-size:var(--density-fs-base);
}
.jt-note-warning{ --jt-note-accent:var(--color-warning); }
.jt-note-error{   --jt-note-accent:var(--color-error); }
.jt-note-success{ --jt-note-accent:var(--color-success); }

/* ═══════════════════════════════════════════════════════════════════════════
   Tier 1 컴포넌트 — 실사용 6개 앱 조사 기반 (2026-08-21)
   전부 위 계약 규칙을 따릅니다: Alias 토큰만 참조 · --jt-* knob 노출 · z-index 이름만
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── ② 셀렉트 (자주측정 27개 · 최다 사용) ────────────────────────────────
   네이티브 <select>를 씁니다 — 모바일에서 OS 기본 선택 UI가 뜨고,
   키보드·스크린리더가 자동으로 동작합니다. 직접 만든 드롭다운보다 안전합니다. */
.jt-select{
  --jt-select-arrow:var(--color-text-tertiary);
  display:block; width:100%;
  min-height:var(--control-height);
  padding:0 var(--space-8) 0 var(--space-3);
  font-family:inherit; font-size:var(--density-fs-base); color:var(--color-text);
  background:var(--color-bg-container);
  border:1px solid var(--color-border-strong); border-radius:var(--r-md);
  cursor:pointer; appearance:none;
  /* 화살표 — 아이콘 파일 없이 CSS만으로. currentColor가 아니라 토큰을 씁니다 */
  background-image:linear-gradient(45deg,transparent 50%,var(--jt-select-arrow) 50%),
                   linear-gradient(135deg,var(--jt-select-arrow) 50%,transparent 50%);
  background-position:calc(100% - 20px) calc(50% + 2px),calc(100% - 15px) calc(50% + 2px);
  background-size:5px 5px,5px 5px; background-repeat:no-repeat;
}
.jt-select:focus{ border-color:var(--color-focus); outline:none;
  box-shadow:0 0 0 3px var(--color-accent-bg); }
.jt-select[disabled]{ background-color:var(--color-fill-disabled);
  color:var(--color-text-disabled); cursor:not-allowed; }
.jt-select[aria-invalid="true"]{ border-color:var(--color-error); }

/* ── ④ 모달 / 다이얼로그 (Visiter 24개) ──────────────────────────────────
   HTML: <div class="jt-overlay"><div class="jt-modal" role="dialog" aria-modal="true"
           aria-labelledby="t1"> … </div></div>
   ⚠️ 열릴 때 포커스를 모달 안으로 옮기고, 닫으면 원래 버튼으로 되돌리세요(JS 몫). */
.jt-overlay{
  position:fixed; inset:0; z-index:var(--z-overlay);
  background:var(--color-overlay);
  display:flex; align-items:center; justify-content:center;
  padding:var(--space-4);
  overflow-y:auto;
}
.jt-modal{
  --jt-modal-max:var(--container-narrow);
  position:relative; z-index:var(--z-modal);
  width:100%; max-width:var(--jt-modal-max);
  margin:auto;                                   /* 내용이 길면 위아래 스크롤 */
  background:var(--color-bg-elevated);
  border-radius:var(--r-lg); box-shadow:var(--elev-modal);
  padding:var(--space-6);
}
.jt-modal-sm{ --jt-modal-max:420px; }            /* 확인·경고 다이얼로그 */
.jt-modal-title{ font-size:var(--fs-xl); font-weight:700; margin:0 0 var(--space-3); }
.jt-modal-actions{ display:flex; gap:var(--space-2); justify-content:flex-end;
  margin-top:var(--space-6); flex-wrap:wrap; }
@media (max-width:639px){
  /* 모바일에서는 하단 시트처럼 — 엄지 도달 범위 */
  .jt-overlay{ align-items:flex-end; padding:0; }
  .jt-modal{ border-radius:var(--r-lg) var(--r-lg) 0 0; max-width:none; }
  .jt-modal-actions .jt-btn,.jt-modal-actions .jt-btn-ghost,
  .jt-modal-actions .jt-btn-danger{ flex:1 1 auto; }
}

/* ── ⑦ 탭 (Visiter 12개) ─────────────────────────────────────────────────
   HTML: <div class="jt-tabs" role="tablist">
           <button class="jt-tab" role="tab" aria-selected="true">…</button> … </div>
   ⚠️ aria-selected로 상태를 표시하세요. class로만 하면 스크린리더가 못 읽습니다. */
.jt-tabs{
  display:flex; gap:var(--space-1);
  border-bottom:1px solid var(--color-border);
  overflow-x:auto;                                /* 탭이 많으면 가로 스크롤 */
  scrollbar-width:thin;
}
.jt-tab{
  --jt-tab-fg:var(--color-text-secondary);
  flex:none;
  min-height:var(--control-height); padding:0 var(--space-4);
  background:none; border:none;
  border-bottom:2px solid transparent;
  color:var(--jt-tab-fg); font:inherit; font-weight:600;
  cursor:pointer; white-space:nowrap;
  transition:color var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard);
}
.jt-tab:hover{ --jt-tab-fg:var(--color-text); }
.jt-tab[aria-selected="true"]{
  --jt-tab-fg:var(--color-text-selected);
  border-bottom-color:var(--color-border-selected);
}
.jt-tab[disabled]{ --jt-tab-fg:var(--color-text-disabled); cursor:not-allowed; }

/* ── ⑥ 단계 표시기 (Visiter Step 1~4) ────────────────────────────────────
   HTML: <ol class="jt-steps"><li class="jt-step" data-state="done|current|todo">
           <span class="jt-step-dot">1</span> 기본 정보</li> … </ol>
   ⚠️ 현재 단계에 aria-current="step"을 함께 넣으세요. */
.jt-steps{
  display:flex; flex-wrap:wrap; gap:var(--space-3);
  list-style:none; padding:0; margin:0;
}
.jt-step{
  display:flex; align-items:center; gap:var(--space-2);
  font-size:var(--density-fs-sm); color:var(--color-text-secondary);
}
.jt-step-dot{
  width:var(--icon-lg); height:var(--icon-lg); flex:none;
  border-radius:var(--r-full); display:grid; place-items:center;
  font-family:var(--font-num); font-size:var(--fs-xs); font-weight:700;
  background:var(--color-fill-disabled); color:var(--color-text-disabled);
}
.jt-step[data-state="done"]{ color:var(--color-text); }
.jt-step[data-state="done"] .jt-step-dot{
  background:var(--color-primary); color:var(--color-on-primary); }
.jt-step[data-state="current"]{ color:var(--color-text-selected); font-weight:600; }
.jt-step[data-state="current"] .jt-step-dot{
  background:var(--color-accent); color:var(--neutral-0); }

/* ── ⑧ 체크박스 · 라디오 (Packing·Visiter) ───────────────────────────────
   HTML: <label class="jt-check"><input type="checkbox"> 재고소진 박스 포함</label>
   네이티브 input을 그대로 쓰고 accent-color만 브랜드로 바꿉니다 —
   직접 그리면 키보드·스크린리더·모바일 터치가 전부 깨집니다. */
.jt-check{
  display:inline-flex; align-items:flex-start; gap:var(--space-2);
  --jt-check-size:18px;
  min-height:var(--control-height);              /* 터치 타깃 확보 */
  padding-block:var(--space-1);
  font-size:var(--density-fs-base); color:var(--color-text);
  cursor:pointer;
}
.jt-check input[type="checkbox"],.jt-check input[type="radio"]{
  width:var(--jt-check-size); height:var(--jt-check-size); flex:none; margin:0;
  accent-color:var(--color-accent);              /* 브랜드 파랑 */
  cursor:pointer;
  align-self:center;
}
.jt-check:has(input[disabled]){ color:var(--color-text-disabled); cursor:not-allowed; }
/* 선택 시 배경까지 강조하는 목록형(적재 품목 선택 등) */
.jt-check-row{
  width:100%; padding:var(--space-3);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-check-row:hover{ background:var(--color-fill-hover); }
.jt-check-row:has(input:checked){
  background:var(--color-fill-selected); border-color:var(--color-border-selected); }

/* ── ⑤ 카드 목록형 (Visiter 40개) ────────────────────────────────────────
   제목 + 메타 + 우측 액션 구조. 목록·검색결과·대기열에 씁니다. */
.jt-card-row{
  display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-3) var(--space-4);
  background:var(--color-bg-container);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-card-row:hover{ background:var(--color-fill-hover); }
.jt-card-row[aria-selected="true"]{
  background:var(--color-fill-selected); border-color:var(--color-border-selected); }
.jt-card-row-main{ flex:1 1 auto; min-width:0; }   /* min-width:0 = 긴 텍스트 줄바꿈 허용 */
.jt-card-row-title{ font-weight:600; }
.jt-card-row-meta{
  display:block;                                    /* 항상 제목 아랫줄로 */
  font-family:var(--font-num); font-size:var(--density-fs-sm);
  color:var(--color-text-secondary); margin-top:var(--space-1); }

/* ── ⑫ 앱 셸: 사이드바 + 헤더 + 본문 (Packing·자주측정·Visiter 공통 골격) ──
   HTML: <div class="jt-shell">
           <aside class="jt-sidebar">…</aside>
           <div><header class="jt-topbar">…</header><main class="jt-main">…</main></div>
         </div>
   ⚠️ 구조는 강제가 아닙니다(DS §2-5). 랜딩·단일 화면 도구는 쓰지 않아도 됩니다. */
.jt-shell{
  --jt-sidebar-w:240px;
  display:grid; grid-template-columns:var(--jt-sidebar-w) 1fr;
  min-height:100vh; min-height:100dvh;
  background:var(--color-bg-layout);
}
.jt-sidebar{
  display:flex; flex-direction:column; gap:var(--space-1);
  padding:var(--space-4);
  background:var(--color-bg-container);
  border-inline-end:1px solid var(--color-border);
  position:sticky; top:0; align-self:start;
  max-height:100vh; max-height:100dvh; overflow-y:auto;
}
.jt-nav-item{
  display:flex; align-items:center; gap:var(--space-3);
  min-height:var(--control-height); padding:0 var(--space-3);
  border-radius:var(--r-md);
  color:var(--color-text-secondary); text-decoration:none;
  font-size:var(--density-fs-base);
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-nav-item:hover{ background:var(--color-fill-hover); color:var(--color-text); }
.jt-nav-item[aria-current="page"]{
  background:var(--color-fill-selected); color:var(--color-text-selected); font-weight:600; }
.jt-topbar{
  --jt-topbar-h:56px;
  position:sticky; top:0; z-index:var(--z-sticky);
  display:flex; align-items:center; gap:var(--space-3);
  min-height:var(--jt-topbar-h); padding:0 var(--space-6);
  background:var(--color-bg-container);
  border-bottom:1px solid var(--color-border);
}
.jt-topbar-title{ font-size:var(--fs-lg); font-weight:700; margin:0; }
.jt-topbar-actions{ margin-inline-start:auto; display:flex; align-items:center; gap:var(--space-2); }
.jt-main{ padding:var(--space-6); }
@media (max-width:1023px){
  /* 태블릿 이하 — 사이드바를 접고 본문 전체 폭 */
  .jt-shell{ grid-template-columns:1fr; }
  .jt-sidebar{ display:none; }
  .jt-sidebar[data-open="true"]{
    display:flex; position:fixed; inset:0 auto 0 0; z-index:var(--z-drawer);
    width:min(80vw,var(--jt-sidebar-w)); box-shadow:var(--elev-modal); }
  .jt-main{ padding:var(--space-4); }
}

/* ── ⑩ 표 보강: 고정 헤더 · 정렬 · 선택 행 ─────────────────────────────── */
.jt-table-wrap[data-sticky-head]{ max-height:60vh; overflow-y:auto; }
.jt-table-wrap[data-sticky-head] .jt-table th{
  position:sticky; top:0; z-index:var(--z-sticky); }
.jt-table tbody tr:hover{ background:var(--color-fill-hover); }
.jt-table tbody tr[aria-selected="true"]{ background:var(--color-fill-selected); }
.jt-table th[aria-sort]{ cursor:pointer; user-select:none; }
.jt-table th[aria-sort="ascending"]::after{ content:" ▲"; font-size:var(--fs-2xs); }
.jt-table th[aria-sort="descending"]::after{ content:" ▼"; font-size:var(--fs-2xs); }

/* ── 제품 이미지 — 화장품 컷은 흰 배경이 많아 컨테이너와 경계가 사라집니다 ── */
.jt-product-img{
  display:block; width:100%; height:auto;
  background:var(--color-product-bg);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  object-fit:contain;
}

/* ═══ 아이콘 사용 — 2가지 방식 (v5.0 정책) ═══════════════════════════════════
   ① 폰트 방식 .jt-ico  — 일반 UI. 7,798종 전부 사용 가능, 굵기 조절됨
   ② SVG 방식  .jt-ico-svg — 오프라인·인쇄·이메일·자체 제작 아이콘

   ⚠️ 접근성 (KWCAG·WCAG 1.1.1 — 텍스트 아닌 콘텐츠)
     · 옆에 글자가 있으면  → aria-hidden="true"  (스크린리더가 두 번 읽지 않게)
     · 아이콘만 있으면      → aria-label="저장"   (반드시)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ① 폰트 방식 — <span class="jt-ico" aria-hidden="true">science</span>
   ⚠️ <head>에 Material Symbols Rounded 로드 필요 (TOOLCHAIN.md 참조) */
.jt-ico{
  --jt-ico-size:var(--icon-md);
  --jt-ico-fill:0;                    /* 0=선 / 1=채움 (선택 상태에 사용) */
  --jt-ico-weight:400;                /* 본문 굵기와 맞추면 시각적으로 안정 */
  font-family:'Material Symbols Rounded';
  font-weight:normal; font-style:normal;
  font-size:var(--jt-ico-size); line-height:1;
  width:1em; height:1em; flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  vertical-align:middle;
  letter-spacing:normal; text-transform:none; white-space:nowrap;
  word-wrap:normal; direction:ltr;
  overflow:hidden;                    /* 폰트 로드 실패 시 원문이 새어나오지 않게 */
  -webkit-font-smoothing:antialiased;
  font-variation-settings:'FILL' var(--jt-ico-fill), 'wght' var(--jt-ico-weight),
                          'GRAD' 0, 'opsz' 24;
}
.jt-ico-sm{ --jt-ico-size:var(--icon-sm); }
.jt-ico-lg{ --jt-ico-size:var(--icon-lg); }
.jt-ico-filled{ --jt-ico-fill:1; }     /* 선택된 탭·활성 메뉴 */

/* ② SVG 방식 — <img class="jt-ico-svg" src="/brand/icons/science.svg" alt="">
   또는 인라인 <svg class="jt-ico-svg">. currentColor라 토큰 색·다크 자동 대응 */
.jt-ico-svg{
  width:var(--icon-md); height:var(--icon-md); flex:none;
  vertical-align:middle; color:currentColor; fill:currentColor;
}
.jt-ico-svg.jt-ico-sm{ width:var(--icon-sm); height:var(--icon-sm); }
.jt-ico-svg.jt-ico-lg{ width:var(--icon-lg); height:var(--icon-lg); }

/* ③ SVG mask 방식 .jt-ico-mask — CDN 없이 동작 + currentColor로 색 상속
   HTML: <span class="jt-ico-mask" style="--jt-ico-url:url(/brand/icons/science.svg)"
           aria-hidden="true"></span>
   ⚠️ 사내망·오프라인·인쇄 환경에서 가장 안전합니다. 중요 내비게이션은 이 방식 권장. */
.jt-ico-mask{
  --jt-ico-size:var(--icon-md);
  display:inline-block; flex:none; vertical-align:middle;
  width:var(--jt-ico-size); height:var(--jt-ico-size);
  background:currentColor;
  -webkit-mask:var(--jt-ico-url) center/contain no-repeat;
          mask:var(--jt-ico-url) center/contain no-repeat;
}
.jt-ico-mask.jt-ico-sm{ --jt-ico-size:var(--icon-sm); }
.jt-ico-mask.jt-ico-lg{ --jt-ico-size:var(--icon-lg); }

/* 아이콘 전용 버튼 — 터치 타깃 44px 확보 (aria-label 필수) */
.jt-icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:var(--control-height); height:var(--control-height);
  min-width:var(--touch-target-min); min-height:var(--touch-target-min);
  padding:0; border:none; border-radius:var(--r-md);
  background:transparent; color:var(--color-text-secondary);
  cursor:pointer;
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-icon-btn:hover{ background:var(--color-fill-hover); color:var(--color-text); }
.jt-icon-btn[aria-pressed="true"]{ background:var(--color-fill-selected); color:var(--color-text-selected); }

/* ═══ 모바일 하단 탭바 — v5.0 신설 ═══════════════════════════════════════════
   주요 메뉴가 5개 이하일 때 사용합니다. 그 이상이면 드로어(.jt-sidebar).
   ⚠️ 본문 마지막이 가리지 않도록 .jt-main에 --jt-tabbar-pad 만큼 여백을 줍니다. */
.jt-tabbar{
  --jt-tabbar-h:56px;
  position:fixed; inset-inline:0; bottom:0; z-index:var(--z-sticky);
  display:none;                              /* 모바일에서만 표시 */
  background:var(--color-bg-container);
  border-top:1px solid var(--color-border);
  padding-bottom:env(safe-area-inset-bottom);  /* 아이폰 홈바 대응 */
}
.jt-tabbar-item{
  flex:1 1 0; min-width:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; min-height:var(--jt-tabbar-h);
  padding:var(--space-1) var(--space-1);
  background:none; border:none; cursor:pointer;
  color:var(--color-text-secondary); font:inherit; font-size:var(--fs-xs);
  text-decoration:none; text-align:center;
}
.jt-tabbar-item[aria-current="page"]{ color:var(--color-text-selected); font-weight:600; }
.jt-tabbar-item[aria-current="page"] .jt-ico{ --jt-ico-fill:1; }  /* 선택 시 채움 */
.jt-tabbar-label{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%; }
@media (max-width:1023px){
  .jt-tabbar{ display:flex; }
  /* 하단 탭바가 있는 화면은 본문 아래 여백 확보.
     ⚠️ 탭바는 보통 .jt-shell 바깥(body 직속)에 둡니다 — body 기준으로 판정해야
        여백이 실제로 적용됩니다. (.jt-shell 기준이면 선택자가 빗나감) */
  body:has(.jt-tabbar) .jt-main,
  body:has(.jt-tabbar) .jt-container,
  body:has(.jt-tabbar) .jt-container-narrow,
  body:has(.jt-tabbar) .jt-container-wide,
  body:has(.jt-tabbar) .jt-container-full{
    padding-bottom:calc(var(--jt-tabbar-h,56px) + env(safe-area-inset-bottom) + var(--space-4));
  }
}

/* ═══ 고대비 모드 — v5.0 신설 ═══
   OS·브라우저에서 고대비를 켠 사용자에게 테두리·구분을 강화합니다. */
@media (prefers-contrast:more){
  :root{
    --color-border:        var(--gray-500);
    --color-border-strong: var(--gray-700);
    --color-text-secondary:var(--gray-800);
  }
  [data-theme="dark"]{
    --color-border:        rgba(255,255,255,.55);
    --color-border-strong: rgba(255,255,255,.75);
    --color-text-secondary:rgba(255,255,255,.85);
  }
  .jt-btn,.jt-btn-ghost,.jt-btn-danger,.jt-input,.jt-select{ border-width:2px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Tier 2 컴포넌트 (12종) — 실사용 6개 앱 조사 + TDS 대조 기반
   전부 계약 규칙 준수: Alias 토큰만 · --jt-* knob 노출 · z-index 이름만
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. 토스트 / 스낵바 ──────────────────────────────────────────────────
   HTML: <div class="jt-toast-area" role="status" aria-live="polite">
           <div class="jt-toast">저장했습니다</div></div>
   ⚠️ aria-live="polite" 필수 — 없으면 스크린리더가 알림을 읽지 않습니다.
      오류 알림은 role="alert" + aria-live="assertive" 를 씁니다. */
.jt-toast-area{
  position:fixed; inset-inline:0; bottom:0; z-index:var(--z-toast);
  display:flex; flex-direction:column; align-items:center; gap:var(--space-2);
  padding:var(--space-4);
  padding-bottom:calc(var(--space-4) + env(safe-area-inset-bottom));
  pointer-events:none;
}
.jt-toast{
  --jt-toast-bg:var(--color-primary);
  --jt-toast-fg:var(--color-on-primary);
  --jt-toast-max:560px;
  display:flex; align-items:center; gap:var(--space-2);
  max-width:min(var(--jt-toast-max),100%);
  min-height:var(--control-height);
  padding:var(--space-2) var(--space-4);
  background:var(--jt-toast-bg); color:var(--jt-toast-fg);
  border-radius:var(--r-full); box-shadow:var(--elev-modal);
  font-size:var(--density-fs-base);
  pointer-events:auto;
  animation:jt-toast-in var(--dur-base) var(--ease-decelerate);
}
.jt-toast-error{ --jt-toast-bg:var(--color-error); --jt-toast-fg:var(--neutral-0); }
@keyframes jt-toast-in{ from{opacity:0; transform:translateY(8px)} to{opacity:1; transform:none} }

/* ── 2. 수량 스테퍼 (Bulk-Track +5 버튼) ─────────────────────────────────
   HTML: <div class="jt-stepper">
           <button class="jt-stepper-btn" aria-label="수량 줄이기">−</button>
           <input class="jt-stepper-input" type="number" value="1" aria-label="수량">
           <button class="jt-stepper-btn" aria-label="수량 늘리기">+</button></div>
   ⚠️ 버튼에 aria-label 필수 (−/+ 기호만으로는 의미 전달 안 됨) */
.jt-stepper{
  display:inline-flex; align-items:stretch;
  border:1px solid var(--color-border-strong); border-radius:var(--r-md);
  overflow:hidden; background:var(--color-bg-container);
}
.jt-stepper-btn{
  display:flex; align-items:center; justify-content:center;
  min-width:var(--control-height); min-height:var(--control-height);
  padding:0 var(--space-2);
  background:none; border:none; cursor:pointer;
  color:var(--color-text); font:inherit; font-size:var(--fs-lg); line-height:1;
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-stepper-btn:hover{ background:var(--color-fill-hover); }
.jt-stepper-btn[disabled]{ color:var(--color-text-disabled); cursor:not-allowed; }
.jt-stepper-input{
  width:64px; min-height:var(--control-height);
  border:none; border-inline:1px solid var(--color-border);
  text-align:center; background:none; color:var(--color-text);
  font-family:var(--font-num); font-size:var(--density-fs-base);
  font-variant-numeric:tabular-nums;
  -moz-appearance:textfield;
}
.jt-stepper-input::-webkit-outer-spin-button,
.jt-stepper-input::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.jt-stepper-input:focus{ outline:none; background:var(--color-fill-hover); }

/* ── 3. 슬라이더 (Packing 완충재 두께) ───────────────────────────────────
   HTML: <input type="range" class="jt-slider" min="0" max="50" value="10"
           aria-label="측면 완충재 두께(mm)">
   ⚠️ 값을 숫자로도 보여주세요 — 슬라이더만으로는 정확한 값 확인이 어렵습니다. */
.jt-slider{
  --jt-slider-track:var(--color-fill-disabled);
  --jt-slider-fill:var(--color-accent);
  --jt-slider-thumb:var(--color-bg-container);
  width:100%; height:var(--touch-target-min);   /* 터치 영역 확보 */
  background:none; appearance:none; cursor:pointer;
}
.jt-slider::-webkit-slider-runnable-track{
  height:6px; border-radius:var(--r-full); background:var(--jt-slider-track); }
.jt-slider::-moz-range-track{
  height:6px; border-radius:var(--r-full); background:var(--jt-slider-track); }
.jt-slider::-moz-range-progress{
  height:6px; border-radius:var(--r-full); background:var(--jt-slider-fill); }
.jt-slider::-webkit-slider-thumb{
  appearance:none; width:20px; height:20px; margin-top:-7px;
  border-radius:var(--r-full); background:var(--jt-slider-thumb);
  border:2px solid var(--jt-slider-fill); box-shadow:var(--elev-card); }
.jt-slider::-moz-range-thumb{
  width:20px; height:20px; border-radius:var(--r-full);
  background:var(--jt-slider-thumb); border:2px solid var(--jt-slider-fill); }
.jt-slider[disabled]{ cursor:not-allowed; --jt-slider-fill:var(--color-text-disabled); }

/* ── 4. 검색 필드 (Packing 품목 검색) ────────────────────────────────────
   HTML: <div class="jt-search"><span class="jt-ico jt-ico-sm" aria-hidden="true">search</span>
           <input class="jt-search-input" type="search" placeholder="품목명 / 코드 검색">
           <button class="jt-search-clear" aria-label="검색어 지우기">✕</button></div> */
.jt-search{
  display:flex; align-items:center; gap:var(--space-2);
  min-height:var(--control-height);
  padding-inline:var(--space-3);
  background:var(--color-bg-container);
  border:1px solid var(--color-border-strong); border-radius:var(--r-md);
  color:var(--color-text-secondary);
}
.jt-search:focus-within{ border-color:var(--color-focus);
  box-shadow:0 0 0 3px var(--color-accent-bg); }
.jt-search-input{
  flex:1 1 auto; min-width:0;
  border:none; background:none; outline:none;
  color:var(--color-text); font:inherit; font-size:var(--density-fs-base);
}
.jt-search-input::placeholder{ color:var(--color-text-secondary); }
.jt-search-input::-webkit-search-cancel-button{ display:none; }
.jt-search-clear{
  flex:none; display:flex; align-items:center; justify-content:center;
  width:24px; height:24px; padding:0;
  background:none; border:none; border-radius:var(--r-full);
  color:var(--color-text-secondary); cursor:pointer; }
.jt-search-clear:hover{ background:var(--color-fill-hover); }

/* ── 5. 로더 · 스켈레톤 ──────────────────────────────────────────────────
   HTML: <div class="jt-loader" role="status" aria-label="불러오는 중"></div>
         <div class="jt-skeleton" style="height:20px"></div>
   ⚠️ 로더에 aria-label 필수. 스켈레톤은 aria-hidden="true" (장식) */
.jt-loader{
  --jt-loader-size:24px;
  display:inline-block; flex:none;
  width:var(--jt-loader-size); height:var(--jt-loader-size);
  border:2px solid var(--color-border);
  border-top-color:var(--color-accent);
  border-radius:var(--r-full);
  animation:jt-spin var(--dur-slow) linear infinite;
}
.jt-loader-lg{ --jt-loader-size:40px; }
@keyframes jt-spin{ to{ transform:rotate(360deg) } }
.jt-skeleton{
  background:var(--color-fill-disabled);
  border-radius:var(--r-sm);
  animation:jt-pulse 1.4s var(--ease-standard) infinite;
}
@keyframes jt-pulse{ 0%,100%{opacity:1} 50%{opacity:.55} }
/* 모션 최소화 설정 사용자는 애니메이션 대신 정적 표시 */
@media (prefers-reduced-motion:reduce){
  .jt-loader,.jt-skeleton{ animation:none; }
}

/* ── 6. 페이지네이션 ─────────────────────────────────────────────────────
   HTML: <nav class="jt-pagination" aria-label="페이지 탐색">
           <button class="jt-page" aria-label="이전 페이지">‹</button>
           <button class="jt-page" aria-current="page">1</button> … </nav> */
.jt-pagination{ display:flex; align-items:center; gap:var(--space-1); flex-wrap:wrap; }
.jt-page{
  display:flex; align-items:center; justify-content:center;
  min-width:var(--control-height); min-height:var(--control-height);
  padding:0 var(--space-2);
  background:none; border:1px solid transparent; border-radius:var(--r-md);
  color:var(--color-text-secondary); cursor:pointer;
  font-family:var(--font-num); font-size:var(--density-fs-base);
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-page:hover{ background:var(--color-fill-hover); color:var(--color-text); }
.jt-page[aria-current="page"]{
  background:var(--color-fill-selected); color:var(--color-text-selected);
  border-color:var(--color-border-selected); font-weight:700; }
.jt-page[disabled]{ color:var(--color-text-disabled); cursor:not-allowed; }

/* ── 7. 토글 스위치 ──────────────────────────────────────────────────────
   HTML: <label class="jt-switch"><input type="checkbox" role="switch">
           <span class="jt-switch-track"></span> 다크 모드</label>
   ⚠️ role="switch" 필수 — 체크박스와 의미가 다릅니다(켜짐/꺼짐). */
.jt-switch{
  display:inline-flex; align-items:center; gap:var(--space-3);
  min-height:var(--control-height); cursor:pointer;
  font-size:var(--density-fs-base); color:var(--color-text);
}
.jt-switch input{ position:absolute; opacity:0; width:0; height:0; }
.jt-switch-track{
  position:relative; flex:none;
  width:44px; height:24px; border-radius:var(--r-full);
  background:var(--color-fill-disabled);
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-switch-track::after{
  content:""; position:absolute; top:2px; inset-inline-start:2px;
  width:20px; height:20px; border-radius:var(--r-full);
  background:var(--color-bg-container); box-shadow:var(--elev-card);
  transition:transform var(--dur-fast) var(--ease-standard);
}
.jt-switch input:checked + .jt-switch-track{ background:var(--color-accent); }
.jt-switch input:checked + .jt-switch-track::after{ transform:translateX(20px); }
.jt-switch input:focus-visible + .jt-switch-track{
  outline:var(--focus-ring-width) solid var(--color-focus);
  outline-offset:var(--focus-ring-offset); }
.jt-switch:has(input[disabled]){ color:var(--color-text-disabled); cursor:not-allowed; }

/* ── 8. 아코디언 / 디스클로저 ────────────────────────────────────────────
   HTML: <details class="jt-accordion"><summary class="jt-accordion-head">
           Step 2. 위생 점검</summary><div class="jt-accordion-body">…</div></details>
   네이티브 <details>를 씁니다 — 키보드·스크린리더가 자동 동작합니다. */
.jt-accordion{
  border:1px solid var(--color-border); border-radius:var(--r-md);
  background:var(--color-bg-container); overflow:hidden;
}
.jt-accordion + .jt-accordion{ margin-top:var(--space-2); }
.jt-accordion-head{
  display:flex; align-items:center; gap:var(--space-2);
  min-height:var(--control-height-lg);
  padding:var(--space-3) var(--space-4);
  cursor:pointer; font-weight:600; color:var(--color-text);
  list-style:none;
  transition:background var(--dur-fast) var(--ease-standard);
}
.jt-accordion-head::-webkit-details-marker{ display:none; }
.jt-accordion-head::after{
  content:"⌄"; margin-inline-start:auto; color:var(--color-text-secondary);
  transition:transform var(--dur-fast) var(--ease-standard); }
.jt-accordion[open] .jt-accordion-head::after{ transform:rotate(180deg); }
.jt-accordion-head:hover{ background:var(--color-fill-hover); }
.jt-accordion-body{
  padding:0 var(--space-4) var(--space-4);
  color:var(--color-text-secondary); }

/* ── 9. 툴팁 ─────────────────────────────────────────────────────────────
   HTML: <span class="jt-tooltip"><button class="jt-icon-btn" aria-describedby="tp1">
           <span class="jt-ico" aria-hidden="true">info</span></button>
         <span class="jt-tooltip-body" role="tooltip" id="tp1">규격 근거: KP 제12개정</span></span>
   ⚠️ 툴팁만으로 중요한 정보를 전달하지 마세요 — 터치 기기에서 hover가 없습니다. */
.jt-tooltip{ position:relative; display:inline-flex; }
.jt-tooltip-body{
  --jt-tooltip-max:260px;
  position:absolute; bottom:calc(100% + var(--space-2)); left:50%;
  transform:translateX(-50%);
  z-index:var(--z-tooltip);
  min-width:max-content; max-width:var(--jt-tooltip-max);
  padding:var(--space-2) var(--space-3);
  background:var(--color-primary); color:var(--color-on-primary);
  border-radius:var(--r-md); box-shadow:var(--elev-pop);
  font-size:var(--fs-sm); line-height:var(--lh-snug);
  opacity:0; visibility:hidden;
  transition:opacity var(--dur-fast) var(--ease-standard);
}
.jt-tooltip:hover .jt-tooltip-body,
.jt-tooltip:focus-within .jt-tooltip-body{ opacity:1; visibility:visible; }

/* ── 10. 결과 화면 (Result) — 전면 피드백 ────────────────────────────────
   HTML: <div class="jt-result" role="status">
           <span class="jt-result-icon jt-result-pass"><span class="jt-ico jt-ico-lg"
             aria-hidden="true">task_alt</span></span>
           <h2 class="jt-result-title">보고서를 발행했습니다</h2>
           <p class="jt-result-desc">LOT 26H21-03 시험성적서</p>
           <div class="jt-row" style="justify-content:center">…</div></div> */
.jt-result{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:var(--space-3); padding:var(--space-9) var(--space-5);
}
.jt-result-icon{
  display:grid; place-items:center;
  width:64px; height:64px; border-radius:var(--r-full);
  background:var(--color-fill-selected); color:var(--color-text-selected);
  margin-bottom:var(--space-2);
}
.jt-result-pass{ background:var(--color-pass-bg); color:var(--color-pass-text); }
.jt-result-fail{ background:var(--color-fail-bg); color:var(--color-fail-text); }
.jt-result-hold{ background:var(--color-hold-bg); color:var(--color-hold-text); }
.jt-result-title{ font-size:var(--fs-xl); font-weight:700; margin:0; }
.jt-result-desc{ color:var(--color-text-secondary); margin:0; max-width:44ch; }

/* ── 11. 빈 상태 (Empty) ─────────────────────────────────────────────────
   HTML: <div class="jt-empty"><span class="jt-ico jt-ico-lg" aria-hidden="true">inventory_2</span>
           <p class="jt-empty-title">등록된 품목이 없습니다</p>
           <p class="jt-empty-desc">품목을 먼저 등록하면 적재를 계산할 수 있습니다.</p>
           <button class="jt-btn">품목 등록</button></div>
   ⚠️ 빈 상태에는 "무엇을 하면 되는지" 다음 행동을 반드시 넣습니다. */
.jt-empty{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:var(--space-2); padding:var(--space-9) var(--space-5);
  color:var(--color-text-secondary);
}
.jt-empty > .jt-ico,
.jt-empty > .jt-ico-mask{ color:var(--color-text-disabled); font-size:40px;
  --jt-ico-size:40px; margin-bottom:var(--space-2); }
.jt-empty-title{ font-size:var(--fs-lg); font-weight:600; color:var(--color-text); margin:0; }
.jt-empty-desc{ margin:0 0 var(--space-3); max-width:44ch; }

/* ── 12. 바텀시트 (모바일) ───────────────────────────────────────────────
   모달보다 가벼운 선택·필터용. 뒤가 살짝 보이도록 dim-weak 사용.
   HTML: <div class="jt-sheet-dim"><div class="jt-sheet" role="dialog" aria-modal="true">
           <div class="jt-sheet-grip" aria-hidden="true"></div> … </div></div> */
.jt-sheet-dim{
  position:fixed; inset:0; z-index:var(--z-overlay);
  background:var(--color-dim-weak);
  display:flex; align-items:flex-end;
}
.jt-sheet{
  position:relative; z-index:var(--z-modal);
  width:100%; max-height:85vh; overflow-y:auto;
  background:var(--color-bg-elevated);
  border-radius:var(--r-lg) var(--r-lg) 0 0;
  box-shadow:var(--elev-modal);
  padding:var(--space-3) var(--space-5)
          calc(var(--space-6) + env(safe-area-inset-bottom));
  animation:jt-sheet-up var(--dur-base) var(--ease-decelerate);
}
.jt-sheet-grip{
  width:36px; height:4px; border-radius:var(--r-full);
  background:var(--color-border-strong);
  margin:0 auto var(--space-4); }
@keyframes jt-sheet-up{ from{ transform:translateY(100%) } to{ transform:none } }
@media (prefers-reduced-motion:reduce){
  .jt-sheet,.jt-toast{ animation:none; }
}
/* 데스크톱에서는 가운데 정렬 카드로 */
@media (min-width:1024px){
  .jt-sheet-dim{ align-items:center; justify-content:center; padding:var(--space-4); }
  .jt-sheet{ max-width:var(--container-narrow); border-radius:var(--r-lg);
             padding-bottom:var(--space-6); }
  .jt-sheet-grip{ display:none; }
}

/* ── 이미지 위 텍스트 — 제품 사진 위 흰 글자 가독 확보 ── */
.jt-img-overlay{ position:relative; }
.jt-img-overlay::after{
  content:""; position:absolute; inset:0;
  background:var(--color-dim-image); border-radius:inherit; }
.jt-img-overlay > .jt-img-caption{
  position:absolute; inset-inline:0; bottom:0; z-index:var(--z-raised);
  padding:var(--space-4); color:var(--neutral-0); }

/* ── 스크린리더 전용 텍스트 (건너뛰기 링크·보조 설명) ── */
.jt-sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.jt-sr-only:focus-visible{
  position:fixed; top:var(--space-3); inset-inline-start:var(--space-3);
  z-index:var(--z-tooltip);
  width:auto; height:auto; margin:0; clip:auto; white-space:normal;
  padding:var(--space-2) var(--space-4);
  background:var(--color-primary); color:var(--color-on-primary);
  border-radius:var(--r-md);
}


/* ═══════════════════════════════════════════════════════════════════════════
   TIER 3 — 실무 앱에서 곧 필요해지는 22종  (v1.1 · 2026-08)
   근거: IBM Carbon 40종 전수 대조 + 제니트리 도메인(품질·물류·PLM) 요구
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 26. 여러 줄 입력 (Textarea) ─────────────────────────────────────────────
   ⚠️ 고정 height 금지 — min-height + resize:vertical 로 사용자가 늘리게 둡니다
      (DS §8-4 텍스트 팽창: 번역 시 내용이 길어짐) */
.jt-textarea{
  --jt-textarea-min-h:96px;
  display:block; width:100%; min-height:var(--jt-textarea-min-h);
  padding:var(--space-2) var(--space-3);
  font-family:inherit; font-size:var(--fs-base); line-height:var(--lh-normal);
  color:var(--color-text); background:var(--color-bg-container);
  border:1px solid var(--color-border-strong); border-radius:var(--r-md);
  resize:vertical;                     /* 가로 리사이즈는 레이아웃을 깨므로 금지 */
}
.jt-textarea::placeholder{ color:var(--color-text-secondary); }
.jt-textarea:disabled{ background:var(--color-fill-disabled); color:var(--color-text-disabled); }
.jt-textarea[aria-invalid="true"]{ border-color:var(--color-error); }

/* ── 27. 날짜 입력 (Date / Datetime) ─────────────────────────────────────────
   제조일자·유통기한·시험일 등 제조 도메인 필수.
   OS 기본 달력을 그대로 씁니다 — 직접 만든 달력은 접근성·다국어에서 거의 항상 집니다. */
.jt-date{
  min-height:var(--control-height); width:100%;
  padding:0 var(--space-3);
  font-family:var(--font-num); font-size:var(--fs-base);
  color:var(--color-text); background:var(--color-bg-container);
  border:1px solid var(--color-border-strong); border-radius:var(--r-md);
}
.jt-date::-webkit-calendar-picker-indicator{ cursor:pointer; opacity:.6; }
.jt-date:hover::-webkit-calendar-picker-indicator{ opacity:1; }
.jt-date-range{ display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; }
.jt-date-range > .jt-date{ width:auto; flex:1 1 150px; }

/* ── 28. 파일 업로드 (File uploader) ────────────────────────────────────────
   COA·시험성적서·제품 이미지. <input type=file>을 label로 감싸 쓰세요. */
.jt-upload{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--space-2); min-height:120px; padding:var(--space-5);
  text-align:center; cursor:pointer;
  color:var(--color-text-secondary);
  background:var(--color-bg-container);
  border:1px dashed var(--color-border-strong); border-radius:var(--r-md);
  transition:border-color var(--dur-fast) var(--ease-standard),
             background var(--dur-fast) var(--ease-standard);
}
.jt-upload:hover,.jt-upload:focus-within,
.jt-upload[data-dragover="true"]{
  border-color:var(--color-accent); background:var(--color-accent-bg);
  color:var(--color-text);
}
.jt-upload input[type="file"]{ position:absolute; width:1px; height:1px; opacity:0; }
.jt-upload-hint{ font-size:var(--fs-sm); color:var(--color-text-secondary); }

.jt-upload-list{ list-style:none; margin:var(--space-3) 0 0; padding:0;
  display:flex; flex-direction:column; gap:var(--space-2); }
.jt-upload-item{
  display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-2) var(--space-3);
  background:var(--color-bg-container);
  border:1px solid var(--color-border); border-radius:var(--r-md);
}
.jt-upload-name{ flex:1 1 auto; min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.jt-upload-size{ flex:none; font-family:var(--font-num);
  font-size:var(--fs-sm); color:var(--color-text-secondary); }
.jt-upload-item[data-state="error"]{ border-color:var(--color-error); }

/* ── 29. 진행률 (Progress bar) ──────────────────────────────────────────────
   ⚠️ 반드시 숫자(%)를 함께 보여주세요 — 막대만 있으면 색각·저시력 사용자에게 정보가 없습니다. */
.jt-progress{
  --jt-progress-h:6px;
  display:block; width:100%; height:var(--jt-progress-h);
  overflow:hidden;
  background:var(--color-fill-disabled); border-radius:var(--r-full);
}
.jt-progress-bar{
  display:block; height:100%; width:0%;
  background:var(--color-accent); border-radius:inherit;
  transition:width var(--dur-base) var(--ease-standard);
}
.jt-progress[data-state="success"] .jt-progress-bar{ background:var(--color-success); }
.jt-progress[data-state="error"]   .jt-progress-bar{ background:var(--color-error); }
.jt-progress-row{ display:flex; align-items:center; gap:var(--space-3); }
.jt-progress-row > .jt-progress{ flex:1 1 auto; }
.jt-progress-value{ flex:none; font-family:var(--font-num);
  font-size:var(--fs-sm); color:var(--color-text-secondary); }

/* ── 30. 라벨-값 목록 (Structured list / Descriptions) ──────────────────────
   품목 상세·시험 조건·규격 등 "이름: 값" 화면의 표준. <dl> 사용. */
.jt-desc{
  --jt-desc-label-w:160px;
  margin:0; display:grid; grid-template-columns:var(--jt-desc-label-w) 1fr;
  border-top:1px solid var(--color-split);
}
.jt-desc > dt,.jt-desc > dd{
  margin:0; padding:var(--cell-pad-y) var(--cell-pad-x);
  border-bottom:1px solid var(--color-split);
  line-height:var(--lh-snug);          /* 다국어 모음부호 대비 (DS §7-3) */
}
.jt-desc > dt{ color:var(--color-text-secondary); background:var(--color-bg-layout); }
.jt-desc > dd{ color:var(--color-text); overflow-wrap:anywhere; }
/* 모바일: 라벨을 위로 쌓기 — 160px 라벨 열은 좁은 화면에서 값을 못 담습니다 */
@media (max-width:639px){
  .jt-desc{ grid-template-columns:1fr; }
  .jt-desc > dt{ padding-bottom:0; border-bottom:0; background:transparent;
                 font-size:var(--fs-sm); }
}

/* ── 31. 메뉴 (Menu — 더보기 ⋮ 드롭다운) ────────────────────────────────────
   <details>로 만들면 JS 없이 열리고 닫힙니다. */
.jt-menu{ position:relative; display:inline-block; }
.jt-menu > summary{ list-style:none; cursor:pointer; }
.jt-menu > summary::-webkit-details-marker{ display:none; }
.jt-menu-list{
  --jt-menu-min-w:180px;
  position:absolute; inset-inline-end:0; top:calc(100% + var(--space-1));
  z-index:var(--z-dropdown);
  min-width:var(--jt-menu-min-w); padding:var(--space-1);
  background:var(--color-bg-elevated); box-shadow:var(--elev-pop);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  animation:jt-pop-in var(--dur-fast) var(--ease-decelerate);
}
.jt-menu-item{
  display:flex; align-items:center; gap:var(--space-2); width:100%;
  min-height:var(--control-height-sm); padding:var(--space-2) var(--space-3);
  font:inherit; text-align:start; color:var(--color-text);
  background:none; border:0; border-radius:var(--r-sm); cursor:pointer;
}
.jt-menu-item:hover{ background:var(--color-fill-hover); }
.jt-menu-item[data-danger="true"]{ color:var(--color-error); }
.jt-menu-item[aria-disabled="true"]{ color:var(--color-text-disabled); pointer-events:none; }
.jt-menu-sep{ height:1px; margin:var(--space-1) 0; background:var(--color-split); border:0; }
@keyframes jt-pop-in{ from{opacity:0; transform:translateY(-4px)} to{opacity:1; transform:none} }

/* ── 32. 콘텐츠 스위처 (Content switcher / 세그먼트) ────────────────────────
   탭과 다릅니다: 탭은 "다른 내용", 스위처는 "같은 내용의 다른 표현"(표/카드, 월/연).
   모바일에서 탭보다 안정적이라 기간·보기방식 전환에 권장합니다. */
.jt-switcher{
  display:inline-flex; padding:2px; gap:2px;
  background:var(--color-fill-disabled); border-radius:var(--r-md);
}
.jt-switcher-item{
  min-height:var(--control-height-sm); padding:0 var(--space-3);
  font:inherit; font-size:var(--fs-sm); color:var(--color-text-secondary);
  background:none; border:0; border-radius:calc(var(--r-md) - 2px); cursor:pointer;
  white-space:nowrap;                  /* 번역돼도 줄바꿈되지 않게 */
}
.jt-switcher-item[aria-selected="true"],
.jt-switcher-item[aria-pressed="true"]{
  color:var(--color-text); background:var(--color-bg-container);
  box-shadow:var(--shadow-1); font-weight:600;
}

/* ── 33. 브레드크럼 (Breadcrumb) ────────────────────────────────────────────
   ⚠️ 모바일에서는 감추지 말고 마지막 2단계만 남기세요(현재 위치 정보 상실 방지). */
.jt-crumb{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2);
  margin:0; padding:0; list-style:none;   /* <ol>/<ul> 기본 들여쓰기 제거 */
  font-size:var(--fs-sm); }
.jt-crumb a{ color:var(--color-link); text-decoration:none; }
.jt-crumb a:hover{ text-decoration:underline; }
.jt-crumb li{ display:flex; align-items:center; gap:var(--space-2); list-style:none; }
.jt-crumb li + li::before{ content:"/"; color:var(--color-text-tertiary); }
.jt-crumb [aria-current="page"]{ color:var(--color-text); font-weight:600; }

/* ── 34. 구분선 (Divider) ───────────────────────────────────────────────────*/
.jt-divider{ height:1px; margin:var(--space-4) 0;
  background:var(--color-split); border:0; }
.jt-divider-strong{ background:var(--color-border); }
.jt-divider-v{ width:1px; height:auto; align-self:stretch; margin:0 var(--space-3); }

/* ── 35. 목록 (List / Contained list) ───────────────────────────────────────*/
.jt-list{ list-style:none; margin:0; padding:0;
  border:1px solid var(--color-border); border-radius:var(--r-md); overflow:hidden;
  background:var(--color-bg-container); }
.jt-list-item{
  display:flex; align-items:center; gap:var(--space-3);
  min-height:var(--control-height-lg);
  padding:var(--space-3) var(--space-4);
  border-bottom:1px solid var(--color-split);
}
.jt-list-item:last-child{ border-bottom:0; }
a.jt-list-item,button.jt-list-item{ width:100%; color:inherit; text-decoration:none;
  background:none; border-left:0; border-right:0; border-top:0; text-align:start;
  font:inherit; cursor:pointer; }
a.jt-list-item:hover,button.jt-list-item:hover{ background:var(--color-fill-hover); }
.jt-list-item[aria-selected="true"]{ background:var(--color-fill-selected);
  color:var(--color-text-selected); }

/* ── 36. 선택형 타일 (Selectable tile) ──────────────────────────────────────
   "옵션 중 하나 고르기"를 카드로. 라디오/체크박스를 안에 숨겨 접근성을 유지합니다. */
.jt-tile{
  position:relative; display:block; padding:var(--space-4); cursor:pointer;
  background:var(--color-bg-container);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  transition:border-color var(--dur-fast) var(--ease-standard);
}
.jt-tile:hover{ border-color:var(--color-border-strong); }
.jt-tile input[type="radio"],.jt-tile input[type="checkbox"]{
  position:absolute; inset-inline-end:var(--space-3); top:var(--space-3); margin:0;
  width:var(--jt-check-size,20px); height:var(--jt-check-size,20px);
  accent-color:var(--color-accent);
}
.jt-tile:has(input:checked){
  border-color:var(--color-border-selected); background:var(--color-fill-selected);
  box-shadow:inset 0 0 0 1px var(--color-border-selected);
}
.jt-tile:has(input:disabled){ opacity:.55; cursor:not-allowed; }
.jt-tile-title{ font-weight:600; margin:0 var(--space-7) var(--space-1) 0; }
.jt-tile-desc{ margin:0; font-size:var(--fs-sm); color:var(--color-text-secondary); }

/* ── 37. 필터 태그 (제거 가능한 Tag) ────────────────────────────────────────*/
.jt-tag{
  display:inline-flex; align-items:center; gap:var(--space-1);
  min-height:28px; padding:0 var(--space-1) 0 var(--space-3);
  font-size:var(--fs-sm); white-space:nowrap;
  color:var(--color-text); background:var(--color-fill-hover);
  border:1px solid var(--color-border); border-radius:var(--r-full);
}
.jt-tag-x{
  display:inline-flex; align-items:center; justify-content:center;
  width:20px; height:20px; padding:0; cursor:pointer;
  font:inherit; line-height:1; color:var(--color-text-secondary);
  background:none; border:0; border-radius:var(--r-full);
}
.jt-tag-x:hover{ background:var(--color-fill-active); color:var(--color-text); }
/* 태그를 감싸는 필터 바 */
.jt-filterbar{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2); }

/* ── 38. 토글팁 (Toggletip — 클릭형 도움말) ─────────────────────────────────
   ⚠️ 툴팁(.jt-tooltip)은 hover 기반이라 **모바일에서 열 수 없습니다.**
      터치 기기에서도 필요한 설명은 반드시 이 토글팁을 쓰세요. <details> 기반. */
.jt-toggletip{ position:relative; display:inline-block; }
.jt-toggletip > summary{ list-style:none; cursor:pointer; display:inline-flex;
  align-items:center; justify-content:center;
  min-width:var(--touch-target-min); min-height:var(--touch-target-min);
  color:var(--color-text-secondary); }
.jt-toggletip > summary::-webkit-details-marker{ display:none; }
.jt-toggletip-body{
  --jt-toggletip-max:280px;
  position:absolute; inset-inline-start:0; top:calc(100% + var(--space-1));
  z-index:var(--z-tooltip); max-width:var(--jt-toggletip-max);
  padding:var(--space-3);
  font-size:var(--fs-sm); line-height:var(--lh-snug); color:var(--color-text);
  background:var(--color-bg-elevated); box-shadow:var(--elev-pop);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  animation:jt-pop-in var(--dur-fast) var(--ease-decelerate);
}

/* ── 39. 팝오버 (Popover — 내용이 있는 레이어) ──────────────────────────────*/
.jt-popover{ position:relative; display:inline-block; }
.jt-popover > summary{ list-style:none; cursor:pointer; }
.jt-popover > summary::-webkit-details-marker{ display:none; }
.jt-popover-body{
  --jt-popover-w:320px;
  position:absolute; inset-inline-end:0; top:calc(100% + var(--space-2));
  z-index:var(--z-dropdown); width:min(var(--jt-popover-w), calc(100vw - var(--space-8)));
  padding:var(--space-4);
  background:var(--color-bg-elevated); box-shadow:var(--elev-pop);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  animation:jt-pop-in var(--dur-fast) var(--ease-decelerate);
}

/* ── 40. 버튼 인라인 로딩 (Inline loading) ──────────────────────────────────
   저장 중 두 번 눌리는 사고를 막습니다. 버튼에 data-loading="true" 만 켜세요. */
.jt-btn[data-loading="true"],
.jt-btn-ghost[data-loading="true"],
.jt-btn-danger[data-loading="true"]{ pointer-events:none; opacity:.75; }
.jt-btn[data-loading="true"]::before,
.jt-btn-ghost[data-loading="true"]::before,
.jt-btn-danger[data-loading="true"]::before{
  content:""; flex:none; width:1em; height:1em; margin-inline-end:var(--space-2);
  border:2px solid currentColor; border-top-color:transparent; border-radius:var(--r-full);
  animation:jt-spin .7s linear infinite;
}

/* ── 41. 아바타 (Avatar) ────────────────────────────────────────────────────*/
.jt-avatar{
  --jt-avatar-size:32px;
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:var(--jt-avatar-size); height:var(--jt-avatar-size);
  font-size:var(--fs-sm); font-weight:600; line-height:1;
  color:var(--color-on-primary); background:var(--color-primary);
  border-radius:var(--r-full); overflow:hidden; user-select:none;
}
.jt-avatar img{ width:100%; height:100%; object-fit:cover; }
.jt-avatar-lg{ --jt-avatar-size:48px; font-size:var(--fs-base); }
.jt-avatar-sm{ --jt-avatar-size:24px; font-size:var(--fs-xs); }

/* ── 42. KPI 숫자 (Statistic) ───────────────────────────────────────────────*/
.jt-stat{ display:flex; flex-direction:column; gap:var(--space-1); }
.jt-stat-label{ font-size:var(--fs-sm); color:var(--color-text-secondary); }
.jt-stat-value{ font-family:var(--font-num); font-variant-numeric:tabular-nums;
  font-size:var(--fs-3xl); font-weight:700; line-height:var(--lh-tight);
  color:var(--color-text); }
.jt-stat-unit{ font-size:var(--fs-lg); font-weight:500;
  color:var(--color-text-secondary); margin-inline-start:2px; }
.jt-stat-delta{ display:inline-flex; align-items:center; gap:var(--space-1);
  font-family:var(--font-num); font-size:var(--fs-sm); }
/* ⚠️ 증감은 색만으로 전달 금지 — ▲▼ 기호를 반드시 함께 (DS §15-1) */
.jt-stat-delta[data-dir="up"]{ color:var(--color-success-text); }
.jt-stat-delta[data-dir="down"]{ color:var(--color-error-text); }
.jt-stat-delta[data-dir="flat"]{ color:var(--color-text-secondary); }

/* ── 43. 타임라인 (Timeline — 제조·품질 이력) ───────────────────────────────*/
.jt-timeline{ list-style:none; margin:0; padding:0 0 0 var(--space-6);
  position:relative; }
.jt-timeline::before{ content:""; position:absolute;
  inset-inline-start:7px; top:6px; bottom:6px; width:2px;
  background:var(--color-split); }
.jt-timeline-item{ position:relative; padding-bottom:var(--space-5); }
.jt-timeline-item:last-child{ padding-bottom:0; }
.jt-timeline-item::before{
  content:""; position:absolute; inset-inline-start:calc(-1 * var(--space-6) + 2px);
  top:5px; width:12px; height:12px; border-radius:var(--r-full);
  background:var(--color-bg-container);
  box-shadow:0 0 0 2px var(--color-border-strong);
}
.jt-timeline-item[data-state="done"]::before{ background:var(--color-success);
  box-shadow:0 0 0 2px var(--color-success); }
.jt-timeline-item[data-state="current"]::before{ background:var(--color-accent);
  box-shadow:0 0 0 3px var(--color-accent-bg); }
.jt-timeline-time{ display:block; font-family:var(--font-num);
  font-size:var(--fs-sm); color:var(--color-text-secondary); }
.jt-timeline-title{ font-weight:600; }

/* ── 44. 트리 (Tree view — 카테고리·BOM 계층) ───────────────────────────────
   <details> 중첩으로 JS 없이 동작합니다. */
.jt-tree,.jt-tree ul{ list-style:none; margin:0; padding:0; }
.jt-tree ul{ padding-inline-start:var(--space-5);
  border-inline-start:1px solid var(--color-split); margin-inline-start:var(--space-2); }
.jt-tree-node > summary{
  display:flex; align-items:center; gap:var(--space-2);
  min-height:var(--control-height-sm); padding:0 var(--space-2);
  border-radius:var(--r-sm); cursor:pointer; list-style:none;
}
.jt-tree-node > summary::-webkit-details-marker{ display:none; }
.jt-tree-node > summary::before{
  content:"▸"; flex:none; color:var(--color-text-secondary);
  transition:transform var(--dur-fast) var(--ease-standard); }
.jt-tree-node[open] > summary::before{ transform:rotate(90deg); }
.jt-tree-node > summary:hover{ background:var(--color-fill-hover); }
.jt-tree-leaf{ display:flex; align-items:center; gap:var(--space-2);
  min-height:var(--control-height-sm);
  padding:0 var(--space-2) 0 var(--space-5); border-radius:var(--r-sm); }
.jt-tree-leaf:hover{ background:var(--color-fill-hover); }
.jt-tree [aria-selected="true"]{ background:var(--color-fill-selected);
  color:var(--color-text-selected); }

/* ── 45. 코드 블록 (Code snippet) ───────────────────────────────────────────
   개발자센터·기술 문서용. 가로 스크롤은 이 안에서만 생기게 가둡니다. */
.jt-code{
  margin:0; padding:var(--space-3) var(--space-4);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  font-size:var(--fs-sm); line-height:var(--lh-snug);
  color:var(--color-text); background:var(--color-bg-layout);
  border:1px solid var(--color-border); border-radius:var(--r-md);
  overflow-x:auto; white-space:pre;                /* 코드는 줄바꿈하지 않음 */
}
.jt-code-inline{
  padding:2px 6px; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.92em; color:var(--color-text);
  background:var(--color-fill-hover); border:1px solid var(--color-border);
  border-radius:var(--r-sm); overflow-wrap:anywhere;
}

/* ── 46. 표 확장 — 정렬 · 행 선택 · 선택 액션바 ─────────────────────────────*/
.jt-table th[aria-sort]{ cursor:pointer; user-select:none; white-space:nowrap; }
.jt-table th[aria-sort]:hover{ background:var(--color-fill-hover); }
.jt-table th[aria-sort]::after{ content:"↕"; margin-inline-start:var(--space-1);
  color:var(--color-text-tertiary); }
.jt-table th[aria-sort="ascending"]::after{ content:"↑"; color:var(--color-accent); }
.jt-table th[aria-sort="descending"]::after{ content:"↓"; color:var(--color-accent); }
.jt-table tr[aria-selected="true"] > td{ background:var(--color-fill-selected); }
.jt-table tbody tr:hover > td{ background:var(--color-fill-hover); }
/* 선택 액션바 — 표 위에 겹쳐 뜨는 막대 */
.jt-bulkbar{
  display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap;
  position:sticky; top:0; z-index:var(--z-sticky);
  min-height:var(--control-height-lg);
  padding:var(--space-2) var(--space-4);
  color:var(--color-on-primary); background:var(--color-primary);
  border-radius:var(--r-md);
}
.jt-bulkbar-count{ font-family:var(--font-num); font-weight:700; }
/* ⚠️ 어두운 막대 위의 ghost 버튼은 배경까지 투명으로 바꿔야 합니다.
   fg만 바꾸면 '흰 배경 + 흰 글자'가 되어 글자가 사라집니다. */
.jt-bulkbar .jt-btn-ghost{
  --jt-btn-bg:transparent;
  --jt-btn-fg:var(--color-on-primary);
  --jt-btn-border:rgba(255,255,255,.45);
  --jt-btn-bg-hover:rgba(255,255,255,.14);
  --jt-btn-bg-active:rgba(255,255,255,.22);
}

/* ── 47. 빈 표 행 (표 안의 빈 상태) ─────────────────────────────────────────*/
.jt-table-empty > td{ padding:var(--space-9) var(--space-4) !important;
  text-align:center; color:var(--color-text-secondary); }

/* ── 라운드 유틸리티 (v5.0 --r-none 신설 대응) ─────────────────────────────
   표 셀·풀블리드 배너·이미지 타일 등 각져야 하는 자리에 사용 */
.jt-r-none{ border-radius:var(--r-none) !important; }
.jt-r-sm{ border-radius:var(--r-sm) !important; }
.jt-r-md{ border-radius:var(--r-md) !important; }
.jt-r-lg{ border-radius:var(--r-lg) !important; }
.jt-r-full{ border-radius:var(--r-full) !important; }
