/*
 * My Page 화면 공용 스타일. 규칙과 이탈 기록의 SSOT는 docs/conventions/ui.md 다.
 *
 * 토큰은 2계층이다: Layer 1 `--p-*`(팔레트 원본, 색 리터럴은 이 블록에서만) →
 * Layer 2 시맨틱(컴포넌트가 참조하는 유일한 레이어). 컴포넌트에서 `--p-*`를 직접 쓰면
 * "팔레트 외 색 생성 금지"·"리터럴은 :root만" 두 규칙이 검증 불가능해진다.
 *
 * 값의 출처는 Portlogics 디자인 시스템(DESIGN.md, 이 저장소 밖)과 그 유일한 충실 구현인
 * portlogics-id/apps/web 이다. `docs/overview.html`은 사내 소개 자료이고 제품 UI 토큰의 출처가 아니다.
 *
 * 폰트를 CDN에서 받지 않는 이유: 제품 페이지에 외부 CDN을 물리면 런타임 외부 의존이 생기고
 * CSP를 넓혀야 한다. 선언만 두고 설치된 경우에만 적용시킨다.
 * 다크모드는 지원하지 않는다 — 그래서 `color-scheme: light`를 명시한다. 없으면 OS 다크모드에서
 * 브라우저가 폼 컨트롤·스크롤바를 자체 반전시켜 화면이 반쯤 깨진다.
 */

/* ------------------------------------------------------------------ */
/* Layer 1 — primitive palette (컴포넌트에서 직접 사용 금지)          */
/* ------------------------------------------------------------------ */
:root {
  /* primary (trust blue H=260.5) */
  --p-primary-50: oklch(0.97 0.02 260.5);
  --p-primary-100: oklch(0.93 0.045 260.5);
  --p-primary-400: oklch(0.68 0.185 260.5);
  --p-primary-500: oklch(0.604 0.215 260.5);
  --p-primary-600: oklch(0.52 0.205 260.5);
  --p-primary-700: oklch(0.42 0.175 260.5);
  --p-primary-800: oklch(0.32 0.13 260.5);

  /* accent (teal H=195) — 비브랜드적 보조 정보 전용 */
  --p-accent-500: oklch(0.62 0.1 195);

  /* neutral (cool-tinted, 브랜드와 같은 H) */
  --p-neutral-50: oklch(0.98 0.005 260.5);
  --p-neutral-100: oklch(0.94 0.01 260.5);
  --p-neutral-200: oklch(0.88 0.012 260.5);
  --p-neutral-300: oklch(0.8 0.015 260.5);
  --p-neutral-400: oklch(0.68 0.015 260.5); /* 텍스트 금지 — 2.88:1 */
  --p-neutral-500: oklch(0.56 0.015 260.5); /* 텍스트 최소선 — 4.65:1 */
  --p-neutral-700: oklch(0.34 0.01 260.5);
  --p-neutral-800: oklch(0.24 0.008 260.5);
  --p-neutral-900: oklch(0.16 0.006 260.5);

  /* semantic — bg/border/text 3쌍은 대비가 검증된 조합이다 */
  --p-success: oklch(0.55 0.15 145);
  --p-success-bg: oklch(0.96 0.03 145);
  --p-success-border: oklch(0.65 0.13 145);
  --p-success-text: oklch(0.3 0.12 145);
  --p-warning: oklch(0.68 0.16 78);
  --p-warning-bg: oklch(0.96 0.04 78);
  --p-warning-border: oklch(0.78 0.14 78);
  --p-warning-text: oklch(0.38 0.13 78);
  --p-danger: oklch(0.55 0.21 25);
  --p-danger-bg: oklch(0.96 0.04 25);
  --p-danger-border: oklch(0.7 0.18 25);
  --p-danger-text: oklch(0.38 0.17 25);
  --p-danger-hover: oklch(0.48 0.21 25);
  --p-danger-active: oklch(0.42 0.21 25);
}

/* ------------------------------------------------------------------ */
/* Layer 2 — semantic tokens (컴포넌트가 참조하는 유일한 레이어)      */
/* ------------------------------------------------------------------ */
:root {
  color-scheme: light;

  /* surfaces */
  --surface-app: var(--p-neutral-50);
  --surface-card: #ffffff;
  --surface-subtle: var(--p-neutral-100);
  --surface-hover: var(--p-neutral-100);

  /* borders */
  --border-default: var(--p-neutral-200);
  --border-strong: var(--p-neutral-300);

  /* text */
  --text-primary: var(--p-neutral-900);
  --text-body: var(--p-neutral-800);
  --text-secondary: var(--p-neutral-500);
  --text-placeholder: var(--p-neutral-400);
  --text-error: var(--p-danger);

  /* brand */
  --brand: var(--p-primary-500);
  --brand-hover: var(--p-primary-600); /* Primary 버튼 배경 — 500은 white 대비 3.75:1로 미달 */
  --brand-active: var(--p-primary-700);
  --brand-press: var(--p-primary-800);
  --brand-50: var(--p-primary-50);
  --brand-100: var(--p-primary-100);
  --brand-focus-ring: oklch(0.604 0.215 260.5 / 0.15);
  --brand-glow:
    radial-gradient(ellipse 60% 40% at 50% -10%, oklch(0.93 0.045 260.5 / 0.5), transparent 70%),
    radial-gradient(ellipse 40% 30% at 80% 90%, oklch(0.93 0.02 260.5 / 0.3), transparent 70%);

  /* danger (액션) */
  --danger-solid: var(--p-danger);
  --danger-solid-hover: var(--p-danger-hover);
  --danger-solid-active: var(--p-danger-active);

  /* 빈 상태 일러스트 — 장식이므로 텍스트 대비 기준 밖 */
  --illustration: var(--p-neutral-300);

  /* callout tones */
  --callout-info-bg: var(--brand-50);
  --callout-info-border: var(--p-primary-400);
  --callout-info-text: var(--p-primary-800);
  --callout-success-bg: var(--p-success-bg);
  --callout-success-border: var(--p-success-border);
  --callout-success-text: var(--p-success-text);
  --callout-warning-bg: var(--p-warning-bg);
  --callout-warning-border: var(--p-warning-border);
  --callout-warning-text: var(--p-warning-text);
  --callout-danger-bg: var(--p-danger-bg);
  --callout-danger-border: var(--p-danger-border);
  --callout-danger-text: var(--p-danger-text);

  /* badge tones */
  --badge-success-bg: var(--p-success-bg);
  --badge-success-text: var(--p-success-text);
  --badge-warning-bg: var(--p-warning-bg);
  --badge-warning-text: var(--p-warning-text);
  --badge-danger-bg: var(--p-danger-bg);
  --badge-danger-text: var(--p-danger-text);
  --badge-brand-bg: var(--brand-100);
  --badge-brand-text: var(--brand-hover);
  --badge-neutral-bg: var(--p-neutral-100);
  --badge-neutral-text: var(--p-neutral-500);

  /* elevation — hairline ring + 근거리 + 원거리 3레이어 */
  --shadow-1:
    0 0 0 1px oklch(0.2 0.01 260.5 / 0.03), 0 1px 2px oklch(0.2 0.01 260.5 / 0.04),
    0 4px 12px oklch(0.2 0.01 260.5 / 0.04);
  --shadow-2:
    0 0 0 1px oklch(0.2 0.01 260.5 / 0.03), 0 2px 4px oklch(0.2 0.02 260.5 / 0.03),
    0 12px 32px -8px oklch(0.2 0.02 260.5 / 0.08);

  /* motion */
  --duration-fast: 100ms;
  --duration-normal: 200ms;
  --ease-default: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-enter: cubic-bezier(0, 0, 0.2, 1);

  /* shape */
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;

  --z-sticky: 10;

  --font-sans:
    'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI',
    'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

/* ------------------------------------------------------------------ */
/* Base                                                               */
/* ------------------------------------------------------------------ */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-sans);
  font-feature-settings: 'ss01', 'ss02';
  font-size: 1rem;
  line-height: 1.6;
  /* 한글은 단어 단위로 끊는다 — break-all 은 음절 중간을 자른다 */
  word-break: keep-all;
  overflow-wrap: break-word;
  background: var(--surface-app);
  color: var(--text-body);
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  color: var(--text-primary);
}

a {
  color: inherit;
}

ul {
  list-style: none;
}

/* 포커스 링은 키보드에서만 보인다. outline:none 단독이나 box-shadow만으로 표시하면
   고대비 모드에서 사라진다 */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 2px;
}

[hidden] {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0ms !important;
  }
}

/* ------------------------------------------------------------------ */
/* App shell — 로그인 이후 화면 2장                                    */
/* ------------------------------------------------------------------ */
.app-bar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  border-bottom: 1px solid var(--border-default);
  background: color-mix(in oklab, var(--surface-card) 80%, transparent);
  backdrop-filter: blur(12px);
}

.app-bar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 1120px;
  margin-inline: auto;
  padding: 0.75rem 1.5rem;
}

.app-bar-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
}

.app-bar-brand svg {
  flex-shrink: 0;
  color: var(--brand);
}

.app-bar-brand [data-sub] {
  font-weight: 400;
  color: var(--text-secondary);
}

.app-bar-nav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  font-size: 0.875rem;
}

.app-bar-nav a {
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-default);
}

.app-bar-nav a:hover {
  color: var(--text-primary);
}

.page {
  max-width: 42rem;
  margin-inline: auto;
  padding: 3rem 1.5rem;
}

/*
 * 표가 있는 화면(운영 관리). 42rem은 **읽기 컬럼** 폭이라 열 7개짜리 표가 들어가지 않는다.
 * 상단 바(`.app-bar-inner` 1120px)와 같은 폭으로 맞춰 둘이 어긋나 보이지 않게 한다.
 */
.page--wide {
  max-width: 70rem;
}

@media (min-width: 1024px) {
  .page {
    padding-block: 4rem;
  }
}

.page-header {
  margin-bottom: 2.5rem;
}

.eyebrow {
  margin-bottom: 0.75rem;
  font-size: 0.75rem;
  line-height: 1.4;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--brand);
}

.page-header h1 {
  font-size: 1.875rem;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.page-header p {
  margin-top: 0.75rem;
  color: var(--text-secondary);
}

.page-foot {
  margin-top: 2rem;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ */
/* Auth shell — 로그인 랜딩                                            */
/* ------------------------------------------------------------------ */
.auth-shell {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 3rem 1.5rem;
}

.auth-glow {
  pointer-events: none;
  position: fixed;
  inset: 0;
  background: var(--brand-glow);
}

.auth-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  width: 100%;
  max-width: 26rem;
  border-radius: var(--radius-xl);
  background: var(--surface-card);
  padding: 2rem;
  box-shadow: var(--shadow-2);
}

.auth-card > * {
  width: 100%;
}

.brand-lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.brand-lockup svg {
  color: var(--brand);
}

.brand-lockup h1 {
  font-size: 1.25rem;
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.auth-copy {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--text-secondary);
  text-align: center;
}

.auth-footer {
  margin-top: 0.75rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--text-secondary);
  text-align: center;
}

/* ------------------------------------------------------------------ */
/* Card / panel                                                       */
/* ------------------------------------------------------------------ */
.card {
  margin-bottom: 1.5rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  background: var(--surface-card);
  padding: 1.5rem;
  box-shadow: var(--shadow-1);
}

.card:last-child {
  margin-bottom: 0;
}

.card-header {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-bottom: 1.25rem;
}

.card-header h2 {
  font-size: 1.125rem;
  line-height: 1.5;
  font-weight: 600;
}

.card-header p {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

.card-header--split {
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}

.card-header--split > div {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

/* ------------------------------------------------------------------ */
/* Key-value list                                                     */
/* ------------------------------------------------------------------ */
.kv-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 0;
  border-top: 1px solid var(--border-default);
}

.kv-row:first-child {
  border-top: 0;
  padding-top: 0;
}

.kv-row:last-child {
  padding-bottom: 0;
}

.kv-row dt {
  font-size: 0.875rem;
  color: var(--text-secondary);
  white-space: nowrap;
}

.kv-row dd {
  font-size: 0.875rem;
  color: var(--text-primary);
  text-align: right;
  /* 값 쪽만 임의 지점 줄바꿈을 허용한다 — 긴 식별자(IdP subject·scope URL) 때문 */
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------ */
/* List — 권한 목록 등                                                 */
/* ------------------------------------------------------------------ */
.list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.list-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--surface-subtle) 40%, transparent);
  padding: 0.75rem 1rem;
}

.list-item svg {
  flex-shrink: 0;
  margin-top: 0.2rem;
  color: var(--text-secondary);
}

.list-item strong {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary);
}

.list-item span {
  display: block;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ */
/* Mail — 목록 행과 본문                                               */
/* ------------------------------------------------------------------ */
/* 제목·발신자(좌)와 배지·시각(우) 두 덩이. 좁은 폭에서는 아래로 접힌다 */
.msg-row {
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.msg-main {
  min-width: 0; /* 없으면 긴 제목이 flex 컨테이너를 밀어낸다 */
}

.msg-main > a,
.msg-main > strong {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.msg-meta {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 0.5rem;
}

@media (max-width: 40rem) {
  .msg-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
}

/* 메일 본문은 원문 개행을 그대로 살린다. 긴 URL 한 줄이 카드를 밀지 않게 anywhere로 끊는다 */
.mail-body {
  margin: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  padding: 1rem;
  max-height: 40rem;
  overflow: auto;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--text-body);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------ */
/* Buttons                                                            */
/* ------------------------------------------------------------------ */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 0;
  border-radius: var(--radius-md);
  padding: 0.5rem 1rem;
  font-family: inherit;
  font-size: 0.875rem;
  line-height: 1.5;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--duration-fast) var(--ease-default),
    border-color var(--duration-fast) var(--ease-default),
    transform var(--duration-fast) var(--ease-default);
}

/* 시각 높이는 36px로 두고 히트영역만 44px로 넓힌다 (WCAG 2.2 SC 2.5.8) */
.btn::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  translate: 0 -50%;
  min-height: 44px;
}

.btn svg {
  flex-shrink: 0;
}

.btn-block {
  width: 100%;
}

.btn-sm {
  padding: 0.375rem 0.75rem;
  font-size: 0.75rem;
}

.btn-primary {
  background: var(--brand-hover);
  color: #ffffff;
}

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

.btn-primary:active {
  background: var(--brand-press);
  transform: scale(0.98);
}

.btn-secondary {
  border: 1.5px solid var(--border-default);
  background: var(--surface-card);
  color: var(--text-body);
}

.btn-secondary:hover {
  background: var(--surface-subtle);
}

.btn-secondary:active {
  background: var(--p-neutral-200);
}

.btn-ghost {
  background: transparent;
  color: var(--text-body);
}

.btn-ghost:hover {
  background: var(--surface-hover);
}

.btn-danger {
  background: var(--danger-solid);
  color: #ffffff;
}

.btn-danger:hover {
  background: var(--danger-solid-hover);
}

.btn-danger:active {
  background: var(--danger-solid-active);
  transform: scale(0.98);
}

/* 진한 배경 위에서는 브랜드 색 링이 안 보인다 — 흰 링 + 외곽 링으로 대비를 만든다 */
.btn-primary:focus-visible,
.btn-danger:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--brand-active);
}

.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

/* 버튼 하나짜리 폼이 flex 레이아웃에 끼어들지 않게 한다 */
.actions form {
  display: contents;
}

/* ------------------------------------------------------------------ */
/* Inline text primitives                                             */
/* ------------------------------------------------------------------ */
.link {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--duration-fast) var(--ease-default);
}

.link:hover {
  color: var(--brand-hover);
}

.code-inline {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  padding: 0.05rem 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.85em;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* 수치·타임스탬프. font-feature-settings 는 상속을 덮어쓰므로 ss01·ss02 를 같이 적는다 */
.num {
  font-feature-settings: 'ss01', 'ss02', 'tnum';
  font-variant-numeric: tabular-nums;
}

.hint {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ */
/* Callout — 인라인 알림                                               */
/* ------------------------------------------------------------------ */
/* 좌측 색 띠(border-left) 방식은 쓰지 않는다: 한쪽 귀퉁이만 각져서 radius와 충돌하고
   반쯤 만든 컴포넌트처럼 보인다. 전체 1.5px 테두리 + 아이콘이 의미를 전달한다. */
.callout {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: 1rem 1.125rem;
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* 로그인 카드는 flex gap이 간격을 담당한다 — margin이 겹치면 2배로 벌어진다 */
.auth-card > .callout {
  margin-bottom: 0;
}

/* 값 목록·보조 설명 바로 뒤에 붙는 알림은 위 간격이 필요하다 */
.kv + .callout,
.hint + .callout {
  margin-top: 1.25rem;
}

.callout > svg {
  flex-shrink: 0;
  margin-top: 0.15rem;
}

.callout strong {
  display: block;
  margin-bottom: 0.15rem;
  color: inherit;
}

.callout[data-tone='info'] {
  background: var(--callout-info-bg);
  border-color: var(--callout-info-border);
  color: var(--callout-info-text);
}

.callout[data-tone='success'] {
  background: var(--callout-success-bg);
  border-color: var(--callout-success-border);
  color: var(--callout-success-text);
}

.callout[data-tone='warning'] {
  background: var(--callout-warning-bg);
  border-color: var(--callout-warning-border);
  color: var(--callout-warning-text);
}

.callout[data-tone='danger'] {
  background: var(--callout-danger-bg);
  border-color: var(--callout-danger-border);
  color: var(--callout-danger-text);
}

/* 톤별 아이콘은 넷 다 마크업에 두고 CSS가 고른다 — innerHTML 없이 아이콘을 바꾸는 유일한 방법 */
.callout [data-tone-icon] {
  display: none;
}

.callout[data-tone='info'] [data-tone-icon='info'],
.callout[data-tone='success'] [data-tone-icon='success'],
.callout[data-tone='warning'] [data-tone-icon='warning'],
.callout[data-tone='danger'] [data-tone-icon='danger'] {
  display: block;
}

/* ------------------------------------------------------------------ */
/* Badge — 상태 표시                                                   */
/* ------------------------------------------------------------------ */
/* 상태는 텍스트가 전달하고 색은 보조다(색약 접근성). 톤 매핑은 JS가 아니라 여기가 소유한다 —
   app.js 는 dataset.status / dataset.syncable 만 설정한다. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: 9999px;
  padding: 0.125rem 0.625rem;
  font-size: 0.75rem;
  line-height: 1.4;
  font-weight: 500;
  white-space: nowrap;
  background: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
}

.badge[data-status='ACTIVE'],
.badge[data-syncable='true'],
.badge[data-tone='success'] {
  background: var(--badge-success-bg);
  color: var(--badge-success-text);
}

.badge[data-status='NEEDS_REAUTH'],
.badge[data-tone='warning'] {
  background: var(--badge-warning-bg);
  color: var(--badge-warning-text);
}

.badge[data-status='DEPROVISIONED'],
.badge[data-status='DISABLED'],
.badge[data-tone='danger'] {
  background: var(--badge-danger-bg);
  color: var(--badge-danger-text);
}

.badge[data-status='PAUSED'],
.badge[data-syncable='false'],
.badge[data-tone='neutral'] {
  background: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
}

/* ------------------------------------------------------------------ */
/* Empty state                                                        */
/* ------------------------------------------------------------------ */
/* 아이콘·제목·설명·액션 4요소가 기본이다. 텍스트만 두지 않는다(시각적 힌트 필수). */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  max-width: 480px;
  margin-inline: auto;
  padding: 2rem 0;
  text-align: center;
}

.empty-icon {
  color: var(--illustration);
}

.empty-title {
  font-size: 1.125rem;
  line-height: 1.5;
  font-weight: 600;
  color: var(--text-body);
}

.empty-desc {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ */
/* Loading                                                            */
/* ------------------------------------------------------------------ */
.loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem 0;
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.spinner {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
  border: 2px solid var(--border-default);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: spin 750ms linear infinite;
}

@keyframes spin {
  to {
    rotate: 360deg;
  }
}

/* ------------------------------------------------------------------ */
/* Details — 지원 문의용 기술 정보                                     */
/* ------------------------------------------------------------------ */
details {
  margin-top: 1.25rem;
  border-top: 1px solid var(--border-default);
  padding-top: 1rem;
}

summary {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
}

summary:hover {
  color: var(--text-primary);
}

details > .kv {
  margin-top: 0.75rem;
}

/* ------------------------------------------------------------------ */
/* Tabs — 관리 화면의 섹션 전환                                        */
/* ------------------------------------------------------------------ */
/*
 * 탭은 <a href="/admin?tab=…">다. 탐색이므로 <button>이 아니고, 새로고침·뒤로가기가
 * 그대로 동작한다(상태를 JS 변수에 두면 둘 다 깨진다).
 */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--border-default);
}

.tab {
  padding: 0.5rem 0.75rem;
  border-bottom: 2px solid transparent;
  font-size: 0.875rem;
  line-height: 1.5;
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-default);
}

.tab:hover {
  color: var(--text-primary);
}

.tab[aria-current='page'] {
  border-bottom-color: var(--brand);
  color: var(--text-primary);
}

/* ------------------------------------------------------------------ */
/* Table — 운영 데이터의 가로 비교                                     */
/* ------------------------------------------------------------------ */
/*
 * 사용자 화면에는 표가 없다(카드·kv로 충분하다). 관리 화면은 반대다 — 메일함 하나가
 * 8개 값을 갖고, "어느 메일함이 0건인가"는 세로로 늘어놓으면 눈으로 못 짚는다.
 * 좁은 폭에서는 줄이지 않고 **가로 스크롤**한다: 열을 접으면 비교 대상이 사라진다.
 */
.table-scroll {
  overflow-x: auto;
}

/*
 * `width: max-content` + `min-width: 100%`인 이유: `width: 100%`만 주면 좁은 폭에서 표가
 * 줄어들지 않는 열(nowrap) 대신 **줄바꿈 가능한 열 하나를 세로로 찌그러뜨린다** —
 * 이름이 한 글자씩 쌓이고 조치 버튼이 잘린다. max-content는 열 폭을 지키고 넘치는 만큼
 * `.table-scroll`이 가로로 스크롤한다. 비교 가능한 표가 이 화면의 존재 이유다.
 */
.table {
  width: max-content;
  min-width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  line-height: 1.5;
}

.table th,
.table td {
  padding: 0.75rem;
  border-bottom: 1px solid var(--border-default);
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
}

.table th {
  font-size: 0.75rem;
  line-height: 1.4;
  font-weight: 600;
  color: var(--text-secondary);
}

.table td {
  color: var(--text-body);
}

.table tbody tr:last-child td {
  border-bottom: 0;
}

.table tbody tr:hover {
  background: var(--surface-hover);
}

/* 이메일·이름처럼 긴 값만 줄바꿈을 허용한다 — 나머지는 열 정렬이 흐트러진다 */
.table td[data-wrap] {
  min-width: 12rem;
  max-width: 22rem;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* 조치 버튼이 줄바꿈하면 행 높이가 들쭉날쭉해져 표를 세로로 훑을 수 없다 */
.table td .actions {
  flex-wrap: nowrap;
  margin-top: 0;
  gap: 0.375rem;
}

/* ------------------------------------------------------------------ */
/* Pager — 오프셋 페이지네이션 (관리자 메일 검색 전용)                  */
/* ------------------------------------------------------------------ */
/*
 * 총 건수와 페이지 점프가 필요한 표에만 쓴다. 커서 목록의 "더 보기"(`#user-more`)와 **다른
 * 컴포넌트**다 — 그쪽은 총 건수를 세지 않는 것이 계약이고 여기는 그 숫자가 화면의 값이다.
 *
 * 항목이 `<a href>`인 것이 요점이다: 탐색이므로 `<button>`이 아니고(ui.md §11), 페이지·조건이
 * URL에 남아 새로고침·뒤로가기·공유가 그대로 동작한다(탭 링크와 같은 판단).
 * 창이 항상 1과 마지막 페이지를 포함하므로 "처음·끝" 버튼은 두지 않는다.
 *
 * 새 색·새 토큰이 0이다 — Layer 2만 참조한다. 헌법·픽셀 기준(`portlogics-id`)에 오프셋 페이저
 * 스펙이 없어 파생했고 그 이탈은 ui.md §10에 기록돼 있다.
 */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.pager-summary {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

.pager-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
}

.pager-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  list-style: none;
}

.pager-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  font-size: 0.875rem;
  line-height: 1.5;
  font-weight: 500;
  font-feature-settings: 'ss01', 'ss02', 'tnum';
  font-variant-numeric: tabular-nums;
  color: var(--text-body);
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease-default);
}

/* 시각 높이는 36px로 두고 히트영역만 44px로 넓힌다 (`.btn`과 같은 방식 — WCAG 2.2 SC 2.5.8) */
.pager-link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  translate: 0 -50%;
  min-height: 44px;
}

/* 호버는 실제 링크에만 — 현재 페이지는 `<span>`이라 눌릴 것이 없다 */
a.pager-link:hover {
  background: var(--surface-hover);
}

/* 현재 페이지는 목적지가 아니라 위치다. `<a>`로 두면 눌러서 같은 페이지를 다시 받는다 */
.pager-link[aria-current='page'] {
  border-color: var(--brand);
  background: var(--brand-50);
  color: var(--text-primary);
}

/*
 * 첫·끝 페이지의 이전·다음. `hidden`으로 지우면 옆 번호가 그 자리로 밀려와 오조작이 된다 —
 * 자리를 지키고 비활성만 표시한다(`.btn[aria-disabled='true']`와 같은 규약).
 */
.pager-link[aria-disabled='true'] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* 컨트롤이 아니라 "여기 페이지가 더 있다"는 표시다 */
.pager-gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ */
/* Form controls — 관리 화면의 입력                                    */
/* ------------------------------------------------------------------ */
.form-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 12rem;
  flex: 1 1 12rem;
}

.field label {
  font-size: 0.75rem;
  line-height: 1.4;
  font-weight: 500;
  color: var(--text-secondary);
}

.input,
.select {
  min-height: 2.25rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  font: inherit;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-body);
}

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

.input:focus-visible,
.select:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 0;
  box-shadow: 0 0 0 4px var(--brand-focus-ring);
}

.input:disabled,
.select:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* ------------------------------------------------------------------ */
/* Admin badge tones — 관리 화면에만 있는 상태                         */
/* ------------------------------------------------------------------ */
/* 정지는 되돌릴 수 있는 상태(warning), 해제는 이력으로 남은 과거(neutral)다. */
.badge[data-status='SUSPENDED'] {
  background: var(--badge-warning-bg);
  color: var(--badge-warning-text);
}

.badge[data-status='REVOKED'] {
  background: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
}
