/* ============================================================================
   Tlex 디자인 토큰 + 공통 컴포넌트 — flex UI·UX baseline 충실 재구현.
   ⭐ 모든 원자값의 정본 = Doc_Flex `_library/arch/05_디자인_토큰.md`(실측 추출).
      화면 구조의 정본 = `_library/product/04_flex_화면명세.md` §1 공통 레이아웃.
   ⛔ Bootstrap 기본 파랑(#0d6efd)·기본 폰트·기본 radius 노출 = 회귀다(arch/05 §7).
   ========================================================================== */

/* ── 토큰: Bootstrap 5.3 오버라이드 + --tlex-* (arch/05 §7 그대로) ───────── */
:root {
  /* 브랜드 (primary = flex green) */
  --bs-primary: #09bb1b;
  --bs-primary-rgb: 9, 187, 27;
  --tlex-primary: #09bb1b;
  --tlex-primary-dark: #058012;
  --tlex-primary-darker: #034c0b;
  --tlex-primary-light: #59cd65;
  --tlex-primary-lighter: #b7e8bd;
  --tlex-primary-lightest: #f2fdf3;

  /* 전경/배경 그레이스케일 (§2) */
  --bs-body-color: #242a30;
  --bs-body-color-rgb: 36, 42, 48;
  --bs-secondary-color: #61666a;   /* 보조 텍스트 gray */
  --bs-tertiary-color: #96999c;    /* 흐린 텍스트 placeholder */
  --bs-body-bg: #ffffff;
  --bs-tertiary-bg: #f9fafa;       /* GNB·페이지 캔버스 배경 */
  --bs-secondary-bg: #f4f4f5;
  --bs-border-color: #e5e5e6;
  --tlex-gray: #61666a;
  --tlex-gray-light: #96999c;
  --tlex-gray-lighter: #cacccd;
  --tlex-disabled: #b9bbbd;
  --tlex-thead-bg: #fdfdfd;        /* black001 */
  --tlex-line: #e5e5e6;            /* black012 */
  --tlex-line-strong: #dcddde;     /* black016 */

  /* 시맨틱 팔레트 (§3 — 기본/Darker/Lightest만 컴포넌트가 소비) */
  --bs-danger: #f24b17;  --bs-danger-rgb: 242, 75, 23;
  --bs-warning: #fab300; --bs-warning-rgb: 250, 179, 0;
  --bs-info: #2161dc;    --bs-info-rgb: 33, 97, 220;
  --bs-success: #09bb1b; --bs-success-rgb: 9, 187, 27;
  --tlex-orange-darker: #661400;
  --tlex-gold: #cf7800;  --tlex-gold-darker: #513400;
  --tlex-yellow-darker: #704300;
  --tlex-cyan: #01c6c3;  --tlex-cyan-darker: #005352;
  --tlex-blue: #2161dc;  --tlex-blue-darker: #102a5c;
  --tlex-purple: #8f40de; --tlex-purple-darker: #361853;
  --tlex-magenta: #f04785; --tlex-magenta-darker: #651e38;

  /* 타입 (§1 — 본문 14px/500 Pretendard) */
  --bs-body-font-family: "Pretendard Variable", Pretendard, -apple-system,
      BlinkMacSystemFont, "Segoe UI", Roboto, "Malgun Gothic", sans-serif;
  --bs-body-font-size: 14px;
  --bs-body-font-weight: 500;
  --bs-body-line-height: 1.45;

  /* 모서리 (§5 — 기본 8px) */
  --bs-border-radius: 8px;
  --bs-border-radius-sm: 6px;
  --bs-border-radius-lg: 8px;
  --tlex-radius: 8px;
  --tlex-radius-badge: 4px;
  --tlex-radius-pill: 50px;

  /* 그림자 (§6 — 미러 CSS 원값) */
  --tlex-shadow-button: 0 2px 6px rgba(0, 0, 0, .02), inset 0 -1px 0 rgba(0, 0, 0, .06),
      inset 0 0 0 1px rgba(0, 0, 0, .08);
  --tlex-shadow-input: inset 0 0 0 1px rgba(0, 0, 0, .1);
  --tlex-shadow-input-focus: inset 0 0 0 1px #09bb1b;
  --tlex-shadow-input-error: inset 0 0 0 1px #f44712;
  --tlex-shadow-tab-active: inset 0 -2px 0 #242a30;
  --tlex-shadow-page-root: 0 0 12px rgba(0, 0, 0, .04), -1px 0 0 rgba(0, 0, 0, .04),
      0 0 24px rgba(0, 0, 0, .04);
  --tlex-shadow-popover: 0 0 0 1px rgba(0, 0, 0, .03), 0 14px 60px rgba(0, 0, 0, .15);
  --tlex-shadow-modal: 0 0 0 1px rgba(0, 0, 0, .04), 0 24px 72px rgba(36, 42, 48, .22);
  --tlex-overlay-dark: rgba(36, 42, 48, .5);

  /* 간격 (§4 — 4px 그리드 · 툴바 실측) */
  --tlex-toolbar-min-height: 56px;
  --tlex-toolbar-pad-y: 16px;
  --tlex-gnb-width: 240px;
  --tlex-datepicker-selected-bg: #e5fae8;
}

html { font-size: 14px; }  /* rem 기반 Bootstrap 간격을 flex 밀도로 축소 */
body { background: var(--bs-tertiary-bg); }

/* ── 앱 셸: 좌측 세로 GNB + 우측 콘텐츠 (04 §1) ─────────────────────────── */
.tlex-shell { display: flex; min-height: 100vh; }

/* ⚠️ 배치 규칙은 «데스크톱 전용» 미디어 블록에 둔다 — 바깥에 두면 같은 특이도의
   Bootstrap offcanvas(모바일 fixed/hidden) 규칙을 소스 순서로 이겨 버려,
   모바일에서 숨은 GNB 가 100vh 블록 자리를 차지해 본문을 밀어낸다(실측). */
.tlex-gnb {
  --bs-offcanvas-width: var(--tlex-gnb-width);
  --bs-offcanvas-bg: var(--bs-tertiary-bg);
}
@media (min-width: 992px) {
  .tlex-gnb {
    width: var(--tlex-gnb-width);
    flex: 0 0 var(--tlex-gnb-width);
    background: var(--bs-tertiary-bg);
    display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh;
  }
}
/* offcanvas-body 기본 패딩(1rem)을 GNB 밀도로 교체 */
.tlex-gnb .tlex-gnb-body {
  display: flex; flex-direction: column;
  padding: 12px 10px 16px;
  overflow-y: auto;
}
/* 본문 = 흰 페이지가 회색 캔버스 위에 뜬다 (pageRoot shadow) */
.tlex-main {
  flex: 1 1 auto; min-width: 0;
  background: var(--bs-body-bg);
  box-shadow: var(--tlex-shadow-page-root);
  display: flex; flex-direction: column;
}

/* GNB 상단 — 회사 스위처·근무 시작·프로필·검색·알림 */
.gnb-company {
  display: flex; align-items: center; gap: 8px;
  width: 100%; border: 0; background: transparent; text-align: left;
  padding: 8px; border-radius: var(--tlex-radius);
  font-weight: 700; font-size: 14px; color: var(--bs-body-color);
}
.gnb-company:hover { background: rgba(36, 42, 48, .04); }
.gnb-company .logo {
  width: 26px; height: 26px; border-radius: 6px; flex: 0 0 26px;
  background: var(--tlex-primary); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700;
}
.gnb-workstart { margin: 8px 0 2px; }
.gnb-workstart .btn { width: 100%; font-weight: 700; }

/* ── 근무 시작 팝오버 카드 — 라이브 실측(2026-08-12 ux26 computed):
   카드 260px·radius 10 · 「시작 전」 15px/700 #96999c · 질문 12px/600 rgba(36,42,48,.4) ·
   유형 행 248×32 radius 6 14px/600 · ✓ = primary · 「지금 출근」 244×40 radius 8 primary ── */
.ws-card {
  width: 260px; border-radius: 10px; border: 0; padding: 12px 8px 8px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .06), 0 8px 24px rgba(0, 0, 0, .14);
}
.ws-state {
  font-size: 15px; font-weight: 700; color: var(--tlex-gray-light);
  padding: 2px 8px 8px; display: flex; align-items: center; gap: 6px;
}
/* ⚙ 설정 — «미구현 = 비활성 자리 유지» 관례(ux26 실측: 상태 라벨 우측 haspopup) */
.ws-gear {
  margin-left: auto; border: 0; background: none; padding: 2px;
  color: var(--tlex-gray-lighter); font-size: 14px; line-height: 1; cursor: default;
}
.ws-state .ws-since { font-size: 12px; font-weight: 600; color: var(--tlex-gray); }
.ws-dot { color: var(--tlex-primary); font-size: 12px; }
.ws-q { font-size: 12px; font-weight: 600; color: rgba(36, 42, 48, .4); padding: 0 8px 6px; }
.ws-kinds { display: flex; flex-direction: column; gap: 2px; padding: 0 4px; }
.ws-kinds button {
  display: flex; align-items: center; justify-content: space-between;
  height: 32px; padding: 5px 8px; border: 0; border-radius: 6px; background: none;
  font-size: 14px; font-weight: 600; color: #3e4449; text-align: left;
}
.ws-kinds button:hover { background: rgba(36, 42, 48, .05); }
.ws-kinds .bi { font-size: 14px; color: var(--tlex-gray-light); margin-right: 6px; }
.ws-kinds .ws-check { display: none; color: var(--tlex-primary); font-size: 16px; margin: 0; }
.ws-kinds button.active .ws-check { display: inline; }
.ws-go {
  display: block; width: calc(100% - 12px); margin: 10px 6px 2px; height: 40px;
  border-radius: 8px; background: var(--tlex-primary); color: #fff;
  font-size: 14px; font-weight: 700; border: 0;
}
.ws-go:hover { background: var(--tlex-primary-dark); color: #fff; }
.ws-msg:empty { display: none; }
.ws-msg { padding: 6px 8px 0; }

/* ── 근무 «중» 상태 — 사용자 제공 flex 캡처 실측(2026-08-12 FEAT017):
   GNB 필 = [근무중 초록 미니 배지] + 경과 굵게 · 카드 = 유형 카드(테두리 r10) 안에
   「HH:MM 부터 진행 중」 · 총 휴게 행 · 지금 퇴근(초록) + ⋮ 분할 버튼 ── */
.ws-pill {
  display: inline-flex; align-items: center; height: 18px; padding: 0 6px;
  border-radius: 4px; background: var(--tlex-primary); color: #fff;
  font-size: 11px; font-weight: 700; margin-right: 2px;
}
.ws-elapsed { font-weight: 700; }
.ws-now {
  margin: 0 6px 6px; padding: 10px 12px; border-radius: 10px;
  box-shadow: inset 0 0 0 1px var(--tlex-line);
}
.ws-now-kind { font-size: 14px; font-weight: 700; color: #01a2a0; }
.ws-now-kind .bi { margin-right: 4px; }
.ws-now-since { font-size: 12px; font-weight: 600; color: var(--tlex-gray); margin-top: 3px; }
.ws-rest {
  margin: 0 6px 4px; padding: 8px 12px; border-radius: 10px;
  box-shadow: inset 0 0 0 1px var(--tlex-line);
  font-size: 13px; font-weight: 600; color: var(--tlex-gray);
}
.ws-rest .bi { margin-right: 4px; }
.ws-rest b { font-weight: 700; color: var(--bs-body-color); }
.ws-split { display: flex; gap: 1px; margin: 10px 6px 2px; }
.ws-split .ws-go { flex: 1 1 auto; width: auto; margin: 0; border-radius: 8px 0 0 8px; }
.ws-split .ws-more {
  width: 36px; margin: 0; border-radius: 0 8px 8px 0; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
}
.ws-split .ws-more:disabled { opacity: .85; }

/* ── 근무중 팝오버 메뉴 3종 (FEAT042 — flex E03~E06: 카드/총 휴게/⋮ 전부 menu) ── */
.ws-now, .ws-rest { display: block; width: calc(100% - 12px); text-align: left; border: 0; background: none; }
button.ws-now:hover, button.ws-rest:hover { box-shadow: inset 0 0 0 1px var(--tlex-gray-lighter); }
.ws-menu {
  position: absolute; z-index: 1080; min-width: 168px; max-height: 300px; overflow-y: auto;
  background: var(--bs-body-bg); border-radius: 10px; padding: 4px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .06), 0 8px 24px rgba(0, 0, 0, .16);
}
/* ⛔ 서브메뉴(근무 변경·시작 시각 변경 플라이아웃)는 부모 .ws-menu 의 «스크롤 상자» 안에
   두면 안 된다 — absolute 자식이라 max-height 300px·overflow-y:auto 에 갇혀 화면에 거의
   안 나오고 가로 스크롤바만 생겼다(적대검증 high 2렌즈 + 캡처 육안 재확인 F04).
   ⇒ fixed 로 뷰포트 기준 배치(JS 가 getBoundingClientRect 로 좌표를 준다). */
.ws-menu .ws-sub { position: fixed; z-index: 1081; max-height: 280px; }
.ws-menu button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; border: 0; background: none; border-radius: 6px;
  padding: 7px 10px; font-size: 13px; font-weight: 600; color: #3e4449; text-align: left;
}
.ws-menu button:hover { background: rgba(36, 42, 48, .05); }
.ws-menu .ws-danger { color: var(--bs-danger); }
.ws-menu .ws-two { flex-direction: column; align-items: flex-start; gap: 2px; }
.ws-menu .ws-two small { font-size: 11px; font-weight: 500; color: var(--tlex-gray-light); }
.ws-menu .ws-cur-mark { display: none; color: var(--tlex-primary); }
.ws-menu .cur .ws-cur-mark { display: inline; }
.ws-menu .ws-form-item.cur, .ws-times .cur { color: var(--tlex-primary); }
/* 시각 목록 — «오전 12:00» 이 두 줄로 접혀 «오전 …»만 보이던 것 보정(재스모크 육안 적발) */
.ws-times { min-width: 132px; }
.ws-menu button, .ws-rest-row { white-space: nowrap; }
.ws-rest-row { padding: 7px 10px; font-size: 13px; font-weight: 600; color: var(--tlex-gray); white-space: nowrap; }
.ws-rest-add { color: var(--tlex-primary); }
/* 기록 취소 확인 — flex E04 ③ 이 dialog 를 거친다(적대검증 med: 즉시 삭제였다) */
.ws-confirm {
  position: fixed; inset: 0; z-index: 1090; background: rgba(0, 0, 0, .32);
  display: flex; align-items: center; justify-content: center;
}
.ws-confirm-card {
  width: 340px; background: var(--bs-body-bg); border-radius: 14px; padding: 22px 22px 16px;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .24);
}
.ws-confirm-card h6 { font-size: 16px; font-weight: 700; margin: 0 0 8px; }
.ws-confirm-card p { font-size: 13px; color: var(--tlex-gray); margin: 0 0 16px; line-height: 1.5; }
.ws-confirm-foot { display: flex; justify-content: flex-end; gap: 6px; }
.ws-confirm-foot button {
  border: 0; background: none; border-radius: 8px; padding: 8px 12px;
  font-size: 13px; font-weight: 700; color: var(--tlex-gray);
}
.ws-confirm-foot button:hover { background: rgba(36, 42, 48, .05); }
.ws-confirm-foot .ws-primary { background: var(--tlex-primary); color: #fff; }
.ws-confirm-foot .ws-primary:hover { background: var(--tlex-primary-dark); }
/* disabled 버튼이 활성처럼 그려졌다(E08 [적용하기] — 육안 스모크 적발 · flex 는 흐림) */
.ws-confirm-foot button:disabled { opacity: .45; cursor: default; }
.ws-confirm-foot button:disabled:hover { background: var(--tlex-primary); }

/* «퇴근 시 설정» dialog (FEAT045 · flex E08 — 미리보기 + radio 2절) */
.ws-pref-card { width: 380px; }
.ws-pref-preview {
  display: flex; justify-content: center; padding: 12px 0;
  background: rgba(36, 42, 48, .04); border-radius: 10px; margin-bottom: 14px;
}
.ws-pref-btn { pointer-events: none; min-width: 140px; }
.ws-pref-sec { border: 0; margin: 0 0 12px; padding: 0; }
.ws-pref-sec legend { font-size: 13px; font-weight: 700; margin-bottom: 4px; float: none; width: auto; }
.ws-pref-sec label { display: block; font-size: 13px; padding: 3px 0; cursor: pointer; }
.ws-pref-sec input[type="radio"] { margin-right: 8px; accent-color: var(--tlex-primary); }
.ws-pref-cap { font-size: 12px; color: var(--tlex-gray); margin: 4px 0 0; }

/* 「지난 퇴근 시각으로 닫기」 dialog — 「지금 퇴근」이 좌표 상한에 걸린 세션의 회복 경로.
   ⚠️FLEX-미실측(대응 화면이 flex 에 없다) — 형상은 위 «퇴근 시 설정» dialog 어휘를 그대로 쓴다. */
.ws-late-card { width: 380px; }
.ws-late-row { margin-bottom: 12px; }
.ws-late-row label { display: block; font-size: 13px; font-weight: 700; margin-bottom: 4px; }
.ws-late-row label small { font-weight: 500; color: var(--tlex-gray); }
.ws-late-row select, .ws-late-row input[type="time"], .ws-late-row textarea {
  width: 100%; border: 1px solid var(--tlex-line); border-radius: 8px;
  padding: 7px 10px; font-size: 13px; background: var(--bs-body-bg);
  color: var(--bs-body-color);
}
.ws-late-row textarea { resize: vertical; }
.ws-late-row select:focus, .ws-late-row input[type="time"]:focus, .ws-late-row textarea:focus {
  outline: 0; border-color: var(--tlex-primary);
}
/* 보조 탈출구 — 주 동선(퇴근 저장)보다 약하게. 위험 조작이라 색은 경고 계열이다. */
.ws-late-cancel {
  display: block; margin: 10px auto 0; border: 0; background: none;
  font-size: 12px; font-weight: 600; color: var(--tlex-gray);
  text-decoration: underline; padding: 4px;
}
.ws-late-cancel:hover { color: var(--bs-danger, #d93025); }

.gnb-util { display: flex; flex-direction: column; margin: 4px 0 10px; }
.gnb-util a, .gnb-util button {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border: 0; background: transparent; width: 100%;
  border-radius: var(--tlex-radius); text-align: left;
  color: var(--bs-body-color); font-size: 14px; font-weight: 500;
  text-decoration: none;
}
.gnb-util a:hover, .gnb-util button:hover { background: rgba(36, 42, 48, .04); }
.gnb-util .bi { color: var(--tlex-gray-light); font-size: 15px; }
.gnb-util .kbd-hint {
  margin-left: auto; font-size: 11px; color: var(--tlex-gray-light);
  border: 1px solid var(--tlex-line); border-radius: 4px; padding: 0 4px; background: #fff;
}

/* GNB 주 메뉴 */
.gnb-menu { list-style: none; margin: 0; padding: 0; }
.gnb-menu .group-label {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; margin-top: 2px;
  color: var(--bs-body-color); font-size: 14px; font-weight: 500;
}
/* GNB 그룹 폴딩(flex 실측 FEAT025) — 토글 버튼화 + 하위만 숨김 */
button.gnb-group-toggle {
  border: 0; background: transparent; width: 100%; cursor: pointer;
  text-align: left; border-radius: var(--tlex-radius);
}
button.gnb-group-toggle:hover { background: rgba(36, 42, 48, .04); }
.gnb-group-chevron {
  margin-left: auto; font-size: 12px !important; width: auto !important;
  transition: transform .15s ease;
}
.gnb-group-toggle[aria-expanded="false"] .gnb-group-chevron { transform: rotate(-90deg); }
.gnb-menu .sub.collapsed { display: none; }
.gnb-menu a, .gnb-menu .nav-disabled {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border-radius: var(--tlex-radius);
  color: var(--bs-body-color); text-decoration: none;
  font-size: 14px; font-weight: 500;
}
.gnb-menu a:hover { background: rgba(36, 42, 48, .04); }
.gnb-menu a.active { background: rgba(36, 42, 48, .06); font-weight: 700; }
.gnb-menu .bi { color: var(--tlex-gray-light); font-size: 15px; width: 16px; text-align: center; }
.gnb-menu .sub a, .gnb-menu .sub .nav-disabled { padding-left: 34px; }
.gnb-menu .nav-disabled { color: var(--tlex-disabled); cursor: default; }
.gnb-menu .nav-disabled .bi { color: var(--tlex-gray-lighter); }
.gnb-badge {
  margin-left: auto; background: var(--bs-danger); color: #fff;
  font-size: 11px; font-weight: 600; border-radius: var(--tlex-radius-pill);
  padding: 1px 6px; line-height: 1.4;
}

/* 페이지 헤더(banner) — 제목/페이지 탭 + 우측 액션 (04 §1) */
.page-header {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: var(--tlex-toolbar-min-height);
  padding: var(--tlex-toolbar-pad-y) 24px 0;
  flex-wrap: wrap;
}
.page-header h1 { font-size: 20px; font-weight: 700; margin: 0; }
.page-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.page-body { padding: 16px 24px 32px; }

/* 페이지 헤더 탭(내 근무/구성원 근무 급) — ⭐라이브 computed 실측(2026-08-12):
   선택 28px/700 #3e4449 · 비선택 28px/600 #cacccd. (구값 15px 는 화면 내 tablist 와 혼동) */
.page-tabs { display: flex; gap: 18px; align-items: center; }
.page-tabs a, .page-tabs .tab-off {
  font-size: 28px; font-weight: 600; color: var(--tlex-gray-lighter);
  text-decoration: none; padding: 0 2px; line-height: 1.3;
}
.page-tabs a.active { font-weight: 700; color: #3e4449; }
.page-tabs .tab-off { cursor: default; }  /* 미구현 서브탭 = 비활성 자리(홈 피드 할 일·인정) */

/* 화면 내 탭바(tablist) — 선택 = 검정 2px 밑줄 (⛔파랑 배경 탭 아님)
   15px = 라이브 computed 실측(2026-08-12 work-record tablist — arch/05 「페이지 탭(대) 15px」) */
.tlex-tabs {
  display: flex; gap: 4px; border-bottom: 1px solid var(--tlex-line);
  padding: 0 24px; margin: 4px 0 0;
}
.tlex-tabs a, .tlex-tabs .tab-off {
  font-size: 15px; font-weight: 600; color: var(--tlex-gray-light);
  text-decoration: none; padding: 10px 12px;
}
.tlex-tabs a:hover { color: var(--bs-body-color); }
.tlex-tabs a.active {
  color: var(--bs-body-color); font-weight: 700;
  box-shadow: var(--tlex-shadow-tab-active);
}
.tlex-tabs .tab-off { color: var(--tlex-gray-lighter); cursor: default; }

/* ── Bootstrap 컴포넌트 → flex 표면 ─────────────────────────────────────── */

/* 버튼: 기본 = 흰 표면 + button shadow(테두리 대체) · CTA = primary 초록/700 */
.btn { --bs-btn-font-weight: 600; --bs-btn-font-size: 14px; }
.btn-primary {
  --bs-btn-bg: var(--tlex-primary);
  --bs-btn-border-color: var(--tlex-primary);
  --bs-btn-hover-bg: var(--tlex-primary-dark);
  --bs-btn-hover-border-color: var(--tlex-primary-dark);
  --bs-btn-active-bg: var(--tlex-primary-dark);
  --bs-btn-active-border-color: var(--tlex-primary-dark);
  --bs-btn-disabled-bg: var(--tlex-primary-lighter);
  --bs-btn-disabled-border-color: var(--tlex-primary-lighter);
  --bs-btn-font-weight: 700;
  /* ⛔벤더 컴파일 기본 = 파랑 49,132,253 — 키보드 포커스 링도 초록으로(적대검증 #4) */
  --bs-btn-focus-shadow-rgb: 9, 187, 27;
}
.btn-default, .btn-light {
  --bs-btn-bg: #fff; --bs-btn-border-color: transparent;
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-hover-bg: #fff; --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-active-bg: var(--bs-secondary-bg); --bs-btn-active-border-color: transparent;
  box-shadow: var(--tlex-shadow-button);
}
.btn-ghost {
  --bs-btn-bg: transparent; --bs-btn-border-color: transparent;
  --bs-btn-color: var(--tlex-gray);
  --bs-btn-hover-bg: rgba(36, 42, 48, .05); --bs-btn-hover-color: var(--bs-body-color);
}
.btn-sm { --bs-btn-font-size: 13px; }
/* ⭐새 Bootstrap 변형을 처음 쓸 때마다 벤더 리터럴을 덮는다(§2-8 — 6·7번째 사례).
   FEAT023 삭제 확인 모달이 `.btn-danger`·`.btn-secondary` 를 도입 = 저장소 첫 사용처인데
   벤더 min.css 의 컴파일된 값(danger #dc3545·focus-shadow 225,83,97 / secondary 회색
   #6c757d·focus-shadow 130,138,145)이 그대로 나와 파괴적 조작 버튼만 Tlex 팔레트 밖
   색으로 튄다(적대검증 med — 2렌즈 중복). 위험색은 flex 반려/경고 계열 #f24b17 축으로. */
.btn-danger {
  --bs-btn-bg: #f24b17; --bs-btn-border-color: transparent; --bs-btn-color: #fff;
  --bs-btn-hover-bg: #d8410f; --bs-btn-hover-border-color: transparent; --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: #c0390d; --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-bg: #f7a58c; --bs-btn-disabled-border-color: transparent;
  --bs-btn-focus-shadow-rgb: 242, 75, 23;
}
.btn-secondary {
  --bs-btn-bg: #fff; --bs-btn-border-color: transparent;
  --bs-btn-color: var(--tlex-gray);
  --bs-btn-hover-bg: #fff; --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-active-bg: var(--bs-secondary-bg); --bs-btn-active-border-color: transparent;
  --bs-btn-focus-shadow-rgb: 9, 187, 27;
  box-shadow: var(--tlex-shadow-button);
}
/* 키보드 포커스 — 초록 링 유지 + 표면 그림자(테두리 대체) 소실 방지(적대검증 #6·#10) */
.btn-default:focus-visible, .btn-light:focus-visible, .btn-secondary:focus-visible {
  box-shadow: 0 0 0 3px rgba(9, 187, 27, .25), var(--tlex-shadow-button);
}
.btn-ghost:focus-visible { box-shadow: 0 0 0 3px rgba(9, 187, 27, .25); }
.btn-close:focus { box-shadow: 0 0 0 3px rgba(9, 187, 27, .25); }

/* 입력: 테두리 = inset shadow · 포커스 = ⭐primary 초록 링(파랑 아님) */
.form-control, .form-select {
  border: 0; box-shadow: var(--tlex-shadow-input);
  font-size: 14px; border-radius: var(--tlex-radius);
  color: var(--bs-body-color); background-color: #fff;
}
.form-control:focus, .form-select:focus {
  border: 0; box-shadow: var(--tlex-shadow-input-focus);
  outline: none;
}
.form-control.is-invalid, .was-validated .form-control:invalid {
  box-shadow: var(--tlex-shadow-input-error); border: 0;
}
.form-control::placeholder { color: var(--tlex-gray-light); }
.form-label { font-size: 13px; color: var(--tlex-gray); margin-bottom: 4px; }

/* 체크박스 — ⛔벤더 컴파일 리터럴 파랑(#0d6efd checked·indeterminate / #86b7fe·rgba(13,110,253) focus)
   재정의(§2-8 의 6번째 컴포넌트 — FEAT013 구성원 관리 표에서 첫 사용). */
.form-check-input:checked,
.form-check-input[type=checkbox]:indeterminate {
  background-color: var(--tlex-primary); border-color: var(--tlex-primary);
}
.form-check-input:focus {
  border-color: rgba(9, 187, 27, .4);
  box-shadow: 0 0 0 .25rem rgba(9, 187, 27, .25);
}
/* 스위치 — FEAT027 공지 토글(고정 2종·댓글·이모지)이 form-switch 첫 사용(§2-8 의 7번째).
   벤더 focus 원 svg(#86b7fe)를 초록으로. ⚠️:not(:checked) 필수 — 같은 특이도의 벤더
   :checked(흰 원)를 후행 로드로 이기면 초록 트랙 위 초록 원 = 손잡이가 사라진다. */
.form-switch .form-check-input:focus:not(:checked) {
  --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2309bb1b'/%3e%3c/svg%3e");
}

/* 카드 */
.card {
  --bs-card-border-color: var(--tlex-line);
  --bs-card-border-radius: var(--tlex-radius);
  --bs-card-cap-bg: transparent;
}

/* 표: 헤더 #fdfdfd·13px/500 gray · 셀 하단선 #e5e5e6 (arch/05 §1·§2) */
.tlex-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.tlex-table th {
  background: var(--tlex-thead-bg); color: var(--tlex-gray);
  font-size: 13px; font-weight: 500; text-align: left;
  padding: 9px 12px; border-bottom: 1px solid var(--tlex-line);
  white-space: nowrap;
}
.tlex-table td {
  padding: 9px 12px; border-bottom: 1px solid var(--tlex-line);
  font-weight: 400; vertical-align: middle;
}
.tlex-table tr:hover > td { background: rgba(36, 42, 48, .015); }
.tlex-table .num, .tlex-table th.num, .tlex-table td.num { text-align: right; }
/* 폭 초과 표는 자체 스크롤 (04 §9 — 본문 가로 스크롤 금지) */
.table-scroll { overflow-x: auto; }

/* 상태 배지 — 배경 색상Alpha.12 + 글자 색상Darker · 11px/600 · radius 4px (§3) */
.tlex-badge {
  display: inline-block; font-size: 11px; font-weight: 600;
  border-radius: var(--tlex-radius-badge); padding: 2px 6px; line-height: 1.5;
  background: rgba(36, 42, 48, .06); color: var(--tlex-gray);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .03);
}
.tlex-badge.green   { background: rgba(9, 187, 27, .12);   color: var(--tlex-primary-darker); }
.tlex-badge.orange  { background: rgba(242, 75, 23, .12);  color: var(--tlex-orange-darker); }
.tlex-badge.gold    { background: rgba(207, 120, 0, .12);  color: var(--tlex-gold-darker); }
.tlex-badge.yellow  { background: rgba(250, 179, 0, .12);  color: var(--tlex-yellow-darker); }
.tlex-badge.cyan    { background: rgba(1, 198, 195, .12);  color: var(--tlex-cyan-darker); }
.tlex-badge.blue    { background: rgba(33, 97, 220, .12);  color: var(--tlex-blue-darker); }
.tlex-badge.purple  { background: rgba(143, 64, 222, .12); color: var(--tlex-purple-darker); }
.tlex-badge.magenta { background: rgba(240, 71, 133, .12); color: var(--tlex-magenta-darker); }

/* ── 커스텀 승인 라벨 색 점 (flex A24 색상 피커 10종) ────────────────────────
   ⭐**이 팔레트가 유일 정본이다** — 파이썬(ApprovalLabel.Color)은 키와 한국어 이름만
   갖는다(칠하는 층이 하나여야 한다). 소비처 3곳이 같은 클래스를 쓴다: 설정 pane 목록·
   추가 dialog 피커 · 결재선 편집기 단계 칩 · 문서 상세 결재선/기안 미리보기.
   ⚠️**hex 는 실측 «근사»다(값 오라클 없음)** — flex 는 이 기능을 쓴 적이 없어 API 덤프에
   라벨 행이 0 이고, 색 정의는 미러 번들에도 없다(설정 모듈 미러링 밖). 그래서
   `_verify/FY005/flex_A24_라벨추가_dialog_색상피커.png` 의 스와치 픽셀을 재고,
   그 캡처에 걸린 dialog 오버레이(백색 α≈0.30 — 노랑 스와치가 #ffc107 로 역산되는 값)를
   역보정한 값을 썼다. 원측정값(오버레이 포함)은 순서대로
   #cdd2d6 #aa7ad9 #70afdb #54a6ee #55d9d7 / #59cd65 #d6a754 #ffd454 #f584ad #f57453 이다.
   ⇒ flex 재실측(~2026-09-18 해지 전)이 가능하면 이 10줄만 교체하면 된다. */
.lbl-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: #b8bfc4; vertical-align: middle;
}
.lbl-c-GRAY    { background: #b8bfc4; }
.lbl-c-PURPLE  { background: #8641c9; }
.lbl-c-BLUE    { background: #338dcc; }
.lbl-c-SKYBLUE { background: #0b80e7; }
.lbl-c-TEAL    { background: #0cc9c6; }
.lbl-c-GREEN   { background: #12b823; }
.lbl-c-BROWN   { background: #c4810b; }
.lbl-c-YELLOW  { background: #ffc20b; }
.lbl-c-PINK    { background: #f14f8a; }
.lbl-c-ORANGE  { background: #f13809; }
/* 라벨 칩 — 문서 상세 결재선에서 이름 옆에 붙는 «합의» 류 표기 */
.lbl-chip {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 6px;
  font-size: 11px; font-weight: 600; color: var(--tlex-gray);
  background: rgba(36, 42, 48, .06); border-radius: var(--tlex-radius-badge);
  padding: 1px 6px;
}

/* 드롭다운·모달 표면 */
.dropdown-menu {
  --bs-dropdown-border-radius: var(--tlex-radius);
  --bs-dropdown-border-color: transparent;
  --bs-dropdown-font-size: 14px;
  /* ⛔벤더 기본 active = #0d6efd 파랑 — 중립 강조로 교체(적대검증 #3) */
  --bs-dropdown-link-active-bg: rgba(36, 42, 48, .06);
  --bs-dropdown-link-active-color: var(--bs-body-color);
  box-shadow: var(--tlex-shadow-popover);
}
.modal-content { box-shadow: var(--tlex-shadow-modal); border: 0; border-radius: var(--tlex-radius); }
.modal-backdrop { --bs-backdrop-bg: var(--tlex-overlay-dark); --bs-backdrop-opacity: 1; }

/* 에러 표면 — flex 에러 = orange 계열(⛔Bootstrap 기본 빨강 노출 금지 — 적대검증 #5) */
.alert-danger {
  --bs-alert-bg: #fff7f5;            /* orange lightest */
  --bs-alert-border-color: #ffcec2;  /* orange lighter */
  --bs-alert-color: #c32700;         /* orange dark */
  --bs-alert-link-color: #661400;
}

/* 텍스트 유틸 */
.text-muted2 { color: var(--tlex-gray-light) !important; }
.fs-13 { font-size: 13px; }
a { color: var(--bs-body-color); }
code { color: var(--tlex-gray); }  /* ⛔벤더 기본 #d63384 핑크 = 팔레트 밖(적대검증 #7) */
.link-plain { text-decoration: none; }
.link-plain:hover { text-decoration: underline; }

/* 빈 상태 (flex empty state 관용) */
.empty-state {
  text-align: center; padding: 56px 20px; color: var(--tlex-gray);
}
.empty-state .title { font-size: 15px; font-weight: 700; color: var(--bs-body-color); margin-bottom: 6px; }
.empty-state .desc { font-size: 13px; color: var(--tlex-gray-light); }

/* 요약 숫자 카드 */
.stat-cards { display: flex; gap: 12px; flex-wrap: wrap; }
.stat-cards .stat {
  flex: 1 1 180px; background: #fff; border: 1px solid var(--tlex-line);
  border-radius: var(--tlex-radius); padding: 14px 16px;
}
.stat-cards .stat .label { font-size: 13px; color: var(--tlex-gray); }
.stat-cards .stat .value { font-size: 22px; font-weight: 700; }
.stat-cards .stat .value.primary { color: var(--tlex-primary); }
.stat-cards .stat .value.neg { color: var(--bs-danger); }

/* 잔여 수치 강조 (휴가 잔여·보상휴가) */
.balance-num { font-size: 24px; font-weight: 700; color: var(--tlex-primary); }
.balance-num.neg { color: var(--bs-danger); }

/* ── 근무 관리 대시보드 (ux16 — 라이브 computed 실측 2026-08-12) ────────────
   segmented 컨테이너 rgba(36,42,48,.04)/r7/h24 · 항목 12px/500 h22 r6 (선택 #3e4449·흰 pill) ·
   날짜 라벨 13px/700 #61666a · 기준시각 13px/600 #96999c ·
   KPI 카드 bg #fdfdfd·ring rgba(36,42,48,.1)·구분선 .06 · 아이콘 16px(#FAD052/#EE906F/#59CD65) ·
   현황 카드 그리드 308px/gap10 · 카드 pad 20 24 r10 · 제목 14/600 #3e4449 · 설명 12/500 #96999c ·
   값 20/600 #242a30(0 = #cacccd) · 증감 14/500 «↗ #09bb1b · ↘ #f24b17»(방향 2색 — 픽셀 실측) ·
   변동없음 #cacccd ── */
.dash-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 4px 0 20px; }
.seg { display: inline-flex; align-items: center; gap: 1px; background: rgba(36, 42, 48, .04); border-radius: 7px; padding: 1px; height: 24px; }
.seg a, .seg .off {
  display: inline-flex; align-items: center; height: 22px; padding: 0 10px;
  border-radius: 6px; font-size: 12px; font-weight: 500;
  color: var(--tlex-gray-light); text-decoration: none;
}
.seg a.on { color: #3e4449; background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .08); }
.seg a:hover:not(.on) { color: var(--tlex-gray); }
.seg .off { color: var(--tlex-gray-lighter); cursor: default; }
.date-nav { display: inline-flex; align-items: center; gap: 2px; }
.date-nav b { font-size: 13px; font-weight: 700; color: var(--tlex-gray); padding: 0 6px; white-space: nowrap; }
.nav-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 5px;
  color: var(--tlex-gray-lighter); text-decoration: none; font-size: 14px;
}
.nav-btn:hover { background: rgba(36, 42, 48, .05); color: var(--tlex-gray); }
.chip-btn {
  display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px;
  border: 0; border-radius: 6px; background: transparent;
  font-size: 12px; font-weight: 600; color: var(--bs-body-color);
  box-shadow: var(--tlex-shadow-input);
}
.chip-btn:disabled { color: var(--tlex-disabled); }
.chip-btn .bi { font-size: 12px; color: var(--tlex-gray-light); }
.dash-asof { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--tlex-gray-light); }
.dash-asof .nav-btn { color: var(--tlex-gray); }

/* ── 월 캘린더 드롭다운(날짜 라벨 피커 — FY009 캡처 48 실측: 흰 카드 r10 그림자 ·
   연월 헤더 좌 14/700 + 우 ‹› · 요일 12/500 #96999c · 날짜 칸 r8 13/600 ·
   오늘 = 연한 초록 배경 + primary 글자 · 전/후월 = #cacccd) ── */
.dp { position: relative; display: inline-flex; }
.dp-btn {
  border: 0; background: none; padding: 2px 6px; border-radius: 5px;
  font-size: 13px; font-weight: 700; color: var(--tlex-gray); white-space: nowrap;
}
.dp-btn:hover { background: rgba(36, 42, 48, .05); }
.dp-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 1050;
  display: block; width: 248px; padding: 14px 16px 16px;
  background: var(--bs-body-bg); border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .14), 0 0 0 1px rgba(36, 42, 48, .06);
}
.dp-pop[hidden] { display: none; }
.dp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.dp-title { font-size: 14px; font-weight: 700; color: var(--bs-body-color); }
.dp-nav { display: inline-flex; gap: 2px; }
.dp-mv {
  border: 0; background: none; width: 24px; height: 24px; border-radius: 6px;
  color: var(--tlex-gray-light); font-size: 13px; padding: 0;
}
.dp-mv:hover { background: rgba(36, 42, 48, .05); color: var(--tlex-gray); }
.dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px 0; }
.dp-grid .wd {
  text-align: center; font-size: 12px; font-weight: 500;
  color: var(--tlex-gray-light); padding: 2px 0 6px;
}
.dp-grid .day {
  height: 30px; border: 0; background: none; border-radius: 8px;
  font-size: 13px; font-weight: 600; color: var(--bs-body-color); padding: 0;
}
.dp-grid .day:hover { background: rgba(36, 42, 48, .06); }
.dp-grid .day.out { color: var(--tlex-gray-lighter); }
/* 선택 = 연한 초록 채움(실측 캡처의 «오늘 = 선택» 상태). 오늘이지만 선택이 아닌 날은
   글자만 primary — FY009 미실측(둘이 갈린 상태가 캡처에 없다) · 자체 규정 */
.dp-grid .day.sel { background: var(--tlex-datepicker-selected-bg); color: var(--tlex-primary); }
.dp-grid .day.today:not(.sel) { color: var(--tlex-primary); }

/* ── 대시보드 필터 팝오버(근무 유형·조직 — FY009 캡처 37·38) ──────────────
   검색 인풋 → 그룹 헤더/카운트 행 → 체크 항목. 항목은 링크(서버 토글)다. */
.dash-filter { display: inline-flex; }
.dash-menu {
  min-width: 268px; max-width: 320px; padding: 8px; border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .14), 0 0 0 1px rgba(36, 42, 48, .06); border: 0;
}
.dash-menu .dm-search {
  display: flex; align-items: center; gap: 6px; padding: 6px 8px; margin-bottom: 6px;
  border-radius: 7px; box-shadow: inset 0 0 0 1px var(--tlex-line);
  color: var(--tlex-gray-light);
}
.dash-menu .dm-search input {
  flex: 1; border: 0; outline: 0; background: transparent;
  font-size: 13px; font-weight: 500; color: var(--bs-body-color); min-width: 0;
}
.dash-menu .dm-count { font-size: 12px; font-weight: 600; color: var(--tlex-gray); padding: 4px 8px; }
.dash-menu .dm-note {
  display: flex; align-items: center; gap: 6px; padding: 4px 8px 8px;
  font-size: 12px; font-weight: 600; color: var(--tlex-primary);
}
.dash-menu .dm-group {
  padding: 8px 8px 4px; font-size: 12px; font-weight: 600; color: var(--tlex-gray-light);
}
.dash-menu .dm-list { max-height: 320px; overflow-y: auto; }
.dash-menu .dm-row { display: flex; align-items: center; }
.dash-menu .dm-row .dm-item { flex: 1 1 auto; min-width: 0; }
.dash-menu .dm-item {
  display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 7px;
  font-size: 13px; font-weight: 500; color: var(--bs-body-color); text-decoration: none;
}
.dash-menu .dm-item:hover { background: rgba(36, 42, 48, .05); }
.dash-menu .dm-item .box {
  flex: 0 0 16px; width: 16px; height: 16px; border-radius: 4px;
  box-shadow: inset 0 0 0 1px var(--tlex-gray-lighter);
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-size: 10px;
}
.dash-menu .dm-item[aria-checked="true"] .box {
  background: var(--tlex-primary); box-shadow: inset 0 0 0 1px var(--tlex-primary);
}
.dash-menu .dm-item[aria-checked="true"] { font-weight: 600; }
.dash-menu .hide, .dash-menu .collapsed { display: none; }
/* 조직 트리 — 캐럿(▾)/불릿(·) + 계층 레벨 위첨자 배지(캡처 대조: 회사¹·개발실²) */
.dash-tree .tw-caret {
  flex: 0 0 16px; width: 16px; height: 16px; border: 0; background: none; padding: 0;
  color: var(--tlex-gray-light); font-size: 10px; line-height: 1;
}
.dash-tree .tw-dot { flex: 0 0 16px; text-align: center; color: var(--tlex-gray-lighter); }
.dash-tree .tw-lv { font-size: 10px; color: var(--tlex-gray-lighter); margin-left: 3px; }

.kpi-card {
  display: grid; grid-template-columns: repeat(3, 1fr);
  background: var(--tlex-thead-bg); border-radius: 10px;
  box-shadow: inset 0 0 0 1px rgba(36, 42, 48, .1);
  margin-bottom: 8px;
}
.kpi-item { padding: 20px 24px; min-height: 131px; }
.kpi-item + .kpi-item { border-left: 1px solid rgba(36, 42, 48, .06); }
.kpi-ico {
  width: 16px; height: 16px; border-radius: 50%; flex: 0 0 16px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-size: 9px; margin-right: 6px; vertical-align: -2px;
}
.kpi-ico.in { background: #fad052; }
.kpi-ico.out { background: #ee906f; }
.kpi-ico.work { background: #59cd65; }

.dash-section {
  display: flex; align-items: center; gap: 6px; padding-left: 4px;
  margin: 28px 0 12px; font-size: 14px; font-weight: 600; color: #3e4449;
}
.dash-section .bi { color: var(--tlex-gray-light); font-size: 16px; }
.dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; }
.dash-card { background: #fff; border-radius: 10px; box-shadow: var(--tlex-shadow-button); padding: 20px 24px; min-height: 124px; }
.dash-card .head, .kpi-item .head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
  font-size: 14px; font-weight: 600; color: #3e4449;
}
.dash-card .head .bi, .kpi-item .head > .bi { color: var(--tlex-gray-lighter); font-size: 14px; }
.dash-card .d, .kpi-item .d { font-size: 12px; font-weight: 500; color: var(--tlex-gray-light); margin-top: 2px; }
.dash-card .v-row, .kpi-item .v-row { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.dash-card .v, .kpi-item .v { font-size: 20px; font-weight: 600; color: var(--bs-body-color); }
.dash-card .v.zero, .dash-card .v.off, .kpi-item .v.off { color: var(--tlex-gray-lighter); }
.delta { display: inline-flex; align-items: center; gap: 2px; font-size: 14px; font-weight: 500; color: var(--bs-danger); }
.delta .bi { font-size: 14px; }
.delta.up { color: var(--tlex-primary); }   /* ↗ = 초록(#09bb1b) — flex 픽셀 실측(적대검증 #2) */
.delta.same { color: var(--tlex-gray-lighter); }

/* «근무 기록 관리» 헤더 메뉴 — 280px·항목 제목 14/설명 12 (라이브 실측) */
.record-menu { width: 280px; padding: 6px; }
.record-menu .dropdown-item {
  display: flex; flex-direction: column; gap: 1px;
  padding: 8px 10px; border-radius: 6px; white-space: normal;
}
.record-menu .dropdown-item b { font-size: 14px; font-weight: 500; }
.record-menu .dropdown-item span { font-size: 12px; font-weight: 500; color: rgba(36, 42, 48, .48); }
.record-menu .dropdown-item:disabled b, .record-menu .dropdown-item:disabled span { color: var(--tlex-disabled); }

/* 근태 마감 (ux17) — 빈 상태 아이콘 24px rgba(36,42,48,.4)·제목 14/600 .56·설명 13 .4
   ⭐ flex 는 «콘텐츠 패널 수직 중앙»(라이브 아이콘 y≈546/1080 — 적대검증 #5).
   고정 padding 대신 min-height 중앙 배치 — 240px ≈ 헤더 72 + 탭 44 + 본문 상하 pad 실측. */
.lock-empty {
  /* 가용 = 100vh − (헤더+탭 ≈131 + 본문 패딩 16/32) — 상속 패딩 56 은 중앙 계산을 흔들어 제거 */
  min-height: calc(100vh - 180px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 0 20px;
}
.lock-empty > .bi { font-size: 24px; color: rgba(36, 42, 48, .4); display: block; margin-bottom: 10px; }
.lock-empty .title { font-size: 14px; font-weight: 600; color: rgba(36, 42, 48, .56); }
.lock-empty .desc { font-size: 13px; color: rgba(36, 42, 48, .4); margin: 4px 0 16px; }
.lock-box {
  border-radius: 10px; box-shadow: inset 0 0 0 1px rgba(36, 42, 48, .1);
  padding: 16px 20px; display: flex; flex-direction: column; gap: 14px;
}
.lock-box .row-line { display: flex; align-items: center; gap: 16px; }
.lock-box label { flex: 0 0 64px; font-size: 14px; color: var(--tlex-gray); margin: 0; }
.lock-box .range { display: flex; align-items: center; gap: 8px; flex: 1; }
.lock-box .range .bi { color: var(--tlex-gray-light); }

/* 로그인 (셸 밖 단독 카드) */
.login-wrap { max-width: 360px; margin: 12vh auto 0; padding: 0 16px; }
.login-title { font-size: 22px; font-weight: 700; color: var(--tlex-primary); margin: 0; }

/* 첫 접속 온보딩 (FEAT034) — 로그인 카드와 같은 골격, 폼이 길어 조금 넓고 위로 올린다 */
.onboarding-wrap { max-width: 420px; margin-top: 8vh; }
.ob-steps {
  display: flex; gap: 8px; list-style: none; padding: 0; margin: 0 0 16px;
  font-size: 12px; font-weight: 600; color: var(--tlex-gray-light);
}
.ob-steps li { flex: 1; padding: 6px 8px; border-radius: 8px; background: var(--bs-tertiary-bg); text-align: center; }
.ob-steps li.now { background: var(--tlex-primary); color: #fff; }
.ob-steps li.done { color: var(--tlex-primary); }

/* ── 아바타 — flex 사용자별 파스텔 고정색(실측: 채세병 #c18fe3 · 이니셜 11/600 흰.88).
   FEAT009 people.css 에서 승격(FEAT012 — 구성원 근무·휴가 보유 현황도 쓴다). ── */
.ppl-avatar {
  width: 32px; height: 32px; border-radius: 10px; flex: 0 0 32px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; color: rgba(255, 255, 255, .88);
}
/* 슬롯 배치 = 이름 해시가 실측색에 앉도록(채세병→c3 보라 · 하유진→c2 초록) */
.ppl-avatar.c0 { background: #efa66f; }
.ppl-avatar.c1 { background: #7ba8ef; }
.ppl-avatar.c2 { background: #59cd65; }  /* 실측 초록(하유진) 계열 = primary light */
.ppl-avatar.c3 { background: #c18fe3; }  /* 실측 보라(채세병) */
.ppl-avatar.c4 { background: #64c9c4; }
.ppl-avatar.c5 { background: #ef8fb0; }

/* ── 목록의 «인물 셀» — 아바타 + 이름 층(FEAT012 timeoff_manage.css 에서 승격: FEAT052 로
   휴가 사용 내역·보상 휴가 부여도 같은 셀을 쓴다. 아바타 기본형 승격과 같은 이유) ──
   flex 형상 = 아바타(사진 또는 이니셜 2글자) + 이름 + 직무 = 2층(스냅 b09·b10).
   `i.sub` = 그 «직무» 줄(가장 옅다) · 중간 `i` = 표시명≠본명일 때만 끼는 본명 줄이다. */
.tos-person { display: flex; align-items: center; gap: 12px; }
.tos-id { display: flex; flex-direction: column; min-width: 0; }
.tos-id b, .tos-id i { overflow: hidden; text-overflow: ellipsis; }   /* 220px 초과 이름 방어 */
.tos-id b { font-size: 15px; font-weight: 600; color: var(--bs-body-color); }   /* 실측 15/600 */
.tos-id i { font-style: normal; font-size: 13px; font-weight: 400; color: var(--tlex-gray); }
.tos-id i.sub { font-size: 12px; color: var(--tlex-gray-light); }

/* ── 필터 칩 (구성원 근무·휴가 관리 툴바 — 라이브 실측 2026-08-12:
   활성 = h24·r6·bg #f5fbff·ring #70afdb·글자 12/600 #3b86c8, × 분절 버튼 ·
   «필터 추가» = bg rgba(97,102,106,.07)·r5·12/700 #3e4449) ── */
.filter-chip {
  display: inline-flex; align-items: stretch; height: 24px; border-radius: 6px;
  background: #f5fbff; box-shadow: inset 0 0 0 1px #70afdb;
}
.filter-chip > button {
  display: inline-flex; align-items: center; gap: 4px; border: 0; background: none;
  font-size: 12px; font-weight: 600; color: #3b86c8; padding: 0 4px 0 8px;
}
.filter-chip > button.x { padding: 0 6px; font-size: 11px; }
.filter-chip > button:disabled { color: #8fb6d4; }
.filter-chip .bi { font-size: 12px; }
.filter-add {
  display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px;
  border: 0; border-radius: 5px; background: rgba(97, 102, 106, .07);
  font-size: 12px; font-weight: 700; color: #3e4449;
}
.filter-add:disabled { color: var(--tlex-disabled); }

/* 화면 내 tablist 우측 아이콘 영역(휴가 관리 — 검색·내보내기 실측 배치) */
.tlex-tabs .tabs-right { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; }
.tlex-tabs .tabs-right a, .tlex-tabs .tabs-right button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 0; background: none; border-radius: 6px;
  color: var(--tlex-gray); font-size: 15px; padding: 0;
}
.tlex-tabs .tabs-right a:hover { background: rgba(36, 42, 48, .05); }
.tlex-tabs .tabs-right button:disabled { color: var(--tlex-gray-lighter); }

/* ── GNB 검색 (Ctrl K 커맨드 팔레트 — FEAT026 · flex 동형) ─────────────── */
.gnb-search-backdrop {
  position: fixed; inset: 0; z-index: 1060;
  background: rgba(36, 42, 48, .35);
  display: flex; justify-content: center; align-items: flex-start;
}
.gnb-search {
  margin-top: 12vh; width: 560px; max-width: calc(100vw - 32px);
  background: #fff; border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .18);
  overflow: hidden;
}
.gs-inputwrap {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--tlex-line);
}
.gs-inputwrap .bi-search { color: var(--tlex-gray-light); }
.gs-inputwrap input {
  flex: 1; border: 0; outline: 0; font-size: 15px; font-weight: 500;
  background: transparent;
}
.gs-back {
  border: 0; background: none; padding: 2px 4px; border-radius: 6px;
  color: var(--tlex-gray); font-size: 15px;
}
.gs-back:hover { background: rgba(36, 42, 48, .05); }
.gs-section {
  padding: 10px 16px 4px; font-size: 12px; font-weight: 600;
  color: var(--tlex-gray-light);
}
.gs-list {
  list-style: none; margin: 0; padding: 6px 8px 10px;
  max-height: 320px; overflow-y: auto;
}
.gs-list [role="option"] {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--tlex-radius); cursor: pointer;
  font-size: 14px; font-weight: 500;
}
.gs-list [role="option"] .bi { color: var(--tlex-gray-light); }
.gs-list [role="option"]:hover { background: rgba(36, 42, 48, .04); }
.gs-list [role="option"].active { background: rgba(36, 42, 48, .06); }
.gs-p-main { display: flex; flex-direction: column; min-width: 0; }
.gs-p-main b { font-size: 14px; font-weight: 600; }
.gs-p-meta {
  font-size: 12px; color: var(--tlex-gray);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── 벨 패널 (FEAT026 — flex 우측 알림 패널 동형) ──────────────────────── */
.notif-badge { color: var(--tlex-primary-dark); font-weight: 700; margin-left: 2px; }
.np-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 1055;
  width: 400px; max-width: calc(100vw - 24px);
  background: #fff; border-left: 1px solid var(--tlex-line);
  box-shadow: -8px 0 24px rgba(0, 0, 0, .08);
  display: flex; flex-direction: column;
}
.np-head {
  display: flex; align-items: center; gap: 8px;
  padding: 14px 16px; border-bottom: 1px solid var(--tlex-line);
}
.np-head b { font-size: 16px; margin-right: auto; }
.np-readall {
  border: 0; background: none; border-radius: 6px; padding: 4px 8px;
  font-size: 13px; font-weight: 600; color: var(--tlex-primary-dark);
}
.np-readall:hover { background: var(--tlex-primary-lightest); }
.np-close {
  border: 0; background: none; border-radius: 6px; padding: 4px 8px;
  color: var(--tlex-gray); font-size: 14px;
}
.np-close:hover { background: rgba(36, 42, 48, .05); }
.np-body { overflow-y: auto; flex: 1; }
.np-list { list-style: none; margin: 0; padding: 6px 8px; }
.np-topic { border-radius: var(--tlex-radius); }
.np-row {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  border: 0; background: none; text-align: left;
  padding: 10px; border-radius: var(--tlex-radius); cursor: pointer;
}
.np-row:hover { background: rgba(36, 42, 48, .04); }
.np-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.np-title { font-size: 13px; font-weight: 600; }
.np-topic.unread .np-title { font-weight: 700; }
.np-text { font-size: 13px; color: var(--tlex-gray); }
.np-ago { font-size: 12px; color: var(--tlex-gray-light); }
.np-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--tlex-primary); margin: 6px 2px 0 auto;
}
.np-more {
  border: 0; background: none; border-radius: 6px;
  margin: 0 10px 6px 52px; padding: 3px 8px;
  font-size: 12px; font-weight: 600; color: var(--tlex-gray);
}
.np-more:hover { background: rgba(36, 42, 48, .05); }
.np-rest { list-style: none; margin: 0 10px 8px 52px; padding: 0; }
.np-rest-row { font-size: 13px; color: var(--tlex-gray); padding: 3px 0; }
.np-empty { padding: 40px 16px; text-align: center; font-size: 14px; }

/* ── 다크 툴팁 프리미티브 (FEAT055) ─────────────────────────────────────
   ⭐토큰 = flex Tooltip.Content 실측(미러 CSS 원문): 배경 #3e4449(grayDark — 본문색
     #242a30 «아니다») · 12px/500/1.5 흰 글씨 · radius 8 · padding 8/10 · 3중 그림자 ·
     지연 225ms(Radix Provider delayDuration) · 화살표 없음.
   ⭐2형태가 «같은 토큰»을 공유한다: 이 `[data-tip]` 단문형(::after — attr 이라 표는 못 그린다)과
     화면이 자기 마크업으로 만드는 «요소형»(예: mywork.css `.mw-tip` 의 <dl> 2열).
   ⚠️`mywork.css` 의 `.core-mark::after`(#242a30·지연 없음)는 아직 이 프리미티브로 옮기지
     않았다 — 그 화면 요소를 건드리지 않기 위해서다(이관은 별건). */
:root {
  --tlex-tip-bg: #3e4449;
  --tlex-tip-shadow:
    0 6px 24px rgba(0, 0, 0, .16),
    inset 0 -1px 0 rgba(0, 0, 0, .06),
    inset 0 0 0 1px rgba(0, 0, 0, .12);
  --tlex-tip-delay: .225s;
}
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 4px); left: 50%;
  transform: translateX(-50%) scale(.95); transform-origin: 50% 100%;
  z-index: 10000; width: max-content; max-width: 230px;
  padding: 8px 10px; border-radius: 8px;
  background: var(--tlex-tip-bg); box-shadow: var(--tlex-tip-shadow);
  color: #fff; font-size: 12px; font-weight: 500; line-height: 1.5;
  font-style: normal; text-align: left; white-space: normal;
  /* ⭐마우스를 툴팁 위로 옮겨도 «유지되지 않는다» = flex 의 disableHoverableContent:true.
     pointer-events 를 끄면 트리거 hover 가 끊기는 즉시 닫힌다(그 동작의 CSS 등가다). */
  pointer-events: none;
  visibility: hidden; opacity: 0;
  transition: opacity .1s, transform .1s, visibility .1s;
}
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  visibility: visible; opacity: 1; transform: translateX(-50%) scale(1);
  /* 여는 곡선 = flex 150ms 스프링. 닫기에는 지연을 두지 않는다(위 규칙이 즉시 되돌린다) */
  transition: opacity .15s cubic-bezier(.48, 1.93, 1, .68),
              transform .15s cubic-bezier(.48, 1.93, 1, .68), visibility .15s;
  transition-delay: var(--tlex-tip-delay);
}

/* ── 모바일 (반응형 필수 — 출퇴근 체크인은 모바일) ─────────────────────── */
.tlex-topbar { display: none; }
@media (max-width: 991.98px) {
  .tlex-shell { display: block; }
  .tlex-topbar {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px; background: var(--bs-tertiary-bg);
    border-bottom: 1px solid var(--tlex-line);
    position: sticky; top: 0; z-index: 1030;
  }
  /* ⛔ 여기서 .tlex-gnb 의 position/width 를 만지지 말 것 — 모바일은 Bootstrap
     offcanvas(fixed·슬라이드)가 배치의 주인이다. */
  .page-header, .page-body { padding-left: 16px; padding-right: 16px; }
  /* 탭 4개+아이콘(휴가 관리)이 375px 에서 다중 행으로 꺾이지 않게 — 가로 스크롤(프로필 탭 선례) */
  .tlex-tabs { padding: 0 16px; overflow-x: auto; white-space: nowrap; }
}
