/* ============================================================
   components.css — 버튼/입력/뱃지/탭/그리드/모달/토스트/팝오버/달력
   ============================================================ */

/* ---------- Button ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: 32px; padding: 0 14px; border-radius: var(--r-sm); font-size: var(--fs-14); font-weight: var(--fw-medium); border: 1px solid transparent; white-space: nowrap; }
.btn .icon { fill: currentColor; }
.btn--primary { background: var(--c-brand); color: #fff; }
.btn--primary:hover { background: var(--c-brand-dark); }
.btn--line { background: #fff; border-color: var(--c-border); color: var(--c-text); }
.btn--line:hover { border-color: var(--c-primary); color: var(--c-primary); }
.btn--ghost { background: var(--c-bg-soft); color: var(--c-text-2); }
.btn--ghost:hover { background: #e7eaef; }
.btn--text { color: var(--c-primary); padding: 0 6px; }
.btn--text:hover { text-decoration: underline; }
.btn--blue { background: var(--c-primary); color: #fff; }
.btn--blue:hover { background: #2a5be0; }
.btn--sm { height: 28px; padding: 0 10px; font-size: var(--fs-13); }
.btn:disabled { background: var(--c-bg-soft); color: var(--c-text-disabled); border-color: var(--c-border-2); cursor: not-allowed; }

/* ---------- Input / Select ---------- */
.input, .select { height: 32px; padding: 0 10px; border: 1px solid var(--c-border); border-radius: var(--r-sm); background: #fff; color: var(--c-text); font-size: var(--fs-14); }
.input::placeholder { color: var(--c-text-disabled); }
.input:focus, .select:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 2px rgba(55,108,251,.18); }
.input[readonly] { background: var(--c-bg-soft); color: var(--c-text-2); }
.input--invalid { border-color: var(--c-error); }
.input--invalid:focus { box-shadow: 0 0 0 2px rgba(255,40,40,.18); }
.select { padding-right: 26px; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' fill='none' stroke-width='1.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 9px center; }

.datefield { position: relative; display: inline-flex; align-items: center; }
.input--date { width: 150px; padding-right: 30px; }
.input-affix { position: absolute; right: 4px; width: 24px; height: 24px; display: grid; place-items: center; }
.input-affix .icon { fill: var(--c-text-3); }

/* ---------- ButtonGroup (세그먼트) ---------- */
.btngroup { display: inline-flex; border: 1px solid var(--c-border); border-radius: var(--r-sm); overflow: hidden; }
.btngroup__item { padding: 0 14px; height: 30px; font-size: var(--fs-13); color: var(--c-text-2); border-right: 1px solid var(--c-border); background: #fff; }
.btngroup__item:last-child { border-right: none; }
.btngroup__item:hover { background: var(--c-bg-soft); }
.btngroup__item.is-active { background: var(--c-primary); color: #fff; }

/* ---------- Badge ---------- */
.badge { display: inline-flex; align-items: center; justify-content: center; min-width: 38px; height: 20px; padding: 0 7px; border-radius: var(--r-sm); font-size: var(--fs-12); font-weight: var(--fw-bold); color: #fff; }
.badge--a { background: var(--c-grade-a); }
.badge--b { background: var(--c-grade-b); }
.badge--c { background: var(--c-grade-c); }
.badge--d { background: var(--c-grade-d); }
.badge--status { min-width: auto; height: 19px; font-weight: var(--fw-medium); }
.badge--on { background: #e7f1ff; color: var(--c-primary); }
.badge--off { background: #f0f0f0; color: var(--c-text-3); }

/* ---------- SubTabs ---------- */
.subtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--c-border-2); }
.subtabs__item { padding: 8px 18px; font-size: var(--fs-14); color: var(--c-text-2); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.subtabs__item:hover { color: var(--c-brand); }
.subtabs__item.is-active { color: var(--c-brand); font-weight: var(--fw-bold); border-bottom-color: var(--c-brand); }

/* ---------- 필터바 / 페이지 공통 ---------- */
.page { background: #fff; border: 1px solid var(--c-border-2); border-radius: var(--r-lg); }
.page__pad { padding: var(--sp-4) var(--sp-5); }
.filterbar { display: flex; flex-direction: column; gap: var(--sp-3); margin-bottom: 16px; padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--c-border-2); border-bottom: 1px solid var(--c-border-2); }
.filterrow { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.filterrow__label { width: 76px; flex: none; font-size: var(--fs-13); color: var(--c-text-2); font-weight: var(--fw-medium); }
.toolbar { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-3) var(--sp-5); }
.toolbar__group { display: flex; align-items: center; gap: var(--sp-2); }
.countbar { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-2) var(--sp-5); font-size: var(--fs-13); color: var(--c-text-2); }
.countbar b { color: var(--c-primary); }

/* ===== 모든 그리드/표의 제목행(헤더 th)은 항상 가운데 정렬 (실서비스 정합) =====
   데이터 셀(tbody td)·합계바(별도 *-footgrid table, thead 없음)·폼 라벨 th(tbody)는 영향 없음.
   헤더 셀에 .is-r/.rpt-num/.is-left 등 데이터 정렬 클래스가 붙어도 이 규칙이 덮는다. */
thead th { text-align: center !important; }

/* ---------- DataGrid ---------- */
.grid { border: 1px solid var(--c-border-2); border-radius: var(--r-md); overflow: auto; margin: 0 var(--sp-5) var(--sp-5); max-height: calc(100vh - 320px); }
.grid__table { font-size: var(--fs-13); min-width: 100%; }
.grid__th { position: sticky; top: 0; background: #f4f6f9; color: var(--c-text-2); font-weight: var(--fw-semibold); text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--c-border); white-space: nowrap; z-index: 1; }
.grid__th.is-sortable { cursor: pointer; }
.grid__th.is-right { text-align: right; }
.grid__th.is-center { text-align: center; }
.grid__th--chk { width: 36px; text-align: center; }
.grid__sort { margin-left: 4px; font-size: 9px; color: var(--c-primary); }
.grid__td { padding: 8px 10px; border-bottom: 1px solid var(--c-border-2); white-space: nowrap; color: var(--c-text); }
.grid__td.is-right { text-align: right; }
.grid__td.is-center { text-align: center; }
.grid__td--chk { text-align: center; }
.grid__row:nth-child(even) { background: #fafbfc; }
.grid__row:hover { background: #eef4ff; }
.grid__row.is-selected { background: #e6efff; }
.grid__row.is-flash { animation: flashRow 1.4s ease; }
@keyframes flashRow { 0% { background: #fff6d6; } 100% { background: transparent; } }
.grid__empty { text-align: center; color: var(--c-text-3); padding: var(--sp-10) 0; }

/* ---------- Toast ---------- */
#overlay-root { position: fixed; inset: 0; pointer-events: none; z-index: var(--z-toast); }
#overlay-root > * { pointer-events: auto; }
.toast { position: fixed; right: 24px; bottom: 24px; display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-radius: var(--r-md); background: #1f2a3a; color: #fff; font-size: var(--fs-13); box-shadow: var(--shadow-md); opacity: 0; transform: translateY(10px); transition: .25s; max-width: 360px; }
.toast.is-in { opacity: 1; transform: translateY(0); }
.toast--warn { background: #b4521a; }
.toast .icon { fill: #fff; }
/* 여러개 누적 */
#overlay-root .toast:nth-last-child(2) { bottom: 76px; }
#overlay-root .toast:nth-last-child(3) { bottom: 128px; }

/* ---------- Modal ---------- */
.modal__backdrop { position: fixed; inset: 0; background: var(--c-overlay); display: grid; place-items: center; z-index: var(--z-modal); }
.modal__card { width: 520px; max-width: 94vw; max-height: 90vh; background: #fff; border-radius: 12px; box-shadow: var(--shadow-lg); display: flex; flex-direction: column; overflow: hidden; }
.modal__head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--c-border-2); }
.modal__title { font-size: var(--fs-18); font-weight: var(--fw-bold); }
/* padding:0 필수 — button 의 브라우저 기본 padding(1px 6px)이 남아 있으면 box-sizing:border-box
   에서 내용폭이 12px 로 줄고, flex:none 인 아이콘(.icon)이 좌우로 삐져나간다.
   (업무용승용차 모달처럼 버튼과 아이콘을 같은 24px 로 맞춘 곳에서 실제로 6px 씩 넘쳤다) */
.modal__close { width: 30px; height: 30px; padding: 0; display: grid; place-items: center; border-radius: 4px; }
.modal__close:hover { background: var(--c-bg-soft); }
.modal__close .icon { fill: var(--c-text-2); }
.modal__body { padding: var(--sp-5); overflow-y: auto; }
.modal__foot { display: flex; justify-content: flex-end; gap: var(--sp-2); padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--c-border-2); background: var(--c-bg-soft-2); }

/* 중앙 알림 모달(온보딩/정기점검 등) */
.dialog { width: 380px; text-align: center; }
.dialog__icon { font-size: 40px; margin: var(--sp-4) 0 var(--sp-2); }
.dialog__title { font-size: var(--fs-18); font-weight: var(--fw-bold); margin-bottom: var(--sp-2); }
.dialog__desc { color: var(--c-text-2); font-size: var(--fs-14); line-height: 1.6; }
.dialog__foot { display: flex; gap: 0; margin-top: var(--sp-5); }
.dialog__foot .btn { flex: 1; height: 46px; border-radius: 0; }

/* ---------- Popover ---------- */
.popover { position: fixed; background: #fff; border: 1px solid var(--c-border-2); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); z-index: var(--z-popover); }

/* ---------- 회기 팝오버 ---------- */
.term-pop { width: 420px; padding: var(--sp-5); }
.term-pop__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-3); }
.term-pop__cap { font-size: var(--fs-12); color: var(--c-text-3); }
.term-pop__cur { font-size: var(--fs-20); font-weight: var(--fw-bold); }
.term-pop__create { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-13); color: var(--c-text-2); }
.term-pop__create .icon { fill: var(--c-text-2); }
.term-pop__close-term { width: 100%; height: 40px; border: 1px solid var(--c-border); border-radius: var(--r-md); color: var(--c-text-2); margin-bottom: var(--sp-3); }
.term-list { max-height: 240px; overflow-y: auto; }
.term-row { display: flex; align-items: center; gap: var(--sp-3); padding: 10px 6px; border-top: 1px solid var(--c-border-2); }
.term-row__no { width: 44px; height: 24px; display: grid; place-items: center; background: var(--c-bg-soft); border-radius: var(--r-pill); font-size: var(--fs-12); color: var(--c-text-2); }
.term-row__year { font-size: var(--fs-16); font-weight: var(--fw-bold); width: 64px; }
.term-row__period { flex: 1; font-size: var(--fs-12); color: var(--c-text-3); }
.term-row__action { font-size: var(--fs-13); color: var(--c-text-2); display: inline-flex; align-items: center; gap: 2px; cursor: pointer; }
.term-row__action.is-current { color: var(--c-primary); font-weight: var(--fw-bold); cursor: default; }
.term-pop__foot { text-align: center; margin-top: var(--sp-3); }

/* ---------- 달력(DatePicker) ---------- */
.cal { width: 240px; padding: var(--sp-3); }
.cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-2); }
.cal__title { font-weight: var(--fw-bold); }
.cal__nav { width: 26px; height: 26px; border-radius: 4px; color: var(--c-text-2); font-size: 16px; }
.cal__nav:hover { background: var(--c-bg-soft); }
.cal__grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 2px; }
.cal__dow { text-align: center; font-size: var(--fs-12); color: var(--c-text-3); padding: 4px 0; }
.cal__cell { height: 30px; }
.cal__day { width: 100%; border-radius: 4px; font-size: var(--fs-13); color: var(--c-text); }
.cal__day:hover { background: var(--c-bg-soft); }
.cal__day.is-sel { background: var(--c-primary); color: #fff; }
.cal__day.is-disabled { color: var(--c-border); cursor: not-allowed; }

/* ============================================================
   [전역 안전장치] 그리드 표 셀의 '…' 잘림 방지
   체크박스/라디오만 든 칸에 text-overflow:ellipsis 가 상속되면
   컨트롤이 '…'로 잘려 보임 → 해당 칸은 ellipsis 예외 처리.
   (table 셀에 text-overflow:ellipsis 줄 때 체크박스 칼럼이 함께 걸리는 흔한 버그)
   ============================================================ */
th:has(> input[type="checkbox"]), td:has(> input[type="checkbox"]),
th:has(> input[type="radio"]),    td:has(> input[type="radio"]) {
  overflow: visible;
  text-overflow: clip;
}
