/* =========================================================
   Pilldoc Design System - Components

   전부 pd- 접두사를 쓴다. 기존 pilldocsite 의 .btn / .form-control 과
   이름이 겹치지 않아야 한 페이지에서 공존하며 점진 이관할 수 있다.

   목차
     01 Button / Button group
     02 Field / Input / Textarea / Select
     03 Checkbox / Radio / Switch / Slider
     04 Segmented / Tabs / Breadcrumb / Pagination
     05 Badge / Avatar / Tag
     06 Card / Product card
     07 Accordion
     08 Menu (Dropdown / Context / Combobox)
     09 Calendar / Date picker
     10 Table / Data table
     11 Tooltip / Toast / Modal
     12 Skeleton / Spinner / Empty
     13 Chart
   ========================================================= */


/* =========================================================
   01. BUTTON
   ========================================================= */
.pd-btn {
  font-family: inherit;
  font-size: 14px;
  font-weight: var(--pd-weight-semibold);
  line-height: 1;
  height: var(--pd-control-h);
  padding-inline: var(--pd-space-5);
  border-radius: var(--pd-radius-md);
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--pd-space-2);
  transition: background-color var(--pd-dur) var(--pd-ease),
              border-color var(--pd-dur) var(--pd-ease),
              color var(--pd-dur) var(--pd-ease),
              transform var(--pd-dur-fast) var(--pd-ease);
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
}
.pd-btn:hover { text-decoration: none; }
.pd-btn:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
/* 누르는 순간 1px 내려가 물리적인 반응을 만든다. */
.pd-btn:active { transform: translateY(1px); }

/*
   변형마다 hover 에서 글자색을 **다시 적습니다.**

   base.css 의 `:where(.pd-root) a:hover { color: var(--pd-mint-800) }` 때문입니다.
   :where() 는 괄호 안의 몫만 0 으로 만들고 뒤에 붙은 `a:hover` 의 몫은 그대로라
   그 규칙은 (0,1,1) 입니다. 반면 `.pd-btn--primary` 는 (0,1,0) — **한 수 아래**라
   단추가 <a> 일 때 hover 하면 흰 글자가 짙은 민트로 바뀌었습니다. 민트 판 위의
   짙은 민트 글자라 대비가 무너집니다(2차 메뉴의 [복약안내문 설정]에서 보였습니다).

   `.pd-btn:hover` 한 줄로는 못 막습니다 — 색이 변형마다 다르고, 여기서 쓸 수 있는
   값(inherit·unset)은 전부 **부모의 색**이 되기 때문입니다. 변형별로 적습니다.
   글자색은 쉴 때와 같습니다. 바뀌는 것은 바탕뿐입니다.
*/
.pd-btn--primary   { background: var(--pd-accent); color: var(--pd-text-on-accent); }
.pd-btn--primary:hover  { background: var(--pd-accent-hover); color: var(--pd-text-on-accent); }
.pd-btn--primary:active { background: var(--pd-accent-active); }

.pd-btn--secondary { background: var(--pd-neutral-action); color: var(--pd-text-inverted); }
.pd-btn--secondary:hover { background: var(--pd-neutral-action-hover); color: var(--pd-text-inverted); }

.pd-btn--cta       { background: var(--pd-cta); color: var(--pd-text-on-accent); }
.pd-btn--cta:hover { background: var(--pd-cta-hover); color: var(--pd-text-on-accent); }

.pd-btn--outline   { background: transparent; color: var(--pd-text-secondary); border-color: var(--pd-border-strong); }
.pd-btn--outline:hover { background: var(--pd-surface-sunken); border-color: var(--pd-border-hover); color: var(--pd-text); }

.pd-btn--ghost     { background: transparent; color: var(--pd-text-secondary); }
.pd-btn--ghost:hover { background: var(--pd-surface-muted); color: var(--pd-text); }

.pd-btn--danger    { background: var(--pd-danger); color: var(--pd-text-on-accent); }
.pd-btn--danger:hover { background: var(--pd-red-700); color: var(--pd-text-on-accent); }
.pd-btn--danger:focus-visible { box-shadow: var(--pd-focus-ring-danger); }

.pd-btn--sm { height: var(--pd-control-h-sm); font-size: 13px; padding-inline: var(--pd-space-3); border-radius: var(--pd-radius-sm); }
.pd-btn--lg { height: var(--pd-control-h-lg); font-size: 15px; padding-inline: var(--pd-space-6); }
.pd-btn--pill { border-radius: var(--pd-radius-pill); padding-inline: var(--pd-space-6); }
.pd-btn--block { display: flex; width: 100%; }

.pd-btn[disabled], .pd-btn[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

/* 로딩 상태. 라벨 폭을 유지해 버튼이 줄어들지 않게 한다. */
.pd-btn[data-loading="true"] { pointer-events: none; position: relative; color: transparent; }
.pd-btn[data-loading="true"] > * { visibility: hidden; }
.pd-btn[data-loading="true"]::after {
  content: "";
  position: absolute;
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  color: var(--pd-text-on-accent);
  animation: pd-spin 700ms linear infinite;
}
.pd-btn--outline[data-loading="true"]::after,
.pd-btn--ghost[data-loading="true"]::after { color: var(--pd-text-secondary); }

/* --- 아이콘 조합 ---
   Lucide 아이콘은 stroke 기반이라 굵은 라벨 옆에서 얇아 보인다.
   16px 아이콘 + 14px semibold 라벨이 시각적으로 맞는 조합이다.
   아이콘은 라벨 앞이 기본이고, 방향을 뜻할 때만 뒤에 둔다. */
.pd-btn .pd-icon { width: var(--pd-icon-sm); height: var(--pd-icon-sm); }
.pd-btn--lg .pd-icon { width: var(--pd-icon); height: var(--pd-icon); }

/* 아이콘만 있는 버튼. 정사각형을 유지하고 라벨은 pd-sr-only 로 넣는다. */
.pd-btn--icon {
  width: var(--pd-control-h);
  padding-inline: 0;
}
.pd-btn--icon.pd-btn--sm { width: var(--pd-control-h-sm); }
.pd-btn--icon.pd-btn--lg { width: var(--pd-control-h-lg); }
.pd-btn--icon .pd-icon { width: var(--pd-icon); height: var(--pd-icon); }

/* --- Button group ---
   인접한 버튼의 모서리와 테두리를 합쳐 하나의 덩어리로 만든다. */
.pd-btn-group { display: inline-flex; }
.pd-btn-group > .pd-btn { border-radius: 0; }
.pd-btn-group > .pd-btn:first-child { border-start-start-radius: var(--pd-radius-md); border-end-start-radius: var(--pd-radius-md); }
.pd-btn-group > .pd-btn:last-child  { border-start-end-radius: var(--pd-radius-md); border-end-end-radius: var(--pd-radius-md); }
/* 테두리가 있는 변형끼리는 1px 을 겹쳐 이중선을 없앤다. */
.pd-btn-group > .pd-btn + .pd-btn { margin-inline-start: -1px; }
/* 겹친 테두리 때문에 hover·focus 시 가려지므로 위로 올린다. */
.pd-btn-group > .pd-btn:hover,
.pd-btn-group > .pd-btn:focus-visible,
.pd-btn-group > .pd-btn[aria-pressed="true"] { position: relative; z-index: 1; }
.pd-btn-group > .pd-btn[aria-pressed="true"] {
  background: var(--pd-accent-subtle);
  border-color: var(--pd-accent);
  color: var(--pd-accent-on-subtle);
}
/* 세로 그룹.
   위의 가로용 :first-child / :last-child 규칙보다 특이도가 같거나 높아야 한다.
   `> .pd-btn { border-radius: 0 }` 만으로는 가로 규칙(클래스 2 + 의사클래스 1)을
   이기지 못해서 첫 버튼의 좌하단, 마지막 버튼의 우상단이 남아 둥글어졌다.
   그래서 세로에서는 네 모서리를 매번 전부 지정한다. */
.pd-btn-group--vertical { flex-direction: column; }
.pd-btn-group--vertical > .pd-btn { border-radius: 0; }
.pd-btn-group--vertical > .pd-btn:first-child {
  border-radius: var(--pd-radius-md) var(--pd-radius-md) 0 0;
}
.pd-btn-group--vertical > .pd-btn:last-child {
  border-radius: 0 0 var(--pd-radius-md) var(--pd-radius-md);
}
.pd-btn-group--vertical > .pd-btn:first-child:last-child {
  border-radius: var(--pd-radius-md);
}
.pd-btn-group--vertical > .pd-btn + .pd-btn { margin-inline-start: 0; margin-block-start: -1px; }

/* 버튼을 줄로 늘어놓을 때의 간격. 그룹과 달리 붙지 않는다. */
.pd-btn-row { display: flex; flex-wrap: wrap; gap: var(--pd-space-2); align-items: center; }


/* =========================================================
   02. FIELD / INPUT / TEXTAREA / SELECT
   ========================================================= */
.pd-field { display: flex; flex-direction: column; gap: var(--pd-space-2); }

/* 레이블은 항상 입력 위에 둔다. 플레이스홀더를 레이블로 쓰지 않는다. */
.pd-field__label {
  font-size: 13px;
  font-weight: var(--pd-weight-medium);
  color: var(--pd-text-secondary);
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-1);
}
.pd-field__label[data-required]::after {
  content: "*";
  color: var(--pd-danger);
  font-weight: var(--pd-weight-bold);
}
.pd-field__hint  { font-size: 12px; color: var(--pd-text-muted); }
.pd-field__error { font-size: 12px; color: var(--pd-danger); display: flex; align-items: center; gap: var(--pd-space-1); }
/* 내용이 없을 때 자리를 차지하지 않게 한다. 서버 검증 메시지는 대개 비어 있다. */
.pd-field__error:empty { display: none; }

/* jQuery unobtrusive validation 과의 연결.

   ASP.NET 의 asp-validation-for 는 오류가 나면 입력에 input-validation-error,
   메시지 span 에 field-validation-error 를 붙입니다. 우리 오류 표시는
   .pd-input--error 이지만 그 클래스를 붙이는 것은 서버가 아니라 이 라이브러리라
   두 이름을 함께 받습니다. 그러지 않으면 검증에 걸린 입력의 테두리가 그대로입니다.

   레거시가 아니라 프레임워크 규약이라 legacy-bridge 가 아니라 여기에 둡니다. */
input.pd-input.input-validation-error,
.pd-select.input-validation-error,
.pd-textarea.input-validation-error { border-color: var(--pd-danger); }
input.pd-input.input-validation-error:focus,
.pd-select.input-validation-error:focus,
.pd-textarea.input-validation-error:focus { box-shadow: var(--pd-focus-ring-danger); }
.pd-field .field-validation-error { font-size: 12px; color: var(--pd-danger); }

/* 모든 단일행 컨트롤이 공유하는 기본형. 높이를 토큰으로 고정해서
   type 이나 서체 크기에 따라 높이가 흔들리지 않게 한다. */
.pd-input,
.pd-select,
.pd-textarea {
  font-family: inherit;
  font-size: 14px;
  width: 100%;
  padding-inline: var(--pd-control-px);
  border-radius: var(--pd-radius-md);
  border: 1px solid var(--pd-border-strong);
  background: var(--pd-surface);
  color: var(--pd-text);
  transition: border-color var(--pd-dur) var(--pd-ease), box-shadow var(--pd-dur) var(--pd-ease);
  appearance: none;
}
.pd-input, .pd-select { height: var(--pd-control-h); }

.pd-input::placeholder, .pd-textarea::placeholder { color: var(--pd-text-placeholder); }

.pd-input:hover, .pd-select:hover, .pd-textarea:hover { border-color: var(--pd-border-hover); }
.pd-input:focus, .pd-select:focus, .pd-textarea:focus {
  outline: none;
  border-color: var(--pd-accent);
  box-shadow: var(--pd-focus-ring);
}
.pd-input[disabled], .pd-select[disabled], .pd-textarea[disabled] {
  background: var(--pd-surface-muted);
  color: var(--pd-text-muted);
  border-color: var(--pd-border);
  cursor: not-allowed;
}
.pd-input[readonly] { background: var(--pd-surface-sunken); }

/* type=search 는 값이 있을 때 브라우저가 자체 취소 버튼을 그린다.
   우리 지우기 버튼과 겹쳐 X 가 두 개로 보이고, 두 개의 동작이 서로 다르다
   (브라우저 것은 change 이벤트만 쏘고 지우기 버튼의 표시 상태를 갱신하지 못한다).
   검색 시맨틱은 유지하고 브라우저 위젯만 걷어낸다. */
.pd-input[type="search"]::-webkit-search-cancel-button,
.pd-input[type="search"]::-webkit-search-decoration,
.pd-input[type="search"]::-webkit-search-results-button { -webkit-appearance: none; appearance: none; display: none; }

.pd-input--error, .pd-select--error, .pd-textarea--error { border-color: var(--pd-danger); }
.pd-input--error:focus, .pd-select--error:focus, .pd-textarea--error:focus {
  border-color: var(--pd-danger);
  box-shadow: var(--pd-focus-ring-danger);
}

.pd-input--sm { height: var(--pd-control-h-sm); font-size: 13px; padding-inline: var(--pd-control-px-sm); }
.pd-input--lg { height: var(--pd-control-h-lg); font-size: 15px; padding-inline: var(--pd-control-px-lg); }

/* --- 비밀번호 ---
   v1 은 [type=password] 에만 font-size 20px 을 줘서 다른 입력보다
   높이가 더 컸다. 높이는 위에서 토큰으로 고정했으므로 여기서는
   가림 문자의 크기만 키운다. 가림 원(U+2022 계열 글리프)은 font-size 에
   비례하므로 19px 로 올려 또렷하게 만들고, letter-spacing 으로 원 사이를
   벌려 개수를 세기 쉽게 한다. 높이는 변하지 않는다.
   -webkit-text-security 는 비표준이고 type=password 로 이미 가려지므로 쓰지 않는다. */
.pd-input[type="password"] {
  font-size: 19px;
  letter-spacing: 0.14em;
}
/* 플레이스홀더는 본문 크기로 되돌린다. 안 그러면 안내문이 19px 로 뜬다. */
.pd-input[type="password"]::placeholder {
  font-size: 14px;
  letter-spacing: normal;
}
/* 비밀번호 표시 토글로 type 이 text 가 되면 원래 크기로 돌아온다. */

/* --- Textarea --- */
.pd-textarea {
  min-height: calc(var(--pd-control-h) * 2.5);
  padding-block: var(--pd-space-3);
  line-height: 1.6;
  resize: vertical;
  /* 브라우저 기본 리사이즈 핸들이 모서리를 넘지 않게 한다. */
  overflow: auto;
}
.pd-textarea--fixed { resize: none; }
/* 입력 길이 카운터. textarea 와 한 묶음으로 오른쪽 아래에 붙인다. */
.pd-textarea-wrap { position: relative; display: flex; flex-direction: column; gap: var(--pd-space-1); }
.pd-textarea-count { font-size: 12px; color: var(--pd-text-muted); text-align: right; font-variant-numeric: tabular-nums; }
.pd-textarea-count[data-over="true"] { color: var(--pd-danger); font-weight: var(--pd-weight-semibold); }

/* --- Native select ---
   appearance:none 으로 화살표를 없애고 배경 이미지로 직접 그린다.
   Lucide chevron-down 을 data URI 로 넣는다. currentColor 를 쓸 수 없어
   stroke 색을 --pd-ink-500 값으로 고정했다. 색을 바꾸려면 여기도 바꾼다. */
.pd-select {
  padding-inline-end: calc(var(--pd-space-3) + var(--pd-icon) + var(--pd-space-2));
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A9099' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--pd-space-3) center;
  background-size: var(--pd-icon) var(--pd-icon);
  cursor: pointer;
}
.pd-select[disabled] { cursor: not-allowed; }
/* 줄 안에 여러 개를 늘어놓는 선택. 연월 조회처럼 내용 길이가 정해진 경우다.
   기본은 width:100% 라 flex 줄에 넣으면 서로 늘어난다. */
.pd-select--auto { width: auto; }
.pd-select[multiple] {
  height: auto;
  padding-block: var(--pd-space-2);
  background-image: none;
}
.pd-select[multiple] option { padding: var(--pd-space-1) var(--pd-space-2); }

/* --- Input group ---
   입력 좌우에 아이콘·버튼·고정 단위를 붙인다.
   패딩 보정은 그룹의 수식어로 명시한다. :has() 에 의존하지 않아
   구형 브라우저에서도 어긋나지 않는다.

     pd-input-group--icon-start   왼쪽 아이콘 (검색, 캘린더)
     pd-input-group--action-end   오른쪽 버튼 (지우기, 달력 열기, 비밀번호 보기)
     pd-input-group--action-2     오른쪽 버튼 2개 (지우기 + 검색)
   --------------------------------------------------------- */
.pd-input-group { position: relative; display: flex; align-items: center; width: 100%; }
.pd-input-group > .pd-input { width: 100%; }

/* 아이콘·버튼은 입력 위에 겹쳐 놓는다. 입력의 테두리와 포커스 링이
   끊기지 않게 하려면 이 방식이 flex 분할보다 안전하다. */
.pd-input-group__icon {
  position: absolute;
  inset-inline-start: var(--pd-space-3);
  display: inline-flex;
  color: var(--pd-text-placeholder);
  pointer-events: none;
}
.pd-input-group__icon .pd-icon { width: var(--pd-icon); height: var(--pd-icon); }
.pd-input-group--icon-start > .pd-input {
  padding-inline-start: calc(var(--pd-space-3) + var(--pd-icon) + var(--pd-space-2));
}

/* 오른쪽 액션 버튼. 입력 높이 안에 들어가도록 4px 작게 만든다. */
.pd-input-group__action {
  position: absolute;
  inset-inline-end: var(--pd-space-1);
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.pd-input-group__btn {
  width: calc(var(--pd-control-h) - var(--pd-space-2));
  height: calc(var(--pd-control-h) - var(--pd-space-2));
  display: inline-grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--pd-text-muted);
  border-radius: var(--pd-radius-sm);
  cursor: pointer;
  transition: background-color var(--pd-dur) var(--pd-ease), color var(--pd-dur) var(--pd-ease);
}
.pd-input-group__btn:hover { background: var(--pd-surface-muted); color: var(--pd-text); }
.pd-input-group__btn:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-input-group__btn .pd-icon { width: var(--pd-icon); height: var(--pd-icon); }
.pd-input-group--action-end > .pd-input {
  padding-inline-end: calc(var(--pd-space-1) + var(--pd-control-h) - var(--pd-space-2) + var(--pd-space-1));
}

/*
   입력칸 **옆에** 서는 진짜 버튼(.pd-btn)

   위의 __btn 은 입력칸 안에 겹쳐 놓는 아이콘 단추라 붙어 있어야 하지만,
   .pd-btn 은 나란히 서는 단추입니다. 그런데도 그룹에 gap 이 없어서 입력칸에
   딱 붙어, 둘이 한 덩어리처럼 보였습니다(검색 줄 3곳 — 약사 어드바이스 ·
   복약지도 정보수정 · 기기 등록).

   옆에 단추가 서면 입력칸 안쪽 오른쪽 여백도 필요 없습니다. --action-end 가
   겹쳐 놓을 자리로 비워 둔 것이라, 그대로 두면 글자가 까닭 없이 밀립니다.
*/
.pd-input-group > .pd-btn {
  flex: 0 0 auto;
  margin-inline-start: var(--pd-space-2);
}
.pd-input-group--action-end:has(> .pd-btn) > .pd-input {
  padding-inline-end: var(--pd-control-px);
}
.pd-input-group--action-2 > .pd-input {
  padding-inline-end: calc(var(--pd-space-1) + (var(--pd-control-h) - var(--pd-space-2)) * 2 + var(--pd-space-2));
}

/* 지우기 버튼은 값이 있을 때만 보인다. 값 여부는 JS 가
   data-has-value 로 알려준다. */
.pd-input-group__btn[data-role="clear"] { display: none; }
.pd-input-group[data-has-value="true"] .pd-input-group__btn[data-role="clear"] { display: inline-grid; }

/* 고정 단위·접두 텍스트. 원, 매, % 처럼 바뀌지 않는 표시에 쓴다. */
.pd-input-group__affix {
  position: absolute;
  inset-inline-end: var(--pd-space-3);
  font-size: 13px;
  color: var(--pd-text-muted);
  pointer-events: none;
}
.pd-input-group--affix-end > .pd-input {
  padding-inline-end: calc(var(--pd-space-3) + 2.5em);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* 입력 + 붙은 버튼(주소검색 같은 것). 겹치지 않고 나란히 놓는 형태. */
.pd-input-attached { display: flex; gap: 0; width: 100%; }
.pd-input-attached > .pd-input {
  border-start-end-radius: 0;
  border-end-end-radius: 0;
}
.pd-input-attached > .pd-btn {
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  margin-inline-start: -1px;
  flex-shrink: 0;
}
.pd-input-attached > .pd-input:focus { position: relative; z-index: 1; }

/* 가로로 붙는 필드 묶음(생년월일 3칸 등) */
.pd-field-row { display: flex; gap: var(--pd-space-2); align-items: flex-start; }
.pd-field-row > * { flex: 1 1 0; min-width: 0; }
.pd-field-row > .pd-field-row__sep {
  flex: 0 0 auto;
  color: var(--pd-text-muted);
  align-self: center;
  padding-block-start: 2px;
}


/* =========================================================
   03. CHECKBOX / RADIO / SWITCH / SLIDER
   ========================================================= */
/* 실제 input 은 화면에서 감추되 접근성 트리에는 남긴다.
   반드시 .pd-check__box 를 함께 마크업해야 표시가 나온다.

   상태 규칙은 .pd-check 와 .pd-check-card 양쪽에 걸어야 한다.
   .pd-check 로만 스코프하면 카드형 안의 상자가 기본 모양만 받고
   체크·포커스·비활성 표시가 전혀 나오지 않는다. */
.pd-check {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-2);
  font-size: 14px;
  color: var(--pd-text);
  cursor: pointer;
  user-select: none;
  min-height: 24px;
}
:is(.pd-check, .pd-check-card) input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  pointer-events: none;
}
.pd-check__box {
  width: 18px; height: 18px;
  border-radius: var(--pd-radius-xs);
  border: 1.5px solid var(--pd-border-hover);
  background: var(--pd-surface);
  display: inline-grid;
  place-items: center;
  flex-shrink: 0;
  transition: background-color var(--pd-dur) var(--pd-ease), border-color var(--pd-dur) var(--pd-ease);
}
.pd-check__box .pd-icon {
  width: 12px; height: 12px;
  color: var(--pd-text-on-accent);
  opacity: 0;
  transition: opacity var(--pd-dur-fast) var(--pd-ease);
}
:is(.pd-check, .pd-check-card) input:checked + .pd-check__box {
  background: var(--pd-accent);
  border-color: var(--pd-accent);
}
:is(.pd-check, .pd-check-card) input:checked + .pd-check__box .pd-icon { opacity: 1; }
:is(.pd-check, .pd-check-card) input:indeterminate + .pd-check__box {
  background: var(--pd-accent);
  border-color: var(--pd-accent);
}
:is(.pd-check, .pd-check-card) input:indeterminate + .pd-check__box::after {
  content: "";
  width: 10px; height: 2px;
  border-radius: 1px;
  background: var(--pd-text-on-accent);
  position: absolute;
}
:is(.pd-check, .pd-check-card) input:indeterminate + .pd-check__box .pd-icon { opacity: 0; }
.pd-check__box { position: relative; }
:is(.pd-check, .pd-check-card) input:focus-visible + .pd-check__box { box-shadow: var(--pd-focus-ring); }
:is(.pd-check, .pd-check-card) input:disabled + .pd-check__box { background: var(--pd-surface-muted); border-color: var(--pd-border); }
:is(.pd-check, .pd-check-card) input:disabled ~ * { color: var(--pd-text-muted); }
:is(.pd-check, .pd-check-card):has(input:disabled) { cursor: not-allowed; }

/* Radio. 같은 상자를 원형으로 바꾼다.
   원형은 --radio 수정자로만 만든다. 마크업에서 border-radius 를 인라인으로
   주면 모양만 원이 되고 안쪽 점을 그리는 ::after 가 따라오지 않는다. */
:is(.pd-check--radio, .pd-check-card--radio) .pd-check__box { border-radius: 50%; }
:is(.pd-check--radio, .pd-check-card--radio) .pd-check__box::after {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: transparent;
  transition: background-color var(--pd-dur) var(--pd-ease);
}
:is(.pd-check--radio, .pd-check-card--radio) input:checked + .pd-check__box { background: var(--pd-accent); border-color: var(--pd-accent); }
:is(.pd-check--radio, .pd-check-card--radio) input:checked + .pd-check__box::after { background: var(--pd-text-on-accent); }
:is(.pd-check--radio, .pd-check-card--radio) .pd-check__box .pd-icon { display: none; }

/* 카드형 선택. 선택지에 설명이 붙을 때 쓴다. */
.pd-check-card {
  display: flex;
  align-items: flex-start;
  gap: var(--pd-space-3);
  padding: var(--pd-space-4);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  background: var(--pd-surface);
  cursor: pointer;
  transition: border-color var(--pd-dur) var(--pd-ease), background-color var(--pd-dur) var(--pd-ease);
}
/* 상자를 제목의 첫 줄 가운데에 맞춘다. 제목 line-height 가 상자보다 커서
   flex-start 로만 두면 상자가 약간 위로 붙어 보인다. */
.pd-check-card > .pd-check__box { margin-top: 2px; }
.pd-check-card:hover { border-color: var(--pd-border-hover); }
.pd-check-card:has(input:disabled):hover { border-color: var(--pd-border); }
.pd-check-card:has(input:checked) { border-color: var(--pd-accent); background: var(--pd-accent-subtle); }
.pd-check-card:has(input:disabled) { cursor: not-allowed; background: var(--pd-surface-muted); }
.pd-check-card__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pd-check-card__title { font-size: 14px; font-weight: var(--pd-weight-semibold); color: var(--pd-text); }
.pd-check-card__desc  { font-size: 13px; color: var(--pd-text-muted); line-height: 1.5; }

/* --- Switch --- */
.pd-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-2);
  font-size: 14px;
  color: var(--pd-text);
  cursor: pointer;
  user-select: none;
}
.pd-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.pd-switch__track {
  position: relative;
  width: 44px; height: 24px;
  border-radius: var(--pd-radius-pill);
  background: var(--pd-border-strong);
  transition: background-color var(--pd-dur) var(--pd-ease);
  flex-shrink: 0;
}
.pd-switch__thumb {
  position: absolute;
  top: 2px; left: 2px;
  width: 20px; height: 20px;
  background: var(--pd-surface);
  border-radius: 50%;
  box-shadow: var(--pd-shadow-xs);
  transition: transform var(--pd-dur) var(--pd-ease);
}
.pd-switch input:checked ~ .pd-switch__track { background: var(--pd-accent); }
.pd-switch input:checked ~ .pd-switch__track .pd-switch__thumb { transform: translateX(20px); }
.pd-switch input:focus-visible ~ .pd-switch__track { box-shadow: var(--pd-focus-ring); }
.pd-switch input:disabled ~ .pd-switch__track { opacity: 0.5; }
.pd-switch:has(input:disabled) { cursor: not-allowed; }

.pd-switch--labeled .pd-switch__side {
  font-size: 13px;
  font-weight: var(--pd-weight-semibold);
  color: var(--pd-text-muted);
  transition: color var(--pd-dur) var(--pd-ease);
}
.pd-switch--labeled input:not(:checked) ~ .pd-switch__side--off { color: var(--pd-text); }
.pd-switch--labeled input:checked ~ .pd-switch__side--on { color: var(--pd-text); }

.pd-switch--inline .pd-switch__track { width: 64px; height: 28px; }
.pd-switch--inline .pd-switch__thumb { width: 22px; height: 22px; top: 3px; left: 3px; }
.pd-switch--inline input:checked ~ .pd-switch__track .pd-switch__thumb { transform: translateX(36px); }
.pd-switch--inline .pd-switch__text {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-size: 10px;
  font-weight: var(--pd-weight-bold);
  letter-spacing: 0.06em;
  pointer-events: none;
  transition: opacity var(--pd-dur) var(--pd-ease);
}
.pd-switch--inline .pd-switch__text--on  { left: 10px; color: var(--pd-text-on-accent); opacity: 0; }
.pd-switch--inline .pd-switch__text--off { right: 10px; color: var(--pd-text-muted); opacity: 1; }
.pd-switch--inline input:checked ~ .pd-switch__track .pd-switch__text--on  { opacity: 1; }
.pd-switch--inline input:checked ~ .pd-switch__track .pd-switch__text--off { opacity: 0; }

/* --- Slider ---
   input[type=range] 를 직접 꾸민다. 트랙의 채워진 부분은 JS 가
   --pd-slider-pct 를 갱신해 그린다. */
.pd-slider-field { display: flex; flex-direction: column; gap: var(--pd-space-2); }
.pd-slider-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--pd-space-3); }
.pd-slider-value {
  font-size: 14px;
  font-weight: var(--pd-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--pd-text);
}
.pd-slider {
  --pd-slider-pct: 50%;
  appearance: none;
  width: 100%;
  height: 20px;
  background: transparent;
  cursor: pointer;
  margin: 0;
}
.pd-slider:focus { outline: none; }

/* 트랙은 두 브라우저 엔진에서 각각 선언해야 한다. 묶으면 둘 다 무시된다. */
.pd-slider::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: var(--pd-radius-pill);
  background: linear-gradient(to right,
    var(--pd-accent) 0 var(--pd-slider-pct),
    var(--pd-border-strong) var(--pd-slider-pct) 100%);
}
.pd-slider::-moz-range-track {
  height: 6px;
  border-radius: var(--pd-radius-pill);
  background: var(--pd-border-strong);
}
.pd-slider::-moz-range-progress {
  height: 6px;
  border-radius: var(--pd-radius-pill);
  background: var(--pd-accent);
}
.pd-slider::-webkit-slider-thumb {
  appearance: none;
  width: 18px; height: 18px;
  margin-top: -6px;
  border-radius: 50%;
  background: var(--pd-surface);
  border: 2px solid var(--pd-accent);
  box-shadow: var(--pd-shadow-sm);
  transition: transform var(--pd-dur-fast) var(--pd-ease);
}
.pd-slider::-moz-range-thumb {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--pd-surface);
  border: 2px solid var(--pd-accent);
  box-shadow: var(--pd-shadow-sm);
}
.pd-slider:active::-webkit-slider-thumb { transform: scale(1.12); }
.pd-slider:focus-visible::-webkit-slider-thumb { box-shadow: var(--pd-focus-ring); }
.pd-slider:focus-visible::-moz-range-thumb { box-shadow: var(--pd-focus-ring); }
.pd-slider[disabled] { cursor: not-allowed; opacity: 0.5; }
.pd-slider-ticks {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--pd-text-muted);
  font-variant-numeric: tabular-nums;
}


/* =========================================================
   04. SEGMENTED / TABS / BREADCRUMB / PAGINATION
   ========================================================= */
.pd-segmented {
  background: var(--pd-surface-muted);
  padding: var(--pd-space-1);
  border-radius: var(--pd-radius-pill);
  display: inline-flex;
  gap: 2px;
}
.pd-segmented__item {
  padding: var(--pd-space-2) var(--pd-space-4);
  border-radius: var(--pd-radius-pill);
  font-size: 13px;
  color: var(--pd-text-secondary);
  font-weight: var(--pd-weight-medium);
  cursor: pointer;
  border: 0;
  background: transparent;
  font-family: inherit;
  white-space: nowrap;
  transition: background-color var(--pd-dur) var(--pd-ease), color var(--pd-dur) var(--pd-ease);
}
.pd-segmented__item:hover { color: var(--pd-text); }
.pd-segmented__item[aria-selected="true"], .pd-segmented__item.is-active {
  background: var(--pd-surface);
  color: var(--pd-text);
  box-shadow: var(--pd-shadow-xs);
  font-weight: var(--pd-weight-bold);
}
.pd-segmented__item:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }

/* 라디오로 만드는 세그먼트.

   버튼 세그먼트는 화면 안에서 보기를 바꾸는 데 쓴다. 값이 폼과 함께
   서버로 제출돼야 하면 라디오여야 한다. 버튼으로 만들고 hidden 입력에
   값을 복사하면 JS 가 죽었을 때 조회 조건이 사라진다.

   label 이 .pd-segmented__item 을 그대로 쓰므로 모양 규칙은 위와 공유한다.
   input 은 label 바로 앞에 둔다. */
.pd-segmented input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  pointer-events: none;
}
.pd-segmented input[type="radio"]:checked + .pd-segmented__item {
  background: var(--pd-surface);
  color: var(--pd-text);
  box-shadow: var(--pd-shadow-xs);
  font-weight: var(--pd-weight-bold);
}
.pd-segmented input[type="radio"]:focus-visible + .pd-segmented__item {
  box-shadow: var(--pd-focus-ring);
}
.pd-segmented input[type="radio"]:disabled + .pd-segmented__item {
  color: var(--pd-text-placeholder);
  cursor: not-allowed;
}

/* --- Tabs --- */
.pd-tabs {
  display: flex;
  gap: var(--pd-space-1);
  /* 밑줄을 border 로 그리고 탭을 margin -1px 로 겹치면, 아래의 overflow-x
     때문에 겹친 1px 이 패딩 박스에서 잘려 회색 선이 활성 탭 위로 보인다.
     inset box-shadow 는 부모 배경 층에 그려지므로 자식 탭이 항상 위에 온다. */
  box-shadow: inset 0 -1px 0 var(--pd-border);
  /* 탭이 많으면 줄바꿈 대신 가로 스크롤한다. 두 줄 탭은 만들지 않는다. */
  overflow-x: auto;
  scrollbar-width: none;
}
.pd-tabs::-webkit-scrollbar { display: none; }
.pd-tab {
  padding: var(--pd-space-3) var(--pd-space-5);
  font-size: 14px;
  color: var(--pd-text-muted);
  font-weight: var(--pd-weight-medium);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  background: transparent;
  border-top: 0; border-left: 0; border-right: 0;
  font-family: inherit;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-2);
  transition: color var(--pd-dur) var(--pd-ease), border-color var(--pd-dur) var(--pd-ease);
}
/* 탭이 <a> 일 때 base.css 의 :where(.pd-root) a:hover 가 밑줄을 긋습니다.
   글자에 그어지는 밑줄은 탭의 활성 표시(아래 2px 바)와 뜻이 겹쳐 어느 쪽이
   현재 위치인지 헷갈립니다. 밑줄을 떼고, 대신 활성 탭과 같은 자리의 바를
   연하게 켭니다 — 누르면 이 바가 민트로 진해진다는 것을 미리 보여 줍니다. */
.pd-tab:hover {
  color: var(--pd-text-secondary);
  text-decoration: none;
  border-bottom-color: var(--pd-border-strong);
}
/* 이미 켜져 있는 탭은 hover 로 색이 흐려지지 않게 둡니다. */
.pd-tab[aria-selected="true"]:hover,
.pd-tab.is-active:hover { color: var(--pd-text); border-bottom-color: var(--pd-accent); }
/* 활성 탭 밑줄은 주요색(민트)이다. 코랄은 전환 유도(CTA)에만 쓰고
   현재 위치 표시에는 쓰지 않는다. 색이 뜻을 잃지 않게 하는 규칙이다. */
.pd-tab[aria-selected="true"], .pd-tab.is-active {
  color: var(--pd-text);
  border-bottom-color: var(--pd-accent);
  font-weight: var(--pd-weight-bold);
  position: relative;
  z-index: 1;
}
.pd-tab:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-tab[disabled] { color: var(--pd-text-placeholder); cursor: not-allowed; }
/* 탭 안의 개수 표시 */
.pd-tab__count {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  background: var(--pd-surface-muted);
  color: var(--pd-text-muted);
  padding: 1px var(--pd-space-2);
  border-radius: var(--pd-radius-pill);
}
.pd-tab[aria-selected="true"] .pd-tab__count { background: var(--pd-accent-subtle); color: var(--pd-accent-on-subtle); }
.pd-tabpanel[hidden] { display: none; }

/* --- Breadcrumb ---
   구분자는 CSS 로 그린다. 마크업에 문자를 넣으면 스크린리더가 읽는다. */
.pd-breadcrumb { display: flex; align-items: center; flex-wrap: wrap; gap: var(--pd-space-1); font-size: 13px; }
.pd-breadcrumb__item { display: inline-flex; align-items: center; gap: var(--pd-space-1); }
.pd-breadcrumb__item + .pd-breadcrumb__item::before {
  content: "";
  width: 14px; height: 14px;
  margin-inline: 2px;
  flex-shrink: 0;
  background-color: var(--pd-text-placeholder);
  /* Lucide chevron-right */
  -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.pd-breadcrumb__link { color: var(--pd-text-muted); }
.pd-breadcrumb__link:hover { color: var(--pd-text); text-decoration: underline; }
.pd-breadcrumb__item[aria-current="page"] { color: var(--pd-text); font-weight: var(--pd-weight-semibold); }
/* 경로가 길면 가운데를 접는다. */
.pd-breadcrumb__ellipsis {
  color: var(--pd-text-placeholder);
  padding-inline: var(--pd-space-1);
  background: transparent;
  border: 0;
  cursor: pointer;
  border-radius: var(--pd-radius-sm);
}
.pd-breadcrumb__ellipsis:hover { background: var(--pd-surface-muted); color: var(--pd-text); }

/* --- Pagination --- */
.pd-pagination {
  display: flex;
  align-items: center;
  gap: var(--pd-space-1);
  justify-content: center;
  /* 항목이 많아도 가로로 넘치지 않게 한다. 아래 미디어쿼리가 번호를
     줄이지만, 그 전 단계의 안전장치로 둔다. */
  flex-wrap: wrap;
}
.pd-pagination__item {
  min-width: var(--pd-control-h-sm);
  height: var(--pd-control-h-sm);
  padding-inline: var(--pd-space-2);
  display: inline-grid;
  place-items: center;
  border-radius: var(--pd-radius-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--pd-text-secondary);
  font-size: 13px;
  font-weight: var(--pd-weight-medium);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  font-family: inherit;
  /* 서버가 링크(a)로 그리는 경우가 있다. 밑줄과 색을 버튼과 맞춘다. */
  text-decoration: none;
  transition: background-color var(--pd-dur) var(--pd-ease), color var(--pd-dur) var(--pd-ease);
}
.pd-pagination__item:hover { background: var(--pd-surface-muted); color: var(--pd-text); text-decoration: none; }
.pd-pagination__item[aria-current="page"] {
  background: var(--pd-accent);
  border-color: var(--pd-accent);
  color: var(--pd-text-on-accent);
  font-weight: var(--pd-weight-bold);
}
/* 갈 곳이 없는 이동 버튼. button 이면 disabled, 링크 자리를 span 으로
   그리면 aria-disabled 가 된다. 둘 다 같은 모양이어야 한다. */
.pd-pagination__item[disabled],
.pd-pagination__item[aria-disabled="true"] { color: var(--pd-text-placeholder); cursor: not-allowed; background: transparent; }
.pd-pagination__item:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-pagination__gap { color: var(--pd-text-placeholder); padding-inline: var(--pd-space-1); user-select: none; }

/* 좁은 화면에서는 번호를 모두 보여 주려 하지 않는다.
   현재 페이지와 앞뒤 이동만 남기고, 처음과 마지막으로 가는 버튼도 접는다.
   숫자 버튼에는 .pd-pagination__num 을 붙여야 이 규칙이 걸린다. */
@media (max-width: 640px) {
  .pd-pagination__num:not([aria-current="page"]),
  .pd-pagination__gap,
  .pd-pagination__item[data-page="first"],
  .pd-pagination__item[data-page="last"] { display: none; }
  /* 남은 현재 페이지 표시는 눌러도 하는 일이 없으므로 버튼처럼 보이지 않게 한다. */
  .pd-pagination__num[aria-current="page"] { pointer-events: none; }
}
/* 전체 건수와 페이지 크기 선택을 붙이는 줄 */
.pd-pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pd-space-4);
  flex-wrap: wrap;
}
.pd-pagination-bar__count { font-size: 13px; color: var(--pd-text-muted); font-variant-numeric: tabular-nums; }
.pd-pagination-bar__size { display: flex; align-items: center; gap: var(--pd-space-2); font-size: 13px; color: var(--pd-text-muted); }
.pd-pagination-bar__size .pd-select { width: auto; height: var(--pd-control-h-sm); font-size: 13px; }


/* =========================================================
   05. BADGE / AVATAR / TAG
   ========================================================= */
.pd-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-1);
  padding: 3px var(--pd-space-2);
  font-size: 12px;
  font-weight: var(--pd-weight-bold);
  border-radius: var(--pd-radius-sm);
  letter-spacing: 0.01em;
  white-space: nowrap;
  line-height: 1.4;
}
.pd-badge--mint    { background: var(--pd-accent-subtle); color: var(--pd-accent-on-subtle); }
.pd-badge--coral   { background: var(--pd-cta-subtle); color: var(--pd-cta-on-subtle); }
.pd-badge--gold    { background: var(--pd-warning-subtle); color: var(--pd-warning-on-subtle); }
.pd-badge--success { background: var(--pd-success-subtle); color: var(--pd-success-on-subtle); }
.pd-badge--danger  { background: var(--pd-danger-subtle); color: var(--pd-danger-on-subtle); }
.pd-badge--ink     { background: var(--pd-surface-inverted); color: var(--pd-text-inverted); }
.pd-badge--gray    { background: var(--pd-surface-muted); color: var(--pd-text-secondary); }
.pd-badge--outline { background: transparent; border: 1px solid var(--pd-border-strong); color: var(--pd-text-secondary); }
/* 점은 실제 상태를 뜻할 때만 쓴다. 장식으로 모든 배지에 붙이지 않는다. */
.pd-badge--dot::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.pd-badge .pd-icon { width: 12px; height: 12px; }

/* 닫기 버튼이 있는 태그 */
.pd-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-1);
  padding: var(--pd-space-1) var(--pd-space-1) var(--pd-space-1) var(--pd-space-2);
  font-size: 13px;
  background: var(--pd-surface-muted);
  color: var(--pd-text-secondary);
  border-radius: var(--pd-radius-sm);
}
.pd-tag__remove {
  width: 18px; height: 18px;
  display: inline-grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--pd-text-muted);
  border-radius: var(--pd-radius-xs);
  cursor: pointer;
}
.pd-tag__remove:hover { background: var(--pd-border); color: var(--pd-text); }
.pd-tag__remove .pd-icon { width: 12px; height: 12px; }

/* --- Avatar ---
   이미지가 없으면 이니셜, 이니셜도 없으면 아이콘으로 내려간다.
   배경은 브랜드 색이 아니라 뉴트럴을 기본으로 한다. 사람마다 다른
   브랜드 색을 뿌리면 색이 상태를 뜻한다는 규칙이 무너진다. */
.pd-avatar {
  position: relative;
  width: var(--pd-avatar-size, 40px);
  height: var(--pd-avatar-size, 40px);
  border-radius: 50%;
  overflow: hidden;
  display: inline-grid;
  /* 칸을 컨테이너 폭에 맞추고 글자는 인라인으로 가운데 정렬한다.
     justify-items:center 로 두면 내용이 컨테이너보다 넓을 때(이니셜을 두 자
     넘게 넣은 경우) 정렬이 시작 모서리로 붙어 왼쪽으로 밀려 보인다.
     칸을 늘리고 text-align 으로 정렬하면 넘쳐도 양쪽이 대칭으로 잘린다. */
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  justify-items: stretch;
  text-align: center;
  flex-shrink: 0;
  background: var(--pd-surface-muted);
  color: var(--pd-text-secondary);
  font-size: calc(var(--pd-avatar-size, 40px) * 0.36);
  font-weight: var(--pd-weight-semibold);
  line-height: 1;
  user-select: none;
}
.pd-avatar img { width: 100%; height: 100%; object-fit: cover; }
.pd-avatar .pd-icon { width: 55%; height: 55%; justify-self: center; color: var(--pd-text-placeholder); }
.pd-avatar--xs { --pd-avatar-size: 24px; }
.pd-avatar--sm { --pd-avatar-size: 32px; }
.pd-avatar--lg { --pd-avatar-size: 56px; }
.pd-avatar--xl { --pd-avatar-size: 80px; }
.pd-avatar--square { border-radius: var(--pd-radius-md); }
.pd-avatar--accent { background: var(--pd-accent-subtle); color: var(--pd-accent-on-subtle); }

/* 접속 상태 점. 실제 상태를 나타낼 때만 쓴다. */
.pd-avatar-wrap { position: relative; display: inline-flex; }
.pd-avatar-status {
  position: absolute;
  right: 0; bottom: 0;
  width: 30%; height: 30%;
  min-width: 8px; min-height: 8px;
  border-radius: 50%;
  border: 2px solid var(--pd-surface);
  background: var(--pd-text-placeholder);
}
.pd-avatar-status[data-status="online"] { background: var(--pd-success); }
.pd-avatar-status[data-status="busy"]   { background: var(--pd-danger); }
.pd-avatar-status[data-status="away"]   { background: var(--pd-warning); }

/* 겹쳐 쌓는 그룹 */
.pd-avatar-group { display: inline-flex; }
.pd-avatar-group > .pd-avatar {
  border: 2px solid var(--pd-surface);
  margin-inline-start: -10px;
}
.pd-avatar-group > .pd-avatar:first-child { margin-inline-start: 0; }
.pd-avatar-group > .pd-avatar--sm { margin-inline-start: -8px; }
.pd-avatar-group__more {
  background: var(--pd-surface-inverted);
  color: var(--pd-text-inverted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}


/* =========================================================
   06. CARD
   ========================================================= */
.pd-card {
  background: var(--pd-surface);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  /* 여백은 __head / __body / __foot 이 갖는다. 그래도 0 을 적어 두는 이유는,
     style.css 가 태그 선택자로 section { padding: 80px 0 } 을 걸어 두었기
     때문이다(랜딩 페이지 단락 여백). 카드를 <section> 이나 <article> 로 쓰면
     그 80px 이 그대로 들어와 위아래에 빈 띠가 생겼다. */
  padding: 0;
}
.pd-card__head {
  padding: var(--pd-space-5) var(--pd-space-6);
  border-bottom: 1px solid var(--pd-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pd-space-4);
}
.pd-card__title { font-size: 16px; font-weight: var(--pd-weight-bold); color: var(--pd-text); }
.pd-card__body { padding: var(--pd-space-6); }
.pd-card__foot {
  padding: var(--pd-space-4) var(--pd-space-6);
  border-top: 1px solid var(--pd-border);
  background: var(--pd-surface-sunken);
  display: flex;
  justify-content: flex-end;
  gap: var(--pd-space-2);
  border-end-start-radius: var(--pd-radius-lg);
  border-end-end-radius: var(--pd-radius-lg);
}

/* 상품 카드 */
.pd-product {
  background: var(--pd-surface);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  overflow: hidden;
  transition: box-shadow var(--pd-dur) var(--pd-ease), transform var(--pd-dur) var(--pd-ease);
  position: relative;
  display: flex;
  flex-direction: column;
  /* 카드 전체가 링크인 것이 보통이다(상품 목록). base.css 의
     :where(.pd-root) a 가 글자를 민트로 칠하고 hover 에 밑줄을 그으므로
     여기서 되돌린다 — :where 는 특이도가 0 이라 이 규칙이 이긴다.
     상품구매 목록을 옮기면서 카드 글자가 통째로 민트로 나와 발견했다. */
  color: inherit;
  text-decoration: none;
}
.pd-product:hover { box-shadow: var(--pd-shadow-md); transform: translateY(-2px); color: inherit; text-decoration: none; }
/* 카드가 <a> 일 때 키보드 초점을 보이게 한다. transform 이 걸려 있어
   outline 은 카드와 함께 움직이지만, 그림자 링은 모서리 반경을 따라간다. */
.pd-product:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-product__tag {
  position: absolute; top: 0; left: 0;
  padding: var(--pd-space-1) var(--pd-space-3);
  font-size: 12px;
  font-weight: var(--pd-weight-bold);
  color: var(--pd-ink-900);
  background: var(--pd-gold-400);
  border-end-end-radius: var(--pd-radius-sm);
  z-index: 1;
}
.pd-product__thumb {
  aspect-ratio: 1.2 / 1;
  background: var(--pd-surface-sunken);
  display: grid;
  place-items: center;
  color: var(--pd-text-placeholder);
  font-size: 13px;
}
.pd-product__thumb img { width: 100%; height: 100%; object-fit: cover; }
.pd-product__body { padding: var(--pd-space-4) var(--pd-space-4) var(--pd-space-5); display: flex; flex-direction: column; gap: var(--pd-space-2); }
/* 목록에서 먼저 읽어야 하는 것은 무엇을 파는가(이름)이고, 값은 그다음이다.
   이름 14 → 15px, 값 18 → 16px. 값이 이름보다 두 급 크면 가격표처럼 읽혀
   상품을 고르는 화면이 아니라 견적서처럼 보인다. */
.pd-product__name {
  font-size: 15px;
  font-weight: var(--pd-weight-medium);
  color: var(--pd-text);
  line-height: 1.5;
}
.pd-product__price {
  font-size: 16px;
  font-weight: var(--pd-weight-bold);
  color: var(--pd-text);
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
}
/* 단위("원")는 줄이지 않는다. .t-unit 이 0.78em 이라 값 크기를 따라 함께
   줄어드는데, 원래 크기(18 × 0.78 ≒ 14px)에 못박아 둔다. */
.pd-product__price .t-unit { font-size: 14px; }
.pd-product__currency {
  font-size: 13px;
  font-weight: var(--pd-weight-bold);
  margin-inline-end: var(--pd-space-1);
}
.pd-product__currency[data-kind="mileage"] { color: var(--pd-gold-500); }
.pd-product__currency[data-kind="point"]   { color: var(--pd-accent-hover); }


/* =========================================================
   07. ACCORDION

   v1 은 펼쳐진 본문이 padding: 0 22px 20px 이어서 상단 여백이 0 이었다.

   여백은 머리행과 본문이 나눠 갖는다. 머리행은 접힘·펼침과 무관하게
   위아래 20px 를 유지한다(열릴 때만 아래를 0 으로 만들면 접힌 항목의
   아래가 비어 보이고, 펼칠 때 머리행 높이가 변해 아래 항목들이 흔들린다).
   본문은 머리행이 내준 20px 위에 8px 만 더해 질문과 한 덩어리로 붙이고,
   아래는 다음 항목과의 경계라서 20px 를 준다.
   ========================================================= */
.pd-accordion {
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  background: var(--pd-surface);
  overflow: hidden;
}
.pd-accordion__item + .pd-accordion__item { border-top: 1px solid var(--pd-border); }
.pd-accordion__trigger {
  width: 100%;
  padding: var(--pd-space-5) var(--pd-space-6);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pd-space-4);
  background: transparent;
  border: 0;
  font-family: inherit;
  text-align: start;
  color: var(--pd-text);
  transition: background-color var(--pd-dur) var(--pd-ease);
}
.pd-accordion__trigger:hover { background: var(--pd-surface-sunken); }
.pd-accordion__trigger:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-accordion__q { font-size: 15px; font-weight: var(--pd-weight-semibold); line-height: 1.5; }
.pd-accordion__chev {
  color: var(--pd-text-muted);
  display: inline-flex;
  flex-shrink: 0;
  transition: transform var(--pd-dur) var(--pd-ease);
}
.pd-accordion__chev .pd-icon { width: var(--pd-icon); height: var(--pd-icon); }

.pd-accordion__trigger[aria-expanded="true"] .pd-accordion__chev { transform: rotate(180deg); color: var(--pd-text); }
.pd-accordion__trigger[aria-expanded="true"] .pd-accordion__q { color: var(--pd-text); }

/* 머리행이 이미 아래로 20px 를 내주므로 본문 위 여백은 8px 만 준다.
   같은 20px 를 또 주면 질문과 답변 사이가 40px 로 벌어져 한 덩어리로 읽히지 않는다.
   아래 20px 는 다음 항목과의 경계라서 그대로 둔다. */
.pd-accordion__panel {
  padding: var(--pd-space-2) var(--pd-space-6) var(--pd-space-5);
  font-size: 14px;
  color: var(--pd-text-secondary);
  line-height: 1.75;
}
.pd-accordion__panel[hidden] { display: none; }
/* 본문 안의 문단 사이 간격 */
.pd-accordion__panel > * + * { margin-top: var(--pd-space-3); }


/* =========================================================
   08. MENU (Dropdown / Context / Combobox)
   세 컴포넌트가 같은 팝오버 표면을 공유한다.
   ========================================================= */
.pd-menu {
  position: absolute;
  z-index: var(--pd-z-dropdown);
  min-width: 200px;
  max-height: 320px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--pd-space-1);
  background: var(--pd-surface);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  box-shadow: var(--pd-shadow-lg);
}
.pd-menu[hidden] { display: none; }
.pd-menu__label {
  padding: var(--pd-space-2) var(--pd-space-3) var(--pd-space-1);
  font-size: 12px;
  font-weight: var(--pd-weight-bold);
  color: var(--pd-text-muted);
}
.pd-menu__item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--pd-space-2);
  padding: var(--pd-space-2) var(--pd-space-3);
  font-size: 14px;
  color: var(--pd-text);
  background: transparent;
  border: 0;
  border-radius: var(--pd-radius-sm);
  cursor: pointer;
  font-family: inherit;
  text-align: start;
  white-space: nowrap;
  transition: background-color var(--pd-dur-fast) var(--pd-ease);
}
/* 키보드 이동과 마우스 hover 를 같은 표시로 통일한다. */
.pd-menu__item:hover,
.pd-menu__item[data-active="true"] { background: var(--pd-surface-muted); }
.pd-menu__item[aria-selected="true"] { background: var(--pd-accent-subtle); color: var(--pd-accent-on-subtle); font-weight: var(--pd-weight-semibold); }
.pd-menu__item[disabled] { color: var(--pd-text-placeholder); cursor: not-allowed; background: transparent; }
.pd-menu__item--danger { color: var(--pd-danger); }
.pd-menu__item--danger:hover { background: var(--pd-danger-subtle); }
.pd-menu__item .pd-icon { color: var(--pd-text-muted); }
.pd-menu__item--danger .pd-icon { color: var(--pd-danger); }
.pd-menu__item-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* 단축키 표시. 오른쪽 끝에 연하게. */
.pd-menu__shortcut {
  font-size: 12px;
  color: var(--pd-text-placeholder);
  font-family: var(--pd-font-mono);
  margin-inline-start: var(--pd-space-4);
}
.pd-menu__check { width: var(--pd-icon-sm); flex-shrink: 0; }
.pd-menu__item[aria-selected="true"] .pd-menu__check .pd-icon { opacity: 1; }
.pd-menu__check .pd-icon { opacity: 0; }
.pd-menu__sep { height: 1px; background: var(--pd-border); margin: var(--pd-space-1) 0; }
.pd-menu__empty { padding: var(--pd-space-4) var(--pd-space-3); font-size: 13px; color: var(--pd-text-muted); text-align: center; }

/* 팝오버를 띄우는 기준점 */
.pd-popover-host { position: relative; display: inline-flex; }
.pd-popover-host--block { display: block; }

/* --- Dropdown trigger --- */
.pd-menu-trigger[aria-expanded="true"] { background: var(--pd-surface-muted); }

/* --- Context menu ---
   기본 우클릭 메뉴를 대체한다. 대체할 만한 이유가 있을 때만 쓴다. */
.pd-context-area {
  border: 1px dashed var(--pd-border-strong);
  border-radius: var(--pd-radius-lg);
  padding: var(--pd-space-8);
  text-align: center;
  color: var(--pd-text-muted);
  font-size: 13px;
  background: var(--pd-surface-sunken);
  user-select: none;
}

/* --- Combobox ---
   입력으로 걸러서 고르는 목록. 값이 목록에 없어도 되는 경우에 쓰고,
   목록에 있는 값만 허용하면 Native select 를 쓴다. */
.pd-combobox { position: relative; display: block; }
.pd-combobox .pd-menu { inset-inline: 0; margin-top: var(--pd-space-1); min-width: 0; }
.pd-combobox__mark { background: var(--pd-warning-subtle); color: var(--pd-warning-on-subtle); border-radius: 2px; }
/* 여러 개 고르는 경우 선택된 것을 입력 위에 태그로 쌓는다. */
.pd-combobox__tags { display: flex; flex-wrap: wrap; gap: var(--pd-space-1); margin-bottom: var(--pd-space-2); }


/* =========================================================
   09. CALENDAR / DATE PICKER
   ========================================================= */
.pd-calendar {
  /* 292px 가 설계 폭이지만 담는 칸이 그보다 좁을 수 있다.
     max-width 없이 두면 좁은 칸에서 페이지 전체가 가로로 밀린다. */
  width: 292px;
  max-width: 100%;
  padding: var(--pd-space-3);
  background: var(--pd-surface);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  user-select: none;
}
.pd-calendar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pd-space-2);
  margin-bottom: var(--pd-space-2);
}
.pd-calendar__title {
  font-size: 14px;
  font-weight: var(--pd-weight-bold);
  color: var(--pd-text);
  font-variant-numeric: tabular-nums;
}
.pd-calendar__nav {
  width: 28px; height: 28px;
  display: inline-grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--pd-text-muted);
  border-radius: var(--pd-radius-sm);
  cursor: pointer;
}
.pd-calendar__nav:hover { background: var(--pd-surface-muted); color: var(--pd-text); }
.pd-calendar__nav:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-calendar__nav[disabled] { color: var(--pd-text-placeholder); cursor: not-allowed; background: transparent; }

.pd-calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.pd-calendar__dow {
  height: 28px;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: var(--pd-weight-semibold);
  color: var(--pd-text-muted);
}
/* 일요일과 토요일만 색을 달리한다. 한국 달력 관례다. */
.pd-calendar__dow[data-weekend="sun"] { color: var(--pd-danger); }
.pd-calendar__dow[data-weekend="sat"] { color: var(--pd-accent-hover); }

.pd-calendar__day {
  aspect-ratio: 1;
  min-height: 34px;
  display: grid;
  place-items: center;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--pd-text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--pd-radius-sm);
  cursor: pointer;
  font-family: inherit;
  transition: background-color var(--pd-dur-fast) var(--pd-ease);
}
.pd-calendar__day:hover { background: var(--pd-surface-muted); }
.pd-calendar__day:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-calendar__day[data-outside="true"] { color: var(--pd-text-placeholder); }
.pd-calendar__day[data-today="true"] { border-color: var(--pd-accent); font-weight: var(--pd-weight-bold); }
.pd-calendar__day[aria-selected="true"] {
  background: var(--pd-accent);
  border-color: var(--pd-accent);
  color: var(--pd-text-on-accent);
  font-weight: var(--pd-weight-bold);
}
.pd-calendar__day[disabled] { color: var(--pd-text-placeholder); cursor: not-allowed; text-decoration: line-through; }
.pd-calendar__day[disabled]:hover { background: transparent; }
/* 기간 선택. 양 끝은 채우고 사이는 옅게 깐다.

   격자에 gap 2px 이 있어서 배경만 칠하면 띠가 2px 마다 끊겨 세로 줄무늬로
   보인다. 좌우로 2px 짜리 box-shadow 를 뻗어 칸 사이를 메운다.
   주가 바뀌는 지점의 세로 간격은 그대로 둔다. 주 단위로 끊기는 것은
   달력에서 자연스럽고, 메우면 오히려 어느 주인지 읽기 어려워진다. */
.pd-calendar__day[data-in-range="true"] {
  background: var(--pd-accent-subtle);
  border-radius: 0;
  color: var(--pd-accent-on-subtle);
  box-shadow: -2px 0 0 var(--pd-accent-subtle), 2px 0 0 var(--pd-accent-subtle);
}
/* 양 끝은 범위 쪽으로만 간격을 메우고 바깥쪽 모서리는 둥글게 남긴다. */
.pd-calendar__day[data-range-start="true"] {
  border-start-end-radius: 0;
  border-end-end-radius: 0;
  box-shadow: 2px 0 0 var(--pd-accent-subtle);
}
.pd-calendar__day[data-range-end="true"] {
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  box-shadow: -2px 0 0 var(--pd-accent-subtle);
}

.pd-calendar__foot {
  display: flex;
  justify-content: space-between;
  gap: var(--pd-space-2);
  margin-top: var(--pd-space-3);
  padding-top: var(--pd-space-3);
  border-top: 1px solid var(--pd-border);
}

/* --- Date picker ---
   입력 + 캘린더 팝오버. 입력은 직접 타이핑도 허용한다.
   달력만 허용하고 입력을 막으면 과거 날짜를 찾아가기가 느려진다. */
.pd-datepicker { position: relative; display: block; }
.pd-datepicker .pd-calendar {
  position: absolute;
  z-index: var(--pd-z-dropdown);
  top: calc(100% + var(--pd-space-1));
  inset-inline-start: 0;
  box-shadow: var(--pd-shadow-lg);
  /* .pd-calendar 의 max-width:100% 는 좁은 칸에 놓인 인라인 달력을 위한 것이다.
     팝오버는 기준 요소가 입력이라 100% 가 입력 폭이 되고, 292px 설계 폭이
     그 아래로 눌려 격자가 찌그러진다. 팝오버는 문서 흐름을 밀지 않으므로
     제 폭을 유지하고, 좁은 화면만 뷰포트로 제한한다. */
  width: 292px;
  max-width: calc(100vw - var(--pd-space-8));
}
.pd-datepicker .pd-calendar[hidden] { display: none; }
/* 기간 선택용 두 달 나란히.

   뷰포트 기준 미디어쿼리로 접지 않는다. 두 달이 들어갈지는 뷰포트 폭이
   아니라 담는 칸의 폭이 결정한다. 넓은 화면의 좁은 칸(2단 그리드 안,
   사이드 패널 안)에서는 뷰포트가 1440px 이어도 596px 이 안 나온다.
   flex-wrap 으로 안 맞을 때 알아서 아래로 내려가게 한다. */
.pd-calendar-pair {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pd-space-3);
}
.pd-calendar-pair > .pd-calendar { flex: 1 1 258px; }
/* 자주 쓰는 기간 프리셋 */
.pd-date-presets { display: flex; flex-wrap: wrap; gap: var(--pd-space-1); }


/* =========================================================
   10. TABLE

   v1 문제: border-collapse: collapse 상태에서 border-radius +
   overflow:hidden 을 걸어 모서리가 셀 배경에 잘려 나갔고, 바깥
   테두리도 셀 테두리에 먹혔다. 여기서는 래퍼가 테두리와 반경을
   담당하고 표 자체는 border-collapse: separate 를 쓴다.
   ========================================================= */
.pd-table-wrap {
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  background: var(--pd-surface);
  /* hidden 이 아니라 auto 다. hidden 이면 좁은 화면에서 오른쪽 열이
     잘려 나가고 사용자가 볼 방법이 없다. auto 는 반경 클리핑을 유지하면서
     넘칠 때만 스크롤바를 만든다. 넓은 표는 여기서 스크롤되고
     페이지 본문은 가로로 밀리지 않는다. */
  overflow-x: auto;
}
.pd-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}
.pd-table caption {
  padding: var(--pd-space-3) var(--pd-space-4);
  text-align: start;
  font-size: 13px;
  color: var(--pd-text-muted);
  border-bottom: 1px solid var(--pd-border);
}
.pd-table th, .pd-table td {
  padding: var(--pd-space-3) var(--pd-space-4);
  text-align: start;
  vertical-align: middle;
}
.pd-table thead th {
  background: var(--pd-surface-sunken);
  color: var(--pd-text-secondary);
  font-weight: var(--pd-weight-semibold);
  font-size: 13px;
  white-space: nowrap;
  border-bottom: 1px solid var(--pd-border);
}
.pd-table tbody td { border-bottom: 1px solid var(--pd-border); color: var(--pd-text); }
/* 마지막 행의 아래 선을 지운다. 래퍼 테두리와 겹쳐 2px 로 보인다. */
.pd-table tbody tr:last-child > td { border-bottom: 0; }
.pd-table tbody tr:hover > td { background: var(--pd-surface-sunken); }

/* 표 안에서 비어 있음을 알리는 칸.

   기본은 표 바깥에 .pd-empty 영역을 두는 것이다. 하지만 조회 결과로
   tbody 만 갈아 끼우는 화면에서는 표 밖을 건드릴 수 없다. 그런 경우에만
   이 칸을 쓴다.

     <tr><td colspan="4" class="pd-table__empty">조회된 내역이 없습니다.</td></tr> */
/* `.pd-table td` 가 클래스+요소(0,1,1)라서 클래스 하나(0,1,0)로는 못 이긴다.
   정렬과 여백을 되돌리려면 td 를 함께 적어야 한다. */
.pd-table td.pd-table__empty {
  text-align: center;
  color: var(--pd-text-muted);
  padding-block: var(--pd-space-12);
}
.pd-table tbody tr:hover > .pd-table__empty { background: transparent; }

/* 행 머리글 열. scope="row" 를 붙인 th 다. */
.pd-table tbody th[scope="row"] {
  font-weight: var(--pd-weight-semibold);
  color: var(--pd-text);
  border-bottom: 1px solid var(--pd-border);
  background: var(--pd-surface);
}
.pd-table tbody tr:last-child > th[scope="row"] { border-bottom: 0; }

/* 숫자 열. 표에서는 data-numeric 을 쓴다.

   base.css 의 .t-num--end 도 같은 뜻이지만 표 안에서는 아무 일도 하지 않는다.
   `.pd-table th, .pd-table td` 가 클래스+요소(0,1,1)라 클래스 하나(0,1,0)를
   이기기 때문이다. 마일리지 화면 이관에서 금액이 왼쪽에 붙어 발견했다.
   시스템이 두 가지 방법을 알려 주면서 하나만 동작하면 안 되므로 함께 받는다. */
.pd-table [data-numeric],
.pd-table :is(th, td).t-num--end { text-align: end; font-variant-numeric: tabular-nums; }
/* 줄바꿈 금지 열 */
.pd-table [data-nowrap] { white-space: nowrap; }

/* 밀도 변형 */
.pd-table--compact th, .pd-table--compact td { padding: var(--pd-space-2) var(--pd-space-3); font-size: 13px; }
.pd-table--relaxed th, .pd-table--relaxed td { padding: var(--pd-space-4) var(--pd-space-5); }
/* 줄무늬는 세로 구분선 대신 쓴다. 둘 다 쓰면 격자가 시끄럽다. */
.pd-table--striped tbody tr:nth-child(even) > td { background: var(--pd-surface-sunken); }
.pd-table--striped tbody tr:hover > td { background: var(--pd-accent-subtle); }
/* 세로 구분선이 꼭 필요한 고밀도 표 */
.pd-table--grid th + th, .pd-table--grid td + td { border-inline-start: 1px solid var(--pd-border); }

/* ---------------------------------------------------------
   스크롤 테이블

   가로·세로 최대 크기를 정하고 내부에서만 스크롤한다.
   thead 는 위로, 첫 열(data-sticky-col)은 왼쪽으로 고정된다.
   교차하는 좌상단 셀은 z-index 를 한 단 더 올려야 가려지지 않는다.

     <div class="pd-table-scroll" style="--pd-table-h: 320px; --pd-table-w: 100%">
   --------------------------------------------------------- */
.pd-table-scroll {
  max-height: var(--pd-table-h, 400px);
  max-width: var(--pd-table-w, 100%);
  overflow: auto;
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  background: var(--pd-surface);
  /* sticky 셀이 둥근 모서리 밖으로 새지 않게 한다. */
  position: relative;
}
.pd-table-scroll > .pd-table { border-collapse: separate; border-spacing: 0; }

.pd-table-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  /* sticky 요소에는 border-bottom 이 스크롤 시 함께 붙지 않는 경우가 있어
     box-shadow 로 경계선을 그린다. */
  box-shadow: inset 0 -1px 0 var(--pd-border);
  border-bottom: 0;
}
.pd-table-scroll [data-sticky-col] {
  position: sticky;
  inset-inline-start: 0;
  z-index: 1;
  background: var(--pd-surface);
  /* 고정 열과 스크롤되는 본문 사이 경계 */
  box-shadow: inset -1px 0 0 var(--pd-border);
}
.pd-table-scroll thead [data-sticky-col] {
  z-index: 3;
  background: var(--pd-surface-sunken);
  box-shadow: inset -1px 0 0 var(--pd-border), inset 0 -1px 0 var(--pd-border);
}
/* 고정 열은 hover 배경도 따라가야 한다. 안 그러면 행이 끊겨 보인다. */
.pd-table-scroll tbody tr:hover > [data-sticky-col] { background: var(--pd-surface-sunken); }

/* ---------------------------------------------------------
   좁은 화면에서 열 감추기

   숨길 열의 th 와 td 양쪽에 같은 클래스를 붙인다.
     pd-col-hide-sm   640px 이하에서 숨김
     pd-col-hide-md   768px 이하에서 숨김
     pd-col-hide-lg   1024px 이하에서 숨김
   숨긴 정보가 그 화면에서 정말 필요 없는지 먼저 판단한다.
   필요하면 감추지 말고 아래의 리스트 변환을 쓴다.

   리스트 변환(.pd-table--stack)과 같이 쓰면 카드에서는 되살아난다.
   카드에는 자리가 있으니 좁은 화면에서 정보를 잃지 않는다는 뜻이다.
   카드에서도 끝까지 감추려면 pd-col-drop-* 를 쓴다.
     pd-col-drop-sm / -md / -lg   표에서도 카드에서도 숨김
   --------------------------------------------------------- */
/* 표 안에서는 셀 선택자를 함께 적는다. 리스트 변환이 `tbody td`(0,1,2)로
   display 를 걸기 때문에 클래스 하나(0,1,0)로는 감추기가 무효가 된다.

   그 셀 선택자를 :not(.pd-table--stack) 으로 묶어 두는 것이 핵심이다.
   이게 없으면 감추기(0,2,1)가 아래의 되살리기(0,2,0)를 명시도로 눌러서,
   두 기능을 같이 쓰는 화면에서 열이 통째로 사라진다. 주문내역의 「옵션」이
   그렇게 사라졌다(PILLDOC-2008). */
@media (max-width: 640px) {
  .pd-col-hide-sm,
  .pd-col-drop-sm { display: none; }
  .pd-table:not(.pd-table--stack) :is(th, td).pd-col-hide-sm,
  .pd-table :is(th, td).pd-col-drop-sm { display: none; }
}
@media (max-width: 768px) {
  .pd-col-hide-md,
  .pd-col-drop-md { display: none; }
  .pd-table:not(.pd-table--stack) :is(th, td).pd-col-hide-md,
  .pd-table :is(th, td).pd-col-drop-md { display: none; }
}
@media (max-width: 1024px) {
  .pd-col-hide-lg,
  .pd-col-drop-lg { display: none; }
  .pd-table:not(.pd-table--stack) :is(th, td).pd-col-hide-lg,
  .pd-table :is(th, td).pd-col-drop-lg { display: none; }
}

/* ---------------------------------------------------------
   모바일 리스트 변환

   .pd-table--stack 을 붙이고 각 td 에 data-label 을 준다.
   768px 이하에서 각 행이 카드가 되고 셀마다 레이블이 붙는다.

     <td data-label="처방일">2026.08.03</td>

   열이 6개 이상이면 감추기보다 이 방식이 낫다.
   --------------------------------------------------------- */
@media (max-width: 768px) {
  .pd-table--stack { border-collapse: separate; border-spacing: 0; }
  .pd-table--stack thead { display: none; }
  .pd-table--stack tbody, .pd-table--stack tr, .pd-table--stack td, .pd-table--stack th { display: block; }
  .pd-table--stack tbody tr {
    border: 1px solid var(--pd-border);
    border-radius: var(--pd-radius-lg);
    padding: var(--pd-space-2) var(--pd-space-4);
    margin-bottom: var(--pd-space-3);
    background: var(--pd-surface);
  }
  .pd-table--stack tbody tr:last-child { margin-bottom: 0; }
  .pd-table--stack tbody tr:hover > td { background: transparent; }
  .pd-table--stack tbody td,
  .pd-table--stack tbody th[scope="row"] {
    display: flex;
    align-items: baseline;
    /* space-between 으로 두면 셀 안의 자식이 여럿일 때(금액 + 단위처럼)
       서로 양 끝으로 벌어진다. 레이블만 auto 로 밀고 나머지는 붙여 둔다.

       gap 도 쓰지 않는다. flex 의 gap 은 항목 사이 전부에 걸려서
       숫자와 단위 사이까지 벌린다. 레이블의 padding 으로 대신한다. */
    justify-content: flex-end;
    column-gap: 0;
    padding: var(--pd-space-2) 0;
    border-bottom: 1px solid var(--pd-border);
    text-align: end;
  }
  .pd-table--stack tbody tr > *:last-child { border-bottom: 0; }
  /* 비어 있음을 알리는 칸은 레이블도 정렬도 붙이지 않는다. */
  .pd-table--stack tbody td.pd-table__empty {
    display: block;
    text-align: center;
    border-bottom: 0;
  }
  .pd-table--stack tbody td.pd-table__empty::before { content: none; }
  .pd-table--stack tbody tr:has(> .pd-table__empty) {
    border: 0;
    background: transparent;
    padding: 0;
  }
  .pd-table--stack tbody td::before,
  .pd-table--stack tbody th[scope="row"]::before {
    content: attr(data-label);
    flex: 0 0 auto;
    margin-inline-end: auto;
    padding-inline-end: var(--pd-space-4);
    font-size: 13px;
    font-weight: var(--pd-weight-medium);
    color: var(--pd-text-muted);
    text-align: start;
  }
  /* data-label 이 없는 셀(액션 버튼 등)은 레이블 자리를 비운다. */
  .pd-table--stack tbody td:not([data-label])::before { content: ""; }
  /* 변환된 표에서는 감추기 클래스를 무시한다. 카드에는 자리가 있다.

     한 클래스가 「카드에서 숨김」과 「카드에서 보임」을 동시에 뜻할 수 없다는
     지적(PILLDOC-2008)이 맞아서, 클래스를 둘로 갈랐다. 카드에서도 끝까지
     감추려는 열은 pd-col-drop-* 를 쓰고, 그것은 여기서 되살아나지 않는다. */
  .pd-table--stack :is(th, td).pd-col-hide-sm,
  .pd-table--stack :is(th, td).pd-col-hide-md,
  .pd-table--stack :is(th, td).pd-col-hide-lg { display: flex; }
  /* 래퍼의 테두리는 카드가 대신하므로 없앤다. */
  .pd-table-wrap:has(.pd-table--stack) { border: 0; border-radius: 0; background: transparent; }
}

/* ---------------------------------------------------------
   Data table
   툴바 + 선택 + 정렬 + 빈 상태 + 페이지네이션을 갖춘 표.
   --------------------------------------------------------- */
.pd-datatable { display: flex; flex-direction: column; gap: var(--pd-space-4); }
.pd-datatable__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pd-space-3);
  flex-wrap: wrap;
}
.pd-datatable__filters { display: flex; align-items: center; gap: var(--pd-space-2); flex-wrap: wrap; }
.pd-datatable__search { width: 260px; max-width: 100%; }
.pd-datatable__actions { display: flex; align-items: center; gap: var(--pd-space-2); }

/* 선택된 행 개수 안내줄. 선택이 있을 때만 나타난다. */
.pd-datatable__selection {
  display: flex;
  align-items: center;
  gap: var(--pd-space-3);
  padding: var(--pd-space-2) var(--pd-space-4);
  background: var(--pd-accent-subtle);
  color: var(--pd-accent-on-subtle);
  border-radius: var(--pd-radius-md);
  font-size: 13px;
  font-weight: var(--pd-weight-medium);
}
.pd-datatable__selection[hidden] { display: none; }
.pd-datatable__selection-count { font-variant-numeric: tabular-nums; font-weight: var(--pd-weight-bold); }

/* 체크박스 열은 폭을 고정한다. */
.pd-table [data-col="select"] { width: 44px; padding-inline-end: 0; }
.pd-table [data-col="actions"] { width: 1%; white-space: nowrap; text-align: end; }
.pd-table tbody tr[aria-selected="true"] > td,
.pd-table tbody tr[aria-selected="true"] > th { background: var(--pd-accent-subtle); }

/* 정렬 가능한 머리글 */
.pd-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-1);
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border-radius: var(--pd-radius-xs);
}
.pd-table__sort:hover { color: var(--pd-text); }
.pd-table__sort:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }
.pd-table__sort .pd-icon { width: 14px; height: 14px; opacity: 0.35; transition: opacity var(--pd-dur) var(--pd-ease), transform var(--pd-dur) var(--pd-ease); }
.pd-table__sort:hover .pd-icon { opacity: 0.7; }
/* 정렬 상태는 th 의 aria-sort 가 유일한 출처다. */
[aria-sort="ascending"] .pd-table__sort .pd-icon,
[aria-sort="descending"] .pd-table__sort .pd-icon { opacity: 1; color: var(--pd-accent-hover); }
[aria-sort="descending"] .pd-table__sort .pd-icon { transform: rotate(180deg); }
[aria-sort="ascending"] .pd-table__sort,
[aria-sort="descending"] .pd-table__sort { color: var(--pd-text); font-weight: var(--pd-weight-bold); }


/* =========================================================
   11. TOOLTIP / TOAST / MODAL
   ========================================================= */
/* --- Tooltip ---
   CSS 만으로 동작한다. 마우스뿐 아니라 키보드 포커스에도 뜬다.
   툴팁은 보조 설명만 담는다. 툴팁에만 있는 정보를 만들지 않는다.
   터치 기기에는 hover 가 없으므로 필수 정보는 본문에 둔다. */
.pd-tip { position: relative; display: inline-flex; }
.pd-tip__bubble {
  position: absolute;
  z-index: var(--pd-z-tooltip);
  bottom: calc(100% + var(--pd-space-2));
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  padding: var(--pd-space-2) var(--pd-space-3);
  background: var(--pd-surface-inverted);
  color: var(--pd-text-inverted);
  font-size: 13px;
  font-weight: var(--pd-weight-medium);
  line-height: 1.5;
  border-radius: var(--pd-radius-md);
  box-shadow: var(--pd-shadow-md);
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--pd-dur) var(--pd-ease), transform var(--pd-dur) var(--pd-ease), visibility var(--pd-dur);
  pointer-events: none;
}
.pd-tip__bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--pd-surface-inverted);
}
.pd-tip:hover .pd-tip__bubble,
.pd-tip:focus-within .pd-tip__bubble {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
/* 여러 줄 툴팁 */
.pd-tip__bubble--wrap { white-space: normal; width: max-content; max-width: 240px; text-align: start; }
/* 아래로 열리는 변형 */
.pd-tip--bottom .pd-tip__bubble { bottom: auto; top: calc(100% + var(--pd-space-2)); transform: translateX(-50%) translateY(-4px); }
.pd-tip--bottom .pd-tip__bubble::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: var(--pd-surface-inverted); }
.pd-tip--bottom:hover .pd-tip__bubble,
.pd-tip--bottom:focus-within .pd-tip__bubble { transform: translateX(-50%) translateY(0); }

/* 도움말 아이콘 버튼 */
.pd-tip-btn {
  width: 20px; height: 20px;
  display: inline-grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--pd-text-placeholder);
  border-radius: 50%;
  cursor: help;
  padding: 0;
}
.pd-tip-btn:hover { color: var(--pd-text-muted); }
.pd-tip-btn:focus-visible { outline: none; box-shadow: var(--pd-focus-ring); }

/* --- Toast --- */
.pd-toast-region {
  position: fixed;
  z-index: var(--pd-z-toast);
  bottom: var(--pd-space-6);
  inset-inline-end: var(--pd-space-6);
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-2);
  pointer-events: none;
}
.pd-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--pd-space-3);
  background: var(--pd-surface-inverted);
  color: var(--pd-text-inverted);
  padding: var(--pd-space-3) var(--pd-space-4);
  border-radius: var(--pd-radius-md);
  font-size: 14px;
  line-height: 1.5;
  max-width: 380px;
  box-shadow: var(--pd-shadow-lg);
  pointer-events: auto;
}
.pd-toast__icon {
  width: 20px; height: 20px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  margin-top: 1px;
  background: var(--pd-accent);
  color: var(--pd-text-on-accent);
}
.pd-toast__icon .pd-icon { width: 12px; height: 12px; }
.pd-toast--danger  .pd-toast__icon { background: var(--pd-danger); }
.pd-toast--warning .pd-toast__icon { background: var(--pd-warning); color: var(--pd-ink-900); }
.pd-toast--success .pd-toast__icon { background: var(--pd-success); }
.pd-toast__body { flex: 1 1 auto; min-width: 0; }
.pd-toast__title { font-weight: var(--pd-weight-semibold); margin-bottom: 2px; }
.pd-toast__close {
  border: 0;
  background: transparent;
  color: var(--pd-ink-400);
  cursor: pointer;
  padding: 0;
  width: 20px; height: 20px;
  display: grid;
  place-items: center;
  border-radius: var(--pd-radius-xs);
  flex-shrink: 0;
}
.pd-toast__close:hover { color: var(--pd-white); background: rgba(255, 255, 255, 0.12); }

/* --- Modal --- */
.pd-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--pd-z-overlay);
  background: rgba(31, 35, 40, 0.5);
  display: grid;
  place-items: center;
  padding: var(--pd-space-4);
}
.pd-modal-backdrop[hidden] { display: none; }
.pd-modal {
  position: relative;
  z-index: var(--pd-z-modal);
  width: 100%;
  max-width: 440px;
  max-height: calc(100vh - var(--pd-space-8));
  display: flex;
  flex-direction: column;
  background: var(--pd-surface);
  border-radius: var(--pd-radius-lg);
  box-shadow: var(--pd-shadow-lg);
  overflow: hidden;
}
.pd-modal--lg { max-width: 640px; }
.pd-modal--sm { max-width: 360px; }
.pd-modal__head {
  padding: var(--pd-space-6) var(--pd-space-6) var(--pd-space-3);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--pd-space-4);
}
.pd-modal__title { font-size: 18px; font-weight: var(--pd-weight-bold); line-height: 1.45; }
.pd-modal__body {
  padding: 0 var(--pd-space-6) var(--pd-space-6);
  font-size: 14px;
  color: var(--pd-text-secondary);
  line-height: 1.65;
  overflow-y: auto;
}
.pd-modal__foot {
  padding: var(--pd-space-4) var(--pd-space-6);
  border-top: 1px solid var(--pd-border);
  background: var(--pd-surface-sunken);
  display: flex;
  justify-content: flex-end;
  gap: var(--pd-space-2);
}
/* 파괴적 동작을 확인받는 모달은 제목 위에 경고 아이콘을 둔다. */
.pd-modal__icon {
  width: 40px; height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--pd-danger-subtle);
  color: var(--pd-danger);
  margin-bottom: var(--pd-space-3);
}
.pd-modal__icon .pd-icon { width: var(--pd-icon); height: var(--pd-icon); }


/* =========================================================
   12. SKELETON / SPINNER / EMPTY
   ========================================================= */
/* 스켈레톤은 실제 콘텐츠의 모양을 흉내내야 한다. 화면 전체를
   회색 덩어리로 덮으면 로딩이 더 길게 느껴진다. */
.pd-skeleton {
  display: block;
  background: var(--pd-surface-muted);
  border-radius: var(--pd-radius-sm);
  position: relative;
  overflow: hidden;
}
.pd-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.65), transparent);
  animation: pd-shimmer 1.4s var(--pd-ease) infinite;
}
.pd-skeleton--text { height: 1em; border-radius: var(--pd-radius-xs); }
/* 마지막 줄은 짧게 해서 문단처럼 보이게 한다. */
.pd-skeleton--text:last-child { width: 65%; }
.pd-skeleton--title { height: 1.4em; width: 45%; }
.pd-skeleton--circle { border-radius: 50%; }
.pd-skeleton--thumb { aspect-ratio: 1.2 / 1; border-radius: var(--pd-radius-md); }
.pd-skeleton-group { display: flex; flex-direction: column; gap: var(--pd-space-2); }

/* 움직임을 줄이는 설정에서는 반짝임을 멈추고 정적인 회색만 남긴다. */
@media (prefers-reduced-motion: reduce) {
  .pd-skeleton::after { animation: none; display: none; }
}

/* --- Spinner ---
   결정적인 진행률을 알 수 있으면 스피너 대신 진행 표시를 쓴다.
   스피너는 얼마나 남았는지 모를 때만 쓴다. */
.pd-spinner {
  width: var(--pd-spinner-size, 20px);
  height: var(--pd-spinner-size, 20px);
  border-radius: 50%;
  border: 2px solid var(--pd-border-strong);
  border-top-color: var(--pd-accent);
  animation: pd-spin 700ms linear infinite;
  flex-shrink: 0;
}
.pd-spinner--sm { --pd-spinner-size: 14px; border-width: 2px; }
.pd-spinner--lg { --pd-spinner-size: 32px; border-width: 3px; }
.pd-spinner--inverted { border-color: rgba(255, 255, 255, 0.3); border-top-color: var(--pd-white); }
/* 로딩 중임을 문자로도 알린다. 스피너만으로는 스크린리더가 침묵한다. */
.pd-loading { display: inline-flex; align-items: center; gap: var(--pd-space-2); font-size: 14px; color: var(--pd-text-muted); }
/* display 를 정한 컴포넌트는 hidden 을 스스로 되받아야 한다. 브라우저 기본
   [hidden] { display: none } 은 작성자 스타일에 밀린다 — 그러지 않으면
   hidden 을 걸어 둔 요소가 그대로 보인다. */
.pd-loading[hidden] { display: none; }

@keyframes pd-spin { to { transform: rotate(360deg); } }
@keyframes pd-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  /* 스피너는 회전이 곧 의미다. 멈추지 않고 느리게만 만든다. */
  .pd-spinner, .pd-btn[data-loading="true"]::after { animation-duration: 2s; }
}

/* --- Empty state --- */
.pd-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--pd-space-3);
  padding: var(--pd-space-12) var(--pd-space-6);
  text-align: center;
}
.pd-empty__icon {
  width: 48px; height: 48px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--pd-surface-muted);
  color: var(--pd-text-placeholder);
}
.pd-empty__icon .pd-icon { width: var(--pd-icon-lg); height: var(--pd-icon-lg); }
.pd-empty__title { font-size: 15px; font-weight: var(--pd-weight-semibold); color: var(--pd-text); }
.pd-empty__desc { font-size: 14px; color: var(--pd-text-muted); max-width: 34em; line-height: 1.6; }
.pd-empty[hidden] { display: none; }

/* --- Prose (편집기에서 온 본문) ---

   공지사항 본문, 상품 상세, FAQ 처럼 **DB 에 저장된 HTML** 을 그리는 자리다.
   마크업을 우리가 정하지 못한다. 편집기가 만든 것을 그대로 받는다.

   그래서 이 컨테이너 안에서는 리셋을 되돌린다. .pd-root 와 기존 common.css 는
   둘 다 ul 의 불릿과 제목의 여백을 지우는데, 그 상태로 본문을 넣으면 목록이
   그냥 문단으로 보이고 문단 사이가 붙는다. 실제로 그래서 notice-rich-text.css
   라는 파일이 따로 생겼었다. 그 역할을 여기로 가져왔다.

   .pd-root 의 리셋은 :where() 로 특이도가 0 이라 아래 규칙이 항상 이긴다.

   안의 내용에 클래스를 붙일 수 없으므로 요소 선택자를 쓴다. 이 파일에서
   요소 선택자를 쓰는 유일한 곳이고, 반드시 .pd-prose 안으로 제한한다. */
.pd-prose {
  font-size: 15px;
  line-height: 1.75;
  color: var(--pd-text-secondary);
  word-break: keep-all;
  overflow-wrap: anywhere;
}
.pd-prose > :first-child { margin-top: 0; }
.pd-prose > :last-child { margin-bottom: 0; }

.pd-prose p { margin: 0 0 var(--pd-space-4); }
.pd-prose :is(h1, h2, h3, h4) {
  color: var(--pd-text);
  font-weight: var(--pd-weight-bold);
  line-height: 1.4;
  margin: var(--pd-space-8) 0 var(--pd-space-3);
}
.pd-prose h1 { font-size: 24px; letter-spacing: -0.02em; }
.pd-prose h2 { font-size: 20px; letter-spacing: -0.015em; }
.pd-prose h3 { font-size: 17px; }
.pd-prose h4 { font-size: 15px; }

/* 편집기가 만든 목록은 불릿이 있어야 목록으로 읽힌다. */
.pd-prose ul { list-style: disc; margin: 0 0 var(--pd-space-4); padding-inline-start: var(--pd-space-6); }
.pd-prose ol { list-style: decimal; margin: 0 0 var(--pd-space-4); padding-inline-start: var(--pd-space-6); }
/* li 에 직접 list-style 을 되살려야 한다. module.css 의
   `dl, ul, ol, li { list-style: none }` 이 li 를 직접 잡고 있어서
   부모 ul 에 disc 를 줘도 마커가 나오지 않는다. */
.pd-prose :is(ul, ol) > li { list-style: inherit; padding-inline-start: 0; }
.pd-prose li { margin-bottom: var(--pd-space-1); }
/* 기존 CSS 가 li 앞에 '∙' 를 넣는다(style.css). 진짜 마커와 겹친다. */
.pd-prose li::before { content: none; display: none; }
.pd-prose :is(ul, ol) :is(ul, ol) { margin-bottom: 0; }

.pd-prose strong, .pd-prose b { font-weight: var(--pd-weight-bold); color: var(--pd-text); }
.pd-prose em, .pd-prose i { font-style: italic; }
.pd-prose u { text-decoration: underline; }
.pd-prose s { text-decoration: line-through; }

.pd-prose a { color: var(--pd-accent-on-subtle); text-decoration: underline; }
.pd-prose a:hover { color: var(--pd-mint-800); }

.pd-prose blockquote {
  margin: var(--pd-space-4) 0;
  padding: var(--pd-space-2) var(--pd-space-4);
  border-inline-start: 3px solid var(--pd-border-strong);
  color: var(--pd-text-muted);
}

/* 편집기가 크기를 지정한 이미지가 있을 수 있으므로 폭만 제한한다. */
.pd-prose :is(img, video) { max-width: 100%; height: auto; margin-bottom: var(--pd-space-4); }
.pd-prose video { width: 100%; }

/* 본문 안의 표는 .pd-table 을 붙일 수 없다. 최소한만 정리한다. */
.pd-prose table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--pd-space-4) 0;
  font-size: 14px;
}
.pd-prose :is(th, td) {
  border: 1px solid var(--pd-border);
  padding: var(--pd-space-2) var(--pd-space-3);
  text-align: start;
  vertical-align: middle;
}
.pd-prose th { background: var(--pd-surface-sunken); color: var(--pd-text); font-weight: var(--pd-weight-semibold); }
/* 표가 좁은 화면을 밀지 않게 한다. 안의 표는 열 수를 우리가 모른다. */
.pd-prose-scroll { overflow-x: auto; }

.pd-prose hr { border: 0; border-top: 1px solid var(--pd-border); margin: var(--pd-space-8) 0; }

/* --- Note (안내 문구) ---

   화면에 계속 남아 있는 안내다. 저절로 사라지는 알림은 Toast 를 쓴다.
   기존 사이트의 .message / .message-success 가 하던 자리다.

   기본은 중립이다. 색을 붙이는 것은 그 색의 뜻이 맞을 때만 한다.
   화면에서 가장 눈에 띄는 것이 안내 문구가 되면 정작 할 일이 묻힌다.

     <div class="pd-note">
       <svg class="pd-icon pd-icon--md" aria-hidden="true"><use href="#i-info"/></svg>
       <p>...</p>
     </div> */
.pd-note {
  display: flex;
  align-items: flex-start;
  gap: var(--pd-space-3);
  padding: var(--pd-space-4) var(--pd-space-5);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  background: var(--pd-surface-sunken);
  color: var(--pd-text-secondary);
  font-size: 14px;
  line-height: 1.6;
}
/* 아이콘을 첫 줄 가운데에 맞춘다. 본문 line-height 가 아이콘보다 크다. */
.pd-note > .pd-icon { margin-top: 2px; color: var(--pd-text-muted); }
.pd-note strong { color: var(--pd-text); font-weight: var(--pd-weight-semibold); }

.pd-note--accent  { background: var(--pd-accent-subtle);  border-color: var(--pd-mint-100);  color: var(--pd-accent-on-subtle); }
.pd-note--success { background: var(--pd-success-subtle); border-color: var(--pd-green-500); color: var(--pd-success-on-subtle); }
.pd-note--warning { background: var(--pd-warning-subtle); border-color: var(--pd-gold-400); color: var(--pd-warning-on-subtle); }
.pd-note--danger  { background: var(--pd-danger-subtle);  border-color: var(--pd-red-500);  color: var(--pd-danger-on-subtle); }
.pd-note--accent > .pd-icon,
.pd-note--success > .pd-icon,
.pd-note--warning > .pd-icon,
.pd-note--danger > .pd-icon { color: inherit; }
.pd-note--accent strong,
.pd-note--success strong,
.pd-note--warning strong,
.pd-note--danger strong { color: inherit; }


/* =========================================================
   13. CHART
   ECharts 를 담는 껍데기만 CSS 로 정의한다. 색과 축 스타일은
   scripts/charts.js 의 테마가 토큰을 읽어 주입한다.
   ========================================================= */
.pd-chart {
  /* 높이를 지정하지 않으면 ECharts 가 0px 로 잡아 아무것도 안 보인다. */
  height: var(--pd-chart-h, 280px);
  width: 100%;
}
.pd-chart-card { display: flex; flex-direction: column; gap: var(--pd-space-4); }
.pd-chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--pd-space-3); flex-wrap: wrap; }
.pd-chart-title { font-size: 15px; font-weight: var(--pd-weight-bold); color: var(--pd-text); }
.pd-chart-sub { font-size: 13px; color: var(--pd-text-muted); }
/* 지표 한 줄. 차트 위에 현재 값을 크게 보여줄 때 쓴다. */
.pd-metric { display: flex; flex-direction: column; gap: 2px; }
.pd-metric__label { font-size: 13px; color: var(--pd-text-muted); }
.pd-metric__value {
  font-size: 28px;
  font-weight: var(--pd-weight-bold);
  color: var(--pd-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.pd-metric__delta { font-size: 13px; font-weight: var(--pd-weight-semibold); display: inline-flex; align-items: center; gap: 2px; }
.pd-metric__delta[data-dir="up"]   { color: var(--pd-success-on-subtle); }
.pd-metric__delta[data-dir="down"] { color: var(--pd-danger); }
.pd-metric__delta[data-dir="flat"] { color: var(--pd-text-muted); }
.pd-metric-row { display: flex; gap: var(--pd-space-8); flex-wrap: wrap; }

/* 범례를 직접 그릴 때. ECharts 기본 범례를 끄고 쓰는 경우다. */
.pd-legend { display: flex; flex-wrap: wrap; gap: var(--pd-space-4); font-size: 13px; color: var(--pd-text-secondary); }
.pd-legend__item { display: inline-flex; align-items: center; gap: var(--pd-space-2); }
.pd-legend__swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
