/* design_system 컴포넌트 시각·상태 (design-spec §9.2).
   색·타이포·radius·그림자·모션은 tokens.css의 var()로만 소비한다.
   컴포넌트 고유 구조 치수(버튼 높이·마크 크기·gap·padding)는 근거 시안의 값을
   직접 적는다 — 공용 spacing 토큰이 아닌 부품 내재 치수(design-spec §9.2 근거 치수·
   app_shell.css 구조 px 선례). letter-spacing .06em은 SpecialButton.jsx 고유값.

   글래스 재질 토큰 --glass-filter · --glass-border 는 tokens.css(§9.1 신규 등록·@kind other)에
   정의돼 있고 여기서 var() 로 참조한다. */

/* ── SpecialButton (button/special_button.html) ────────────────────
   m3 hover 화문 회전 · m4 hover 배경 · m5 press 축소+inset. */
.special-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;   /* 2026-09-09 시안: 화문을 각 절반 가운데로(spacer flex:1 1 0)·라벨 자연폭 (SpecialButton.jsx) */
  border: 1px solid var(--gold-400);
  border-radius: var(--radius-button);
  background: var(--accent);
  color: var(--text-inverse);
  box-shadow: var(--shadow-accent), inset 0 0 0 1px var(--special-button-inner-glow); /* SpecialButton.jsx 쉼 inner 하이라이트 */
  cursor: pointer;
  transition: var(--transition-control);
}

.special-button--full {
  display: flex;
  width: 100%;
}

.special-button--sm { height: 44px; gap: 10px; padding: 0 16px; }
.special-button--md { height: 56px; gap: 14px; padding: 0 22px; }
.special-button--lg { height: 68px; gap: 18px; padding: 0 26px; }
.special-button--xl { height: 80px; gap: 22px; padding: 0 32px; }

.special-button__label {
  flex: 0 0 auto;        /* 2026-09-09 시안: 라벨 자연폭(가운데) · 화문 spacer 가 양옆을 채움 */
  text-align: center;
  font-family: var(--font-sans);    /* 2026-09-09 시안 변경: SpecialButton 라벨 serif→sans (SpecialButton.jsx) */
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-body);   /* 2026-09-09 시안 변경: .06em→var(--ls-body)=-0.01em */
  line-height: 1;
  white-space: nowrap;
  text-shadow: 0 1px 2px var(--special-button-label-shadow); /* SpecialButton.jsx label */
}

.special-button--sm .special-button__label { font-size: var(--fs-caption); }
.special-button--md .special-button__label { font-size: var(--fs-body-sm); }
.special-button--lg .special-button__label { font-size: var(--fs-title-3); }
.special-button--xl .special-button__label { font-size: var(--fs-title-2); }

.special-button__mark {
  flex: 1 1 0;           /* 2026-09-09 시안: 화문 span 이 각 절반을 채우고 배경 화문을 contain·center 로 가운데 정렬 */
  min-width: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: drop-shadow(0 1px 1px var(--special-button-mark-shadow)); /* SpecialButton.jsx mark */
  transition: transform var(--dur-slow) var(--ease-glass); /* m3 */
}

.special-button--sm .special-button__mark { width: 18px; height: 18px; }
.special-button--md .special-button__mark { width: 24px; height: 24px; }
.special-button--lg .special-button__mark { width: 30px; height: 30px; }
.special-button--xl .special-button__mark { width: 36px; height: 36px; }

@media (hover: hover) and (pointer: fine) {
  .special-button:hover:not(:disabled) { background: var(--accent-hover); }               /* m4 */
}
@media (hover: hover) and (pointer: fine) {
  .special-button:hover:not(:disabled) .special-button__mark { transform: rotate(45deg); } /* m3 */
}

.special-button:active:not(:disabled) {
  background: var(--accent-press);
  transform: scale(var(--press-scale));
  box-shadow: var(--shadow-inset-press);
} /* m5 */

.special-button:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  box-shadow: none;
}

.special-button:disabled .special-button__mark { opacity: 0.7; }

/* ── PrimaryButton (button/primary_button.html) — DS Button variant=primary · lg 고정(56px) ──
   가입/비번찾기 단계 CTA. 도화 배경 · inverse 텍스트. _ds_bundle 미수집(D14)이라 토큰 근사.
   높이 56px = dc primary lg hint-size(100%,56px) — web-auth-5 md 48→lg 56(§16.4·D40 · 전 소비자 lg).
   m14: hover lift(translateY) · press darken(accent-press) + scale(--press-scale). */
.primary-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 56px;
  padding: 0 22px;
  border: none;
  border-radius: var(--radius-button);
  background: var(--accent);
  color: var(--text-inverse);
  box-shadow: var(--shadow-accent);
  cursor: pointer;
  transition: var(--transition-control);
}

.primary-button--full { display: flex; width: 100%; }

.primary-button__label {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body);
  line-height: 1;
  letter-spacing: var(--ls-body);
  white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
  .primary-button:hover:not(:disabled) { background: var(--accent-hover); transform: translateY(-1px); }  /* m14 hover lift */
}
.primary-button:active:not(:disabled) {
  background: var(--accent-press);
  transform: scale(var(--press-scale));
  box-shadow: var(--shadow-inset-press);
} /* m14 press */

.primary-button:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  box-shadow: none;
}

/* ── SuccessButton (button/success_button.html) — 완료(done) CTA · primary 판형 복제·색만 success(청·초록)
   근거 §17.4·D52: 채움 --success(jade-500) · 라벨 --text-inverse · hover 리프트+jade-600 · press scale.
   그림자는 accent(도화) 대신 중립 --shadow-solid(풀 jade 무-쉐도우 → §17.4 shadow latitude·색 누수 방지). */
.success-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 56px;
  padding: 0 22px;
  border: none;
  border-radius: var(--radius-button);
  background: var(--success);
  color: var(--text-inverse);
  box-shadow: var(--shadow-solid);
  cursor: pointer;
  transition: var(--transition-control);
}

.success-button--full { display: flex; width: 100%; }

.success-button__label {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body);
  line-height: 1;
  letter-spacing: var(--ls-body);
  white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
  .success-button:hover:not(:disabled) { background: var(--jade-600); transform: translateY(-1px); }  /* hover lift + darken */
}
.success-button:active:not(:disabled) {
  background: var(--jade-600);
  transform: scale(var(--press-scale));
  box-shadow: var(--shadow-inset-press);
} /* press scale */

.success-button:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  box-shadow: none;
}

/* ── GhostButton (button/ghost_button.html) — m13 hover/press · m15 ghost(--transition-control) ── */
.ghost-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  line-height: 1;
  letter-spacing: var(--ls-body);
  text-decoration: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: var(--transition-control);
}

.ghost-button--full { display: flex; width: 100%; }
.ghost-button--sm { height: 36px; padding: 0 16px; font-size: var(--fs-caption); }
.ghost-button--lg { height: 68px; padding: 0 20px; font-size: var(--fs-body); }
.ghost-button > i { font-size: var(--icon-size-sm); }

@media (hover: hover) and (pointer: fine) {
  .ghost-button:hover { background: var(--surface-hover); }  /* m13 — 번들 ghost hover 색 무변 */
}
.ghost-button:active { background: var(--surface-press); transform: scale(var(--press-scale)); box-shadow: var(--shadow-inset-press); }  /* m13 — 색 무변·press scale+inset */
.ghost-button:disabled { opacity: 0.42; cursor: not-allowed; }

/* ── IconButton (button/icon_button.html) ── */
.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: var(--transition-control);
  text-decoration: none;
}

.icon-button--sm { width: 32px; height: 32px; }
.icon-button--md { width: 40px; height: 40px; }
.icon-button > i { font-size: var(--icon-size); }
.icon-button--sm > i { font-size: var(--icon-size-sm); }
@media (hover: hover) and (pointer: fine) {
  .icon-button:hover { background: var(--surface-hover); text-decoration: none; }  /* 링크 아이콘 단추에 전역 a:hover 밑줄 0 */
}
.icon-button:active { transform: scale(var(--press-scale)); }

/* glass 변종 — 상담 기록 상세(record_detail)·유저 정보(user_info) 상단 back 등 «캡슐 아닌» 원형 글래스
   IconButton(42×42). auth 가입·비번찾기 back 은 2026-09-09 시안 재디자인으로 app_bar 캡슐로 이관(아래 .app-bar).
   이 변종은 그 두 소비자를 위해 유지(세션 시작 상태). */
.icon-button--glass {
  width: 42px;
  height: 42px;
  border: var(--glass-border);
  background: var(--glass-tint-strong);
  box-shadow: var(--glass-edge);
  color: var(--ink-700);
}
.icon-button--glass > i { font-size: var(--icon-size-lg); }
@media (hover: hover) and (pointer: fine) {
  .icon-button--glass:hover { background: var(--glass-tint-strong); color: var(--ink-900); transform: translateY(-1px); }
}
.icon-button--glass:active { background: var(--glass-tint-strong); transform: scale(var(--press-scale)); }

/* soft 변종 — DS IconButton soft(ds:578-584 · 설정 프로필 닉네임 연필 sm 32 원): 배경 · 글리프 · hover 배경만 더한다.
   원본의 투명 테두리(1px solid transparent)는 border-box · 배경이 테두리 밑까지 칠해져 기본 .icon-button 의 border: none 과
   같은 픽셀이라 그대로 물려받는다(plain 변종과 같은 표현). 크기 · 글리프 크기 · 누름 · 전환은 기본 규칙. */
.icon-button--soft {
  background: var(--accent-soft);
  color: var(--text-accent);
}
@media (hover: hover) and (pointer: fine) {
  .icon-button--soft:hover { background: var(--accent-soft-hover); }
}

/* AppBar — 화면 상단 바(가입·비번찾기 상단 back). design-ref/…/components/navigation/AppBar.jsx 의
   제목 없는 iconsOnly transparent 형: 투명 sticky 헤더 안에서 leading(back)을 glass 캡슐로 감싼다.
   2026-09-09 시안 재디자인: glass 를 «버튼»이 아니라 «캡슐 그룹»이 소유(back 자체는 plain .icon-button).
   캡슐 backdrop-filter 는 radial mask(--icon-glass-mask)로 pill 모양에 가둔다(Chrome 사각합성 교정·groupCapsule). */
.app-bar {
  position: sticky;
  top: 0;
  z-index: 30;   /* 스크롤 시 카드 위 고정(--z-tabbar 와 동급 · z 토큰은 home 스코프라 정수 리터럴) */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  padding: 24px var(--gutter) 0;   /* 상단행 배치(옛 __top 24/20 유지) · AppBar inset=0 → 거터는 여기가 제공 */
}
.app-bar__lead {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--appbar-h);
  padding: 0 var(--space-3);
  box-sizing: border-box;
  border-radius: var(--radius-pill);
  isolation: isolate;
  background: var(--glass-tint-bar);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  border: var(--glass-border);
  box-shadow: var(--shadow-3), var(--glass-edge-sm);
  -webkit-mask-image: var(--icon-glass-mask);
  mask-image: var(--icon-glass-mask);
}
.app-bar .icon-button > i { font-size: 19px; }   /* DS IconButton size md(40) → chevron 19 */

/* ── Input 필드 (field/input_field.html) ── */
.input-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.input-field__label {
  font: var(--type-label);
  letter-spacing: var(--ls-body);
  color: var(--ink-700);
}

.input-field__control {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  height: 52px;
  padding: 0 18px;
  border: 1px solid var(--glass-rim);
  border-radius: var(--radius-pill);
  background: var(--surface-field);
  box-shadow: var(--field-dome);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  transition: var(--transition-control);
}

.input-field__control:focus-within {
  border-color: var(--border-accent);
  background: var(--surface-field-focus);
  box-shadow: var(--focus-ring), var(--field-flat);
}

.input-field__control:focus-within .input-field__icon {
  color: var(--accent);
}

.input-field__icon {
  flex: 0 0 auto;
  color: var(--ink-400);
  font-size: 18px;
}

.input-field__input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: var(--type-body);
  letter-spacing: var(--ls-body);
  color: var(--text-primary);
}

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

/* DS Input.jsx: 내부 <input> 은 boxShadow:'none' — 포커스 표현은 컨트롤 래퍼(:focus-within)가 소유.
   전역 base.css :focus-visible(--focus-ring)가 input 에 얹는 «안쪽 링»을 억제한다(0,2,0 > 전역 0,1,0). */
.input-field__input:focus-visible { box-shadow: none; }

/* 링 소유권(final.md §링 소유권): 래퍼 :focus-within 가 링을 소유하면 안쪽 «모든» 포커스 가능
   자손이 자기 전역 링을 억제해야 한다. trailing 슬롯의 아이콘 버튼(eye 토글 등)을 빠뜨리면
   그 버튼이 전역 :focus-visible(--focus-ring)을 그대로 받아 래퍼 링과 «두 겹»이 된다. */
.input-field__control .icon-button:focus-visible { box-shadow: none; }

.input-field__trailing {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
}

.input-field__hint {
  font: var(--type-caption);
  letter-spacing: var(--ls-body);
  color: var(--text-tertiary);
}

.input-field__error {
  font: var(--type-caption);
  letter-spacing: var(--ls-body);
  color: var(--text-danger);
  padding-left: var(--space-2);
}

.input-field--error .input-field__control { border-color: var(--danger); }

/* ── Textarea 필드 (field/textarea_field.html · 신설 · additive · 기존 셀렉터 무변) ──
   input_field 판형을 여러 줄로 옮김 — 표면 dome·focus·error 토큰을 그대로 재사용한다(관계인 메모 · PD-4). */
.textarea-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.textarea-field__label {
  font: var(--type-label);
  letter-spacing: var(--ls-body);
  color: var(--ink-700);
  padding-left: var(--space-2);
}

.textarea-field__control {
  position: relative;
  display: flex;
  padding: 14px var(--space-6);
  border: 1px solid var(--glass-rim);
  border-radius: var(--radius-field);
  background: var(--surface-field);
  box-shadow: var(--field-dome);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  transition: var(--transition-control);
}

.textarea-field__control:focus-within {
  border-color: var(--border-accent);
  background: var(--surface-field-focus);
  box-shadow: var(--focus-ring), var(--field-flat);
}

.textarea-field__input {
  flex: 1 1 auto;
  width: 100%;
  min-height: 48px;
  border: none;
  outline: none;
  background: transparent;
  font: var(--type-body);
  letter-spacing: var(--ls-body);
  color: var(--text-primary);
  resize: none;
}

.textarea-field__input:focus-visible { box-shadow: none; }
.textarea-field__input::placeholder { color: var(--text-placeholder); }

.textarea-field__hint {
  font: var(--type-caption);
  letter-spacing: var(--ls-body);
  color: var(--text-tertiary);
}

.textarea-field__error {
  font: var(--type-caption);
  letter-spacing: var(--ls-body);
  color: var(--text-danger);
  padding-left: var(--space-2);
}

.textarea-field--error .textarea-field__control { border-color: var(--danger); }

.textarea-field__support {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding-left: var(--space-2);
}

.textarea-field__count {
  margin-left: auto;
  font: var(--type-caption);
  color: var(--text-tertiary);
  white-space: nowrap;
}

/* ── GlassPanel (panel/glass_panel.html) ──
   --glass-filter · --glass-border 는 tokens.css 정의를 var() 로 참조(위 헤더 주석). */
.glass-panel {
  position: relative;
  padding: var(--card-pad);
  border: var(--glass-border);
  border-radius: var(--radius-panel);
  background: var(--glass-tint-strong);
  box-shadow: var(--glass-edge), var(--shadow-3);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  overflow: hidden;
  isolation: isolate;
}

.glass-panel--strong { background: var(--glass-tint-strong); }
.glass-panel--default { background: var(--glass-tint); }
.glass-panel--dim { background: var(--glass-tint-dim); }
.glass-panel--bar { background: var(--glass-tint-bar); }

/* 14:55 _ds_bundle.js:123-221 — 새 상세가 쓰는 light/solid는 source 기본 elevation 2,
   card radius와 전량 sheen을 가진다. 기존 strong/default/dim/bar 재질은 유지한다. */
.glass-panel--light,
.glass-panel--solid {
  color: var(--text-primary);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-2), var(--glass-edge);
  overflow: visible;
}
.glass-panel--light { background: var(--glass-tint); }
.glass-panel--solid {
  background: var(--surface-solid);
  border: 1px solid var(--border-hairline);
}
.glass-panel--light .glass-panel__sheen,
.glass-panel--solid .glass-panel__sheen { opacity: 1; }

.glass-panel__sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background: var(--glass-sheen);
  opacity: 0.55;
}

.glass-panel__content {
  position: relative;
  z-index: 1;
}

/* 14:55 _ds_bundle.js:3193-3293 — SegmentedControl pill.
   count/index는 화면 상태가 주는 위치 값이고 원본의 4px track·38px option·2px gap을 유지한다. */
.segmented-choice {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--segmented-choice-count), minmax(0, 1fr));
  gap: var(--segmented-choice-gap);
  padding: var(--segmented-choice-inset);
  border: 1px solid var(--glass-rim-dim);
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  box-shadow: var(--shadow-inset-track);
}
.segmented-choice__indicator {
  position: absolute;
  top: var(--segmented-choice-inset);
  bottom: var(--segmented-choice-inset);
  left: var(--segmented-choice-inset);
  width: calc((100% - var(--segmented-choice-inset) * 2) / var(--segmented-choice-count));
  border-radius: var(--radius-pill);
  background: var(--surface-solid);
  box-shadow: var(--shadow-1), var(--glass-edge);
  transform: translateX(calc(var(--segmented-choice-index) * 100%));
  transition: transform var(--dur-base) var(--ease-glass);
  pointer-events: none;
}
.segmented-choice__option {
  position: relative;
  z-index: 1;
  min-height: var(--segmented-choice-option-height);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font: var(--fw-medium) var(--fs-label)/1 var(--font-sans);
  letter-spacing: var(--ls-body);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}
.segmented-choice__option[aria-selected="true"] {
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}

/* 14:55 _ds_bundle.js:1308-1341 — 원본 Spinner의 미스트 트랙·선두 색·회전. */
.loading-feedback {
  display: inline-flex;
  align-items: center;
  gap: var(--inline);
}
.loading-feedback__ring {
  width: var(--spinner-size-md);
  height: var(--spinner-size-md);
  border: var(--spinner-border-md) solid var(--track-off);
  border-top-color: var(--info);
  border-radius: 50%;
  animation: cm-spin var(--spinner-spin-duration) linear infinite;
}
.loading-feedback--lg .loading-feedback__ring {
  width: var(--spinner-size-lg);
  height: var(--spinner-size-lg);
  border-width: var(--spinner-border-lg);
}
.loading-feedback__label { font: var(--type-caption); color: var(--text-tertiary); }

/* 14:55 Button intent=detail(_ds_bundle.js:467-590). 국소 변수는 기존 상담 Button의
   primary 배경·hover·shadow 소비를 바꾸면서 다른 호출자의 primary를 보존한다. */
.standard-button--ink {
  --accent: var(--ink-fill);
  --accent-hover: var(--ink-fill-hover);
  --accent-press: var(--ink-fill-press);
  --chat-control-primary-shadow: var(--shadow-ink-fill), var(--on-fill-highlight);
  background: var(--ink-fill);
}
@media (hover: hover) and (pointer: fine) {
  .standard-button--ink:hover:not(:disabled) { background: var(--ink-fill-hover); }
}
.standard-button--ink:active:not(:disabled) { background: var(--ink-fill-press); }

/* 5-1-6 m1 — _ds_bundle.js:394~400/549~557와 L hover/focus 실제 관찰. */
@media (hover: hover) and (pointer: fine) {
  .conversation-card .standard-button--ghost:hover {
    background: var(--surface-hover);
    transform: none;
    transition: background-color var(--duration-control) var(--ease-out),
      color var(--duration-control) var(--ease-out),
      border-color var(--duration-control) var(--ease-out),
      box-shadow var(--duration-control) var(--ease-out),
      transform var(--duration-control) var(--ease-out);
  }
}

/* L/D/M/N의 kind만 공용 focus 규칙(0,3,0)보다 우선한다(0,4,0). */
.conversation-card:is(
  [data-card-kind="related_person"],
  [data-card-kind="request_inputs"],
  [data-card-kind="summary_confirm"]
) .standard-button--ghost:focus-visible {
  outline: none;
  box-shadow: none;
}

.standard-button__icon.standard-button__icon--plus { font: var(--typography-icon-plus-md); }
.standard-button--sm .standard-button__icon.standard-button__icon--plus { font: var(--typography-icon-plus-sm); }
.standard-button--lg .standard-button__icon.standard-button__icon--plus { font: var(--typography-icon-plus-lg); }

.standard-button__spinner {
  position: relative;
  width: var(--button-loading-size-md);
  height: var(--button-loading-size-md);
  border: var(--spinner-border-md) solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  opacity: var(--button-loading-opacity);
  animation: cm-spin var(--button-loading-spin-duration) linear infinite;
}
.standard-button--sm .standard-button__spinner {
  width: var(--button-loading-size-sm);
  height: var(--button-loading-size-sm);
}
.standard-button--lg .standard-button__spinner {
  width: var(--button-loading-size-lg);
  height: var(--button-loading-size-lg);
}

/* ── ProgressBar (bar/progress_bar.html) — 단계 세그먼트(steps개) · height 5px ──
   design-diff 13: 구 value/max 트랙 → steps 세그먼트. 현재 step 까지 accent 채움 · 나머지는 sunken 트랙.
   web-auth-5: label 을 segments «위»로 재배치(ProgressBar.jsx 정합)·짧은 라벨(type-caption/secondary) ·
   inline h1/p 가 제목을 소유(구 «label=제목» 폐기 · §16.5·D39). 세그먼트 채움 전이 m14 근사. */
.progress-bar {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.progress-bar__segments {
  display: flex;
  gap: 6px;
  height: 5px;
}

.progress-bar__segment {
  flex: 1 1 0;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  transition: background-color var(--dur-base) var(--ease-out);
}

.progress-bar__segment--filled { background: var(--accent); }

/* _ds_bundle.js:1234~1241/1283~1298 — 연속 트랙만 원본 부모·inset·채움 전이를 소비한다. */
.progress-bar--continuous {
  gap: var(--space-3);
  width: var(--chat-input-progress-full);
}

.progress-bar--continuous .progress-bar__label {
  font: var(--type-caption);
  color: var(--text-secondary);
}

.progress-bar--continuous .progress-bar__track {
  height: var(--chat-input-progress-height);
  border-radius: var(--radius-pill);
  background: var(--track-off);
  box-shadow: var(--shadow-inset-track);
  overflow: hidden;
}

.progress-bar--continuous .progress-bar__fill {
  height: var(--chat-input-progress-full);
  border-radius: var(--radius-pill);
  background: var(--accent);
  transition: width var(--dur-slow) var(--ease-glass);
}

/* ── 인증 타이머 표시 (verification_timer.js가 --danger 클래스만 토글 · m6) ──
   색은 여기 토큰으로 소유하고 JS는 상태 클래스만 갈아끼운다. */
.verification-timer__display {
  font-weight: var(--fw-semibold);
  font-size: var(--fs-caption);
  letter-spacing: .02em;
  line-height: 1;
  color: var(--info);
  font-variant-numeric: tabular-nums;
}

.verification-timer__display--danger { color: var(--text-danger); } /* 만료 시에만 (§17.3·m8·D55 — ≤60s 규칙 폐기) */

/* ── BackgroundMedia (background/media_background.html) — poster 바닥 + 영상 슬롯 + veil ──
   m1 native <video autoplay muted playsinline>(no-loop) · m3 veil. web-auth-5: 4화면 전부 region full
   (가입/비번찾기 top 배너 62%+fade 마스크 폐기 · D35). app_shell.css는 .background-media*를 이 파일에 위임(§3.2).
   web-video-poster(§19.3): poster 층은 영상과 동일 rect(DOM 순서상 영상 아래 = paint 바닥) · 영상은 기본 가시
   (no-JS 폴백)이되 JS init(--enhanced)이 걸리면 숨겨 `playing`(--playing)에서만 페이드-인한다. 새 토큰·keyframe 0. */
.background-media {
  position: absolute;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.background-media--full { inset: 0; }

.background-media__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.background-media__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 1;
  transition: opacity var(--dur-base) var(--ease-out);
}

/* JS init 이 --enhanced 를 걸어야 영상을 숨긴다(no-JS 면 위 opacity 1 유지 = 현행 즉시 가시 폴백). */
.background-media--enhanced .background-media__video {
  opacity: 0;
}

/* `playing` 이벤트에서 --playing 부여 → 영상이 poster 위로 페이드-인(loadeddata/canplay 아님). */
.background-media--enhanced.background-media--playing .background-media__video {
  opacity: 1;
}

.background-media__veil {
  position: absolute;
  inset: 0;
  background: var(--bg-veil);
  opacity: var(--veil-strength);
}

/* ── AlertDialog (dialog/alert_dialog.html) — 로그인 실패 모달 (design-spec §18.4) ──
   프레임 안 절대 위치 오버레이(native <dialog> top-layer 미사용). 컨테이닝 블록 =
   .app-frame__body(position relative·app_shell.css) → nav 슬롯 포함 프레임 body 전체를 덮고
   .app-frame__content overflow 밖에서 클립되지 않는다(컨테이닝 블록이 스크롤 컨테이너의 조상).
   글래스 판은 .glass-panel--strong 재질을 계승하고(§9.2 recipe), 아이콘은 --text-danger(알림·기본안).
   backdrop scrim·판 정적(무모션·§18.7). 신규 토큰 0 · 생 색 0(178 풀 재사용). */
.alert-dialog {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gutter);
}

.alert-dialog__backdrop {
  position: absolute;
  inset: 0;
  background: var(--scrim);
}

.alert-dialog__panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--dialog-max-width);
  padding: var(--sheet-pad);
}

.alert-dialog__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--stack-loose);
  text-align: center;
}

.alert-dialog__icon {
  font-size: var(--icon-size-xl);
  line-height: 1;
  color: var(--text-danger);
}

.alert-dialog__title {
  margin: 0;
  font: var(--type-title-1);
  color: var(--text-primary);
}

.alert-dialog__description {
  margin: 0;
  font: var(--type-body-sm);
  color: var(--text-secondary);
}

.alert-dialog__actions {
  display: flex;
  flex-direction: column;
  gap: var(--stack);
  width: 100%;
}

/* 관계인 목록 실패: 동결 Dialog의 320px 판, 원형 아이콘과 가로 md 버튼. */
.alert-dialog--failure {
  background: var(--scrim);
  -webkit-backdrop-filter: var(--scrim-blur);
  backdrop-filter: var(--scrim-blur);
  animation: rp_scrim_in var(--dur-fast) var(--ease-out);
}

.alert-dialog--failure .alert-dialog__backdrop { background: transparent; }

.alert-dialog--failure .alert-dialog__panel {
  max-height: 100%;
  background: var(--glass-tint-sheet);
  box-shadow: var(--shadow-4), var(--glass-edge);
  -webkit-backdrop-filter: var(--glass-filter-lg);
  backdrop-filter: var(--glass-filter-lg);
  animation: rp_panel_in var(--dur-base) var(--ease-soft-spring);
}

.alert-dialog--failure .alert-dialog__body { display: block; }

.alert-dialog--failure .alert-dialog__icon-badge {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin: 0 auto 14px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--text-accent);
}

.alert-dialog--failure .alert-dialog__icon-badge i { font-size: 24px; }

.alert-dialog--failure .alert-dialog__title {
  font: var(--type-title-2);
  letter-spacing: var(--ls-title);
}

.alert-dialog--failure .alert-dialog__description { margin-top: var(--space-4); }

.alert-dialog--failure .alert-dialog__actions {
  flex-direction: row;
  gap: var(--space-4);
  margin-top: var(--space-8);
}

.alert-dialog--failure .alert-dialog__button {
  flex: 0 1 auto;
  width: 100%;
  height: 48px;
  padding: 0 var(--related-failure-button-inline-padding);
}
.alert-dialog--failure .glass-button.alert-dialog__button {
  position: relative;
  isolation: isolate;
  background: transparent;
  box-shadow: var(--shadow-1);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.alert-dialog--failure .glass-button.alert-dialog__button::before {
  content: "";
  position: absolute;
  inset: var(--space-0);
  border-radius: inherit;
  pointer-events: none;
  background: var(--glass-tint);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  -webkit-mask-image: var(--icon-glass-mask);
  mask-image: var(--icon-glass-mask);
}
@media (hover: hover) and (pointer: fine) {
  .alert-dialog--failure .glass-button.alert-dialog__button:hover::before {
    background: var(--glass-tint-strong);
  }
}
.alert-dialog--failure .glass-button.alert-dialog__button:active::before {
  background: var(--glass-tint-press);
}
.alert-dialog--failure .glass-button__label { position: relative; }
.alert-dialog--failure .primary-button.alert-dialog__button {
  border: var(--on-fill-border);
  box-shadow: var(--shadow-accent), var(--on-fill-highlight);
}

.alert-dialog--failure .alert-dialog__button .glass-button__label,
.alert-dialog--failure .alert-dialog__button .primary-button__label {
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-semibold);
}

.alert-dialog__retrying,
.alert-dialog__retry.htmx-request .alert-dialog__retry-label { display: none; }
.alert-dialog__retry.htmx-request .alert-dialog__retrying { display: inline; }

@keyframes rp_scrim_in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes rp_panel_in {
  from { opacity: 0; transform: scale(.94); }
  to { opacity: 1; transform: scale(1); }
}
/* ── ChoicePair (choice/pair_choice.html) — 2분할 세그먼트 토글 · dc ChoicePair(글래스 트랙 + 종이빛 thumb) ──
   트랙 dome(쉼)→flat(포커스) · 선택 thumb 슬라이드(--dur-base ease-glass) · 라벨 강조 도화. m2 트랜지션.
   accent-soft(§13.4 X 미채택)→--surface-selected · glass-rim(X)→--glass-border 치환. 높이 52/44는 dc hint-size. */
.choice-pair {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  padding: 4px;
  border: var(--glass-border);
  border-radius: var(--radius-pill);
  background: var(--surface-field);
  box-shadow: var(--field-dome);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  transition: var(--transition-control);
}

.choice-pair--md { height: 52px; }
.choice-pair--sm { height: 44px; }

.choice-pair:focus-within {
  border-color: var(--border-accent);
  background: var(--surface-field-focus);
  box-shadow: var(--focus-ring), var(--field-flat);
}

.choice-pair--disabled { opacity: 0.42; }

/* 시각적으로 숨긴 native radio (키보드 포커스·화살표 이동 유지). */
.choice-pair__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.choice-pair__option {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  cursor: pointer;
  font: var(--type-body);
  letter-spacing: var(--ls-body);
  color: var(--text-tertiary);
  transition: var(--transition-control); /* m2 */
}

.choice-pair--disabled .choice-pair__option { cursor: not-allowed; }

.choice-pair__input:checked + .choice-pair__option {
  font-weight: var(--fw-semibold);
  color: var(--text-accent);
}

.choice-pair__thumb {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc(50% - 6px);
  border-radius: var(--radius-pill);
  background: var(--surface-selected);
  border: 1px solid var(--border-accent);
  box-shadow: var(--shadow-1);
  opacity: 0;
  transition: transform var(--dur-base) var(--ease-glass);
}

.choice-pair__input:checked ~ .choice-pair__thumb { opacity: 1; }
.choice-pair__input:first-of-type:checked ~ .choice-pair__thumb { transform: translateX(0); }
.choice-pair__input:last-of-type:checked ~ .choice-pair__thumb { transform: translateX(100%); }

/* ── RadioGroup (choice/radio_choice.html) — 세로 리스트 라디오 · dc RadioGroup(plain · 원형 마커 + 부제) ──
   미체크 원 glass-tint-strong+border-strong+glass-edge-sm · 체크 도화 링 + 도화 점(soft-spring). 부제=시간대. */
.radio-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.radio-option {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  cursor: pointer;
}

.radio-option__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.radio-option__marker {
  position: relative;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--glass-tint-strong);
  border: 1px solid var(--border-strong);
  box-shadow: var(--glass-edge-sm);
  transition: var(--transition-control);
}

.radio-option__marker::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%) scale(0);
  transition: transform var(--dur-fast) var(--ease-soft-spring);
}

.radio-option__input:checked + .radio-option__marker {
  border-color: var(--accent);
  box-shadow: var(--focus-ring);
}

.radio-option__input:checked + .radio-option__marker::after { transform: translate(-50%, -50%) scale(1); }

.radio-option__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.radio-option__label {
  font: var(--type-body-sm);
  color: var(--text-primary);
}

.radio-option__desc {
  font: var(--type-caption);
  color: var(--text-tertiary);
}

/* ── Checkbox (field/checkbox_field.html) — 둥근 사각 체크(도화 채움) · dc Checkbox · m9 ──
   미체크 glass-tint-strong+border-strong+glass-edge-sm · 체크 accent 채움 + accent-hover 테두리 + shadow-1 +
   check 글리프(inverse). 전이 --transition-control(m9). 박스 22·글리프 15(round 22×0.68)는 dc 내재 치수. */
.checkbox {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-5);
  cursor: pointer;
}

.checkbox--disabled { opacity: 0.5; cursor: not-allowed; }

.checkbox__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.checkbox__box {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: var(--glass-tint-strong);
  border: 1px solid var(--border-strong);
  box-shadow: var(--glass-edge-sm);
  color: var(--text-inverse);
  transition: var(--transition-control);
}

.checkbox__check {
  font-size: 15px;
  opacity: 0;
}

.checkbox__input:checked + .checkbox__box {
  background: var(--accent);
  border-color: var(--accent-hover);
  box-shadow: var(--shadow-1);
}

.checkbox__input:checked + .checkbox__box .checkbox__check { opacity: 1; }

.checkbox__label {
  font: var(--type-body-sm);
  letter-spacing: var(--ls-body);
  color: var(--text-primary);
}

/* ── SelectField (field/select_field.html) — 커스텀 드롭다운(트리거 button + hidden input + role=menu 팝오버) ──
   §0.5 V6 재현: bundle components/navigation/Dropdown.jsx(variant=field) + components/forms/Select.jsx 정확 인용.
   native <select> → 커스텀 드롭다운 재정의(identity 충실 · 숨은 native mirror 금지). intake user_info 와 공유(§0.5 V6-2).
   닫힘 트리거 = cmDropTrigger.field(h52·pad 0 18px·radius-pill·surface-field·glass-filter-sm·field-dome).
   열림 = surface-field-focus·border-accent·focus-ring+field-flat · chevron rotate(180) · 메뉴 cm-menu-in.
   메뉴 = absolute 글래스 팝오버(dc override surface-solid·max-height 264·glass-filter-lg·radius-lg·shadow-3).
   항목 = 라벨(type-body) + 선택형 description(type-caption) 2줄 + 선택 시 check(accent).
   개폐·바깥클릭/Esc·ArrowUp/Down·선택→hidden input+native change dispatch·overflow 가드 = select_menu.js([data-select-menu] · §6). */
.select-field {
  display: flex;
  flex-direction: column;
  gap: var(--stack-tight);
  width: 100%;
}

.select-field__label {
  font: var(--type-label);
  color: var(--text-secondary);
  padding-left: 4px;
}

/* 트리거+메뉴 앵커(bundle Dropdown wrap div{position:relative}) — 라벨/힌트가 아닌 트리거 기준 팝오버 위치 */
.select-field__control {
  position: relative;
  display: block;
  width: 100%;
}

/* 닫힘 트리거 — cmDropTrigger.field */
.select-field__trigger {
  display: flex;
  align-items: center;
  gap: var(--inline);
  width: 100%;
  height: 52px;
  padding: 0 18px;
  border: 1px solid var(--glass-rim);
  border-radius: var(--radius-pill);
  background: var(--surface-field);
  backdrop-filter: var(--glass-filter-sm);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  box-shadow: var(--field-dome);
  font: var(--type-body);
  letter-spacing: var(--ls-body);
  color: var(--text-primary);
  cursor: pointer;
  transition: var(--transition-control);
}

.select-field__trigger:disabled {
  opacity: 0.42;
  cursor: not-allowed;
}

/* 열림(bundle open) — surface-field-focus · border-accent · focus-ring+field-flat */
.select-field.is-open .select-field__trigger {
  background: var(--surface-field-focus);
  border-color: var(--border-accent);
  box-shadow: var(--focus-ring), var(--field-flat);
}

.select-field--error .select-field__trigger { border-color: var(--danger); }

/* 링 소유권(final.md · check_focus_ring): 트리거가 전역 :focus-visible(--focus-ring · 0,1,0)을 자기 규칙(0,2,0)으로
   덮어 field-flat 과 합쳐 «한 겹»만 낸다(래퍼/안쪽 이중 링 방지 · input/select 선례). */
.select-field__trigger:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring), var(--field-flat);
}

.select-field__face {
  flex: 1;
  min-width: 0;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select-field__face--muted { color: var(--text-placeholder); }

.select-field__chevron {
  flex: none;
  font-size: 18px;
  color: var(--text-tertiary);
  transition: transform var(--dur-base) var(--ease-glass);
}

.select-field.is-open .select-field__chevron { transform: rotate(180deg); }

/* 열림 메뉴(bundle open menu · dc override surface-solid·max-height 264) — 닫힘 기본 hidden(display 미지정 → UA [hidden] 적용) */
.select-field__menu {
  position: absolute;
  z-index: var(--z-menu);
  top: calc(100% + 8px);
  left: 0;
  min-width: 100%;
  max-width: 320px;
  max-height: 264px;
  overflow-y: auto;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  background: var(--surface-solid);
  backdrop-filter: var(--glass-filter-lg);
  -webkit-backdrop-filter: var(--glass-filter-lg);
  border: var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3), var(--glass-edge);
  transform-origin: top left;
  animation: cm-menu-in var(--dur-base) var(--ease-glass);
}

.select-field.is-open .select-field__menu { display: flex; }

/* 커스텀 드롭다운 메뉴 진입(web motion.css 엔 cm-rise 만 존재 → 여기 신규 · 컴포넌트 keyframe 이라 DS명 유지 · §7 m5)
   reduced-motion 은 tokens.css --dur-* → 0ms 전역 가드로 자동 무효. */
@keyframes cm-menu-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* 메뉴 항목 — 라벨 + 선택형 description 2줄(bundle menuitem) */
.select-field__option {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  text-align: left;
  min-height: var(--touch-min);
  padding: 9px 12px;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out);
}

.select-field__option:focus-visible { background: var(--surface-hover); }
@media (hover: hover) and (pointer: fine) {
  .select-field__option:hover:not(:disabled) { background: var(--surface-hover); }
}

.select-field__option:focus-visible { outline: none; box-shadow: none; }

/* 선택 항목은 hover/focus 보다 우선(bundle on ? surface-selected : hot ? surface-hover) — 소스 순서로 승 */
.select-field__option.is-selected { background: var(--surface-selected); }

.select-field__option:disabled {
  opacity: 0.42;
  cursor: not-allowed;
}

.select-field__option-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.select-field__option-label {
  font: var(--type-body);
  letter-spacing: var(--ls-body);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select-field__option-desc {
  font: var(--type-caption);
  color: var(--text-secondary);
}

.select-field__check {
  flex: none;
  font-size: 18px;
  color: var(--accent);
}

.select-field__hint {
  font: var(--type-caption);
  color: var(--text-tertiary);
  padding-left: 4px;
}

.select-field__error {
  font: var(--type-caption);
  color: var(--text-danger);
  padding-left: 4px;
}

/* ── ListRow (row/list_row.html) — 요약 행(제목/부제 + chevron) · dc ListRow · 확인 요약 ──
   tappable(href/hx) 시 hover surface-hover + chevron-right · divider 하단 hairline. 제목 title-3·부제 caption.
   button 모드는 기본 스타일 리셋(테두리·배경·정렬·폭). 확인 요약은 title=값·subtitle=필드명(호출부). */
.list-row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  min-height: calc(var(--touch-min) + 16px);
  padding: 12px var(--space-2);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  text-align: left;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}

.list-row--tappable { cursor: pointer; }
@media (hover: hover) and (pointer: fine) {
  .list-row--tappable:hover { background: var(--surface-hover); }
}

.list-row--divider { border-bottom: 1px solid var(--border-hairline); }

.list-row__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.list-row__title {
  font: var(--type-title-3);
  letter-spacing: var(--ls-title);
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.list-row__subtitle {
  font: var(--type-caption);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.list-row__chevron {
  flex: 0 0 auto;
  color: var(--text-tertiary);
  font-size: 18px;
}

/* ── Toast (feedback/toast_feedback.html) — 떠 있는 글래스 pill(success) · dc Toast · m6 등장 ──
   글래스 tint-strong + filter + border + edge · min-height 48 · 등장 cm-rise(--dur-base ease-out · m6).
   success: check 아이콘 --text-success + 부양 --shadow-success(N). 오버레이 위치는 화면 CSS 소관(슬라이스 5). */
.toast {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 48px;
  padding: 10px 16px;
  border: var(--glass-border);
  border-radius: var(--radius-pill);
  background: var(--glass-tint-strong);
  box-shadow: var(--shadow-3), var(--glass-edge);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  animation: cm-rise var(--dur-base) var(--ease-out) both; /* m6 등장 */
}

.toast[hidden] { display: none; }

.toast__icon {
  flex: 0 0 auto;
  font-size: 18px;
  color: var(--text-primary);
}

.toast__message {
  flex: 1 1 auto;
  font: var(--type-body-sm);
  color: var(--text-primary);
}

.toast--success { box-shadow: var(--shadow-success), var(--glass-edge); }
.toast--success .toast__icon { color: var(--text-success); }
.toast--danger .toast__icon { color: var(--text-danger); }

.toast__action {
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  font: var(--fw-semibold) var(--fs-caption)/1 var(--font-sans);
  color: var(--text-accent);
}

@media (hover: hover) and (pointer: fine) {
  .toast__action:hover:not(:disabled) { color: var(--accent-press); }
}
.toast__action:disabled { cursor: wait; }

/* LoadingOverlay — 계산 요청 동안 프레임을 덮는 글래스 판. */
.loading-overlay {
  position: absolute;
  inset: var(--space-0);
  z-index: var(--z-modal);
  display: none;
  place-items: center;
  padding: var(--gutter);
  background: var(--scrim);
  -webkit-backdrop-filter: var(--scrim-blur);
  backdrop-filter: var(--scrim-blur);
}

.loading-overlay--open,
.loading-overlay.htmx-request { display: grid; }

.loading-overlay__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  min-width: calc(var(--space-12) + var(--space-9));
  padding: var(--space-6) var(--space-7);
  background: var(--glass-tint-sheet);
  -webkit-backdrop-filter: var(--glass-filter-lg);
  backdrop-filter: var(--glass-filter-lg);
  border: var(--glass-border);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-4), var(--glass-edge);
}

.loading-overlay__spinner {
  width: calc(var(--space-8) + var(--space-2));
  height: calc(var(--space-8) + var(--space-2));
  border: var(--space-1) solid var(--track-off);
  border-top-color: var(--accent);
  border-radius: var(--radius-pill);
  animation: chart_spin .72s linear infinite;
}

@keyframes chart_spin {
  to { transform: rotate(360deg); }
}

.loading-overlay__label {
  font: var(--type-caption);
  color: var(--text-secondary);
  text-align: center;
  text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
  .loading-overlay__spinner { animation: none; }
}

/* ── GlassButton 복원(2026-09-08 발주자) — login 레인이 인증 화면에서 제거했으나 intake(사용자 정보 입력) 화면이 「이전」 버튼으로 쓴다. 블록은 f34bbc9a 시점 그대로. ── */
/* ── GlassButton (button/glass_button.html) — DS Button variant=glass ──
   비번찾기 rAtCode «다시 받기»(dc 303 · variant="glass" size="lg" icon-left rotate-ccw). per-kind 관례.
   글래스 스킨: glass-tint-strong 배경 · glass-border 테두리 · glass-edge 그림자 · glass-filter backdrop ·
   radius-button. _ds_bundle 미수집(D14)이라 기존 glass 토큰 재현 → G2 시각 대조. lg 56px. */
.glass-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: var(--glass-border);
  background: var(--glass-tint-strong);
  box-shadow: var(--glass-edge);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  color: var(--text-primary);
  border-radius: var(--radius-button);
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition-control);
}

.glass-button--full { display: flex; width: 100%; }
.glass-button--lg { height: 56px; padding: 0 20px; }
.glass-button--sm {
  position: relative;
  min-height: var(--glass-button-sm-height);
  height: var(--glass-button-sm-height);
  gap: var(--space-3);
  padding: var(--space-0) var(--space-6);
  border-radius: var(--radius-pill);
}
/* md — 시안 Button variant=glass size=md(cmBtnSizes.md: 높이 48 · 좌우 22 · 간격 8 · radius-button · 글 15 · 아이콘 18 —
   _ds_bundle.js:484-491). 유리 층(cmBtnTones.glass · :377-385 · :549-574)은 sm 과 같은 아래 규칙을 함께 쓴다. */
.glass-button--md {
  position: relative;
  height: 48px;
  min-height: 48px;
  gap: var(--space-4);
  padding: var(--space-0) 22px;
  border-radius: var(--radius-button);
}
:is(.glass-button--sm, .glass-button--md) {
  background: transparent;
  box-shadow: var(--shadow-1);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
:is(.glass-button--sm, .glass-button--md)::before {
  content: "";
  position: absolute;
  inset: var(--space-0);
  border-radius: inherit;
  pointer-events: none;
  background: var(--glass-tint);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  -webkit-mask-image: var(--icon-glass-mask);
  mask-image: var(--icon-glass-mask);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.glass-button > i { font-size: var(--icon-size-sm); }
.glass-button--sm > i { position: relative; font-size: var(--fs-body-sm); }
.glass-button--md > i { position: relative; font-size: var(--spacing-icon-18); }

.glass-button__label {
  font-family: var(--font-sans);
  font-weight: var(--fw-medium);
  font-size: var(--fs-body-sm);
  line-height: 1;
  letter-spacing: var(--ls-body);
  white-space: nowrap;
}
.glass-button--sm .glass-button__label {
  position: relative;
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
}
.glass-button--md .glass-button__label {
  position: relative;
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-semibold);
}

@media (hover: hover) and (pointer: fine) {
  .glass-button:hover:not(:disabled) { color: var(--ink-900); transform: translateY(-1px); }
}
.glass-button:active:not(:disabled) { transform: scale(var(--press-scale)); }
.glass-button:disabled { opacity: 0.5; cursor: not-allowed; }
@media (hover: hover) and (pointer: fine) {
  :is(.glass-button--sm, .glass-button--md):hover:not(:disabled) { transform: none; }
}
@media (hover: hover) and (pointer: fine) {
  :is(.glass-button--sm, .glass-button--md):hover:not(:disabled)::before { background: var(--glass-tint-strong); }
}
:is(.glass-button--sm, .glass-button--md):active:not(:disabled) {
  box-shadow: var(--shadow-inset-press);
  transform: scale(var(--press-scale));
}
:is(.glass-button--sm, .glass-button--md):active:not(:disabled)::before { background: var(--glass-tint-press); }
:is(.glass-button--sm, .glass-button--md):disabled { opacity: .42; box-shadow: none; }

/* soft_badge — Badge.jsx soft 원본을 재현하는 공용 분류·상태 부품. */
.soft-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-badge-gap-md);
  height: var(--ds-badge-height-md);
  padding: var(--ds-badge-padding-md);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  border: var(--on-fill-border);
  border-color: transparent;
  font: var(--ds-badge-font-md);
  letter-spacing: var(--ls-body);
}

.soft-badge--neutral {
  background: var(--surface-muted);
  color: var(--text-secondary);
}

.soft-badge--jade {
  background: var(--success-soft);
  color: var(--text-success);
}

.soft-badge--sm {
  gap: var(--ds-badge-gap-sm);
  height: var(--ds-badge-height-sm);
  padding: var(--ds-badge-padding-sm);
  font: var(--ds-badge-font-sm);
}

.soft-badge__icon {
  font-size: var(--ds-badge-icon-md);
}

.soft-badge--sm > .soft-badge__icon {
  font-size: var(--space-5);
}

/* 점쟁이 상세 s5 — 동결 DS의 Badge, Wonbo, SoundToggle과 source-exact IconButton. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-badge-gap-md);
  height: var(--ds-badge-height-md);
  padding: var(--ds-badge-padding-md);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  font: var(--ds-badge-font-md);
  letter-spacing: var(--ls-body);
}

.badge--solid {
  color: var(--text-inverse);
  border: var(--on-fill-border);
}

.badge--solid.badge--seal { background: var(--danger); }
.badge--solid.badge--mist { background: var(--info); }

.badge__icon {
  flex: none;
  font-size: var(--ds-badge-icon-md);
  line-height: inherit;
}

.wonbo {
  display: inline-flex;
  align-items: center;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-body);
  white-space: nowrap;
  vertical-align: middle;
}

.wonbo--sm {
  gap: var(--ds-wonbo-gap-sm);
  font: var(--ds-wonbo-font-sm);
  font-variant-numeric: tabular-nums;
}

/* font 단축이 .wonbo 의 font-variant-numeric 을 초기화하므로 sm · md 모두 font 뒤에 tabular-nums 를 다시 선언한다(ds:869). */
.wonbo--md {
  gap: var(--ds-wonbo-gap-md);
  font: var(--ds-wonbo-font-md);
  font-variant-numeric: tabular-nums;
}

.wonbo--md .wonbo__image {
  width: var(--ds-wonbo-md-width);
}

.wonbo__image {
  display: block;
  flex: none;
  width: var(--ds-wonbo-sm-width);
  aspect-ratio: var(--ds-wonbo-image-ratio);
  object-fit: contain;
}

.wonbo__unit {
  margin-left: var(--ds-wonbo-unit-margin);
  color: var(--text-secondary);
  font-weight: var(--fw-regular);
}

.sound-toggle {
  position: absolute;
  z-index: var(--ds-sound-z-index);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-inverse);
  background: transparent;
  border: var(--ds-sound-border);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-2), var(--glass-edge-sm);
  cursor: pointer;
  transform: none;
  transition: var(--transition-control);
  white-space: nowrap;
}

.sound-toggle--sm {
  right: var(--ds-sound-inset);
  bottom: var(--ds-sound-inset);
  min-width: var(--ds-sound-sm-height);
  height: var(--ds-sound-sm-height);
  padding: var(--ds-sound-muted-padding-sm);
  font: var(--ds-sound-font);
  font-weight: var(--fw-semibold);
}

.sound-toggle--sm[aria-pressed="true"] {
  padding: var(--space-0);
}

.sound-toggle--sm[aria-pressed="true"] .sound-toggle__label {
  display: none;
}

.sound-toggle__glass {
  position: absolute;
  inset: var(--space-0);
  border-radius: inherit;
  background: var(--glass-tint-ink);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  -webkit-mask-image: var(--icon-glass-mask);
  mask-image: var(--icon-glass-mask);
  pointer-events: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .sound-toggle:hover .sound-toggle__glass {
    background: var(--ds-sound-background-hover);
  }
}

.sound-toggle:active:not(:disabled) {
  transform: scale(var(--press-scale));
}

.sound-toggle:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring), var(--shadow-2), var(--glass-edge-sm);
}

.sound-toggle__content {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--ds-sound-gap);
}

.sound-toggle__icon {
  flex: none;
  font-size: var(--ds-sound-icon-sm);
  line-height: inherit;
}

.icon-button--glass.icon-button--source-exact.icon-button--md {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--ds-icon-button-size-md);
  height: var(--ds-icon-button-size-md);
  padding: var(--space-0);
  color: var(--text-primary);
  background: transparent;
  border: var(--glass-border);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-1);
  transform: none;
}

.icon-button--source-exact .icon-button__glass {
  position: absolute;
  inset: var(--space-0);
  border-radius: inherit;
  background: var(--glass-tint);
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
  -webkit-mask-image: var(--icon-glass-mask);
  mask-image: var(--icon-glass-mask);
  pointer-events: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}

.icon-button--source-exact .icon-button__icon {
  position: relative;
  display: flex;
  font-size: var(--ds-icon-button-icon-md);
  line-height: inherit;
}

@media (hover: hover) and (pointer: fine) {
  .icon-button--glass.icon-button--source-exact:hover:not(:disabled) {
    color: var(--text-primary);
    background: transparent;
    transform: none;
  }
}

@media (hover: hover) and (pointer: fine) {
  .icon-button--glass.icon-button--source-exact:hover:not(:disabled) .icon-button__glass {
    background: var(--glass-tint-strong);
  }
}

.icon-button--glass.icon-button--source-exact:active:not(:disabled) {
  background: transparent;
  transform: scale(var(--press-scale));
}

.icon-button--glass.icon-button--source-exact:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring), var(--shadow-1);
}

.icon-button--glass.icon-button--source-exact:disabled {
  opacity: var(--ds-icon-button-disabled-opacity);
  cursor: not-allowed;
}

/* AuraBackground (background/aura_background.html) — 원본 AppFrame 틀 바탕(ds:2214 · tok/colors.css:123-124)과
   aura blob 넷(ds:2276-2296 · 자리 · 크기 = cmAuraBlobs ds:2156-2176 · 채움 ds:2295)을 쓰는 틀 전체를 덮는 한 층으로 그린다.
   원본 aura 층(absolute · inset 0 · z 0 · pointer-events none · overflow hidden)과 같은 층이고, 틀이 칠하던 바탕을
   이 층이 함께 칠한다(첫 자식이 틀 전체를 덮어 같은 칠). 값은 토큰 --aura-background-* 뿐. */
.aura-background {
  position: absolute;
  inset: var(--space-0);
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--aura-background-bg);
}

.aura-background__blob {
  position: absolute;
  border-radius: var(--aura-background-blob-radius);
}

.aura-background__blob--blossom {
  top: var(--aura-background-blob-blossom-top);
  left: var(--aura-background-blob-blossom-left);
  width: var(--aura-background-blob-blossom-size);
  height: var(--aura-background-blob-blossom-size);
  background: var(--aura-background-blob-blossom-fill);
}

.aura-background__blob--gold {
  top: var(--aura-background-blob-gold-top);
  right: var(--aura-background-blob-gold-right);
  width: var(--aura-background-blob-gold-size);
  height: var(--aura-background-blob-gold-size);
  background: var(--aura-background-blob-gold-fill);
}

.aura-background__blob--mist {
  top: var(--aura-background-blob-mist-top);
  left: var(--aura-background-blob-mist-left);
  width: var(--aura-background-blob-mist-size);
  height: var(--aura-background-blob-mist-size);
  background: var(--aura-background-blob-mist-fill);
}

.aura-background__blob--rose {
  top: var(--aura-background-blob-rose-top);
  right: var(--aura-background-blob-rose-right);
  width: var(--aura-background-blob-rose-size);
  height: var(--aura-background-blob-rose-size);
  background: var(--aura-background-blob-rose-fill);
}

/* ChoicePair 버튼 판 (choice/button_pair_choice.html) — 원본 ChoicePair(ds:1577-1702). 트랙 치수 · 테두리 · 바탕 · dome ·
   초점(:focus-within = 버튼 onFocus) · 선택 표시 자리 · 크기는 기반 .choice-pair 규칙과 같아 그대로 받고, 원본과 다른 값만
   여기서 덮는다: 트랙 흐림 glass-filter-sm(ds:1634) · 선택 표시 바탕 accent-soft · 그림자(ds:1652-1654) · 선택 없음에도 첫 칸
   (ds:1599 idx 0) · 둘째 버튼이 골리면 한 칸 미끄러짐(ds:1650 translateX(idx × 100%) · ds:1655 · m22) · 버튼 = 투명 · 테두리 0 ·
   행간 1 · 초점 링 0(트랙이 가짐 · ds:1675-1681) · 글자색 전환(ds:1684). 고르기는 static/js/choice_pair.js 가 aria-checked 로 싣는다. */
.choice-pair--buttons {
  -webkit-backdrop-filter: var(--glass-filter-sm);
  backdrop-filter: var(--glass-filter-sm);
}

.choice-pair--buttons .choice-pair__thumb {
  background: var(--accent-soft);
  box-shadow: var(--choice-pair-buttons-thumb-shadow);
  opacity: 1;
  transition: transform var(--dur-base) var(--ease-glass);
}

.choice-pair--buttons:has(> .choice-pair__option:nth-of-type(2)[aria-checked="true"]) .choice-pair__thumb {
  transform: translateX(100%);
}

.choice-pair--buttons .choice-pair__option {
  gap: var(--space-3);
  border: 0;
  background: transparent;
  font: var(--fw-regular) var(--fs-body)/1 var(--font-sans);
  letter-spacing: var(--ls-body);
  transition: color var(--dur-fast) var(--ease-out);
}

.choice-pair--buttons .choice-pair__option:focus-visible {
  outline: none;
  box-shadow: none;
}

.choice-pair--buttons .choice-pair__option[aria-checked="true"] {
  font-weight: var(--fw-semibold);
  color: var(--text-accent);
}
