/*
 * Study2Play 공통 컴포넌트 (W4-G1). fonts.css·tokens.css 다음에 읽는다.
 * - 색·크기는 tokens.css 변수만 쓴다(색 코드 직접 사용 금지).
 * - 모든 클래스는 s2p- 접두어. 앱 인라인 스타일과 겹치지 않게 전역 요소 규칙은 리셋 몇 줄로 제한한다.
 * - 기준: docs/36 §1.1~1.3(대비·포커스·320px), docs/45 §3.1 D-01~D-09.
 * 마크업 예시는 preview.html 에 있다.
 */

/* ===== 리셋: 전역은 box-sizing·body 기본값·[hidden] 만. 앱 인라인 body 규칙이 뒤에 오면 그 값이 이긴다. ===== */
*,
[class*="s2p-"]::before,
[class*="s2p-"]::after { box-sizing: border-box; }
[hidden] { display: none !important; }
body {
  margin: 0;
  font-family: var(--s2p-font-sans);
  font-size: var(--s2p-text-body-lg);
  line-height: var(--s2p-leading-body);
  color: var(--s2p-color-text);
  background: var(--s2p-color-bg);
}
/* s2p 컴포넌트 안의 폼 요소는 글꼴을 물려받는다. */
[class*="s2p-"] :where(button, input, select, textarea),
:where(button, input, select, textarea)[class*="s2p-"] { font-family: inherit; color: inherit; }
/* 포커스: s2p 요소에만 3px 외곽선(docs/36 §1.3). 앱 고유 요소의 포커스 스타일은 바꾸지 않는다. */
[class*="s2p-"]:focus-visible,
[class*="s2p-"] :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--s2p-focus-ring-width) solid var(--s2p-focus-ring-color);
  outline-offset: var(--s2p-focus-ring-offset);
}

/* ===== 아이콘: <svg class="s2p-icon" aria-hidden="true"><use href="/web/design-system/icons.svg#i-home"/></svg>. 장식이면 aria-hidden, 아이콘만 있는 버튼은 버튼에 이름을 준다. ===== */
.s2p-icon {
  width: 20px; height: 20px; flex-shrink: 0;
  display: inline-block; vertical-align: middle;
  color: inherit;
}
.s2p-icon--sm { width: 16px; height: 16px; }
.s2p-icon--lg { width: 24px; height: 24px; }

/* ===== 건너뛰기 링크: 첫 Tab 에서 보인다. <a class="s2p-skip" href="#main">본문으로 건너뛰기</a> ===== */
.s2p-skip {
  position: fixed; left: var(--s2p-space-4); top: var(--s2p-space-2);
  z-index: var(--s2p-z-dialog);
  padding: var(--s2p-space-2) var(--s2p-space-4);
  background: var(--s2p-color-surface); color: var(--s2p-color-link);
  border: 2px solid var(--s2p-color-primary); border-radius: var(--s2p-radius-sm);
  font-weight: var(--s2p-weight-semibold);
  transform: translateY(-200%);
}
.s2p-skip:focus, .s2p-skip:focus-visible { transform: none; }

/* ===== 뼈대: 사이드바 240 + 상단바 56 + 본문(max 1200, 패딩 24). 960px 이하 사이드바는 드로어(.s2p-shell.is-drawer-open). ===== */
.s2p-shell {
  display: grid;
  grid-template-columns: var(--s2p-sidebar-width) minmax(0, 1fr);
  grid-template-rows: var(--s2p-topbar-height) minmax(0, 1fr);
  grid-template-areas: "side top" "side main";
  min-height: 100vh;
  background: var(--s2p-color-bg);
}
/* 사이드바 없는 뼈대(온보딩: 상단바+본문)와 맨 뼈대(로그인: 본문만). shell.js setChrome() 이 클래스를 건다. */
.s2p-shell.s2p-shell--no-sidebar { grid-template-columns: minmax(0, 1fr); grid-template-areas: "top" "main"; }
.s2p-shell.s2p-shell--bare { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); grid-template-areas: "main"; }
.s2p-shell.s2p-shell--no-sidebar > .s2p-sidebar, .s2p-shell.s2p-shell--bare > .s2p-sidebar, .s2p-shell.s2p-shell--bare > .s2p-topbar { display: none; }
.s2p-shell > .s2p-sidebar { grid-area: side; }
.s2p-shell > .s2p-topbar { grid-area: top; }
.s2p-shell > .s2p-main { grid-area: main; }
.s2p-main { min-width: 0; outline: none; }
.s2p-main__inner {
  max-width: var(--s2p-content-max);
  margin: 0 auto;
  padding: var(--s2p-space-6);
}
.s2p-shell__backdrop {
  position: fixed; inset: 0;
  background: var(--s2p-color-backdrop);
  z-index: var(--s2p-z-drawer-backdrop);
}

/* ===== 사이드바 메뉴: 그룹 제목 + 항목. 현재 화면은 aria-current="page"(색 + 굵기 + 왼쪽 막대로 표시). ===== */
.s2p-sidebar {
  position: sticky; top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--s2p-space-4);
  padding: var(--s2p-space-5) var(--s2p-space-3);
  background: var(--s2p-sidebar-bg);
  color: var(--s2p-sidebar-text);
  z-index: var(--s2p-z-sidebar);
}
.s2p-sidebar :where(a, button):focus-visible { outline-color: var(--s2p-focus-ring-color-inverse); }
.s2p-sidebar__head { display: flex; align-items: center; gap: var(--s2p-space-2); }
.s2p-sidebar__brand {
  display: flex; align-items: center; gap: var(--s2p-space-2);
  padding: 0 var(--s2p-space-2);
  color: var(--s2p-sidebar-active);
  font-size: var(--s2p-text-body-lg); font-weight: var(--s2p-weight-bold);
  text-decoration: none;
}
.s2p-btn.s2p-sidebar__close { display: none; margin-left: auto; } /* .s2p-btn 보다 높은 특이성: 데스크톱에서 숨김 */
.s2p-sidebar__footer { margin-top: auto; padding: 0 var(--s2p-space-2); font-size: var(--s2p-text-caption); }
.s2p-nav { display: flex; flex-direction: column; gap: var(--s2p-space-4); }
.s2p-nav__group {
  margin: 0 0 var(--s2p-space-1);
  padding: 0 var(--s2p-space-3);
  font-size: var(--s2p-text-caption-sm); font-weight: var(--s2p-weight-semibold);
  letter-spacing: 0.04em;
  color: var(--s2p-sidebar-group);
}
.s2p-nav__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.s2p-nav__item {
  display: flex; align-items: center; gap: var(--s2p-space-3);
  min-height: var(--s2p-control-height);
  padding: var(--s2p-space-2) var(--s2p-space-3);
  border-radius: var(--s2p-radius-sm);
  border-left: 3px solid transparent;
  color: var(--s2p-sidebar-text);
  font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-medium);
  text-decoration: none;
  transition: background-color var(--s2p-duration-fast) var(--s2p-ease), color var(--s2p-duration-fast) var(--s2p-ease);
}
.s2p-nav__item:hover { background: var(--s2p-sidebar-hover); color: var(--s2p-sidebar-active); }
.s2p-nav__item[aria-current="page"] {
  background: var(--s2p-sidebar-hover);
  color: var(--s2p-sidebar-active);
  font-weight: var(--s2p-weight-bold);
  border-left-color: var(--s2p-sidebar-group);
}
.s2p-nav__count { margin-left: auto; font-size: var(--s2p-text-caption-sm); }

/* ===== 상단바: 화면 제목 1개(24px) + 오른쪽 계정 영역. 좁은 화면에서 햄버거(aria-controls·aria-expanded) ===== */
.s2p-topbar {
  position: sticky; top: 0;
  z-index: var(--s2p-z-topbar);
  display: flex; align-items: center; gap: var(--s2p-space-3);
  height: var(--s2p-topbar-height);
  padding: 0 var(--s2p-space-6);
  background: var(--s2p-color-surface);
  border-bottom: 1px solid var(--s2p-color-border-subtle);
}
.s2p-btn.s2p-topbar__menu { display: none; } /* 960px 이하에서만 보임(아래 미디어 쿼리) */
/* 라우트 전환 때 shell 이 제목에 프로그램 포커스를 준다(tabindex=-1): 비대화형 요소라 외곽선은 그리지 않는다. */
.s2p-topbar__title:focus { outline: none; }
.s2p-topbar__title {
  margin: 0; min-width: 0;
  font-size: var(--s2p-text-title); font-weight: var(--s2p-weight-bold);
  line-height: var(--s2p-leading-tight);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.s2p-topbar__account {
  margin-left: auto;
  display: flex; align-items: center; gap: var(--s2p-space-2);
  min-width: 0;
  font-size: var(--s2p-text-body); color: var(--s2p-color-text-muted);
}
.s2p-topbar__account-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 16ch; }

@media (max-width: 960px) {
  .s2p-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "top" "main";
  }
  .s2p-shell > .s2p-sidebar {
    position: fixed; left: 0; top: 0; bottom: 0;
    width: min(var(--s2p-sidebar-width), 85vw);
    height: 100%;
    z-index: var(--s2p-z-drawer);
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform var(--s2p-duration) var(--s2p-ease), visibility 0s linear var(--s2p-duration);
    box-shadow: var(--s2p-shadow-md);
  }
  .s2p-shell.is-drawer-open > .s2p-sidebar {
    transform: none; visibility: visible;
    transition: transform var(--s2p-duration) var(--s2p-ease);
  }
  .s2p-btn.s2p-topbar__menu { display: inline-flex; }
  .s2p-btn.s2p-sidebar__close { display: inline-flex; }
  .s2p-topbar { padding: 0 var(--s2p-space-4); }
  .s2p-topbar__title { font-size: var(--s2p-text-title-sm); }
}
@media (min-width: 961px) {
  .s2p-shell__backdrop { display: none !important; }
}
@media (max-width: 600px) {
  .s2p-main__inner { padding: var(--s2p-space-4); }
  .s2p-topbar__account-name { display: none; }
}

/* ===== 페이지 제목 블록: 제목 + 설명 + 오른쪽 행동. 화면당 primary 버튼 1개 ===== */
.s2p-page-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: var(--s2p-space-4);
  margin-bottom: var(--s2p-space-6);
}
.s2p-page-head__title {
  margin: 0;
  font-size: var(--s2p-text-title-lg); font-weight: var(--s2p-weight-bold);
  line-height: var(--s2p-leading-tight);
}
.s2p-page-head__desc { margin: var(--s2p-space-1) 0 0; color: var(--s2p-color-text-muted); font-size: var(--s2p-text-body); }
.s2p-page-head__actions { display: flex; flex-wrap: wrap; gap: var(--s2p-space-2); }

/* ===== 버튼: 기본은 외곽선 보조, --primary 는 화면당 1개, --danger 는 되돌리기 어려운 행동. 처리 중은 aria-busy="true" + disabled ===== */
.s2p-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2p-space-2);
  min-height: var(--s2p-control-height);
  padding: 0 var(--s2p-space-4);
  border: 1px solid var(--s2p-color-border-input);
  border-radius: var(--s2p-radius-sm);
  background: var(--s2p-color-surface);
  color: var(--s2p-color-text);
  font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-semibold);
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--s2p-duration-fast) var(--s2p-ease), border-color var(--s2p-duration-fast) var(--s2p-ease);
}
.s2p-btn:hover { background: var(--s2p-color-surface-muted); }
.s2p-btn--primary {
  background: var(--s2p-color-primary); border-color: var(--s2p-color-primary);
  color: var(--s2p-color-on-primary);
}
.s2p-btn--primary:hover { background: var(--s2p-color-primary-hover); border-color: var(--s2p-color-primary-hover); }
.s2p-btn--danger {
  background: var(--s2p-color-danger); border-color: var(--s2p-color-danger);
  color: var(--s2p-color-on-primary);
}
.s2p-btn--danger:hover { background: var(--s2p-color-danger-hover); border-color: var(--s2p-color-danger-hover); }
/* 상단바·사이드바의 아이콘 전용 버튼(이름은 s2p-visually-hidden 글자로 준다). */
.s2p-btn--ghost { background: transparent; border-color: transparent; color: inherit; }
.s2p-btn--ghost:hover { background: var(--s2p-color-surface-muted); }
.s2p-sidebar .s2p-btn--ghost:hover { background: var(--s2p-sidebar-hover); }
.s2p-btn--icon { padding: 0; width: var(--s2p-control-height); }
.s2p-btn--sm { min-height: var(--s2p-control-height-sm); padding: 0 var(--s2p-space-3); font-size: var(--s2p-text-caption); }
.s2p-btn--sm.s2p-btn--icon { width: var(--s2p-control-height-sm); padding: 0; }
.s2p-btn--block { width: 100%; }
.s2p-btn:disabled, .s2p-btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.s2p-btn[aria-busy="true"] { cursor: progress; }
.s2p-btn[aria-busy="true"]::before {
  content: "";
  width: 1em; height: 1em;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%;
  animation: s2p-spin 0.8s linear infinite;
}
.s2p-btn[aria-busy="true"] > .s2p-icon { display: none; }

/* ===== 입력: label 은 항상 보이게, hint·error 는 aria-describedby 로 연결, 오류는 aria-invalid="true" + 글자 ===== */
.s2p-field { display: flex; flex-direction: column; gap: var(--s2p-space-1); min-width: 0; }
.s2p-field + .s2p-field { margin-top: var(--s2p-space-4); }
.s2p-field__label { font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text); }
.s2p-field__optional { font-weight: var(--s2p-weight-regular); color: var(--s2p-color-text-muted); font-size: var(--s2p-text-caption); }
.s2p-field__hint { margin: 0; font-size: var(--s2p-text-caption); color: var(--s2p-color-text-muted); }
.s2p-field__error {
  margin: 0;
  display: flex; align-items: flex-start; gap: var(--s2p-space-1);
  font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold);
  color: var(--s2p-color-danger-text);
}
.s2p-input {
  display: block; width: 100%;
  min-height: var(--s2p-control-height);
  padding: var(--s2p-space-2) var(--s2p-space-3);
  border: 1px solid var(--s2p-color-border-input);
  border-radius: var(--s2p-radius-sm);
  background: var(--s2p-color-surface);
  color: var(--s2p-color-text);
  font-size: var(--s2p-text-body-lg); /* 16px: iOS 확대 방지 */
  line-height: 1.4;
}
textarea.s2p-input { min-height: 96px; resize: vertical; }
.s2p-input::placeholder { color: var(--s2p-color-text-subtle); }
.s2p-input:focus-visible { outline: var(--s2p-focus-ring-width) solid var(--s2p-focus-ring-color); outline-offset: 1px; border-color: var(--s2p-color-primary); }
.s2p-input[aria-invalid="true"] { border-color: var(--s2p-color-danger); box-shadow: inset 0 0 0 1px var(--s2p-color-danger); }
.s2p-input:disabled { background: var(--s2p-color-surface-muted); color: var(--s2p-color-text-muted); cursor: not-allowed; }

/* ===== 체크박스·라디오: label 이 input 을 감싸 누르는 면적을 넓힌다. 묶음은 fieldset.s2p-choices + legend ===== */
.s2p-choices { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: var(--s2p-space-2); }
.s2p-choices > legend { padding: 0; margin-bottom: var(--s2p-space-1); font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-semibold); }
.s2p-check {
  display: inline-flex; align-items: flex-start; gap: var(--s2p-space-2);
  min-height: 32px; padding-top: var(--s2p-space-1);
  font-size: var(--s2p-text-body); cursor: pointer;
}
.s2p-check > input {
  width: 18px; height: 18px; margin: 1px 0 0; flex-shrink: 0;
  accent-color: var(--s2p-color-primary);
  cursor: pointer;
}

/* ===== 카드: 카드 하나 = 결정 하나. header(제목 + 보조 행동) / body / footer(결정 버튼) ===== */
.s2p-card {
  background: var(--s2p-color-surface);
  border: 1px solid var(--s2p-color-border-subtle);
  border-radius: var(--s2p-radius);
  box-shadow: var(--s2p-shadow-sm);
  min-width: 0;
}
.s2p-card__header {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s2p-space-2);
  padding: var(--s2p-space-4) var(--s2p-space-5) 0;
}
.s2p-card__title { margin: 0; font-size: var(--s2p-text-title-sm); font-weight: var(--s2p-weight-bold); line-height: var(--s2p-leading-tight); }
.s2p-card__subtitle { margin: var(--s2p-space-1) 0 0; font-size: var(--s2p-text-caption); color: var(--s2p-color-text-muted); }
.s2p-card__body { padding: var(--s2p-space-4) var(--s2p-space-5); font-size: var(--s2p-text-body); }
.s2p-card__footer {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s2p-space-2);
  padding: var(--s2p-space-3) var(--s2p-space-5) var(--s2p-space-4);
  border-top: 1px solid var(--s2p-color-border-subtle);
}

/* ===== 표: 래퍼가 가로 스크롤(본문 폭을 넘지 않게, tabindex="0" + aria-label), 머리 고정, 숫자 우측 정렬(.s2p-num), 빈 상태 행 ===== */
.s2p-table-wrap {
  overflow: auto;
  max-width: 100%;
  border: 1px solid var(--s2p-color-border-subtle);
  border-radius: var(--s2p-radius);
  background: var(--s2p-color-surface);
}
.s2p-table-wrap--scroll { max-height: 480px; }
.s2p-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--s2p-text-body); }
.s2p-table caption { padding: var(--s2p-space-3) var(--s2p-space-4); text-align: left; font-weight: var(--s2p-weight-semibold); }
.s2p-table th, .s2p-table td {
  padding: var(--s2p-space-3) var(--s2p-space-4);
  text-align: left; vertical-align: middle;
  border-bottom: 1px solid var(--s2p-color-border-subtle);
}
.s2p-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--s2p-color-surface-muted);
  color: var(--s2p-color-text-muted);
  font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold);
  white-space: nowrap;
}
.s2p-table tbody tr:hover > td { background: var(--s2p-color-surface-muted); }
.s2p-table tbody tr:last-child > td { border-bottom: 0; }
.s2p-table .s2p-num, .s2p-num { text-align: right; font-variant-numeric: tabular-nums; }
.s2p-table__empty > td { padding: var(--s2p-space-8) var(--s2p-space-4); text-align: center; color: var(--s2p-color-text-muted); }
.s2p-table tbody tr.s2p-table__empty:hover > td { background: transparent; }

/* ===== 배지: 상태는 글자로도 쓴다(색만으로 전달 금지). PENDING 은 success 색을 쓰지 않는다(docs/36 §1.1) ===== */
.s2p-badge {
  display: inline-flex; align-items: center; gap: var(--s2p-space-1);
  padding: 2px var(--s2p-space-2);
  border: 1px solid transparent;
  border-radius: var(--s2p-radius-pill);
  font-size: var(--s2p-text-caption-sm); font-weight: var(--s2p-weight-semibold);
  line-height: 1.5;
  white-space: nowrap;
  background: var(--s2p-color-neutral-light); color: var(--s2p-color-neutral-text);
}
.s2p-badge > .s2p-icon { width: 14px; height: 14px; }
.s2p-badge--success { background: var(--s2p-color-success-light); color: var(--s2p-color-success-strong); }
.s2p-badge--warning { background: var(--s2p-color-warning-light); color: var(--s2p-color-warning-text); }
.s2p-badge--danger { background: var(--s2p-color-danger-light); color: var(--s2p-color-danger-text); }
.s2p-badge--neutral { background: var(--s2p-color-neutral-light); color: var(--s2p-color-neutral-text); }
.s2p-badge--info { background: var(--s2p-color-info-light); color: var(--s2p-color-info-text); }
/* 적용 대기·검토 중: 점선 테두리로 확정 상태와 모양부터 다르게 한다. */
.s2p-badge--pending {
  background: var(--s2p-color-warning-light); color: var(--s2p-color-warning-text);
  border-color: var(--s2p-color-warning); border-style: dashed;
}

/* ===== 콜아웃: 페이지 안 안내문. 상태는 제목 글자 + 아이콘으로도 밝힌다(색만으로 전달 금지) ===== */
.s2p-callout {
  display: flex; align-items: flex-start; gap: var(--s2p-space-3);
  padding: var(--s2p-space-3) var(--s2p-space-4);
  border-left: 4px solid currentColor;
  border-radius: var(--s2p-radius-sm);
  font-size: var(--s2p-text-body);
  background: var(--s2p-color-info-light); color: var(--s2p-color-info-text);
}
.s2p-callout > .s2p-icon { margin-top: 1px; }
.s2p-callout__title { margin: 0 0 2px; font-weight: var(--s2p-weight-bold); }
.s2p-callout p { margin: 0; }
.s2p-callout--info { background: var(--s2p-color-info-light); color: var(--s2p-color-info-text); }
.s2p-callout--warning { background: var(--s2p-color-warning-light); color: var(--s2p-color-warning-text); }
.s2p-callout--danger { background: var(--s2p-color-danger-light); color: var(--s2p-color-danger-text); }
.s2p-callout--success { background: var(--s2p-color-success-light); color: var(--s2p-color-success-strong); }

/* ===== 토스트: 영역 <div class="s2p-toast-region" role="status" aria-live="polite"> 은 미리 두고 항목만 넣는다. 우하단, 600px 이하 하단 전체 폭 ===== */
.s2p-toast-region {
  position: fixed; right: var(--s2p-space-6); bottom: var(--s2p-space-6);
  z-index: var(--s2p-z-toast);
  display: flex; flex-direction: column; gap: var(--s2p-space-2);
  width: min(380px, calc(100vw - 2 * var(--s2p-space-6)));
  pointer-events: none;
}
.s2p-toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: var(--s2p-space-3);
  padding: var(--s2p-space-3) var(--s2p-space-4);
  background: var(--s2p-color-surface);
  color: var(--s2p-color-text);
  border: 1px solid var(--s2p-color-border);
  border-left: 4px solid var(--s2p-color-text-subtle);
  border-radius: var(--s2p-radius-sm);
  box-shadow: var(--s2p-shadow-md);
  font-size: var(--s2p-text-body);
  animation: s2p-toast-in var(--s2p-duration) var(--s2p-ease);
}
.s2p-toast__text { flex: 1 1 auto; min-width: 0; margin: 0; }
.s2p-toast--success { border-left-color: var(--s2p-color-success); }
.s2p-toast--success > .s2p-icon { color: var(--s2p-color-success-text); }
.s2p-toast--warning { border-left-color: var(--s2p-color-warning); }
.s2p-toast--warning > .s2p-icon { color: var(--s2p-color-warning); }
.s2p-toast--danger { border-left-color: var(--s2p-color-danger); }
.s2p-toast--danger > .s2p-icon { color: var(--s2p-color-danger-text); }
.s2p-toast--info { border-left-color: var(--s2p-color-primary); }
.s2p-toast--info > .s2p-icon { color: var(--s2p-color-info-text); }
@media (max-width: 600px) {
  .s2p-toast-region { left: var(--s2p-space-4); right: var(--s2p-space-4); bottom: var(--s2p-space-4); width: auto; }
}

/* ===== 다이얼로그: <dialog class="s2p-dialog" aria-labelledby> + showModal(). 머리(제목)·본문·바닥(취소 왼쪽, 결정 오른쪽) ===== */
.s2p-dialog {
  width: min(520px, calc(100vw - 2 * var(--s2p-space-4)));
  max-height: calc(100vh - 2 * var(--s2p-space-8));
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--s2p-radius);
  background: var(--s2p-color-surface);
  color: var(--s2p-color-text);
  box-shadow: var(--s2p-shadow-md);
  overflow: auto;
}
.s2p-dialog[open] { display: flex; flex-direction: column; animation: s2p-dialog-in var(--s2p-duration) var(--s2p-ease); }
.s2p-dialog::backdrop { background: var(--s2p-color-backdrop); }
.s2p-dialog__header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2p-space-2);
  padding: var(--s2p-space-5) var(--s2p-space-6) 0;
}
.s2p-dialog__title { margin: 0; font-size: var(--s2p-text-title-sm); font-weight: var(--s2p-weight-bold); line-height: var(--s2p-leading-tight); }
.s2p-dialog__body { padding: var(--s2p-space-4) var(--s2p-space-6); font-size: var(--s2p-text-body); }
.s2p-dialog__body p { margin: 0 0 var(--s2p-space-2); }
.s2p-dialog__footer {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s2p-space-2);
  padding: 0 var(--s2p-space-6) var(--s2p-space-5);
}

/* ===== 탭: 같은 화면 안 탭은 role="tablist" / role="tab" + aria-selected + aria-controls / role="tabpanel". 화면 이동 링크 탭은 <nav class="s2p-tabs"><a class="s2p-tab" aria-current="page">,
   눌러 바꾸는 버튼 탭은 aria-pressed. 선택은 밑줄 + 굵기 + 색(셋 중 어느 속성이든 같은 모양) ===== */
.s2p-tabs {
  display: flex; gap: var(--s2p-space-1);
  overflow-x: auto;
  border-bottom: 1px solid var(--s2p-color-border);
  margin-bottom: var(--s2p-space-4);
}
.s2p-tab {
  flex-shrink: 0;
  display: inline-flex; align-items: center;
  min-height: var(--s2p-control-height);
  padding: 0 var(--s2p-space-4);
  border: 0; border-bottom: 3px solid transparent;
  background: transparent;
  color: var(--s2p-color-text-muted);
  font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-medium);
  text-decoration: none;
  cursor: pointer;
}
.s2p-tab:hover { color: var(--s2p-color-text); }
.s2p-tab[aria-selected="true"], .s2p-tab[aria-current="page"], .s2p-tab[aria-pressed="true"] {
  color: var(--s2p-color-link);
  border-bottom-color: var(--s2p-color-primary);
  font-weight: var(--s2p-weight-bold);
}
.s2p-tab:focus-visible { outline-offset: -3px; }

/* ===== 필터 칩: 목록을 거르는 알약 버튼. 눌린 상태는 aria-pressed="true"(채움 + 흰 글자). 묶음은 <div class="s2p-chips" role="group" aria-label>.
   개수는 <span class="s2p-chip__count"> ===== */
.s2p-chips { display: flex; flex-wrap: wrap; gap: var(--s2p-space-2); }
.s2p-chip {
  display: inline-flex; align-items: center; gap: var(--s2p-space-1);
  min-height: var(--s2p-control-height-sm);
  padding: 0 var(--s2p-space-3);
  border: 1px solid var(--s2p-color-border-input);
  border-radius: var(--s2p-radius-pill);
  background: var(--s2p-color-surface);
  color: var(--s2p-color-text);
  font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold);
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--s2p-duration-fast) var(--s2p-ease), border-color var(--s2p-duration-fast) var(--s2p-ease);
}
.s2p-chip:hover { background: var(--s2p-color-surface-muted); }
.s2p-chip[aria-pressed="true"] { background: var(--s2p-color-primary); border-color: var(--s2p-color-primary); color: var(--s2p-color-on-primary); }
.s2p-chip[aria-pressed="true"]:hover { background: var(--s2p-color-primary-hover); border-color: var(--s2p-color-primary-hover); }
.s2p-chip:disabled { opacity: 0.55; cursor: not-allowed; }
.s2p-chip__count { margin-left: var(--s2p-space-1); font-weight: var(--s2p-weight-medium); color: var(--s2p-color-text-muted); }
.s2p-chip[aria-pressed="true"] .s2p-chip__count { color: var(--s2p-primary-100); } /* primary-600 위 5.10:1 */

/* ===== 상태 블록: Loading·Empty·Error 를 따로 보여 준다(docs/36 §1.2). 오류에는 다음 행동 버튼 ===== */
.s2p-empty, .s2p-loading, .s2p-error {
  display: flex; flex-direction: column; align-items: center; gap: var(--s2p-space-2);
  padding: var(--s2p-space-8) var(--s2p-space-4);
  text-align: center;
  font-size: var(--s2p-text-body);
  color: var(--s2p-color-text-muted);
}
.s2p-empty > .s2p-icon, .s2p-error > .s2p-icon { width: 32px; height: 32px; }
.s2p-empty__title, .s2p-error__title { margin: 0; font-size: var(--s2p-text-body-lg); font-weight: var(--s2p-weight-bold); color: var(--s2p-color-text); }
.s2p-empty p, .s2p-error p, .s2p-loading p { margin: 0; }
.s2p-error { color: var(--s2p-color-danger-text); }
.s2p-error > .s2p-icon { color: var(--s2p-color-danger); }
/* 스피너: 처리 중임을 글자(.s2p-loading p 또는 visually-hidden)로도 알린다. */
.s2p-spinner {
  display: inline-block;
  width: 28px; height: 28px;
  border: 3px solid var(--s2p-color-border);
  border-top-color: var(--s2p-color-primary);
  border-radius: 50%;
  animation: s2p-spin 0.8s linear infinite;
}
.s2p-spinner--sm { width: 16px; height: 16px; border-width: 2px; }

/* ===== 지표 타일: 숫자 + 라벨 + 보조. --urgent 는 바로 행동이 필요한 값(라벨에 글자로도 표시), --muted 는 참고값 ===== */
.s2p-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: var(--s2p-space-4); }
.s2p-stat {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--s2p-space-4) var(--s2p-space-5);
  background: var(--s2p-color-surface);
  border: 1px solid var(--s2p-color-border-subtle);
  border-top: 4px solid var(--s2p-color-primary);
  border-radius: var(--s2p-radius);
  box-shadow: var(--s2p-shadow-sm);
  min-width: 0;
}
.s2p-stat__label { margin: 0; font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text-muted); }
.s2p-stat__value {
  margin: 0;
  font-size: var(--s2p-text-title-lg); font-weight: var(--s2p-weight-bold);
  line-height: var(--s2p-leading-tight);
  font-variant-numeric: tabular-nums;
  color: var(--s2p-color-text);
  overflow-wrap: anywhere;
}
.s2p-stat__unit { font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text-muted); margin-left: 2px; }
.s2p-stat__meta { margin: 0; font-size: var(--s2p-text-caption); color: var(--s2p-color-text-muted); }
.s2p-stat--urgent { border-top-color: var(--s2p-color-danger); background: var(--s2p-color-danger-light); }
.s2p-stat--urgent .s2p-stat__label, .s2p-stat--urgent .s2p-stat__meta, .s2p-stat--urgent .s2p-stat__unit { color: var(--s2p-color-danger-text); }
.s2p-stat--muted { border-top-color: var(--s2p-color-border); box-shadow: none; }
/* 지표 아래 바로가기 링크: <a class="s2p-stat__go">(숨은 글자로 지표 라벨 + "바로가기" + 화살표 아이콘). --urgent 타일에서는 글자색도 위험색 */
.s2p-stat__go {
  display: inline-flex; align-items: center; gap: var(--s2p-space-1);
  align-self: flex-start;
  margin-top: var(--s2p-space-2);
  color: var(--s2p-color-link);
  font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold);
  text-decoration: none;
}
.s2p-stat__go:hover { text-decoration: underline; }
.s2p-stat--urgent .s2p-stat__go { color: var(--s2p-color-danger-text); }

/* ===== 단계 표시: <ol class="s2p-steps"> 온보딩·검수 3단계. 현재 단계 aria-current="step", 끝난 단계 .is-done(체크 + "완료" visually-hidden 글자) ===== */
.s2p-steps {
  list-style: none; margin: 0 0 var(--s2p-space-6); padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--s2p-space-2) var(--s2p-space-4);
  counter-reset: s2p-step;
}
.s2p-steps__item {
  counter-increment: s2p-step;
  display: flex; align-items: center; gap: var(--s2p-space-2);
  font-size: var(--s2p-text-body); color: var(--s2p-color-text-muted);
}
.s2p-steps__item::before {
  content: counter(s2p-step);
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex-shrink: 0;
  border: 2px solid var(--s2p-color-border-input);
  border-radius: 50%;
  font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-bold);
  background: var(--s2p-color-surface);
}
.s2p-steps__item:not(:last-child)::after {
  content: "";
  width: 24px; height: 2px;
  background: var(--s2p-color-border);
}
.s2p-steps__item[aria-current="step"] { color: var(--s2p-color-text); font-weight: var(--s2p-weight-bold); }
.s2p-steps__item[aria-current="step"]::before { border-color: var(--s2p-color-primary); background: var(--s2p-color-primary); color: var(--s2p-color-on-primary); }
.s2p-steps__item.is-done { color: var(--s2p-color-text); }
.s2p-steps__item.is-done::before { content: "\2713"; border-color: var(--s2p-color-success); background: var(--s2p-color-success-light); color: var(--s2p-color-success-strong); }

/* ===== 접는 도움말: <details class="s2p-help"><summary>도움말</summary><div class="s2p-help__body"><p>…</p></div></details>. 알약 모양 "?" 단추, 열면 연한 상자.
   summary 글자는 무엇을 접어 두었는지 말한다("도움말", "인증 메일은 어떻게 쓰이나요?") ===== */
.s2p-help { font-size: var(--s2p-text-caption); color: var(--s2p-color-text-muted); }
.s2p-help > summary {
  display: inline-flex; align-items: center; gap: var(--s2p-space-1);
  min-height: 28px; padding: 0 var(--s2p-space-2);
  border: 1px solid var(--s2p-color-border); border-radius: var(--s2p-radius-pill);
  background: var(--s2p-color-surface); color: var(--s2p-color-text-muted);
  font-weight: var(--s2p-weight-semibold);
  cursor: pointer; list-style: none;
}
.s2p-help > summary::-webkit-details-marker { display: none; }
.s2p-help > summary::before {
  content: "?";
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex-shrink: 0;
  border: 1.5px solid currentColor; border-radius: 50%;
  font-size: var(--s2p-text-caption-sm); font-weight: var(--s2p-weight-bold); line-height: 1;
}
.s2p-help > summary:hover { color: var(--s2p-color-text); }
.s2p-help[open] > summary { color: var(--s2p-color-link); border-color: var(--s2p-color-primary); }
.s2p-help__body {
  margin-top: var(--s2p-space-2); max-width: 72ch; padding: var(--s2p-space-3);
  background: var(--s2p-color-surface-muted); border-radius: var(--s2p-radius-sm);
  font-size: var(--s2p-text-body);
}
.s2p-help__body > * { margin: 0; }
.s2p-help__body > * + * { margin-top: var(--s2p-space-2); }
.s2p-help__body :where(ul, ol) { padding-left: var(--s2p-space-5); }
.s2p-help__body li + li { margin-top: var(--s2p-space-1); }

/* ===== 접는 영역(자주 안 쓰는 직접 입력 등): <details class="s2p-fold"><summary>…</summary>…</details>. 위쪽 점선 + 작은 글씨 summary ===== */
.s2p-fold { margin-top: var(--s2p-space-4); border-top: 1px dashed var(--s2p-color-border); padding-top: var(--s2p-space-3); }
.s2p-fold > summary { cursor: pointer; font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text-muted); }
.s2p-fold[open] > summary { margin-bottom: var(--s2p-space-3); }

/* ===== 아코디언(묻고 답하기 등): <details class="s2p-accordion"><summary>질문</summary><div class="s2p-accordion__body">…</div></details>. 열림 표시는 + / − 기호 + 글자 ===== */
.s2p-accordion {
  margin-bottom: var(--s2p-space-3);
  background: var(--s2p-color-surface);
  border: 1px solid var(--s2p-color-border-subtle);
  border-radius: var(--s2p-radius);
  box-shadow: var(--s2p-shadow-sm);
}
.s2p-accordion > summary {
  display: flex; align-items: flex-start; gap: var(--s2p-space-3);
  padding: var(--s2p-space-4) var(--s2p-space-5);
  font-size: var(--s2p-text-body-lg); font-weight: var(--s2p-weight-bold);
  cursor: pointer; list-style: none;
}
.s2p-accordion > summary::-webkit-details-marker { display: none; }
.s2p-accordion > summary::before {
  content: "+"; flex: 0 0 auto;
  width: 24px; height: 24px; line-height: 22px; text-align: center;
  border-radius: 50%; background: var(--s2p-color-info-light); color: var(--s2p-color-info-text);
  font-weight: var(--s2p-weight-bold);
}
.s2p-accordion[open] > summary::before { content: "\2212"; }
.s2p-accordion__body {
  padding: 0 var(--s2p-space-5) var(--s2p-space-5) calc(var(--s2p-space-5) + 24px + var(--s2p-space-3));
  font-size: var(--s2p-text-body-lg); line-height: 1.75; color: var(--s2p-color-neutral-text);
  overflow-wrap: anywhere;
}
.s2p-accordion__body p { margin: 0 0 var(--s2p-space-2); }
.s2p-accordion__body :where(ol, ul) { margin: var(--s2p-space-2) 0 var(--s2p-space-3); padding-left: var(--s2p-space-5); }
.s2p-accordion__body li { margin-bottom: var(--s2p-space-1); }
.s2p-accordion__body .s2p-callout { margin-top: var(--s2p-space-3); }
@media (max-width: 480px) { .s2p-accordion__body { padding-left: var(--s2p-space-5); } }

/* ===== 진행 막대: <div class="s2p-progress"><div class="s2p-progress__bar"></div></div> (너비는 CSSOM 으로). 값은 곁의 글자로도 말한다.
   머리 줄이 있으면 <div class="s2p-progress-row"><div class="s2p-progress-row__head"><span>라벨</span><span>값</span></div><div class="s2p-progress">…</div></div> ===== */
.s2p-progress { display: block; height: 8px; border-radius: var(--s2p-radius-pill); background: var(--s2p-color-border-subtle); overflow: hidden; }
.s2p-progress__bar { display: block; height: 100%; border-radius: inherit; background: var(--s2p-color-primary); }
.s2p-progress__bar--success { background: var(--s2p-color-success); }
.s2p-progress__bar--soft { background: var(--s2p-primary-300); }
.s2p-progress-row { margin: var(--s2p-space-2) 0; }
.s2p-progress-row__head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s2p-space-2); margin-bottom: var(--s2p-space-2); font-size: var(--s2p-text-body); }

/* ===== 이름-값 목록: <dl class="s2p-dl"><dt>이름</dt><dd>값</dd>…</dl>. 600px 이하에서는 위아래로. --sm 은 작은 글자, --strong 은 값을 굵게 ===== */
.s2p-dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--s2p-space-2) var(--s2p-space-4); margin: 0; font-size: var(--s2p-text-body); }
.s2p-dl > dt { color: var(--s2p-color-text-muted); }
.s2p-dl > dd { margin: 0; overflow-wrap: anywhere; }
.s2p-dl--sm { gap: 2px var(--s2p-space-3); font-size: var(--s2p-text-caption); }
.s2p-dl--strong > dd { font-weight: var(--s2p-weight-semibold); }
@media (max-width: 600px) {
  .s2p-dl { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .s2p-dl > dd { margin-bottom: var(--s2p-space-2); }
}

/* ===== 비밀번호 규칙 목록: <ul class="s2p-pw-rules"><li>글자 수</li>…</ul>. 지킨 규칙은 li.is-met(○ → ✓ + 성공 글자색). 기호와 글자로 말하고 색만으로 전달하지 않는다 ===== */
.s2p-pw-rules {
  list-style: none; padding: 0; margin: var(--s2p-space-2) 0 0;
  display: flex; flex-wrap: wrap; gap: var(--s2p-space-1) var(--s2p-space-3);
  font-size: var(--s2p-text-caption); color: var(--s2p-color-text-muted);
}
.s2p-pw-rules > li::before { content: "\25CB  "; }
.s2p-pw-rules > li.is-met { color: var(--s2p-color-success-text); }
.s2p-pw-rules > li.is-met::before { content: "\2713  "; }

/* ===== 표 펼침 행: 목록 행 바로 아래 <tr class="s2p-table__more" hidden><td colspan>…</td></tr> 를 [자세히] 로 펼친다.
   안은 <div class="s2p-table__more-grid"> 에 <div><span>이름</span><span>값</span></div> 를 나란히 ===== */
.s2p-table__more > td { white-space: normal; background: var(--s2p-color-surface-muted); }
.s2p-table__more-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: var(--s2p-space-2) var(--s2p-space-4); padding: var(--s2p-space-1) 0; }
.s2p-table__more-grid > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.s2p-table__more-grid > div > span:first-child { font-size: var(--s2p-text-caption-sm); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text-muted); }

/* ===== 차트 범례: <span class="s2p-chart-swatch" aria-hidden="true"> 옆에 항상 이름과 값을 글자로 쓴다. 색은 tokens.css 의 --s2p-chart-1..6, --s2p-chart-other.
   막대·호는 SVG 에 fill/stroke="var(--s2p-chart-N)" 로 칠한다(색 코드 직접 사용 금지) ===== */
.s2p-chart-swatch { display: inline-block; flex: 0 0 auto; width: 12px; height: 12px; border-radius: 3px; background: var(--s2p-color-border); }

/* ===== 요금 카드와 단계 카드(공개 사이트): .s2p-card 위에 얹는다. 둘 다 격자이고 한 줄의 카드는 같은 높이 ===== */
.s2p-plans { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); gap: var(--s2p-space-4); }
.s2p-plan > .s2p-card__body { display: flex; flex-direction: column; gap: var(--s2p-space-2); height: 100%; padding: var(--s2p-space-5); }
.s2p-plan .s2p-badge { align-self: flex-start; }
.s2p-plan__price { margin: 0; font-size: var(--s2p-text-title); font-weight: var(--s2p-weight-bold); line-height: var(--s2p-leading-tight); font-variant-numeric: tabular-nums; }
.s2p-plan__price small { display: block; margin-top: 2px; font-size: var(--s2p-text-caption); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text-muted); }
.s2p-plan__unit { margin-left: 2px; font-size: var(--s2p-text-body); font-weight: var(--s2p-weight-semibold); color: var(--s2p-color-text-muted); }
.s2p-plan__scope { margin: 0 0 var(--s2p-space-3); font-size: var(--s2p-text-body); color: var(--s2p-color-text-muted); }
.s2p-plan .s2p-btn { align-self: flex-start; margin-top: auto; }
.s2p-flow { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--s2p-space-4); text-align: left; }
.s2p-flow > .s2p-card > .s2p-card__body { display: flex; flex-direction: column; gap: var(--s2p-space-2); height: 100%; }
.s2p-flow .s2p-badge { align-self: flex-start; }
.s2p-flow__title { margin: 0; font-size: var(--s2p-text-body-lg); font-weight: var(--s2p-weight-bold); }
.s2p-flow__text { margin: 0; color: var(--s2p-color-text-muted); font-size: var(--s2p-text-body); }

/* ===== 유틸 ===== */
/* 화면에는 안 보이고 화면 읽기 프로그램에는 읽힌다. */
.s2p-visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}
.s2p-stack { display: flex; flex-direction: column; gap: var(--s2p-space-4); }
.s2p-stack--sm { gap: var(--s2p-space-2); }
.s2p-stack--lg { gap: var(--s2p-space-6); }
.s2p-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2p-space-2); }
.s2p-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: var(--s2p-space-4); }
.s2p-section + .s2p-section { margin-top: var(--s2p-space-8); }
.s2p-section__title { margin: 0 0 var(--s2p-space-3); font-size: var(--s2p-text-title-sm); font-weight: var(--s2p-weight-bold); line-height: var(--s2p-leading-tight); }
.s2p-text-muted { color: var(--s2p-color-text-muted); }
.s2p-text-caption { font-size: var(--s2p-text-caption); }
.s2p-mono { font-family: var(--s2p-font-mono); }
.s2p-mt-0 { margin-top: 0; }
.s2p-mt-4 { margin-top: var(--s2p-space-4); }
.s2p-mb-4 { margin-bottom: var(--s2p-space-4); }

/* ===== 움직임 ===== */
@keyframes s2p-spin { to { transform: rotate(360deg); } }
@keyframes s2p-toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes s2p-dialog-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* 움직임 줄이기: 전환·등장 효과를 끄고, 스피너는 느리게만 돈다(상태는 글자로도 알린다). */
@media (prefers-reduced-motion: reduce) {
  [class*="s2p-"], [class*="s2p-"]::before, [class*="s2p-"]::after { transition-duration: 0.01ms !important; }
  .s2p-toast, .s2p-dialog[open] { animation: none; }
  .s2p-spinner, .s2p-btn[aria-busy="true"]::before { animation-duration: 2.4s; }
}
