/* color */
:root {
    /* surface alias — 라이트·다크 모두 --bp-bg-surface 로 자동 정렬
     * (기존 --white = #fff / 다크 #1a1a2e 보라끼 제거) */
    --white: var(--bp-bg-surface);
    --black: #000;
    --wblack: #080808;
    
    /* gray */
    --gray-50: #F2F2F2;
    --gray-100: #D9D9D9;
    --gray-200: #BFBFBF;
    --gray-300: #A6A6A6;
    --gray-400: #8C8C8C;
    --gray-500: #737373;
    --gray-600: #636363;
    --gray-700: #545454;
    --gray-800: #454545;
    --gray-900: #363636;
    --gray-950: #262626;

    /* primary — BPack Deep Teal (디자인 가이드 정렬) */
    --primary-50:  #E7F3F2;
    --primary-100: #C5E2E0;
    --primary-200: #9FCEC9;
    --primary-300: #75B9B1;
    --primary-400: #4B9F95;
    --primary-500: #0B4F4A;   /* Deep Teal — main */
    --primary-600: #094340;
    --primary-700: #073735;
    --primary-800: #052B29;
    --primary-900: #041F1E;
    --primary-950: #021312;
    --primary-op-01: rgba(11, 79, 74, 0.08);
    --primary-op-02: rgba(11, 79, 74, 0.16);
    --primary-op-03: rgba(11, 79, 74, 0.20);
    --primary-op-04: rgba(11, 79, 74, 0.30);
    --primary-op-05: rgba(11, 79, 74, 0.50);

    /* neutrals */
    --neutrals-50: #F9FAFB;
    --neutrals-100: #F0F3F9;
    --neutrals-200: #E9EFF6;
    --neutrals-300: #D7DFE9;
    --neutrals-400: #AFBACA;
    --neutrals-500: #8897AE;
    --neutrals-600: #5E718D;
    --neutrals-700: #455468;
    --neutrals-800: #3D4A5C;
    --neutrals-900: #2D3643;
    --neutrals-950: #0A0C11;
    --neutrals-op-01: rgba(61, 74, 92, 0.08);
    --neutrals-op-02: rgba(61, 74, 92, 0.16);
    --neutrals-op-03: rgba(61, 74, 92, 0.2);
    --neutrals-op-04: rgba(61, 74, 92, 0.3);
    --neutrals-op-05: rgba(61, 74, 92, 0.5);

    /* success */
    --success-50: #F6FEEC;
    --success-100: #EBFCD5;
    --success-200: #D4F9AC;
    --success-300: #B1EE80;
    --success-400: #8FDE5D;
    --success-500: #5FC92E;
    --success-600: #44AC21;
    --success-700: #2D9017;
    --success-800: #1A740E;
    --success-900: #1A740E;
    --success-950: #184616;
    --success-op-01: rgba(26, 116, 14, 0.08);
    --success-op-02: rgba(26, 116, 14, 0.16);
    --success-op-03: rgba(26, 116, 14, 0.2);
    --success-op-04: rgba(26, 116, 14, 0.3);
    --success-op-05: rgba(26, 116, 14, 0.5);

    /* info */
    --info-50: #EBF3FF;
    --info-100: #CDE2FE;
    --info-200: #A7C9FD;
    --info-300: #7BA8F9;
    --info-400: #598CF4;
    --info-500: #2561ED;
    --info-600: #1B4ACB;
    --info-700: #1236AA;
    --info-800: #0B2589;
    --info-900: #071971;
    --info-950: #040F43;
    --info-op-01: rgba(11, 37, 137, 0.08);
    --info-op-02: rgba(11, 37, 137, 0.16);
    --info-op-03: rgba(11, 37, 137, 0.2);
    --info-op-04: rgba(11, 37, 137, 0.3);
    --info-op-05: rgba(11, 37, 137, 0.5);

    /* warning */
    --warning-50: #FEF5E6;
    --warning-100: #FEEAC8;
    --warning-200: #FDE0AF;
    --warning-300: #FDD491;
    --warning-400: #FCC873;
    --warning-500: #FBBC55;
    --warning-600: #E9A23B;
    --warning-700: #C8811A;
    --warning-800: #C8811A;
    --warning-900: #8B4400;
    --warning-950: #572A00;
    --warning-op-01: rgba(163, 92, 0, 0.08);
    --warning-op-02: rgba(163, 92, 0, 0.16);
    --warning-op-03: rgba(163, 92, 0, 0.2);
    --warning-op-04: rgba(163, 92, 0, 0.3);
    --warning-op-05: rgba(163, 92, 0, 0.5);

    /* error */
    --error-50: #FDF1F1;
    --error-100: #FBDDDD;
    --error-200: #F7BBBB;
    --error-300: #F29899;
    --error-400: #EE7677;
    --error-500: #EA5455;
    --error-600: #E24445;
    --error-700: #BF1719;
    --error-800: #921213;
    --error-900: #640C0D;
    --error-950: #370707;
    --error-op-01: rgba(146, 18, 19, 0.08);
    --error-op-02: rgba(146, 18, 19, 0.16);
    --error-op-03: rgba(146, 18, 19, 0.2);
    --error-op-04: rgba(146, 18, 19, 0.3);
    --error-op-05: rgba(146, 18, 19, 0.5);

    /* orange */
    --orange-50: #FFF7ED;
    --orange-100: #FFEDD5;
    --orange-200: #FED7AA;
    --orange-300: #FEBA73;
    --orange-400: #FC933B;
    --orange-500: #FA7415;
    --orange-600: #EA580B;
    --orange-700: #C3420B;
    --orange-800: #9B3411;
    --orange-900: #7C2D12;
    --orange-950: #431407;

    /* fuchsia */
    --fuchsia-50: #FEF4FF;
    --fuchsia-100: #FCE8FF;
    --fuchsia-200: #F8D0FE;
    --fuchsia-300: #F1ABFC;
    --fuchsia-400: #E879F9;
    --fuchsia-500: #D946EF;
    --fuchsia-600: #BC26D3;
    --fuchsia-700: #BC26D3;
    --fuchsia-800: #80198F;
    --fuchsia-900: #691A75;
    --fuchsia-950: #44044E;

    /* purple */
    --purple-50: #F7F3FF;
    --purple-100: #EFE9FE;
    --purple-200: #E2D6FE;
    --purple-300: #CBB5FD;
    --purple-400: #AD8BFA;
    --purple-500: #8B5CF6;
    --purple-600: #713AED;
    --purple-700: #5E28D9;
    --purple-800: #4E21B6;
    --purple-900: #421D95;
    --purple-950: #2A1065;
    --purple-op-01: rgba(94, 40, 217, 0.08);
    --purple-op-02: rgba(94, 40, 217, 0.16);
    --purple-op-03: rgba(94, 40, 217, 0.2);

    /* lilac */
    --lilac-50: #EEEEFF;
    --lilac-100: #E0E1FF;
    --lilac-200: #C7C8FE;
    --lilac-300: #A5A7FC;
    --lilac-400: #8184F8;
    --lilac-500: #6366F1;
    --lilac-600: #4649E5;
    --lilac-700: #383BCA;
    --lilac-800: #3032A3;
    --lilac-900: #2E3081;
    --lilac-950: #1B1C4B;

    /* pink */
    --pink-50: #FDF2F8;
    --pink-100: #FCE7F3;
    --pink-200: #FBCFE8;
    --pink-300: #F9A8D4;
    --pink-400: #F373B6;
    --pink-500: #EB4899;
    --pink-600: #DA2878;
    --pink-700: #BD195D;
    --pink-800: #9C184D;
    --pink-900: #821943;
    --pink-950: #500724;

}

:root{
  color-scheme: light;
  --bp-font-primary: 'Pretendard';
  --text: var(--gray-900);
  --border-100: 1px solid var(--neutrals-100);
  --border-200: 1px solid var(--neutrals-200);
  --border-300: 1px solid var(--neutrals-300);
  --bg-hover: var(--neutrals-100);
  --disabled: var(--gray-300);

  /* 입력 컴포넌트 기본 높이 (md). 사이즈별 높이는 5-tier 토큰(--bp-h-xs..xl) 사용.
     legacy 7-tier 높이 토큰(--bp-input-height-*/--bp-btn-height-*)은 제거됨. */
  --bp-input-height:    40px;

  /* 시맨틱 토큰 */
  --bg-surface: var(--white);
  --bg-page: var(--neutrals-50);
  --bg-elevated: var(--white);
  --bg-overlay: rgba(0, 0, 0, 0.10);
  --text-primary: var(--gray-900);
  --text-secondary: var(--neutrals-700);
  --text-tertiary: var(--neutrals-500);
  --text-disabled: var(--gray-300);
  --text-inverse: var(--white);
  --border-default: var(--neutrals-300);
  --border-light: var(--neutrals-100);
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
  --shadow-md: 0 4px 6px rgba(0,0,0,0.07);
  --shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}

/* 폰트 선택 */
[data-font="pretendard"] { --bp-font-primary: 'Pretendard'; }
[data-font="d2coding"] { --bp-font-primary: 'D2Coding'; }
[data-font="nanumgothiccoding"] { --bp-font-primary: 'NanumGothicCoding'; }

/* 다크 모드 */
[data-theme="dark"] {
  color-scheme: dark;
  /* --white 는 :root 에서 var(--bp-bg-surface) 로 이미 alias.
   * 라이트 = #FFFFFF, 다크 = #1A1D23 자동 적용. */
  --black: #f0f0f0;
  --wblack: #e8e8e8;

  /* gray 반전 */
  --gray-50: #262626;
  --gray-100: #363636;
  --gray-200: #454545;
  --gray-300: #545454;
  --gray-400: #636363;
  --gray-500: #737373;
  --gray-600: #8C8C8C;
  --gray-700: #A6A6A6;
  --gray-800: #BFBFBF;
  --gray-900: #D9D9D9;
  --gray-950: #F2F2F2;

  /* neutrals 반전 */
  --neutrals-50: #0A0C11;
  --neutrals-100: #2D3643;
  --neutrals-200: #3D4A5C;
  --neutrals-300: #455468;
  --neutrals-400: #5E718D;
  --neutrals-500: #8897AE;
  --neutrals-600: #AFBACA;
  --neutrals-700: #D7DFE9;
  --neutrals-800: #E9EFF6;
  --neutrals-900: #F0F3F9;
  --neutrals-950: #F9FAFB;
  --neutrals-op-01: rgba(200, 215, 235, 0.08);
  --neutrals-op-02: rgba(200, 215, 235, 0.16);
  --neutrals-op-03: rgba(200, 215, 235, 0.2);
  --neutrals-op-04: rgba(200, 215, 235, 0.3);
  --neutrals-op-05: rgba(200, 215, 235, 0.5);

  /* success */
  --success-50: #184616;
  --success-100: #1A740E;
  --success-200: #1A740E;

  /* info */
  --info-50: #040F43;
  --info-100: #071971;

  /* warning */
  --warning-50: #572A00;
  --warning-100: #8B4400;

  /* purple */
  --purple-50: #1E0A3C;
  --purple-100: #2D1065;

  /* error */
  --error-50: #370707;
  --error-100: #640C0D;
  --error-200: #921213;

  /* 시맨틱 토큰 오버라이드 · 디자인 가이드 (중성 Slate) 와 정렬 */
  --bg-surface: #1A1D23;      /* 보라끼 제거 · --bp-bg-surface 와 동일 */
  --bg-page: #0F1115;         /* was #0f0f1a → 디자인 가이드 정렬 */
  --bg-elevated: #222831;     /* was #252540 → 디자인 가이드 정렬 */
  --bg-overlay: rgba(0, 0, 0, 0.50);
  --text-primary: #E9EEF6;    /* was #e8e8e8 → --bp-text-primary 정렬 */
  --text-secondary: #AFBACA;
  --text-tertiary:  #8897AE;
  --text-disabled:  #5E718D;
  --text-inverse:   #0F1115;
  --border-default: #2D3643;
  --border-light:   #222831;
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
  --shadow-md: 0 4px 8px -2px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 12px 24px -6px rgba(0, 0, 0, 0.5);
}

/* --- badge --- */
.bp-badge{
    width: fit-content;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    font-weight: 400;
}
.bp-badge.bp-sm{
    padding: 0 6px;
    height: 12px;
    font-size: 14px;
}
.bp-badge.bp-md{
    padding: 0 6px;
    height: 22px;
    font-size: 14px;
}
.bp-badge.bp-lg{
    padding: 0 10px;
    height: 30px;
    font-size: 16px;
}
.bp-badge.bp-primary, .bp-badge.bp-secondary, .bp-badge.bp-success, .bp-badge.bp-info, .bp-badge.bp-warning, .bp-badge.bp-error, .bp-badge.bp-gray{
    color: var(--bp-neutral-0) !important;
}
.bp-badge.bp-gray{
    background-color: var(--bp-surface-track);
}

/* --- btn --- */
.bp-btn{
  position:relative;
  border-radius: var(--bp-radius-sm);
  display:flex;
  align-items:center;
  justify-content:center;
  overflow:hidden;
  outline:none;
  background:transparent;
  border:none;
  color: var(--bp-neutral-0);
  cursor:pointer;
  transition: background-color 300ms;
}
.bp-btn .bi::before{
  vertical-align: middle;
}

/* 버튼 사이즈는 5-tier(.bp-xs/sm/md/lg/xl) 단일 기준 — 아래 'Button alias' 블록 참조.
   legacy 7-tier(.bp-t/es/s/m/l/el/b) 는 제거됨(입력 호환은 C# BpSize.Normalize 에서 처리). */
.bp-btn:disabled{
    cursor:default;
    pointer-events:none;
}
.bp-btn[class*="-outline"]{
    border-width: 1px;
    border-style: solid;
    background-color: var(--bp-bg-surface);
}
.bp-btn .bp-btn-text{
    white-space: nowrap;
    color: inherit;    /* 부모 .bp-btn 의 variant 색 상속 — 모달 등 외부 p 규칙 차단 */
}
.bp-btn i{
    font-size: 24px;
}
.bp-btn i:not(:last-child){ 
    margin-right:4px;
}
.bp-btn i:not(:first-child){
    margin-left:4px;
}
.bp-btn.bp-round{
    border-radius: 50%;
}

/* icon */
.bp-btn.bp-i{
    padding: 0;
}
/* 아이콘 전용/아이콘 크기도 5-tier 'Button alias' 블록에서 처리. */

/* ripple */
.bp-btn::before{
  content:""; position:absolute; inset:auto;
  opacity:0; padding:350% 0 0 350%; margin:-120% 0 0 -50%;
  transition:all 1000ms; border-radius:9999px;
}
.bp-btn:active::before{ opacity:1; padding:0; margin:0; transition-duration:0s; }

/* color */
/* primary */
.bp-primary{
    background-color: var(--bp-primary-500);
}
.bp-btn.bp-primary:hover{
    background-color: var(--bp-primary-600);
}
.bp-btn.bp-primary:active{
    background-color: var(--bp-primary-700);
} 
.bp-btn.bp-primary:disabled{
    background-color: var(--bp-primary-500);
    color: var(--bp-neutral-0);
    opacity: 0.4;
}
/* .bp-primary::before{ background:#ffffff8f; } */
/* primary-outline */
/* 팔레트(--bp-primary-500)가 아니라 **시맨틱**(--bp-*-brand)을 든다.
   팔레트는 다크 재정의가 없어 #0B4F4A 가 그대로 남고, #1A1D23 위에서 1.79 —
   비활성(2.19)보다 흐려 순서가 뒤집혔다(HR-DGW-001). 시맨틱은 다크에서
   --bp-primary-400 이라 5.38 이 된다. **라이트는 두 값이 같아 변화가 없다.**
   상태 표시는 배경 워시가 맡는다 — 글자·테두리를 어둡히면 다크에서 다시 묻힌다. */
.bp-primary-outline{
    border-color: var(--bp-border-brand);
    color: var(--bp-text-brand);
}
.bp-btn.bp-primary-outline:hover{
    border-color: var(--bp-border-brand);
    background-color: var(--bp-primary-op-01);
    color: var(--bp-text-brand);
}
.bp-btn.bp-primary-outline:active{
    border-color: var(--bp-border-brand);
    background-color: var(--bp-primary-op-02);
    color: var(--bp-text-brand);
}
/* 비활성은 브랜드색을 쓰지 않는다 — --bp-primary-* 팔레트는 다크 재정의가 없어
   다크에서 #9FCEC9(9.76)로 **활성(5.38)보다 도드라진다**. secondary-outline 과 같은
   중립 토큰을 쓰면 두 테마에서 다 죽는다(라이트 1.34 · 다크 2.19). */
.bp-btn.bp-primary-outline:disabled{
    border-color: var(--bp-surface-track);
    color: var(--bp-surface-track);
}
/* secondary — 다크 슬레이트 (디자인 가이드 .btn-secondary 기준).
   --bp-neutral-* 는 라이트/다크 공통(불변) 스케일이라 양쪽 테마에서 동일한 슬레이트로 렌더된다. */
.bp-secondary{
    background-color: var(--bp-neutral-700);
}
.bp-btn.bp-secondary:hover{
    background-color: var(--bp-neutral-800);
}
.bp-btn.bp-secondary:active{
    background-color: var(--bp-neutral-900);
}
.bp-btn.bp-secondary:disabled{
    background-color: var(--bp-neutral-700);
    color: var(--bp-neutral-0);
    opacity: 0.4;
}
/* secondary-outline */
.bp-secondary-outline{
    border-color: var(--bp-neutral-500);;
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-outline:hover{
    border-color: var(--bp-text-secondary);
    background-color: var(--bp-overlay-hover);
    color: var(--bp-ink-strong);
}
.bp-btn.bp-secondary-outline:active{
    border-color: var(--bp-ink-body);
    background-color: var(--bp-overlay-active);
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-outline:disabled{ 
    border-color: var(--bp-surface-track);
    color: var(--bp-surface-track);
}
/* secondary-outline_icon only */
.bp-secondary-outline:has(> i:only-child){
    border-color: var(--bp-surface-track);;
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-outline:hover{
    border-color: var(--bp-text-disabled);
    background-color: var(--bp-overlay-hover);
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-outline:active{
    border-color: var(--bp-text-disabled);
    background-color: var(--bp-overlay-active);
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-outline:disabled{ 
    border-color: var(--bp-surface-track);
    color: var(--bp-surface-track);
}
/* error */
.bp-error{
    background-color: var(--bp-error-solid);
    color: var(--bp-error-on);
}
.bp-btn.bp-error:hover{
    background-color: var(--bp-error-solid-hover);
}
.bp-btn.bp-error:active{
    background-color: var(--bp-error-solid-active);
} 
.bp-btn.bp-error:disabled{
    background-color: var(--bp-error-200);
}
/* error-outline */
.bp-error-outline{
    border-color: var(--bp-error-fg);
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-outline:hover{
    border-color: var(--bp-error-fg);
    background-color: var(--bp-error-op-01);
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-outline:active{
    border-color: var(--bp-error-fg);
    background-color: var(--bp-error-op-02);
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-outline:disabled{ 
    border-color: var(--bp-error-200);
    color: var(--bp-error-200);
}
/* success */
.bp-success{
    background-color: var(--bp-success-solid);
    color: var(--bp-success-on);
}
.bp-btn.bp-success:hover{
    background-color: var(--bp-success-solid-hover);
}
.bp-btn.bp-success:active{
    background-color: var(--bp-success-solid-active);
} 
.bp-btn.bp-success:disabled{
    background-color: var(--bp-success-200);
}
/* success-outline */
.bp-success-outline{
    border-color: var(--bp-success-fg);
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-outline:hover{
    border-color: var(--bp-success-fg);
    background-color: var(--bp-success-op-01);
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-outline:active{
    border-color: var(--bp-success-fg);
    background-color: var(--bp-success-op-02);
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-outline:disabled{ 
    border-color: var(--bp-success-200);
    color: var(--bp-success-200);
}

/* warning */
.bp-warning{
    background-color: var(--bp-warning-solid);
    color: var(--bp-warning-on);
}
.bp-btn.bp-warning:hover{
    background-color: var(--bp-warning-solid-hover);
}
.bp-btn.bp-warning:active{
    background-color: var(--bp-warning-solid-active);
} 
.bp-btn.bp-warning:disabled{
    background-color: var(--bp-warning-200);
}
/* info */
.bp-info{
    background-color: var(--bp-info-solid);
    color: var(--bp-info-on);
}
/* info 채움에는 hover/active 규칙이 아예 없어 상호작용 피드백이 없었다. */
.bp-btn.bp-info:hover{
    background-color: var(--bp-info-solid-hover);
}
.bp-btn.bp-info:active{
    background-color: var(--bp-info-solid-active);
}
/* gray */
.bp-gray{
    background-color: var(--bp-surface-track);
}
/* warning-outline */
.bp-warning-outline{
    border-color: var(--bp-warning-fg);
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-outline:hover{
    border-color: var(--bp-warning-fg);
    background-color: var(--bp-warning-op-01);
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-outline:active{
    border-color: var(--bp-warning-fg);
    background-color: var(--bp-warning-op-02);
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-outline:disabled{
    border-color: var(--bp-warning-200);
    color: var(--bp-warning-200);
}
/* info-outline */
.bp-info-outline{
    border-color: var(--bp-info-fg);
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-outline:hover{
    border-color: var(--bp-info-fg);
    background-color: var(--bp-info-op-01);
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-outline:active{
    border-color: var(--bp-info-fg);
    background-color: var(--bp-info-op-02);
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-outline:disabled{
    border-color: var(--bp-info-200);
    color: var(--bp-info-200);
}
/* gray-outline */
.bp-gray-outline{
    border-color: var(--bp-text-disabled);
    color: var(--bp-text-secondary);
}
.bp-btn.bp-gray-outline:hover{
    border-color: var(--bp-neutral-500);
    background-color: var(--bp-overlay-hover, rgba(107, 114, 128, 0.08));
    color: var(--bp-ink-body);
}
.bp-btn.bp-gray-outline:active{
    border-color: var(--bp-text-secondary);
    background-color: var(--bp-overlay-active, rgba(107, 114, 128, 0.16));
    color: var(--bp-ink-strong);
}
.bp-btn.bp-gray-outline:disabled{
    border-color: var(--bp-surface-raised);
    color: var(--bp-surface-raised);
}
/* primary-light */
/* 배경을 --bp-primary-50 (다크 재정의 없는 팔레트) 대신 surface 와 섞는다 —
   그러면 다크에서도 면이 어두워져 hover/active 사다리와 어긋나지 않는다. */
.bp-primary-light{
    background-color: color-mix(in srgb, var(--bp-primary-500) 8%, var(--bp-bg-surface));
    color: var(--bp-primary-fg);
}
/* hover/active 에서 글자색을 바꾸지 않는다 — 다크에서 primary-600/700 은 배경(밝은
   --bp-primary-50)과 붙어 hover 1.47 · active 1.20 으로 글자가 사라졌다. */
.bp-btn.bp-primary-light:hover{
    background-color: color-mix(in srgb, var(--bp-primary-500) 14%, var(--bp-bg-surface));
    color: var(--bp-primary-fg);
}
.bp-btn.bp-primary-light:active{
    background-color: color-mix(in srgb, var(--bp-primary-500) 20%, var(--bp-bg-surface));
    color: var(--bp-primary-fg);
}
.bp-btn.bp-primary-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-surface-track);
}
/* secondary-light */
.bp-secondary-light{
    background-color: var(--bp-surface-faint);
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-light:hover{
    background-color: var(--bp-overlay-hover);
    color: var(--bp-ink-strong);
}
.bp-btn.bp-secondary-light:active{
    background-color: var(--bp-overlay-active);
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-surface-track);
}
/* error-light */
.bp-error-light{
    background-color: var(--bp-error-50);
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-light:hover{
    background-color: color-mix(in srgb, var(--bp-error) 14%, var(--bp-bg-surface));
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-light:active{
    background-color: color-mix(in srgb, var(--bp-error) 20%, var(--bp-bg-surface));
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-error-200);
}
/* success-light */
.bp-success-light{
    background-color: var(--bp-success-50);
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-light:hover{
    background-color: color-mix(in srgb, var(--bp-success) 14%, var(--bp-bg-surface));
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-light:active{
    background-color: color-mix(in srgb, var(--bp-success) 20%, var(--bp-bg-surface));
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-success-200);
}
/* warning-light */
.bp-warning-light{
    background-color: var(--bp-warning-50);
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-light:hover{
    background-color: color-mix(in srgb, var(--bp-warning) 14%, var(--bp-bg-surface));
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-light:active{
    background-color: color-mix(in srgb, var(--bp-warning) 20%, var(--bp-bg-surface));
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-warning-200);
}
/* info-light · accent-light — 규칙이 없어 .bp-btn 기본(흰 글자+투명)만 남았고
   라이트에서 대비 1.00 이었다(RVW-TSK-F08-001-R1 [중대-2]).
   ButtonDoc 은 색상 8종 × 수식어 3종을 유효 조합으로 안내한다 — 문서와 CSS 를 맞춘다. */
.bp-info-light{
    background-color: var(--bp-info-50);
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-light:hover{
    background-color: color-mix(in srgb, var(--bp-info) 14%, var(--bp-bg-surface));
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-light:active{
    background-color: color-mix(in srgb, var(--bp-info) 20%, var(--bp-bg-surface));
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-info-200);
}
/* 배경에 --bp-accent-50 을 쓰면 안 된다 — 다크 재정의가 없어 밝은 크림이 그대로 남고
   그 위에 밝은 accent-fg 가 얹혀 다크에서 1.61 이 된다. 투명 워시는 두 테마에서 다 맞다. */
.bp-accent-light{
    background-color: color-mix(in srgb, var(--bp-accent-500) 8%, var(--bp-bg-surface));
    color: var(--bp-accent-fg);
}
.bp-btn.bp-accent-light:hover{
    background-color: color-mix(in srgb, var(--bp-accent-500) 14%, var(--bp-bg-surface));
    color: var(--bp-accent-fg);
}
.bp-btn.bp-accent-light:active{
    background-color: color-mix(in srgb, var(--bp-accent-500) 20%, var(--bp-bg-surface));
    color: var(--bp-accent-fg);
}
.bp-btn.bp-accent-light:disabled{
    background-color: var(--bp-bg-surface);
    color: var(--bp-surface-track);
}
/* primary-ghost => icon only */
/* ghost 도 같은 이유 — 투명 배경이라 다크에서 그대로 묻힌다. */
.bp-primary-ghost{
    color: var(--bp-text-brand);
}
.bp-btn.bp-primary-ghost:hover{
    background-color: var(--bp-primary-op-01);
}
.bp-btn.bp-primary-ghost:active{
    background-color: var(--bp-primary-op-02);
}
.bp-btn.bp-primary-ghost:disabled{
    color: var(--bp-surface-track);
}
/* secondary-ghost => icon only */
.bp-secondary-ghost{
    color: var(--bp-ink-body);
}
.bp-btn.bp-secondary-ghost:hover{
    background-color: var(--bp-overlay-hover);
}
.bp-btn.bp-secondary-ghost:active{
    background-color: var(--bp-overlay-active);
}
.bp-btn.bp-secondary-ghost:disabled{
    color: var(--bp-surface-track);
}
/* success-ghost => icon only */
.bp-success-ghost{
    color: var(--bp-success-fg);
}
.bp-btn.bp-success-ghost:hover{
    background-color: var(--bp-success-op-01);
}
.bp-btn.bp-success-ghost:active{
    background-color: var(--bp-success-op-02);
}
.bp-btn.bp-success-ghost:disabled{
    color: var(--bp-success-100);
}
/* warning-ghost => icon only */
.bp-warning-ghost{
    color: var(--bp-warning-fg);
}
.bp-btn.bp-warning-ghost:hover{
    background-color: var(--bp-warning-op-01);
}
.bp-btn.bp-warning-ghost:active{
    background-color: var(--bp-warning-op-02);
}
.bp-btn.bp-warning-ghost:disabled{
    color: var(--bp-warning-100);
}
/* error-ghost => icon only */
.bp-error-ghost{
    color: var(--bp-error-fg);
}
.bp-btn.bp-error-ghost:hover{
    background-color: var(--bp-error-op-01);
}
.bp-btn.bp-error-ghost:active{
    background-color: var(--bp-error-op-02);
}
.bp-btn.bp-error-ghost:disabled{
    color: var(--bp-error-100);
}
/* info-ghost · accent-ghost — 위와 같은 이유로 빠져 있었다. */
.bp-info-ghost{
    color: var(--bp-info-fg);
}
.bp-btn.bp-info-ghost:hover{
    background-color: var(--bp-info-op-01);
}
.bp-btn.bp-info-ghost:active{
    background-color: var(--bp-info-op-02);
}
.bp-btn.bp-info-ghost:disabled{
    color: var(--bp-info-100);
}
.bp-accent-ghost{
    color: var(--bp-accent-fg);
}
.bp-btn.bp-accent-ghost:hover{
    background-color: var(--bp-accent-op-01);
}
.bp-btn.bp-accent-ghost:active{
    background-color: var(--bp-accent-op-02);
}
.bp-btn.bp-accent-ghost:disabled{
    color: var(--bp-surface-track);
}

/* ═══════════════════════════════════════════════════════════════
 * BPack Design System Tokens · v0.3 (2026-04-19)
 *
 * docs/01-company/design-guide/styles.css 의 :root 블록과 동기화된 새 토큰들.
 * 기존 변수(--primary-*, --neutrals-*, --bg-surface 등)는 그대로 유지되어
 * 기존 컴포넌트 CSS 호환성이 보장된다.
 *
 * Phase 2~7 에서 각 컴포넌트 CSS 를 점진적으로 `--bp-*` 시맨틱 토큰 참조로
 * 전환한다. 원칙은 `docs/04-technical/bp-components-migration-plan.md` 참조.
 * ═══════════════════════════════════════════════════════════════ */
:root {
  /* ── Brand scale (11-step) ── */
  --bp-primary-50:  #E7F3F2;
  --bp-primary-100: #C5E2E0;
  --bp-primary-200: #9FCEC9;
  --bp-primary-300: #75B9B1;
  --bp-primary-400: #4B9F95;
  --bp-primary-500: #0B4F4A;   /* Deep Teal — main */
  --bp-primary-600: #094340;
  --bp-primary-700: #073735;
  --bp-primary-800: #052B29;
  --bp-primary-900: #041F1E;
  --bp-primary-950: #021312;

  --bp-accent-50:  #FFFBEB;
  --bp-accent-100: #FEF3C7;
  --bp-accent-200: #FDE68A;
  --bp-accent-300: #FCD34D;
  --bp-accent-400: #FBBF24;
  --bp-accent-500: #F59E0B;    /* Signal Amber — main */
  --bp-accent-600: #D97706;
  --bp-accent-700: #B45309;
  --bp-accent-800: #92400E;
  --bp-accent-900: #78350F;
  --bp-accent-950: #451A03;

  /* ── Neutral scale ── */
  --bp-neutral-0:   #FFFFFF;
  --bp-neutral-50:  #F9FAFB;
  --bp-neutral-100: #F0F3F9;
  --bp-neutral-200: #E5E9F0;   /* Mist */
  --bp-neutral-300: #D7DFE9;
  --bp-neutral-400: #AFBACA;
  --bp-neutral-500: #8897AE;
  --bp-neutral-600: #5E718D;
  --bp-neutral-700: #455468;
  --bp-neutral-800: #3D4A5C;
  --bp-neutral-900: #2E3440;   /* Slate / Ink */
  --bp-neutral-950: #1B2028;

  /* ── Status ── */
  --bp-success: #2FB380;
  --bp-warning: #F6B94C;
  --bp-error:   #E0443E;
  --bp-info:    #3B82F6;

  /* ── 시맨틱 토큰 (bp-* prefix) ── */
  --bp-bg-page:      var(--bp-neutral-100);
  --bp-bg-surface:   var(--bp-neutral-0);
  --bp-bg-elevated:  var(--bp-neutral-0);
  --bp-bg-muted:     var(--bp-neutral-50);
  --bp-bg-overlay:   rgba(11, 79, 74, 0.04);

  --bp-text-primary:   var(--bp-neutral-900);
  --bp-text-secondary: var(--bp-neutral-600);
  --bp-text-tertiary:  var(--bp-neutral-500);
  --bp-text-disabled:  var(--bp-neutral-400);
  --bp-text-inverse:   var(--bp-neutral-0);
  --bp-text-brand:     var(--bp-primary-500);

  --bp-border-default: var(--bp-neutral-300);
  --bp-border-light:   var(--bp-neutral-200);
  --bp-border-strong:  var(--bp-neutral-400);
  --bp-border-brand:   var(--bp-primary-500);

  /* ── 상호작용 워시 · 컴포넌트 면 (라이트) ──
   * F04: legacy --neutrals-op-* / --gray-900 이 담당하던 자리를 --bp-* 로 옮긴 것.
   * 값은 옮기기 전과 동일하다(시각 변화 0). 스킨은 이 4개만 덮으면 된다. */
  /* ── 브랜드 자산 (F06) ──
   * 스킨이 로고를 바꾸는 자리. 기본값은 none/inline 이라 건드리지 않으면 지금과 같다.
   *   --bp-brand-mark            마크 이미지. url(...) 을 주면 그것이 뜬다
   *   --bp-brand-default-display  기본 BPackCore 마크의 표시 여부. 스킨이 none 으로 끈다
   *   --bp-brand-mark-bg         마크 뒤 바탕. 헤더용.
   * 이 셋만 넣으면 로딩·재접속·헤더 마크가 함께 바뀐다.
   *
   * 바탕이 왜 필요한가: 로딩의 마크는 회전하는 사각형 **위에** 얹히므로 글리프만
   * 있으면 되지만, 헤더의 마크는 맨 바탕에 놓인다. 그래서 흰 글리프 하나로 두 자리를
   * 다 쓰려면 헤더 쪽에만 바탕이 있어야 한다. 기본은 transparent 라 무변화. */
  --bp-brand-mark:           none;
  --bp-brand-default-display: block;
  --bp-brand-mark-bg:        transparent;

  --bp-surface-faint:  #F9FAFB;   /* 가장 옅은 면 — legacy --neutrals-50 에서 옮김 */
  --bp-status-normal:  #52C41A;   /* 알람 '정상' — legacy --green-500 에서 옮김 */
  --bp-text-on-fill:   #FFFFFF;   /* 채워진 면 위 글자 — legacy --white 의 색상 용도 */

  /* ── 상태색 스케일 · 투명도 변형 ──
   * F05: **단일 토큰(--bp-error 등)에서 파생**한다. 스킨은 그 하나만 덮으면
   * 스케일 전체가 따라온다. 예전에는 --bp-error 와 --bp-error-500 이 값이 다른
   * 별개 토큰이라, 스킨이 둘을 다 덮지 않으면 화면의 상당수가 기본색으로 남았다
   * (실측 422건 중 418건이 그 원인).
   *
   * **-fg 는 전경 전용**이다. 상태색은 면(배경)으로 쓰라고 고른 밝은 색이라
   * 흰 바탕 위 **글자로는 규정을 못 맞춘다** — #F6B94C 는 1.76 으로 비문자 최소
   * 3.0 에도 미달이다(HR-DVM-003). 그래서 글자·테두리에 쓸 어두운 변형을 따로 둔다.
   * 55% 는 임의 브랜드 색에 대해 고른 값이다 — 순노랑(#FFD400) 같은 최악의 경우에도
   * 흰 바탕 4.52:1 이 나온다(60% 면 3.89 로 미달). 다크에서는 반대로 밝힌다. */
  --bp-error-50:    color-mix(in srgb, var(--bp-error)  8%, white);
  --bp-error-100:   color-mix(in srgb, var(--bp-error) 20%, white);
  --bp-error-200:   color-mix(in srgb, var(--bp-error) 40%, white);
  --bp-error-500:   var(--bp-error);
  --bp-error-600:   color-mix(in srgb, var(--bp-error) 87%, black);
  --bp-error-700:   color-mix(in srgb, var(--bp-error) 70%, black);
  --bp-error-op-01: color-mix(in srgb, var(--bp-error)  8%, transparent);
  --bp-error-op-02: color-mix(in srgb, var(--bp-error) 16%, transparent);
  --bp-error-fg:    color-mix(in srgb, var(--bp-error) 55%, black);

  --bp-success-50:    color-mix(in srgb, var(--bp-success)  8%, white);
  --bp-success-100:   color-mix(in srgb, var(--bp-success) 20%, white);
  --bp-success-200:   color-mix(in srgb, var(--bp-success) 40%, white);
  --bp-success-500:   var(--bp-success);
  --bp-success-600:   color-mix(in srgb, var(--bp-success) 87%, black);
  --bp-success-700:   color-mix(in srgb, var(--bp-success) 70%, black);
  --bp-success-op-01: color-mix(in srgb, var(--bp-success)  8%, transparent);
  --bp-success-op-02: color-mix(in srgb, var(--bp-success) 16%, transparent);
  --bp-success-fg:    color-mix(in srgb, var(--bp-success) 55%, black);

  --bp-warning-50:    color-mix(in srgb, var(--bp-warning)  8%, white);
  --bp-warning-100:   color-mix(in srgb, var(--bp-warning) 20%, white);
  --bp-warning-200:   color-mix(in srgb, var(--bp-warning) 40%, white);
  --bp-warning-500:   var(--bp-warning);
  --bp-warning-600:   color-mix(in srgb, var(--bp-warning) 87%, black);
  --bp-warning-700:   color-mix(in srgb, var(--bp-warning) 70%, black);
  --bp-warning-op-01: color-mix(in srgb, var(--bp-warning)  8%, transparent);
  --bp-warning-op-02: color-mix(in srgb, var(--bp-warning) 16%, transparent);
  --bp-warning-fg:    color-mix(in srgb, var(--bp-warning) 55%, black);

  --bp-info-50:    color-mix(in srgb, var(--bp-info)  8%, white);
  --bp-info-100:   color-mix(in srgb, var(--bp-info) 20%, white);
  --bp-info-200:   color-mix(in srgb, var(--bp-info) 40%, white);
  --bp-info-500:   var(--bp-info);
  --bp-info-600:   color-mix(in srgb, var(--bp-info) 87%, black);
  --bp-info-700:   color-mix(in srgb, var(--bp-info) 70%, black);
  --bp-info-op-01: color-mix(in srgb, var(--bp-info)  8%, transparent);
  --bp-info-op-02: color-mix(in srgb, var(--bp-info) 16%, transparent);
  --bp-info-fg:    color-mix(in srgb, var(--bp-info) 55%, black);

  /* accent 전경 — accent 팔레트도 다크 재정의가 없어 -700(#B45309)이 다크에서 3.36 이다.
     라이트 값은 지금과 같아 변화가 없고, 다크에서만 밝은 단계로 간다. */
  /* -800 을 쓴다 — -700 은 페이지 배경(순백이 아니다) 위 ghost/outline 에서 4.27~4.41 이었다. */
  --bp-accent-fg:  var(--bp-accent-800);
  /* 브랜드 전경 — --bp-text-brand(=500) 는 **중간 명도 브랜드색**에서 tint 배경 위 대비가
     모자란다(forest #2E7D32 로 primary-light 가 4.49/4.03/3.58 이었다).
     -fg 는 라이트에서 어둡히고 다크에서 밝힌다 — 상태색과 같은 계약이다. */
  --bp-primary-fg: var(--bp-primary-700);

  /* ── 채움(solid) 변형의 면과 글자 ──────────────────────────────
   * 상태색을 그대로 면에 깔고 흰 글자를 얹으면 **어느 것도 문자 AA 를 못 넘는다**:
   *   error 4.15 · info 3.68 · success 2.66 · warning 1.76
   * 진한 글자로 바꿔도 중간 명도 색(error 3.01 · info 3.40)은 여전히 미달이다.
   * 그래서 **면과 글자를 상태마다 따로** 정한다:
   *   · error·info  — 면을 조금 어둡히고 흰 글자 (4.53 / 4.87)
   *   · success·warning — 면은 그대로, 진한 잉크 (4.69 / 7.11)
   * 앰버에 진한 글자를 쓰는 것은 .bp-badge.bp-accent 가 이미 하던 방식이다.
   *
   * ⚠️ 고정 선택이라 **스킨이 밝은 error 나 어두운 warning 을 고르면 다시 어긋난다.**
   *    스킨은 이 두 토큰을 덮어 조정한다(스킨 계약 · 디자이너 대비 표 참조). */
  --bp-error-solid:   color-mix(in srgb, var(--bp-error) 95%, black);
  --bp-info-solid:    color-mix(in srgb, var(--bp-info)  85%, black);
  --bp-success-solid: var(--bp-success);
  --bp-warning-solid: var(--bp-warning);

  /* ⚠️ --bp-text-on-fill 을 쓰면 안 된다 — 그것은 다크에서 #1A1D23 으로 뒤집힌다.
     채움 면은 두 테마에서 같은 색이므로 그 위 글자도 같아야 한다(다크에서 3.74 로 떨어졌다). */
  --bp-error-on:      var(--bp-neutral-0);
  --bp-info-on:       var(--bp-neutral-0);
  --bp-success-on:    var(--bp-neutral-900);
  --bp-warning-on:    var(--bp-neutral-900);

  /* accent 채움도 같은 계약. 기본 앰버는 진한 잉크가 5.82 로 통과한다.
     ⚠️ 스킨이 중간 명도 accent(예: 분홍 #E91E63 — 흰 4.35 · 잉크 2.87)를 고르면
        둘 다 아슬아슬하다. 그때는 스킨이 이 두 토큰을 덮어 조정한다. */
  --bp-accent-solid:  var(--bp-accent-500);
  --bp-accent-on:     var(--bp-neutral-900);

  /* 채움의 hover/active 는 **글자 반대 방향**으로 민다.
     흰 글자면 더 어둡게, 진한 잉크면 더 밝게 — 같은 방향으로 밀면 대비가 무너진다
     (진한 잉크인 success 를 -600/-700 으로 어둡히니 hover 3.62 · active 2.47 이었다). */
  /* hover/active 가 미는 방향. 흰 글자면 black, 진한 잉크면 white 다.
     스킨이 -on 을 뒤집으면 **이것도 함께 뒤집어야 한다** — acme 가 accent 를
     흰 글자로 바꾸고 방향을 안 바꿔 active 가 4.13 이 됐다(RVW R2-A ②). */
  --bp-error-away:   black;
  --bp-info-away:    black;
  --bp-success-away: white;
  --bp-warning-away: white;
  --bp-accent-away:  white;

  --bp-error-solid-hover:    color-mix(in srgb, var(--bp-error-solid)    88%, var(--bp-error-away));
  --bp-error-solid-active:   color-mix(in srgb, var(--bp-error-solid)    78%, var(--bp-error-away));
  --bp-info-solid-hover:     color-mix(in srgb, var(--bp-info-solid)     88%, black);
  --bp-info-solid-active:    color-mix(in srgb, var(--bp-info-solid)     78%, black);
  --bp-success-solid-hover:  color-mix(in srgb, var(--bp-success-solid)  88%, var(--bp-success-away));
  --bp-success-solid-active: color-mix(in srgb, var(--bp-success-solid)  78%, var(--bp-success-away));
  --bp-warning-solid-hover:  color-mix(in srgb, var(--bp-warning-solid)  88%, var(--bp-warning-away));
  --bp-warning-solid-active: color-mix(in srgb, var(--bp-warning-solid)  78%, var(--bp-warning-away));
  --bp-accent-solid-hover:   color-mix(in srgb, var(--bp-accent-solid)   88%, var(--bp-accent-away));
  --bp-accent-solid-active:  color-mix(in srgb, var(--bp-accent-solid)   78%, var(--bp-accent-away));

  --bp-accent-op-01:  color-mix(in srgb, var(--bp-accent-500)   8%, transparent);
  --bp-accent-op-02:  color-mix(in srgb, var(--bp-accent-500)  16%, transparent);
  --bp-primary-op-01: color-mix(in srgb, var(--bp-primary-500)  8%, transparent);
  --bp-primary-op-02: color-mix(in srgb, var(--bp-primary-500) 16%, transparent);

  /* 중립 계단 — 명암에 따라 뒤집힌다(팔레트 --bp-neutral-* 는 고정이라 다른 것이다) */
  --bp-surface-sunken: #F0F3F9;
  --bp-surface-raised: #E9EFF6;
  --bp-surface-track:  #D7DFE9;
  --bp-ink-body:       #455468;
  --bp-ink-strong:     #3D4A5C;
  --bp-ink-secondary:  #455468;
  --bp-ink-max:        #080808;
  --bp-scrim-soft:     rgba(0, 0, 0, 0.10);
  --bp-overlay-hover:  rgba(61, 74, 92, 0.08);
  --bp-overlay-active: rgba(61, 74, 92, 0.16);
  --bp-toast-bg:       rgba(61, 74, 92, 0.5);
  --bp-tooltip-bg:     #363636;

  --bp-shadow-sm: 0 1px 2px 0 rgba(11, 31, 30, 0.06);
  --bp-shadow-md: 0 4px 8px -2px rgba(11, 31, 30, 0.08), 0 2px 4px -1px rgba(11, 31, 30, 0.04);
  --bp-shadow-lg: 0 12px 24px -6px rgba(11, 31, 30, 0.12), 0 4px 8px -2px rgba(11, 31, 30, 0.06);

  /* ── Active / Selected 시맨틱 토큰 (라이트) ──
   * 모든 컴포넌트 (Grid/Tree 행, Nav 메뉴, Tab 등) 가 공용. 이 3개만
   * 조정하면 전역 active 톤이 일괄 변경된다. */
  --bp-active-bg:      var(--bp-primary-50);
  --bp-active-bg-soft: color-mix(in srgb, var(--bp-primary-500) 8%, transparent);
  --bp-active-text:    var(--bp-primary-700);
  --bp-active-accent:  var(--bp-primary-500);

  /* Grid/Tree 행 active 토큰 — accent(Amber) 사용. Grid·Tree 공용. */
  --bp-row-active-bg:   var(--bp-accent-50);
  --bp-row-active-text: var(--bp-accent-700);
  --bp-row-active-accent: var(--bp-accent-500);

  /* BpTreeMenu 의 부모↔자식 세로 connector 라인 색.
   * 라이트는 border-light 로 충분, 다크에선 surface 와 거의 같아져 안 보이므로
   * 다크 블록에서 더 진한 색으로 override. */
  --bp-tree-connector: var(--bp-border-light);

  /* ── Typography ──
   * --bp-font-ui 는 UI 표면(AppShell · layout 등) 의 시맨틱 폰트 토큰.
   * [data-font="..."] 토글이 --bp-font-primary 만 갱신하므로 ui 도 따라가도록
   * alias 로 정의 — 사용자 폰트 변경이 모든 UI 표면에 일관 반영된다.
   * Pretendard 미로드 환경에서도 system UI 폰트로 자연스럽게 폴백. */
  --bp-font-ui:   var(--bp-font-primary), ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --bp-font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --bp-size-display: 48px;
  --bp-size-h1:      32px;
  --bp-size-h2:      24px;
  --bp-size-h3:      20px;
  --bp-size-body:    16px;
  --bp-size-small:   14px;
  --bp-size-xs:      12px;
  --bp-size-2xs:     11px;

  --bp-weight-regular:  400;
  --bp-weight-medium:   500;
  --bp-weight-semibold: 600;
  --bp-weight-bold:     700;
  --bp-weight-heavy:    800;

  --bp-line-tight:   1.2;
  --bp-line-snug:    1.35;
  --bp-line-normal:  1.55;
  --bp-line-relaxed: 1.75;

  --bp-tracking-tight:  -0.02em;
  --bp-tracking-normal: 0;
  --bp-tracking-wide:   0.04em;

  /* ── Spacing (8px grid) ── */
  --bp-space-0:   0;
  --bp-space-1:   4px;
  --bp-space-1-5: 6px;
  --bp-space-2:   8px;
  --bp-space-3:   12px;
  --bp-space-4:   16px;
  --bp-space-5:   20px;
  --bp-space-6:   24px;
  --bp-space-8:   32px;
  --bp-space-10:  40px;
  --bp-space-12:  48px;
  --bp-space-16:  64px;
  --bp-space-20:  80px;
  --bp-space-24:  96px;

  /* mask/`-webkit-mask` 스텐실용 불투명 색. mask 는 **알파만** 읽으므로 테마와 무관하고,
     테마 색 토큰을 쓰면 의도를 오해하게 된다. 색상 하드코딩 금지 규칙의 명시적 예외를
     여기 한 곳에 모아 이름으로 남긴다 — 컴포넌트 CSS 는 이 토큰만 참조한다. */
  --bp-mask-opaque: #000;

  /* ── Radius ── */
  --bp-radius-xs:     2px;
  --bp-radius-sm:     4px;
  --bp-radius-md:     6px;
  --bp-radius-lg:     8px;
  --bp-radius-xl:     12px;
  --bp-radius-2xl:    16px;
  --bp-radius-pill:   999px;
  --bp-radius-circle: 50%;

  /* ── Motion ── */
  --bp-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --bp-duration-fast: 120ms;
  --bp-duration-base: 200ms;
  --bp-duration-slow: 320ms;

  /* ── Control heights (5-size common : buttons · inputs · selects) ── */
  --bp-h-xs: 24px;
  --bp-h-sm: 32px;
  --bp-h-md: 40px;   /* default */
  --bp-h-lg: 48px;
  --bp-h-xl: 56px;

  --bp-control-font-xs: 12px;
  --bp-control-font-sm: 13px;
  --bp-control-font-md: 14px;
  --bp-control-font-lg: 16px;
  --bp-control-font-xl: 18px;

  --bp-control-pad-xs: 8px;
  --bp-control-pad-sm: 12px;
  --bp-control-pad-md: 16px;
  --bp-control-pad-lg: 20px;
  --bp-control-pad-xl: 24px;

  --bp-control-icon-xs: 14px;
  --bp-control-icon-sm: 16px;
  --bp-control-icon-md: 20px;
  --bp-control-icon-lg: 22px;
  --bp-control-icon-xl: 24px;

  --bp-control-weight-xs: 500;
  --bp-control-weight-sm: 500;
  --bp-control-weight-md: 600;
  --bp-control-weight-lg: 600;
  --bp-control-weight-xl: 700;

  /* ── Icon scale (standalone) ── */
  --bp-icon-xs:  12px;
  --bp-icon-sm:  16px;
  --bp-icon-md:  20px;
  --bp-icon-lg:  24px;
  --bp-icon-xl:  32px;
  --bp-icon-2xl: 48px;

  /* ── Badge ── */
  --bp-badge-h-sm: 20px;
  --bp-badge-h-md: 24px;
  --bp-badge-h-lg: 28px;
  --bp-badge-font-sm: 11px;
  --bp-badge-font-md: 12px;
  --bp-badge-font-lg: 13px;
  --bp-badge-pad-sm: 8px;
  --bp-badge-pad-md: 10px;
  --bp-badge-pad-lg: 12px;

  /* ── Avatar ── */
  --bp-avatar-xs:  20px;
  --bp-avatar-sm:  24px;
  --bp-avatar-md:  32px;
  --bp-avatar-lg:  40px;
  --bp-avatar-xl:  56px;
  --bp-avatar-2xl: 80px;

  /* ── Loading spinner ── */
  --bp-loading-sm: 20px;
  --bp-loading-md: 36px;
  --bp-loading-lg: 52px;

  /* ── Row density (Grid · Tree) ── */
  --bp-row-compact:     32px;
  --bp-row-default:     40px;
  --bp-row-comfortable: 52px;
  --bp-row-pad-compact:     4px 8px;
  --bp-row-pad-default:     8px 12px;
  --bp-row-pad-comfortable: 12px 16px;
  --bp-row-font-compact:     12px;
  --bp-row-font-default:     13px;   /* sm 컨트롤(13px) 과 일치 — 데이터 그리드 표준 밀도 */
  --bp-row-font-comfortable: 14px;   /* default 보다 1 단계 큼 — 두 모드를 시각적으로 구분 */

  /* ── Layout ── */
  --bp-layout-header:      56px;
  --bp-layout-toolbar:     48px;
  --bp-layout-statusbar:   32px;
  --bp-layout-sidebar:     240px;
  --bp-layout-sidebar-sm:  64px;
  --bp-layout-tree-menu:   300px;
  --bp-layout-content-max: 1120px;
  --bp-drawer-w:           280px;
  /* 드로어 뒤를 덮는 막(scrim). 하드코딩 rgba 대신 토큰으로 둔다.
     ⚠️ --bp-bg-overlay 와 다른 것이다 — 그쪽은 강조용 엷은 틴트다. */
  --bp-scrim-bg:           rgba(15, 23, 42, 0.45);
  --bp-log-panel-h:        280px;
  --bp-modal-sm: 400px;
  --bp-modal-md: 560px;
  --bp-modal-lg: 800px;
  --bp-modal-xl: 1040px;

  /* ── Z-index ── */
  --bp-z-base:     0;
  --bp-z-dropdown: 100;
  --bp-z-sticky:   200;
  --bp-z-header:   300;
  --bp-z-overlay:  900;
  --bp-z-modal:    1000;
  --bp-z-popover:  1050;
  --bp-z-tooltip:  1100;
  --bp-z-toast:    1200;

  /* ── Breakpoints (CSS @media 는 var() 불가 — 주석으로 동기화) ── */
  --bp-break-sm:  640px;
  --bp-break-md:  768px;
  --bp-break-lg:  1024px;
  --bp-break-xl:  1280px;
  --bp-break-2xl: 1536px;
}

/* ── Dark theme : 신규 bp-* 시맨틱 토큰 오버라이드 ──
 * 기존 [data-theme="dark"] 블록과 병존 (다른 변수를 다룸). */
[data-theme="dark"] {
  --bp-bg-page:      #0F1115;
  --bp-bg-surface:   #1A1D23;
  --bp-bg-elevated:  #222831;
  --bp-bg-muted:     #141820;
  --bp-bg-overlay:   color-mix(in srgb, var(--bp-accent-500) 4%, transparent);
  /* 다크는 바탕이 이미 어두워 같은 값이면 막이 흐려 보인다 — 한 단계 진하게. */
  --bp-scrim-bg:     rgba(0, 0, 0, 0.6);
  --bp-surface-faint:  #0A0C11;
  --bp-text-on-fill:   #1A1D23;
  /* 중립 계단 — 다크에서 뒤집힌다 */
  --bp-surface-sunken: #2D3643;
  --bp-surface-raised: #3D4A5C;
  --bp-surface-track:  #455468;
  --bp-ink-body:       #D7DFE9;
  --bp-ink-strong:     #E9EFF6;
  --bp-ink-secondary:  #AFBACA;
  --bp-ink-max:        #E8E8E8;

  /* 상태색 스케일 — 다크 tint. 라이트는 white 와, 다크는 black 과 섞는다.
     500·600·700·op-* 는 라이트 정의가 그대로 유효하다(단일 토큰 파생). */
  --bp-error-50:    color-mix(in srgb, var(--bp-error) 22%, black);
  --bp-error-100:   color-mix(in srgb, var(--bp-error) 38%, black);
  --bp-error-200:   color-mix(in srgb, var(--bp-error) 58%, black);
  --bp-success-50:    color-mix(in srgb, var(--bp-success) 22%, black);
  --bp-success-100:   color-mix(in srgb, var(--bp-success) 38%, black);
  --bp-success-200:   color-mix(in srgb, var(--bp-success) 58%, black);
  --bp-warning-50:    color-mix(in srgb, var(--bp-warning) 22%, black);
  --bp-warning-100:   color-mix(in srgb, var(--bp-warning) 38%, black);
  --bp-warning-200:   color-mix(in srgb, var(--bp-warning) 58%, black);
  --bp-info-50:    color-mix(in srgb, var(--bp-info) 22%, black);
  --bp-info-100:   color-mix(in srgb, var(--bp-info) 38%, black);
  --bp-info-200:   color-mix(in srgb, var(--bp-info) 58%, black);

  /* 전경 전용 — 다크에서는 어둡히지 않고 **밝힌다**. 상태색 원색 그대로면
     #E0443E 가 #1A1D23 위에서 4.07 로 문자 AA(4.5)에 못 미친다.
     25% 밝히면 면 위 5.70 · **BpTag 의 어두운 tint 배경 위 5.00** 이 된다.
     ⚠️ tint 배경이 더 빡빡하다 — 15% 로는 면은 4.94 로 통과해도 태그가 4.33 로
     미달이었다. 두 배경을 다 봐야 한다. */
  --bp-error-fg:   color-mix(in srgb, var(--bp-error)   75%, white);
  --bp-success-fg: color-mix(in srgb, var(--bp-success) 75%, white);
  --bp-warning-fg: color-mix(in srgb, var(--bp-warning) 75%, white);
  --bp-info-fg:    color-mix(in srgb, var(--bp-info)    75%, white);
  --bp-accent-fg:  var(--bp-accent-400);
  --bp-primary-fg: var(--bp-primary-400);

  --bp-scrim-soft:     rgba(0, 0, 0, 0.50);
  --bp-overlay-hover:  rgba(200, 215, 235, 0.08);
  --bp-overlay-active: rgba(200, 215, 235, 0.16);
  --bp-toast-bg:       rgba(200, 215, 235, 0.5);
  --bp-tooltip-bg:     #D9D9D9;


  --bp-text-primary:   #E9EEF6;
  --bp-text-secondary: #AFBACA;
  --bp-text-tertiary:  #8897AE;
  --bp-text-disabled:  #5E718D;
  --bp-text-inverse:   #0F1115;
  --bp-text-brand:     var(--bp-primary-400);

  --bp-border-default: #2D3643;
  --bp-border-light:   #222831;
  --bp-border-strong:  #455468;
  --bp-border-brand:   var(--bp-primary-400);

  --bp-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
  --bp-shadow-md: 0 4px 8px -2px rgba(0, 0, 0, 0.4);
  --bp-shadow-lg: 0 12px 24px -6px rgba(0, 0, 0, 0.5);

  /* ── Active / Selected (다크) : 라이트보다 높은 대비가 필요
   * 라이트의 --bp-primary-50 (#E7F3F2) 는 다크 배경에서 흰 빨래처럼
   * 보이므로, 반투명 Primary 로 채도 유지. 전역 수정 지점. */
  --bp-active-bg:      color-mix(in srgb, var(--bp-primary-400) 28%, transparent);
  --bp-active-bg-soft: color-mix(in srgb, var(--bp-primary-400) 14%, transparent);
  --bp-active-text:    #A7E5DD;        /* Teal tint — 다크 배경에 잘 떠오름 */
  --bp-active-accent:  #6FCBBF;        /* bar / 좌측 indicator 색 */

  --bp-row-active-bg:     color-mix(in srgb, var(--bp-accent-500) 22%, transparent);
  --bp-row-active-text:   var(--bp-accent-300);    /* Amber tint */
  --bp-row-active-accent: var(--bp-accent-500);

  /* TreeMenu connector — 다크에선 border-light(#222831) 가 surface(#1A1D23) 와
   * 거의 같아 안 보이므로 한 단계 진한 톤으로 교체. */
  --bp-tree-connector: var(--bp-border-strong);
}

/* ── Accessibility : motion · forced-colors ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    transition-duration: 0.01ms;
    scroll-behavior: auto;
  }
}
@media (forced-colors: active) {
  .bp-card, .bp-modal-container { border-color: CanvasText; }
}

/* ═══════════════════════════════════════════════════════════════
 * Size 5-tier (xs/sm/md/lg/xl) — 정식 단일 기준
 *
 * legacy 7-tier(t/es/s/m/l/el/b) CSS 는 제거됨. 컴포넌트는 BpSize.Normalize 를
 * 거쳐 bp-xs/sm/md/lg/xl 만 방출하며, 과거/외부 코드의 legacy 입력은 C# 에서 흡수한다.
 * 신규 CSS 에 7-tier alias 를 다시 추가하지 않는다.
 * ═══════════════════════════════════════════════════════════════ */

/* ── Button sizes (5-tier) ── */
.bp-btn.bp-xs { min-width: unset; height: var(--bp-h-xs); padding: 0 var(--bp-control-pad-xs); font-size: var(--bp-control-font-xs); font-weight: var(--bp-control-weight-xs); }
.bp-btn.bp-sm { height: var(--bp-h-sm); padding: 0 var(--bp-control-pad-sm); font-size: var(--bp-control-font-sm); font-weight: var(--bp-control-weight-sm); }
.bp-btn.bp-md { height: var(--bp-h-md); padding: 0 var(--bp-control-pad-md); font-size: var(--bp-control-font-md); font-weight: var(--bp-control-weight-md); }
.bp-btn.bp-lg { height: var(--bp-h-lg); padding: 0 var(--bp-control-pad-lg); font-size: var(--bp-control-font-lg); font-weight: var(--bp-control-weight-lg); }
.bp-btn.bp-xl { height: var(--bp-h-xl); padding: 0 var(--bp-control-pad-xl); font-size: var(--bp-control-font-xl); font-weight: var(--bp-control-weight-xl); }

/* Icon-only (square) per size */
.bp-btn.bp-xs:has(i:first-child:last-child) { width: var(--bp-h-xs); height: var(--bp-h-xs); padding: 0; }
.bp-btn.bp-xs i { font-size: var(--bp-control-icon-xs); }
.bp-btn.bp-sm:has(i:first-child:last-child) { width: var(--bp-h-sm); height: var(--bp-h-sm); padding: 0; }
.bp-btn.bp-sm i { font-size: var(--bp-control-icon-sm); }
.bp-btn.bp-md:has(i:first-child:last-child) { width: var(--bp-h-md); height: var(--bp-h-md); padding: 0; }
.bp-btn.bp-md i { font-size: var(--bp-control-icon-md); }
.bp-btn.bp-lg:has(i:first-child:last-child) { width: var(--bp-h-lg); height: var(--bp-h-lg); padding: 0; }
.bp-btn.bp-lg i { font-size: var(--bp-control-icon-lg); }
.bp-btn.bp-xl:has(i:first-child:last-child) { width: var(--bp-h-xl); height: var(--bp-h-xl); padding: 0; }
.bp-btn.bp-xl i { font-size: var(--bp-control-icon-xl); }

/* ═══════════════════════════════════════════════════════════════
 * Phase 3 · 디자인 가이드 variants + focus ring + containment
 * ═══════════════════════════════════════════════════════════════ */

:root {
  /* focus ring — 가이드: Primary-500 18% opacity 3px */
  /* 링이 바깥으로 번지는 폭. 링을 잘라내지 않아야 하는 컨테이너(BpSplitPanel 등)의
     overflow-clip-margin 과 값을 공유한다 — 링 두께를 바꾸면 여기만 고친다. */
  --bp-focus-ring-spread: 3px;
  --bp-focus-ring:  0 0 0 3px rgba(11, 79, 74, 0.18);
  --bp-focus-ring-accent: 0 0 0 3px color-mix(in srgb, var(--bp-accent-500) 25%, transparent);
  --bp-focus-ring-error:  0 0 0 3px rgba(224, 68, 62, 0.22);
}
[data-theme="dark"] {
  --bp-focus-ring:  0 0 0 3px rgba(75, 159, 149, 0.32);
  --bp-focus-ring-accent: 0 0 0 3px color-mix(in srgb, var(--bp-accent-400) 32%, transparent);
  --bp-focus-ring-error:  0 0 0 3px rgba(224, 68, 62, 0.30);
}

/* ── Button : accent (Signal Amber) · ghost · light 보강 ── */
.bp-btn.bp-accent {
    background-color: var(--bp-accent-solid);
    color: var(--bp-accent-on);
}
.bp-btn.bp-accent:hover  { background-color: var(--bp-accent-solid-hover); color: var(--bp-accent-on); }
.bp-btn.bp-accent:active { background-color: var(--bp-accent-solid-active); color: var(--bp-accent-on); }
.bp-btn.bp-accent:disabled { background-color: var(--bp-accent-200); color: var(--bp-neutral-700); opacity: .6; }

.bp-btn.bp-accent-outline {
    border: 1px solid var(--bp-accent-600);
    color: var(--bp-accent-fg);
    background-color: var(--bp-bg-surface);
}
.bp-btn.bp-accent-outline:hover  { background-color: var(--bp-accent-op-01); }
.bp-btn.bp-accent-outline:active { background-color: var(--bp-accent-op-02); }
/* 비활성은 중립으로 — accent-200/300 은 다크에서 11.71 로 활성보다 도드라졌다. */
.bp-btn.bp-accent-outline:disabled { border-color: var(--bp-surface-track); color: var(--bp-surface-track); }

.bp-btn.bp-ghost {
    background-color: transparent;
    color: var(--bp-text-primary);
}
.bp-btn.bp-ghost:hover  { background-color: var(--bp-bg-muted); }
.bp-btn.bp-ghost:active { background-color: var(--bp-border-light); }
.bp-btn.bp-ghost:disabled { color: var(--bp-text-disabled); }

/* ── Button : focus ring (universal) ── */
.bp-btn:focus-visible { outline: none; box-shadow: var(--bp-focus-ring); }
.bp-btn.bp-accent:focus-visible,
.bp-btn.bp-accent-outline:focus-visible { box-shadow: var(--bp-focus-ring-accent); }
.bp-btn.bp-error:focus-visible,
.bp-btn.bp-error-outline:focus-visible { box-shadow: var(--bp-focus-ring-error); }

/* Input 계열 3-state(idle/hover/focus) 는 bp-components.css 의
   "Input 3-state 표준" 블록이 전 계열을 한 곳에서 소유한다. */

/* ── Badge : 3-tier (sm 20 / md 24 / lg 28) · 토큰 기반 ── */
.bp-badge.bp-sm {
    height: var(--bp-badge-h-sm);
    padding: 0 var(--bp-badge-pad-sm);
    font-size: var(--bp-badge-font-sm);
    font-weight: var(--bp-weight-medium);
}
.bp-badge.bp-md {
    height: var(--bp-badge-h-md);
    padding: 0 var(--bp-badge-pad-md);
    font-size: var(--bp-badge-font-md);
    font-weight: var(--bp-weight-medium);
}
.bp-badge.bp-lg {
    height: var(--bp-badge-h-lg);
    padding: 0 var(--bp-badge-pad-lg);
    font-size: var(--bp-badge-font-lg);
    font-weight: var(--bp-weight-semibold);
}
/* badge : accent 보강 */
.bp-badge.bp-accent {
    background-color: var(--bp-accent-500);
    color: var(--bp-neutral-900) !important;
}

/* ── Card : 가이드 containment (min-width: 0, overflow: hidden) ── */
.bp-card {
    min-width: 0;
    overflow: hidden;
}

/* ── Containment 원칙 (스크롤 컨테이너 / 표 공통) ── */
.bp-card > *, .bp-modal-container > * { min-width: 0; }

