/* /Components/Layout/JkMobileTabBar.razor.rz.scp.css */
/*
    정본 $lib/components/dms/MobileTabBar.svelte 의 <style> 블록 그대로.
    ⛔ 정본은 Svelte 스코프 CSS 라 wwwroot/jk-shell.css 추출본에 «없다»
       (.dms-mobile-wrapper 만 있다 — jk-shell.css:577). 흉내 내지 않고 원본 값을 옮겼다.
       선례: DmsBrowseDesk/DmsBrowseTypeChips.razor.css · DmsHome/DmsDashboard.razor.css.

    ⛔⛔ 정본이 {#if $isMobile} 로 하던 «표시 판정»을 여기 미디어쿼리가 대신한다.
       중단점은 정본 $lib/js/mobile.js:7 의 matchMedia('(max-width: 768px)') 와 «같은 값»이다.
       ⛔ 값을 새로 고르지 마라 — 셸의 다른 반응형 규칙과 어긋난다.
*/

.mobile-tab-bar[b-rslyzjoozr],
.more-menu[b-rslyzjoozr],
.jk-mtb-backdrop[b-rslyzjoozr] {
    display: none;
}

/* ⛔ @keyframes 는 «미디어쿼리 밖»에 둔다 — 스코프 CSS 재작성기가 중첩 at-rule 안의
   from/to 를 선택자로 오인하는 경우가 있어 애니메이션이 조용히 죽는다.
   ⛔ 이름에 고유 접두를 붙인다 — 한 문서에 같은 이름이 둘이면 뒤엣것이 이긴다. */
@keyframes jk-mtb-slide-up-b-rslyzjoozr {
    from {
        opacity: 0;
        transform: translateY(8px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@media (max-width: 768px) {

    .mobile-tab-bar[b-rslyzjoozr] {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        height: 56px;
        background: var(--vz-card-bg, #fff);
        border-top: 1px solid var(--vz-border-color);
        display: flex;
        justify-content: space-around;
        align-items: center;
        z-index: 1050;
        padding-bottom: env(safe-area-inset-bottom, 0);
    }

    .mobile-tab[b-rslyzjoozr] {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        padding: 6px 8px;
        color: var(--vz-secondary-color);
        text-decoration: none;
        font-size: 13px;
        transition: color 0.15s;
        min-width: 50px;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
        /* ⛔ 정본은 <div> 였다. 여기서는 <a>/<button> 이라 기본 테두리·배경을 지워야 같은 모양이 된다. */
        border: none;
        background: none;
    }

    .mobile-tab i[b-rslyzjoozr] {
        font-size: 20px;
    }

    .mobile-tab.active[b-rslyzjoozr] {
        color: var(--vz-primary);
        /* ⛔ 500 을 넘기지 않는다(폰트 굵기 규약). 정본 600 은 이 제품 표준보다 굵다. */
        font-weight: 500;
    }

    .mobile-tab:active[b-rslyzjoozr] {
        transform: scale(0.92);
    }

    /* ── 더보기 팝업 ── */
    .jk-mtb-backdrop[b-rslyzjoozr] {
        display: block;
        position: fixed;
        inset: 0;
        /* ⛔ 메뉴(1060) «아래», 탭바(1050) «위». 순서를 바꾸면 항목이 안 눌린다. */
        z-index: 1055;
        background: transparent;
    }

    .more-menu[b-rslyzjoozr] {
        position: fixed;
        bottom: 62px;
        right: 8px;
        background: var(--vz-card-bg, #fff);
        border: 1px solid var(--vz-border-color);
        border-radius: 12px;
        box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.12);
        z-index: 1060;
        padding: 8px 0;
        min-width: 180px;
        display: block;
        animation: jk-mtb-slide-up-b-rslyzjoozr 0.15s ease-out;
    }

    .more-item[b-rslyzjoozr] {
        display: flex;
        align-items: center;
        gap: 10px;
        width: 100%;
        padding: 10px 16px;
        border: none;
        background: none;
        color: var(--vz-body-color);
        font-size: 13px;
        cursor: pointer;
        text-align: left;
        text-decoration: none;
    }

    .more-item:active[b-rslyzjoozr] {
        background: var(--vz-light);
    }

    .more-item i[b-rslyzjoozr] {
        font-size: 18px;
        width: 20px;
        text-align: center;
    }

    .more-item-danger[b-rslyzjoozr] {
        color: var(--vz-danger, #ef4444);
    }

    .more-item-danger:active[b-rslyzjoozr] {
        background: rgba(239, 68, 68, 0.08);
    }

    .more-divider[b-rslyzjoozr] {
        height: 1px;
        background: var(--vz-border-color);
        margin: 4px 0;
    }

    .more-user[b-rslyzjoozr] {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 8px 16px;
        font-size: 13px;
        color: var(--vz-secondary-color);
    }

    .more-user i[b-rslyzjoozr] {
        font-size: 1rem;
        width: 20px;
        text-align: center;
    }
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-hll8fnlub6] {
    position: relative;
    display: flex;
    flex-direction: column;
}

main[b-hll8fnlub6] {
    flex: 1;
}

.sidebar[b-hll8fnlub6] {
    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row[b-hll8fnlub6] {
    background-color: #f7f7f7;
    border-bottom: 1px solid #d6d5d5;
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

    .top-row[b-hll8fnlub6]  a, .top-row[b-hll8fnlub6]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
    }

    .top-row[b-hll8fnlub6]  a:hover, .top-row[b-hll8fnlub6]  .btn-link:hover {
        text-decoration: underline;
    }

    .top-row[b-hll8fnlub6]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

@media (max-width: 640.98px) {
    .top-row[b-hll8fnlub6] {
        justify-content: space-between;
    }

    .top-row[b-hll8fnlub6]  a, .top-row[b-hll8fnlub6]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 641px) {
    .page[b-hll8fnlub6] {
        flex-direction: row;
    }

    .sidebar[b-hll8fnlub6] {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }

    .top-row[b-hll8fnlub6] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    .top-row.auth[b-hll8fnlub6]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-hll8fnlub6], article[b-hll8fnlub6] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

#blazor-error-ui[b-hll8fnlub6] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-hll8fnlub6] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

/* 프로필 드롭다운 «바깥 클릭» 감지막 (2026-08-31).
   ⛔⛔ 공용 .context-menu-backdrop 은 z-index 1060 이라 메뉴(.jkia-who-menu, z-index 20)
      «위»에 깔린다 — 그러면 메뉴 항목이 하나도 안 눌린다. 그래서 전용 값(19)을 쓴다.
   ⛔ .jkia-who-wrap 은 position:relative 지만 z-index 가 없어 스택 컨텍스트를 만들지 않는다.
      즉 이 막과 메뉴는 «같은» 컨텍스트에서 19 < 20 으로 비교된다 — 그 전제가 이 값의 근거다.
   ⛔ 스코프 CSS 라 Blazor 가 «직접 그린» 요소에만 붙는다. JS 가 만든 노드에는 안 붙는다. */
.jkia-who-backdrop[b-hll8fnlub6] {
    position: fixed;
    inset: 0;
    z-index: 19;
}

/* DMS 모바일 하단 탭바가 본문을 가리지 않게 하는 여백 (2026-08-31).
   정본 routes/dms/+layout.svelte 의 `class:dms-mobile-wrapper={$isMobile}` → padding-bottom:60px 자리.

   ⛔⛔ 정본의 `.dms-mobile-wrapper`(wwwroot/jk-shell.css:577)를 그대로 쓰지 않는다.
      그 규칙에는 미디어쿼리가 «없다» — 정본은 {#if $isMobile} 로 «클래스 자체»를 껐기 때문이다.
      이 셸은 모바일 판정을 CSS 로 하므로(회로가 창 너비를 모른다), 클래스는 늘 붙고
      «여백만» 미디어쿼리로 켠다. 정본 규칙을 그대로 붙이면 데스크톱에도 60px 이 생긴다.
   ⛔ 중단점 768px 은 정본 $lib/js/mobile.js:7 의 matchMedia 와 «같은 값»이다.
      JkMobileTabBar.razor.css 의 표시 조건과 «짝»이라 한쪽만 바꾸면 여백과 탭바가 어긋난다.
   ⛔ jk-shell.css 의 죽은 `.dms-mobile-wrapper` 규칙은 «건드리지 않는다» —
      그 파일은 scripts/gen-blazor-shell-css.py 가 재생성한다(손으로 고치면 다음 생성에 사라진다). */
@media (max-width: 768px) {
    .jkia-body.jk-dms-mobile-pad[b-hll8fnlub6] {
        padding-bottom: 60px;
    }
}

/* ── 헤더를 접은 화면의 위 여백 (2026-09-01 지시) ─────────────────────────
   정본 _jk-shell.scss 가 .jkia-body 에 padding-top 20px 을 준다. 헤더·서브탭이 없는
   화면에서는 그 20px 이 «맨 위 빈칸»으로만 보인다 — 여기서만 줄인다.
   ⛔ 정본 값을 바꾸지 마라. 나머지 화면 전부가 헤더 밑에 붙어 버린다. */
#jkia-content.jkia-flush[b-hll8fnlub6] {
    padding-top: 0.5rem;
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-z957blwy0h],
.components-reconnect-repeated-attempt-visible[b-z957blwy0h],
.components-reconnect-failed-visible[b-z957blwy0h],
.components-pause-visible[b-z957blwy0h],
.components-resume-failed-visible[b-z957blwy0h],
.components-rejoining-animation[b-z957blwy0h] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-retrying[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-failed[b-z957blwy0h],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-z957blwy0h] {
    display: block;
}


#components-reconnect-modal[b-z957blwy0h] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-z957blwy0h 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-z957blwy0h 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-z957blwy0h 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-z957blwy0h]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-z957blwy0h 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-z957blwy0h {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-z957blwy0h {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-z957blwy0h {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-z957blwy0h] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-z957blwy0h] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-z957blwy0h] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-z957blwy0h] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-z957blwy0h] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-z957blwy0h] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-z957blwy0h] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-z957blwy0h 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-z957blwy0h] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-z957blwy0h {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/AccountDesk/AccountPassword.razor.rz.scp.css */
/* 원본 account/password/+page.svelte 의 <style> 블록 그대로 (110~135행). */

.account-wrap[b-u0fowzlgcz] { max-width: 520px; margin: 0 auto; }
.account-header[b-u0fowzlgcz] { margin-bottom: 20px; }
.field-group[b-u0fowzlgcz] { margin-bottom: 18px; }

.strength-bar[b-u0fowzlgcz] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.strength-bar-track[b-u0fowzlgcz] {
    flex: 1;
    height: 4px;
    background: var(--vz-border-color);
    border-radius: 2px;
    overflow: hidden;
}

.strength-bar-fill[b-u0fowzlgcz] {
    height: 100%;
    transition: width 0.2s, background 0.2s;
}

.strength-label[b-u0fowzlgcz] {
    font-size: 13px;
    font-weight: 600;
    flex-shrink: 0;
}
/* /Components/Pages/AccountDesk/AccountProfile.razor.rz.scp.css */
/* 원본 account/profile/+page.svelte 의 <style> 블록 그대로 (70~76행). */

.account-wrap[b-k7gc26xj66] { max-width: 640px; margin: 0 auto; }
.account-header[b-k7gc26xj66] { margin-bottom: 20px; }
.field-group[b-k7gc26xj66] { margin-bottom: 18px; }
.field-row[b-k7gc26xj66] { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* /Components/Pages/AccountDesk/FirstLoginPanel.razor.rz.scp.css */
/* 원본 first-login/+page.svelte 의 <style> 블록 그대로 (137~164행).
   ⛔ /login 과 값이 겹치지만 «원본이 각자 갖고 있다» — 합치지 않는다(한쪽만 바뀌는 사고를 막는다). */

.auth-wrap[b-yem8j0gbc5] {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%);
    padding: 2rem 1rem;
}

.auth-card[b-yem8j0gbc5] {
    background: var(--vz-secondary-bg);
    padding: 2.5rem;
    border-radius: 10px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
    width: 100%;
    max-width: 420px;
}

.auth-header[b-yem8j0gbc5] { text-align: center; margin-bottom: 2rem; }
.auth-header i[b-yem8j0gbc5] { font-size: 2.5rem; color: var(--vz-primary); }
.auth-header h3[b-yem8j0gbc5] { margin: 0.75rem 0 0.25rem; color: #34495e; font-weight: 700; }
.auth-header p[b-yem8j0gbc5] { color: var(--vz-secondary-color); margin: 0; font-size: 13px; }
.auth-footer[b-yem8j0gbc5] { text-align: center; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid #f0f0f0; }

.input-group-text[b-yem8j0gbc5] { background: var(--vz-tertiary-bg); border-right: 0; color: var(--vz-secondary-color); }
.input-group .form-control[b-yem8j0gbc5] { border-left: 0; }

.strength-bar[b-yem8j0gbc5] { height: 4px; background: var(--vz-tertiary-bg); border-radius: 2px; overflow: hidden; }
.strength-fill[b-yem8j0gbc5] { height: 100%; transition: width 0.3s ease; border-radius: 2px; }

.pw-rules[b-yem8j0gbc5] { text-align: left; display: inline-block; }
.pw-rules small[b-yem8j0gbc5] { line-height: 1.8; }
/* /Components/Pages/AccountDesk/LoginPanel.razor.rz.scp.css */
/* 원본 login/+page.svelte 의 <style> 블록 그대로 (272~312행).
   ⛔ 디자인을 새로 만들지 않는다 — 값 하나도 바꾸지 않았다.
   ⛔ Blazor 스코프 CSS 는 «마지막 선택자»에 [b-xxx] 를 붙인다. 아래 규칙의 대상 요소는
      전부 이 컴포넌트 안에 있어 그대로 동작한다. */

.auth-wrap[b-2ww4asd4xk] {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%);
    padding: 2rem 1rem;
}

.auth-card[b-2ww4asd4xk] {
    background: var(--vz-secondary-bg);
    padding: 2.5rem;
    border-radius: 10px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
    width: 100%;
    max-width: 420px;
}

.auth-header[b-2ww4asd4xk] { text-align: center; margin-bottom: 2rem; }
.auth-header i[b-2ww4asd4xk] { font-size: 2.5rem; color: var(--vz-primary); }
.auth-header h3[b-2ww4asd4xk] { margin: 0.75rem 0 0.25rem; color: #34495e; font-weight: 700; }
.auth-header p[b-2ww4asd4xk] { color: var(--vz-secondary-color); margin: 0; font-size: 13px; }
.desktop-app[b-2ww4asd4xk] { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid #f0f0f0; }
.auth-footer[b-2ww4asd4xk] { text-align: center; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid #f0f0f0; }
.auth-brand[b-2ww4asd4xk] { margin-top: 2rem; }

.input-group-text[b-2ww4asd4xk] { background: var(--vz-tertiary-bg); border-right: 0; color: var(--vz-secondary-color); }
.input-group .form-control[b-2ww4asd4xk] { border-left: 0; }

/*
    포커스 표시 (2026-08-17 야간 usertest PLM-20260817-04).

    ⛔⛔ 종전은 `.form-control:focus { border-color:#ced4da; box-shadow:none; }` 였다 —
       아이콘 addon 과의 이음매를 매끈하게 두려던 규칙인데 «포커스 표시를 통째로 지웠다».
       Tab 으로 비밀번호 칸에 가도 ID 칸과 픽셀 단위로 동일해 지금 어디인지 알 수 없었다.
    ⛔ 개별 칸의 bootstrap 링은 계속 끈다 — border-left:0 인 이음매를 가로질러 잘려 보인다.
       대신 링을 input-group 전체에 씌운다.
*/
.input-group .form-control:focus[b-2ww4asd4xk] { box-shadow: none; }

.input-group:focus-within[b-2ww4asd4xk] {
    border-radius: var(--vz-border-radius, 0.25rem);
    box-shadow: 0 0 0 0.2rem rgba(var(--vz-primary-rgb), 0.3);
}

.input-group:focus-within > .input-group-text[b-2ww4asd4xk],
.input-group:focus-within > .form-control[b-2ww4asd4xk],
.input-group:focus-within > .btn[b-2ww4asd4xk] { border-color: var(--vz-primary); }
/* /Components/Pages/AdminAi/PreparingPlaceholder.razor.rz.scp.css */
/* 원본 PreparingPlaceholder.svelte 의 <style> 블록 그대로 (Svelte 스코프 → Blazor CSS 격리). */
.placeholder-wrap[b-c66vg7nixo] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 60vh;
    color: var(--vz-secondary-color);
}

.placeholder-icon[b-c66vg7nixo] {
    font-size: 4rem;
    opacity: 0.4;
    margin-bottom: 1rem;
}
/* /Components/Pages/AdminOps/AdminHub.razor.rz.scp.css */
/* 축 표기 — 라벨보다 한 단 낮게. 원본 +page.svelte 의 <style> 블록 그대로다.
   문서함 레일 `.sidebar-axis`, 홈 `.jkia-kpi-axis` 와 같은 역할. */
.admin-kpi-axis[b-zi5aiby1py] {
    font-size: 12px;
    font-weight: 400;
    opacity: 0.8;
    white-space: nowrap;
}
/* /Components/Pages/AdminOps/ShellDiagnostics.razor.rz.scp.css */
/* 원본 +page.svelte 의 <style> 블록 그대로. */
.diag-table tbody tr.expanded[b-rqhzulzg7v] { background: var(--vz-tertiary-bg); }
.diag-detail-row td[b-rqhzulzg7v] { border-top: 0; }

/* ⛔ min-width 가 없으면 .table-responsive 안에서 표가 «스크롤되기 전에 열을 먼저 뭉갠다».
   1000px 뷰포트 실측에서 「사용자·설치버전·크래시」가 19px 로 줄어 헤더가 한 글자씩 세로로
   깨졌다. 좁은 화면에서는 뭉개지 말고 가로로 스크롤되게 한다(페이지 자체는 안 밀린다). */
.diag-table[b-rqhzulzg7v] { min-width: 900px; }
/* /Components/Pages/ApprovalAdmin/ApprovalTemplates.razor.rz.scp.css */


/* ══ 정본 스타일 이식 (2026-08-31 스타일 감사) ══════════════════════
   마크업은 쓰는데 «어느 CSS 에도 정의가 없던» 클래스들이다 - 화면이 조용히 무스타일이었다.
   출처: JK.AI.Front/src/routes/admin/approval/templates/+page.svelte
   ⛔ 정본에 «없는» 클래스는 이식하지 않았다 - 정본과 동일하게 맞추는 것이 지시다.
   ⛔ 자식 컴포넌트가 그리는 노드는 스코프가 달라 ::deep 이 필요하다(정본의 :global 과 같은 축). */

/* 좌측 list-group 액션 버튼 — 역할 정의 화면과 동일 패턴 */
	.tpl-action-btn[b-3udwvvzf93] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 4px;
    color: var(--vz-secondary);
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.tpl-action-btn:hover[b-3udwvvzf93] {
    background-color: rgba(0, 0, 0, 0.06);
}

.tpl-action-btn.tpl-delete-btn:hover[b-3udwvvzf93] {
    color: var(--vz-danger);
}

.tpl-action-btn.on-active[b-3udwvvzf93] {
    color: rgba(255, 255, 255, 0.85);
}

.tpl-action-btn.on-active:hover[b-3udwvvzf93] {
    background-color: rgba(255, 255, 255, 0.18);
    color: var(--vz-white);
}
/* /Components/Pages/ApprovalInboxDesk/ApprovalInbox.razor.rz.scp.css */
/*
    결재함 — 이 화면에서만 쓰는 CSS. Blazor CSS 격리(collocation)라 이 컴포넌트 밖으로 새지 않는다.

    ⛔ 새로 «디자인한» 값이 거의 없다. 대부분 원본 Svelte 컴포넌트의 <style> 블록을 그대로 옮긴 것이다:
        ApprovalInbox.svelte 1789~1957행  (.chip-row · .doc-stage-* · .appv-tab* · .inbox-search*)
        ApprovalTimeline.svelte 130~162행 (.timeline · .step-* · .mine-badge · .status-badge)
        ApprovalActionPanel.svelte 160~166행 (.action-panel · .panel-title · .action-row · .delegate-panel)

    ⛔⛔ 여기에 «없는» 것 두 개 — 셸이 서빙하는 global.css 에 이미 있다(실측 2026-08-30,
       JK.AI.Web/bin/Debug/net8.0/wwwroot/_app/immutable/assets/global.*.css):
         · .segtabs / .segtabs-item / .segtabs-n  (14건)
         · .jk-sel                                 (3건)
       ⛔ 사본을 만들지 마라 — 같은 클래스를 두 벌 두면 한쪽만 늙는다(MyWorkBoard.razor.css 의 교훈).
       ⛔ 특히 .jk-sel 을 Bootstrap 의 `.list-group-item.active` 로 되돌리지 마라 (2026-08-08 지적):
          그건 항목을 진한 primary + 흰 글자로 덮는데 안쪽 뱃지는 자기 색을 지켜 «파란 배경에 파란 글자»가 된다.

    ⛔ 새로 «만든» 것은 이 셸에 대응물이 없어서 생긴 넷뿐이고, 값은 이웃 규칙에서 빌려 왔다:
         .req-note (원본 3연 버튼 자리의 안내) · .attach-grid (원본 미리보기 패널 대체) ·
         .reason-text (RichRender 대체) · .picker-box (OrgPickerModal 대체)
*/

/* ── 카드 표면 ─────────────────────────────────────────────────────────────
   ⛔ 여기에 .card / .card-header / .card-body / .card-footer 를 다시 정의하지 마라.
      2026-09-04 에 MES(`/master`) 카드 규격이 «공용»으로 올라갔다 — 정본은 `wwwroot/app.css` 다.
      (테두리 #edf1f5 · 반경 10px · 그림자 없음 · 머리 20/20/14 · 몸 20 · 머리 아래 선 없음)
      이 화면에 사본을 두면 공용을 고칠 때 여기만 늙는다. */

/* ── 좌측 목록 ─────────────────────────────────────────────────────────── */
.inbox-list-body[b-r4491j75j6] {
    max-height: calc(100vh - 220px);
    overflow-y: auto;
}

/* 목록 행 — 카드 좌우 여백(20px)과 줄을 맞춘다(공용 카드 규격과 같은 자리).
   ⛔ 규칙을 둘로 나누지 않는다 — 같은 셀렉터를 두 번 쓰면 한쪽만 고쳐진다. */
.inbox-row[b-r4491j75j6] {
    cursor: pointer;
    padding-left: 20px;
    padding-right: 20px;
}

/* ⛔⛔ 유형 칩이 검색창과 한 줄을 나눠 쓰면 넘친 「수주」가 «소리 없이» 잘린다
   (SegTabs 는 overflow-x:auto 인데 scrollbar-width:none 이다 — 2026-08-18 실측).
   여기서만 wrap 을 허용해 두 줄로 접는다. ⛔ 칩을 더 늘릴 거면 이 규칙을 먼저 확인하라. */
.chip-row .segtabs[b-r4491j75j6] {
    flex-wrap: wrap;
    overflow-x: visible;
    max-width: 100%;
}

/* 두 줄이 되면 윗줄 칸의 아래 경계가 없어 칸이 흘러 보인다 — 가로 구분선을 준다.
   ⛔ 좌우 여백 11px 은 「칩 5개 합이 가용 폭을 6px 넘겨 「수주」가 접혔다」를 고친 값이다(2026-08-18). */
.chip-row .segtabs-item[b-r4491j75j6] {
    border-bottom: 1px solid var(--vz-border-color);
    padding-left: 11px;
    padding-right: 11px;
}

/* 도면·문서 단계 서브필터 — 1차 칩보다 한 단계 «조용한» 알약형. 시각 위계가 곧 개념 위계다. */
.doc-stage-row[b-r4491j75j6] {
    display: flex;
    gap: 6px;
    margin-top: 8px;
}

.doc-stage-chip[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    background: var(--vz-card-bg, #fff);
    border-radius: 999px;
    padding: 2px 11px;
    font-size: 12px;
    color: var(--vz-secondary-color);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.doc-stage-chip.active[b-r4491j75j6] {
    border-color: var(--vz-primary);
    color: var(--vz-primary);
    background: rgba(64, 81, 137, 0.06);
    font-weight: 500;
}

.doc-stage-chip .stage-count[b-r4491j75j6] {
    font-size: 12px;
    opacity: 0.75;
}

/* 「결재요청 · 배포요청 · 변경요청」 3연 버튼 — 원본 ApprovalInbox.svelte:1794~1811 그대로.
   ⛔ 값을 «다시 고르지» 마라. 이 버튼은 필터 칩 줄과 «한 줄»을 나눠 쓰므로 padding·font-size 가
      바뀌면 칩이 두 줄로 접히고, 접히면 「수주」가 아래로 내려가 "빠진 것처럼" 보인다. */
.req-group[b-r4491j75j6] {
    flex: 0 0 auto;
    display: inline-flex;
    gap: 0.375rem;
}

.req-btn[b-r4491j75j6] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
    padding: 0.4rem 0.7rem;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--vz-primary);
    background: var(--vz-secondary-bg, #fff);
    border: 1px solid var(--vz-primary);
    border-radius: 0.375rem;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
    cursor: pointer;
    transition: background-color 0.12s, color 0.12s, box-shadow 0.12s;
}

.req-btn i[b-r4491j75j6] {
    font-size: 14px;
}

.req-btn:hover:not(:disabled)[b-r4491j75j6] {
    background: var(--vz-primary);
    color: var(--vz-white, #fff);
    box-shadow: 0 2px 5px rgba(16, 24, 40, 0.12);
}

.req-btn:active:not(:disabled)[b-r4491j75j6] {
    transform: translateY(1px);
    box-shadow: none;
}

.req-btn:focus-visible[b-r4491j75j6] {
    outline: 2px solid var(--vz-primary);
    outline-offset: 2px;
}

.req-btn:disabled[b-r4491j75j6] {
    opacity: 0.55;
    cursor: default;
}

/* 리스트 검색 — 원본 .inbox-search 그대로.
   ⛔ 배경에 --vz-light 를 쓰지 마라 — 페이지 배경과 거의 같아 입력칸이 안 보인다(2026-08-08 지적). */
.inbox-search[b-r4491j75j6] {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 20px;
    padding: 6px 12px;
    color: var(--vz-secondary-color);
    flex: 1 1 200px;
    min-width: 160px;
}

.inbox-search:focus-within[b-r4491j75j6] {
    border-color: var(--vz-primary);
}

.inbox-search i[b-r4491j75j6] {
    font-size: 15px;
    flex-shrink: 0;
}

.inbox-search input[b-r4491j75j6] {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    outline: none;
    font-size: 13px;
    color: var(--vz-body-color);
}

/* 브라우저 기본 X 버튼은 테마를 안 따라간다 — 우리 버튼으로 대체한다. */
.inbox-search input[b-r4491j75j6]::-webkit-search-cancel-button {
    display: none;
}

.inbox-search-clear[b-r4491j75j6] {
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    padding: 0;
    line-height: 1;
    cursor: pointer;
}

.inbox-search-clear:hover[b-r4491j75j6] {
    color: var(--vz-primary);
}

/* ── 상세 구획 탭 — 카드 안쪽 «밑줄형».
   ⛔ 상단 서브탭(SegTabs)과 같은 모양으로 만들지 마라 — 2층 탭으로 읽힌다(2026-08-08). */
.appv-tabs[b-r4491j75j6] {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 2px;
    padding: 0 12px;
}

.appv-tab[b-r4491j75j6] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 0;
    background: transparent;
    border-bottom: 2px solid transparent;
    padding: 9px 12px;
    font-size: 13px;
    font-weight: 400;
    white-space: nowrap;
    color: var(--vz-secondary-color);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.appv-tab:hover[b-r4491j75j6] {
    color: var(--vz-primary);
}

/* ⛔ font-weight 는 500 까지. 활성은 색 + 밑줄 «둘 다»로 가른다. */
.appv-tab.on[b-r4491j75j6] {
    color: var(--vz-primary);
    border-bottom-color: var(--vz-primary);
    font-weight: 500;
}

.appv-tab:focus-visible[b-r4491j75j6] {
    outline: 2px solid var(--vz-primary);
    outline-offset: -2px;
}

/* ── 결재선 타임라인 (ApprovalTimeline.svelte 130~162행) ─────────────────── */
/* ⛔⛔ 이름이 «.timeline» 이면 Velzon 의 .timeline::before(2px 세로선)가 함께 걸린다 —
   단계 번호 앞에 「|」가 생긴다. 그래서 우리 이름(.appv-line)으로 끊었다. 되돌리지 마라. */
.appv-line[b-r4491j75j6] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.step-group[b-r4491j75j6] {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
}

/* 단계 번호 칸 — 번호를 카드 «머리줄 높이»에 맞춰 붙인다(위로 튀지 않게). */
.step-stage[b-r4491j75j6] {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding-top: 0.25rem;
}

.step-num[b-r4491j75j6] {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--vz-primary);
    color: var(--vz-white);
    font-size: 13px;
    font-weight: 600;
}

.step-list[b-r4491j75j6] {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* ⛔ 2026-09-01 지시 — 단계 하나가 «머리 있는 작은 카드»다.
   머리줄: 아이콘 · 이름 · 나/내 차례 · (위임) — 오른쪽에 상태·날짜.
   몸통: 의견(있을 때만). ⛔ 의견이 없으면 몸통을 그리지 않는다 — 빈 칸이 카드를 늘린다.
   ⛔ .step-item 은 더 쓰지 않는다(이 카드가 대신한다) — 되살릴 거면 한쪽을 지워라. */
.step-card[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    background: var(--vz-card-bg, #fff);
    overflow: hidden;
    font-size: 13px;
}

/* 내 차례인 단계만 «테두리»로 말한다 — 배경을 칠하면 상태 뱃지 색과 싸운다. */
.step-card.turn[b-r4491j75j6] {
    border-color: var(--vz-warning);
    box-shadow: 0 0 0 1px var(--vz-warning-border-subtle, rgba(247, 184, 75, 0.35));
}

.step-card-head[b-r4491j75j6] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    padding: 0.4rem 0.6rem;
    background: var(--vz-light);
    border-bottom: 1px solid transparent;
}

/* 몸통이 있을 때만 머리에 밑줄이 생긴다. */
.step-card-head:not(:last-child)[b-r4491j75j6] {
    border-bottom-color: var(--vz-border-color);
}

/* 상태·날짜는 «한 덩어리»로 오른쪽 끝에 붙인다 — 종전엔 날짜만 ms-auto 라 상태 뱃지가 이름에 붙어 흘렀다. */
.step-card-meta[b-r4491j75j6] {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
}

.step-date[b-r4491j75j6] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    white-space: nowrap;
}

.step-card-body[b-r4491j75j6] {
    padding: 0.45rem 0.6rem;
}

.approver[b-r4491j75j6] {
    font-weight: 500;
}

.status-badge[b-r4491j75j6] {
    font-size: 13px;
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--vz-secondary-bg-subtle, #eef0f5);
    color: var(--vz-secondary-color);
}

/* 본인 단계 표식 — 「내 차례」만 색을 쓴다. 「나」는 조용히(내 단계지만 아직/이미 지난 차례). */
.mine-badge[b-r4491j75j6] {
    font-size: 13px;
    padding: 1px 6px;
    border-radius: 3px;
    font-weight: 600;
    background: var(--vz-secondary-bg-subtle, #eef0f5);
    color: var(--vz-secondary-color);
}

.mine-badge.turn[b-r4491j75j6] {
    background: var(--vz-warning);
    color: var(--vz-white);
}

/* ⛔ 의견은 카드 «몸통» 안이라 더는 들여쓰기·기울임으로 구분하지 않는다.
   왼쪽 선 하나로 「인용」임을 말한다 — 긴 반려 사유에서 기울임체는 읽기 어렵다. */
.step-comment[b-r4491j75j6] {
    /* ⛔⛔ global.css 의 정본 규칙(.step-comment)이 «여기 없는 값»을 계속 먹인다 —
       italic 과 padding-left:1.5rem 이다. 둘 다 «명시»로 꺼야 한다(실측: 지우면 24px 이 돌아온다).
       2026-09-01 지시 「내용 앞 여백이 너무 많다」의 정체가 그 24px 이었다. */
    font-style: normal;
    padding-left: 0;
    color: var(--vz-body-color);
    font-size: 13px;
    white-space: pre-wrap;
    margin: 0;
}

.parallel-label[b-r4491j75j6] {
    padding-left: 0.5rem;
}


/* ── 결재 액션 패널 (ApprovalActionPanel.svelte 160~166행) ───────────────── */
.action-panel[b-r4491j75j6] {
    padding: 0.75rem;
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    background: var(--vz-secondary-bg);
}

.action-panel-disabled[b-r4491j75j6] {
    padding: 0.5rem 0;
    font-size: 13px;
}

.panel-title[b-r4491j75j6] {
    font-weight: 600;
    margin-bottom: 0.5rem;
    font-size: 13px;
}

.action-row[b-r4491j75j6] {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.delegate-panel[b-r4491j75j6] {
    padding: 0.5rem;
    background: var(--vz-light);
    border-radius: 4px;
}

/* OrgPickerModal 대체 목록 — 모달이 아니라 «그 자리»에 뜬다(결재 맥락을 끊지 않는다). */
.picker-box[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    background: var(--vz-card-bg, #fff);
    padding: 0.4rem;
}

.picker-list[b-r4491j75j6] {
    max-height: 220px;
    overflow-y: auto;
}

/* ── 내용 탭 ────────────────────────────────────────────────────────────── */
/* RichRender 대체 — 서식 없이 «원문 그대로». 줄바꿈은 살린다. */
.reason-text[b-r4491j75j6] {
    white-space: pre-wrap;
    word-break: break-word;
    font-family: inherit;
    font-size: 13px;
    color: var(--vz-body-color);
    background: var(--vz-light);
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    padding: 0.6rem;
    margin-bottom: 0.25rem;
}

/* 첨부 미리보기 — 원본 ApprovalAttachmentPanel 의 «썸네일 + 파일정보» 두 조각만 옮긴 것.
   ⛔ 핀 메모·3D 뷰어는 없다(화면이 그 사실을 말한다). */
.attach-grid[b-r4491j75j6] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.attach-card[b-r4491j75j6] {
    width: 200px;
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    overflow: hidden;
    background: var(--vz-card-bg, #fff);
}

/* ⛔ 2026-09-01 — 썸네일이 <a> 에서 <button> 이 됐다(새창 대신 파일 상세 모달).
   버튼 기본 스타일(테두리·배경·패딩)을 지우지 않으면 카드 안에 회색 상자가 생긴다. */
.attach-thumb[b-r4491j75j6] {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.attach-card img[b-r4491j75j6] {
    display: block;
    width: 100%;
    height: 130px;
    object-fit: contain;
    background: var(--vz-light);
}

.attach-meta[b-r4491j75j6] {
    padding: 0.4rem 0.5rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   D1 — 파일 선택 모달 · 변경요청 작성 모달 · AI 체크리스트 · 배포 정보 · 수주 상세
   ══════════════════════════════════════════════════════════════════════════ */

/* ⛔ 폴더 트리 스타일을 여기서 «덮지 않는다» — 2026-08-31 에 JkDmsPickerTree.razor.css 로 옮겼다.
      부품이 자기 스타일을 들고 있으면 어느 화면에서 열어도 같아 보인다.
      ⛔ 종전에 여기 있던 ::deep 사본은 값이 원본과 «달랐다»(0.85rem vs .9rem 등) —
         「같은 값」이라 적힌 주석과 달리 이미 갈라져 있었다. 그게 사본을 두면 생기는 일이다. */
/* 변경요청 작성 모달 — 원본 EcrCreateModal.svelte 218~250행 그대로.
   ⛔ 값을 새로 고르지 마라. 목록 화면(EcrList.razor.css)과 «같은 모달»이라 어긋나면 진입로마다 다르게 보인다. */
.pick-q[b-r4491j75j6] {
    font-weight: 500;
    margin-bottom: 8px;
}

.mode-seg[b-r4491j75j6] {
    display: inline-flex;
    gap: 0;
    margin-bottom: 10px;
    border: 1px solid var(--vz-border-color);
    border-radius: 7px;
    overflow: hidden;
}

.mode-seg button[b-r4491j75j6] {
    border: none;
    background: var(--vz-card-bg, #fff);
    padding: 5px 16px;
    font-size: 13px;
    color: var(--vz-secondary-color);
    cursor: pointer;
}

.mode-seg button.on[b-r4491j75j6] {
    background: var(--vz-primary);
    color: #fff;
}

.pick-list[b-r4491j75j6] {
    display: flex;
    flex-direction: column;
    gap: 3px;
    max-height: 190px;
    overflow-y: auto;
    border: 1px solid var(--vz-border-color);
    border-radius: 7px;
    padding: 5px;
}

.pick-row[b-r4491j75j6] {
    display: flex;
    align-items: center;
    gap: 7px;
    width: 100%;
    border: none;
    background: none;
    text-align: left;
    padding: 6px 8px;
    border-radius: 5px;
    cursor: pointer;
    font-size: 13px;
}

.pick-row:hover[b-r4491j75j6] {
    background: var(--vz-secondary-bg-subtle, #eef0f5);
}

.pick-row.on[b-r4491j75j6] {
    background: var(--vz-primary-bg-subtle, #eef0f7);
}

.pick-main[b-r4491j75j6] {
    font-weight: 500;
    flex-shrink: 0;
}

.pick-sub[b-r4491j75j6] {
    color: var(--vz-secondary-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pick-empty[b-r4491j75j6] {
    padding: 22px 8px;
    text-align: center;
    color: var(--vz-secondary-color);
    font-size: 13px;
}

.picked-row[b-r4491j75j6] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 9px;
}

.picked-label[b-r4491j75j6] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    margin-right: 3px;
}

.picked-chip[b-r4491j75j6] {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    background: var(--vz-primary-bg-subtle, #eef0f7);
    color: var(--vz-primary-text-emphasis, #2e3d6b);
    border-radius: 999px;
    padding: 2px 5px 2px 10px;
    font-size: 12px;
}

.picked-chip button[b-r4491j75j6] {
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
    padding: 0 2px;
    line-height: 1;
}

/* AI 결재 체크리스트 — 원본 ApprovalChecklistPanel.svelte 의 .checklist-panel 자리. */
.checklist-panel[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    padding: 0.6rem;
    background: var(--vz-card-bg, #fff);
}

.checklist-head[b-r4491j75j6] {
    display: flex;
    align-items: center;
    font-size: 13px;
    margin-bottom: 0.5rem;
}

.verdict-card[b-r4491j75j6] {
    border-radius: 6px;
    padding: 0.5rem 0.6rem;
    font-size: 12px;
    margin-bottom: 0.5rem;
}

.checklist-items[b-r4491j75j6] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.check-item[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    border-radius: 5px;
    padding: 0.4rem 0.5rem;
}

.check-item.failed[b-r4491j75j6] {
    border-color: var(--vz-danger-border-subtle, #f5c2c7);
}

.check-head[b-r4491j75j6] {
    display: flex;
    align-items: center;
    font-size: 12px;
}

.check-label[b-r4491j75j6] {
    font-weight: 500;
}

.check-summary[b-r4491j75j6] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    margin-top: 0.15rem;
    white-space: pre-wrap;
}

.check-sections[b-r4491j75j6] {
    margin: 0.25rem 0 0 1rem;
    padding: 0;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 배포 정보 — 원본 DistributionInfoCard.svelte(.blk / .kv / .targets).
   ⛔ 조건을 3열 가로로 되돌리지 마라 — 우측 패널 폭(~500px)에서 라벨이 잘리고 값이 붙는다. */
.dist-card[b-r4491j75j6] {
    margin-bottom: 0.5rem;
}

.dist-head[b-r4491j75j6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
}

.dist-title[b-r4491j75j6] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 13px;
    font-weight: 500;
}

.dist-title i[b-r4491j75j6] {
    font-size: 1rem;
    color: var(--vz-secondary-color);
}

.dist-meta[b-r4491j75j6] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 12px;
}

.dist-chip[b-r4491j75j6] {
    background: var(--vz-light);
    border-radius: 999px;
    padding: 1px 8px;
    color: var(--vz-secondary-color);
}

/* ⛔⛔ 2026-09-01 사용자 지시로 «간격만» 다시 잡았다 — 행이 붙어 읽히지 않았다.
   종전: .dist-kv 행 간격 0.2rem · 수령자 li 패딩 0.25rem → 글자 높이와 거의 같아
         어디까지가 한 행인지 눈으로 안 잘렸다.
   ⛔ 색·글자 크기는 «그대로»다(디자인 표준: 색을 새로 고르지 않는다). 바꾼 것은 여백·구획선뿐이다.
   ⛔ 조건을 3열 가로로 되돌리지 마라 — 우측 패널 폭(~500px)에서 라벨이 잘린다. */
.dist-body[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    padding: 0.75rem 0.85rem;
}

.dist-kv[b-r4491j75j6] {
    display: grid;
    grid-template-columns: 6.5rem 1fr;
    /* 행 0.2 → 0.55rem. 라벨과 값 사이(열)도 0.5 → 0.75rem 로 벌린다. */
    gap: 0.55rem 0.75rem;
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
}

.dist-kv dt[b-r4491j75j6] {
    color: var(--vz-secondary-color);
    font-weight: 400;
}

.dist-kv dd[b-r4491j75j6] {
    margin: 0;
    /* 값이 길면(메시지·만료 D-day) 라벨 옆에서 그대로 접힌다. */
    min-width: 0;
    overflow-wrap: anywhere;
}

.dist-sub[b-r4491j75j6] {
    margin-left: 0.35rem;
    color: var(--vz-secondary-color);
    font-size: 12px;
}

/* 조건(정의목록)과 수령자 목록을 «선 하나»로 가른다 — 종전에는 둘이 이어져 보였다. */
.dist-sub-head[b-r4491j75j6] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    margin: 0.85rem 0 0.35rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--vz-border-color);
}

.dist-targets[b-r4491j75j6] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.dist-targets li[b-r4491j75j6] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    /* 0.25 → 0.55rem. 행 높이가 글자보다 커야 한 행으로 읽힌다. */
    padding: 0.55rem 0;
    border-top: 1px solid var(--vz-border-color);
    font-size: 12px;
    line-height: 1.4;
}

.dist-targets li:first-child[b-r4491j75j6] {
    border-top: none;
    padding-top: 0;
}

.dist-targets li:last-child[b-r4491j75j6] {
    padding-bottom: 0;
}

.dist-ico[b-r4491j75j6] {
    color: var(--vz-secondary-color);
}

.dist-t-main[b-r4491j75j6] {
    min-width: 0;
    flex: 1;
    display: flex;
    gap: 0.4rem;
    align-items: baseline;
}

.dist-t-name[b-r4491j75j6] {
    font-weight: 500;
}

.dist-t-mail[b-r4491j75j6] {
    color: var(--vz-secondary-color);
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dist-t-side[b-r4491j75j6] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 12px;
    color: var(--vz-secondary-color);
    flex-shrink: 0;
}

.dist-t-prep i[b-r4491j75j6] {
    font-size: 0.5rem;
    margin-right: 0.2rem;
    vertical-align: middle;
}

.dist-note[b-r4491j75j6] {
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--vz-border-color);
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 변경요청 패널 머리 — 공유 컴포넌트(EcrDetailPanel)가 자기 헤더를 끄고 있어 여기서 한 줄만 그린다. */
.ecr-panel-head[b-r4491j75j6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/* 수주 결재 상세 KPI — 원본 SalesApprovalDetailPanel 의 .kpi 자리. */
.sales-kpi-label[b-r4491j75j6] {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--vz-secondary-color);
}

.sales-kpi[b-r4491j75j6] {
    font-size: 13px;
}

/* ── 결재 요청 사유 「더 보기 / 접기」 (2026-08-31) ─────────────────────────
   ⛔⛔ 「넘치는가」는 브라우저가 재다(ApprovalInbox.razor.js: syncReasonClamp).
      그 결과는 .reason-wrap[data-overflowing] «한 개»로만 들어온다 — 회로는 모른다.
   ⛔ 본문 박스(.reason-text)는 이 파일 365행에 «이미» 있다(테두리+라운드 4px).
      전역 jk-shell.css 의 .blk-body 를 감싸지 않는 이유다 — 감싸면 테두리가 두 겹이 된다.
   ⛔ 넘치지 않을 때는 clamped 의 «마스크»까지 꺼야 한다. max-height 만 풀면
      짧은 사유의 아랫부분이 흐려진 채로 남는다(에러 없이 «모양만» 틀리는 자리). */
.reason-wrap[b-r4491j75j6] {
    position: relative;
}

.reason-wrap:not([data-overflowing]) .reason-more[b-r4491j75j6] {
    display: none;
}

.reason-wrap:not([data-overflowing]) .reason-text.clamped[b-r4491j75j6] {
    max-height: none;
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
}

/* 넘칠 때만 버튼과 붙인다 — 안 넘치면 박스는 종전 모양 그대로여야 한다. */
.reason-wrap[data-overflowing] .reason-text[b-r4491j75j6] {
    margin-bottom: 0;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.reason-wrap .reason-more[b-r4491j75j6] {
    border: 1px solid var(--vz-border-color);
    border-top: 0;
    border-radius: 0 0 4px 4px;
    margin-bottom: 0.25rem;
}

/* ── 다운로드 이력(접근 로그) 표 (2026-08-31) ────────────────────────────────
   ⛔ 껍데기(.blk / .blk-head / .blk-title / .blk-body / .blk-meta.chips)는 전역
      wwwroot/jk-shell.css 184~198 이다. 여기서 다시 칠하지 마라.
   ⛔ 표는 부트스트랩 .table 을 쓴다 — 정본의 .tbl 사전을 옮기면 값이 두 벌이 된다.
      blk-body 의 라운드 안으로 표를 «자르는» overflow 만 여기서 준다. */
.access-log-body[b-r4491j75j6] {
    overflow: hidden;
}

.access-log-empty[b-r4491j75j6] {
    padding: 0.9rem 0.875rem;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

.access-log-table[b-r4491j75j6] {
    font-size: 12px;
}

.access-log-table th[b-r4491j75j6] {
    font-weight: 500;
    font-size: 12px;
    color: var(--vz-secondary-color);
    background: var(--vz-tertiary-bg);
    white-space: nowrap;
}

.access-log-table tr:last-child td[b-r4491j75j6] {
    border-bottom: 0;
}

/* ⛔ 2026-09-01 — 수령자 이름이 「김진 석」으로 잘려 있었다. 나머지 열이 고정폭(9.5+7+6+8rem)
   이라 이름 열에 남는 폭이 거의 없다. 이름은 «끊지 않고», 넘치면 말줄임으로 접는다. */
.access-log-name[b-r4491j75j6] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 8rem;
}

/* 시각·IP 는 «자릿수»가 맞아야 읽힌다(정본 .mono). */
.access-log-mono[b-r4491j75j6] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--vz-secondary-color);
}

/* ══ 파일 선택 모달 — 정본 DmsDocPicker.svelte <style>(627~719행) 이식 ══════════
   ⛔⛔ 이 CSS 는 global.css 에 «없다». Svelte 컴포넌트 <style> 안에 스코프돼 있어서,
      클래스 이름만 맞춰도 모양이 안 나온다(2026-08-31 사용자 지적의 원인).
   ⛔ Bootstrap .modal 로 되돌리지 마라 — 정본은 자체 레이아웃이다.
   ⛔ 트리 노드는 자식 컴포넌트(JkDmsPickerTree)가 그려 스코프 속성이 «안 붙는다» → ::deep 필요. */

/* ⛔⛔ 2026-09-01 — 파일 선택 모달 CSS 는 «공용 부품»으로 갔다:
     Components/Shared/DocPicker/JkDocPickerModal.razor.css
   ⛔ 여기로 되돌리지 마라. 스코프 CSS 는 그 부품의 마크업에만 붙는다. */


/* ⛔⛔ 2026-09-04 — QA시트 #77 의 `::deep .jk-rte` 두 줄은 «정본»(wwwroot/app.css 의 .jk-rte)으로
   올라갔다. 여기에 사본을 다시 만들지 마라 — #68 과 #77 이 같은 규칙을 두 벌 들고 있었다. */

/* ⛔ 확정 내용 구획(.jk-rel-*)의 CSS 는 «공용 부품»으로 옮겼다 —
   Components/Shared/PartRelease/JkPartReleaseContent.razor.css.
   ⛔ 여기에 사본을 만들지 마라(한쪽만 늙는다). */
/* /Components/Pages/ApprovalLineDesk/ApprovalDelegations.razor.rz.scp.css */
/* 위임 대상 선택 목록 — OrgPickerModal 자리를 대신하는 인라인 목록.
   ⛔ 모달이 아니라 카드 안이라 길어지면 폼이 통째로 밀린다. 높이만 잡고 스크롤을 준다.
   ⛔ overflow-x 를 hidden 으로 두지 않는다 — 좁은 폭에서 «가로 스크롤바가 하나 더» 생기는
      알려진 함정(feedback_overflow_hidden_forces_second_scrollbar)을 피한다. */
.jk-picker-list[b-whzg1y5nnt] {
    max-height: 220px;
    overflow-y: auto;
}
/* /Components/Pages/ApprovalLineDesk/PersonalApprovalTemplates.razor.rz.scp.css */
/* 결재선 편집기 스타일 — 원본 ApprovalLineEditor.svelte 의 <style> 블록(233~266행)을 그대로 옮겼다.
   ⛔ 색·크기를 새로 고르지 않았다. var(--vz-*) 는 Velzon 토큰이고 원본이 쓰던 그 이름이다.
   ⛔ 클래스 이름에 jk- 접두를 붙였다 — 이 셸의 공통 CSS(.step-row 등 흔한 이름)와 섞이지 않게. */

.jk-order-block[b-lgapb4nxgz] {
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    background: var(--vz-light);
    margin-bottom: 0.5rem;
}

.jk-order-header[b-lgapb4nxgz] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px dashed var(--vz-border-color);
}

.jk-order-num[b-lgapb4nxgz] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--vz-primary);
    color: var(--vz-white);
    font-size: 13px;
    font-weight: 600;
}

.jk-order-label[b-lgapb4nxgz] {
    font-size: 13px;
    color: var(--vz-secondary-color);
}

.jk-step-row[b-lgapb4nxgz] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0;
    font-size: 13px;
}

.jk-step-approver[b-lgapb4nxgz] {
    font-weight: 500;
}

.jk-step-affil[b-lgapb4nxgz] {
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 원본 .step-type-badge.ai (QA#192 — AI 단계에만 붙는다) */
.jk-step-badge[b-lgapb4nxgz] {
    display: inline-block;
    padding: 1px 6px;
    font-size: 13px;
    border-radius: 3px;
    background: #f0eaff;
    color: #6a3fc7;
}
/* /Components/Pages/ApprovalRequest/ApprovalRequestForm.razor.rz.scp.css */
/*
    결재 요청 — 원본 +page.svelte 의 <style>(1708~2678행)에서 «이 셸에서 살아 있는 것»만 옮겼다.

    ⛔ 원본의 `.approval-split { height: calc(100vh - var(--split-top)) }` 은 «옮기지 않았다».
       그 값은 마운트/리사이즈 때 JS 로 실측해 넣는 것이고, 원본이 「100vh 로 되돌리지 마라」
       「상수(110px)로 빼지도 마라 — 레일이 바뀌면 또 어긋난다」고 못박아 뒀다(1745~1752행).
       여기서 숫자를 지어내는 대신 이 셸의 일반 페이지 스크롤을 쓴다.
    ⛔ 확대/드래그(`.preview-zoomwrap`)·라이트박스(`.lightbox*`)·핀(`.preview-annotator-host`)
       규칙은 그 기능을 안 옮겼으므로 «죽은 CSS» 가 되지 않게 함께 뺐다.
*/

.approval-split[b-9gbbvrylkj] {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.split-preview-pane[b-9gbbvrylkj] {
    flex: 0 0 38%;
    max-width: 38%;
    padding: 12px;
    background: var(--vz-card-bg, #fff);
}

.split-form-pane[b-9gbbvrylkj] {
    flex: 1 1 auto;
    min-width: 0;
}

@media (max-width: 1199.98px) {
    .approval-split[b-9gbbvrylkj] { flex-direction: column; }
    .split-preview-pane[b-9gbbvrylkj] { flex: 1 1 auto; max-width: 100%; width: 100%; }
}

/* ══ 미리보기 · 대상 문서 — 정본 routes/dms/approvals/request/+page.svelte <style> 이식 ══
   ⛔⛔ 종전 이관본은 여기를 «자체 디자인»으로 다시 지었다(.preview-carousel · max-height:320px 등).
      그래서 화면이 정본과 통째로 달랐다 - 제목 입력, 미리보기 확대, 여러 건일 때 대상 문서까지.
      (2026-08-31 사용자 지적: "완전 다 달라. 똑같이 맞춰줘")
   ⛔ 규칙 안의 결정 주석을 지우지 마라 - 높이 500px, overflow:hidden, flex-shrink:1 은
      전부 사용자 지시로 정해진 값이다. 임의로 바꾸면 같은 지적이 다시 온다.
   ⛔ Svelte 의 :global(...) 은 Blazor 에서 ::deep 이다(자식 컴포넌트에 닿게 하는 축). */

/* ⛔ 확대(⑧)하면 내용이 스테이지를 넘친다 — `overflow: auto` 가 있어야 나머지를 볼 수 있다. */
.preview-zoomwrap[b-9gbbvrylkj] {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ⛔ 2026-08-21 지시 "미리보기 이미지는 스크롤이 없이 처음엔 나오게" —
	   `DrawingPinAnnotator` 의 이미지는 `width:100%; height:auto` 라 세로가 긴 도면이면
	   스테이지(4:3)를 넘쳐 아래가 잘렸다(overflow:hidden). 가로·세로 **둘 다** 담기게 바꾼다.
	   ⛔ `.dpa-imgwrap` 을 `fit-content` 로 함께 좁히지 않으면 **핀 위치가 어긋난다** —
	      핀은 그 래퍼 기준으로 절대 배치되기 때문이다. 한 짝으로 봐야 한다. */
.preview-annotator-host[b-9gbbvrylkj] {
    max-height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
}

.preview-annotator-host[b-9gbbvrylkj]  .dpa-root {
    max-height: 100%; min-height: 0;
}

.preview-annotator-host[b-9gbbvrylkj]  .dpa-imgwrap {
    width: fit-content;
    max-width: 100%;
    max-height: 100%;
}

.preview-annotator-host[b-9gbbvrylkj]  .dpa-img {
    width: auto;
    max-width: 100%;
    max-height: 100%;
}

/* 확대 상태에서만 「끌 수 있다」고 알린다. */
.preview-stage.panning[b-9gbbvrylkj] {
    cursor: grab;
}

.preview-stage.panning:active[b-9gbbvrylkj] {
    cursor: grabbing;
}

.preview-zoom-reset[b-9gbbvrylkj] {
    position: absolute;
    left: 8px;
    bottom: 8px;
    z-index: 3;
    border: 1px solid var(--vz-border-color);
    background: rgba(255, 255, 255, 0.92);
    border-radius: 6px;
    padding: 2px 8px;
    font-size: 12px;
    cursor: pointer;
}

.preview-stage[b-9gbbvrylkj] {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    /* ⛔ 600px 였다 (2026-05-27 에 300→600 으로 키운 자리). 2026-08-21 에 다시 줄인다 —
    그 높이 때문에 **대상 문서 목록이 화면 밖으로 밀려** 스크롤해야 보였다.
    크게 볼 수단은 따로 있다: 휠 확대(⑧)와 [상세보기] 버튼.
    2026-08-21 재조정: 400 → **500px** (사용자 지시). 폭 48% 와 같이 본다. */
    max-height: 500px;
    border-radius: 12px;
    background: white;
    border: 1px solid var(--vz-border-color);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
    /* ⛔ 2026-08-21 지시 ④ "미리보기는 스크롤은 안보이게" — 스크롤바를 만들지 않는다.
    확대는 `transform`(아래 preview-zoomwrap)으로 하고, 넘치는 부분은 잘라 낸다.
    ⛔ `overflow: auto` 로 바꾸지 마라 — 확대할 때마다 스크롤바 두 줄이 생긴다. */
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    /* ⛔⛔ `flex-shrink: 0` 이었다 (2026-08-21 지시: "수량이 많지 않을 경우에는 스크롤이
    안생겼으면"). 고정이면 대상 문서가 늘어날 때 **넘치는 쪽이 항상 목록**이라 스크롤이 났다.
    이제 미리보기가 먼저 양보한다 — 대상이 적으면 500px 그대로, 많으면 줄어들어 한 화면에 담긴다.
    ⛔ `min-height` 를 빼지 마라. 없으면 대상이 많을 때 도면이 알아볼 수 없게 납작해진다. */
    flex-shrink: 1;
    min-height: 260px;
    cursor: zoom-in;
    transition: box-shadow 0.15s;
}

.preview-stage:hover[b-9gbbvrylkj] {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
}

.preview-zoom-btn[b-9gbbvrylkj] {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--vz-border-color);
    color: var(--vz-body-color);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    opacity: 0;
    transition: opacity 0.15s, background 0.15s;
    z-index: 4;
    cursor: pointer;
}

.preview-stage:hover .preview-zoom-btn[b-9gbbvrylkj] {
    opacity: 1;
}

.preview-zoom-btn:hover[b-9gbbvrylkj] {
    background: white;
    color: var(--vz-primary);
}

/* ── 큰 프리뷰 좌우 네비 ── */
.preview-nav[b-9gbbvrylkj] {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid var(--vz-border-color);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    color: var(--vz-body-color);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s, transform 0.15s;
    z-index: 3;
}

.preview-stage:hover .preview-nav[b-9gbbvrylkj] {
    opacity: 1;
}

.preview-nav:hover[b-9gbbvrylkj] {
    background: white;
    color: var(--vz-primary);
}

.preview-nav-prev[b-9gbbvrylkj] {
    left: 12px;
}

.preview-nav-next[b-9gbbvrylkj] {
    right: 12px;
}

.preview-counter[b-9gbbvrylkj] {
    position: absolute;
    bottom: 12px;
    right: 12px;
    padding: 4px 12px;
    background: rgba(0, 0, 0, 0.72);
    color: white;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    z-index: 3;
}

.preview-counter-sep[b-9gbbvrylkj] {
    margin: 0 2px;
    opacity: 0.5;
}

/* 인라인 핀 주석 호스트 — stage 를 채우고 내부 이미지+핀을 폭 기준으로 fit, 넘치면 스크롤 */
.preview-annotator-host[b-9gbbvrylkj] {
    position: absolute;
    inset: 0;
    padding: 12px;
    overflow: auto;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.preview-iframe[b-9gbbvrylkj],
	.preview-pdf-object[b-9gbbvrylkj] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
    background: var(--vz-secondary-bg);
    z-index: 1;
}

.preview-image-fallback[b-9gbbvrylkj] {
    font-size: 4rem;
    color: var(--vz-secondary-color);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.preview-unsupported[b-9gbbvrylkj] {
    position: absolute;
    inset: 0;
    font-size: 2.8rem;
    padding: 24px;
    text-align: center;
    z-index: 1;
}

.preview-carousel[b-9gbbvrylkj] {
    padding-top: 14px;
    border-top: 1px solid var(--vz-border-color);
    flex: 0 0 auto;  /* QA#191: 내용 높이만큼 자연 확장 → pane 스크롤로 전체 노출 */
    display: flex;
    flex-direction: column;
}

.preview-carousel-header[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.preview-carousel-label[b-9gbbvrylkj] {
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--vz-secondary-color);
}

.preview-carousel-hint[b-9gbbvrylkj] {
    font-size: 13px;
    color: var(--vz-secondary-color);
    padding: 2px 8px;
    background: var(--vz-secondary-bg-subtle, #eef0f5);
    border-radius: 4px;
    font-variant-numeric: tabular-nums;
}

.preview-carousel-grid[b-9gbbvrylkj] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 10px;
    padding-right: 4px;
    align-content: start;  /* QA#191: 내부 스크롤 제거 — pane 전체 스크롤로 통일 */
}

.preview-thumb[b-9gbbvrylkj] {
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 4px;
    transition: transform 0.15s;
}

.preview-thumb:hover[b-9gbbvrylkj] {
    transform: translateY(-2px);
}

.preview-thumb-img[b-9gbbvrylkj] {
    position: relative;
    aspect-ratio: 1;
    background: white;
    border: 2px solid transparent;
    border-radius: 6px;
    overflow: hidden;
    transition: border-color 0.15s;
}

.preview-thumb.active .preview-thumb-img[b-9gbbvrylkj] {
    border-color: var(--vz-primary);
    box-shadow: 0 0 0 2px rgba(64, 81, 137, 0.2);
}

.preview-thumb:not(.active):hover .preview-thumb-img[b-9gbbvrylkj] {
    border-color: var(--vz-border-color, #c5c7ce);
}

.preview-thumb-img img[b-9gbbvrylkj] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.preview-thumb-fallback[b-9gbbvrylkj] {
    width: 100%; height: 100%;
    flex-direction: column;
    align-items: center; justify-content: center;
    gap: 4px;
    background: #f6f7f8;
    color: var(--vz-secondary-color);
}

.preview-thumb-fallback i[b-9gbbvrylkj] {
    font-size: 1.5rem;
}

.preview-thumb-fallback .small[b-9gbbvrylkj] {
    font-size: 11px; font-weight: 500;
}

/* ⭐ 썸네일 하단 상세 버튼 — 평소엔 숨기고 hover/포커스에서만 (2026-08-21). */
.preview-thumb-open[b-9gbbvrylkj] {
    position: absolute;
    left: 4px;
    right: 4px;
    bottom: 4px;
    z-index: 2;
    display: none;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 5px;
    background: rgba(17, 24, 39, 0.82);
    color: #fff;
    font-size: 11px;
    line-height: 1;
    padding: 4px 0;
    cursor: pointer;
}

.preview-thumb:hover .preview-thumb-open[b-9gbbvrylkj],
	.preview-thumb:focus-within .preview-thumb-open[b-9gbbvrylkj] {
    display: flex;
}

.preview-thumb-open:hover[b-9gbbvrylkj] {
    background: var(--vz-primary, #1a6fc4);
}

.preview-thumb-del[b-9gbbvrylkj] {
    position: absolute;
    top: 2px;
    right: 2px;
    z-index: 2;
    width: 18px;
    height: 18px;
    line-height: 1;
    display: none;              /* 평소엔 숨기고 hover 에서만 — 썸네일이 작다 */
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 12px;
    cursor: pointer;
    padding: 0;
}

/* ⛔ 무장(armed) 상태는 hover 가 풀려도 보여야 한다 — 안 그러면 「한 번 더」를 못 누른다. */
.preview-thumb-del.armed[b-9gbbvrylkj] {
    display: flex; background: #b91c1c;
}

.preview-thumb:hover .preview-thumb-del[b-9gbbvrylkj],
	.preview-thumb:focus-within .preview-thumb-del[b-9gbbvrylkj] {
    display: flex;
}

.preview-thumb-del:hover[b-9gbbvrylkj] {
    background: #b91c1c;
}

.preview-thumb-idx[b-9gbbvrylkj] {
    position: absolute;
    top: 4px;
    left: 4px;
    width: 18px;
    height: 18px;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    border-radius: 50%;
    font-size: 13px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}

.preview-thumb-name[b-9gbbvrylkj] {
    font-size: 13px;
    color: var(--vz-secondary-color);
    text-align: center;
    padding: 0 2px;
}

.preview-thumb.active .preview-thumb-name[b-9gbbvrylkj] {
    color: var(--vz-primary);
    font-weight: 600;
}

/* ── 폼 ── */
.field-group[b-9gbbvrylkj] { margin-bottom: 16px; }
.field-label[b-9gbbvrylkj] { font-size: 13px; font-weight: 500; display: block; margin-bottom: 6px; }
.field-label-optional[b-9gbbvrylkj],
.field-label-count[b-9gbbvrylkj] { font-size: 12px; font-weight: 400; color: var(--vz-secondary-color, #878a99); }
.field-label-row[b-9gbbvrylkj] { margin-bottom: 6px; }

/* 제목 입력 - ⛔ Bootstrap .form-control 로 되돌리지 마라. 정본은 «밑줄 한 줄 + 1.4rem 굵게»다
   (routes/dms/approvals/request/+page.svelte:1243 field-input-title). 화면에서 가장 먼저 눈에 띄는 차이였다. */
.field-input-title[b-9gbbvrylkj] {
    display: block;
    width: 100%;
    padding: 10px 0;
    font-size: 1.4rem;
    font-weight: 600;
    color: var(--vz-body-color);
    background: transparent;
    border: none;
    border-bottom: 2px solid var(--vz-border-color);
    outline: none;
    transition: border-color 0.15s;
}
.field-input-title[b-9gbbvrylkj]::placeholder { color: #c0c4cc; font-weight: 400; }
.field-input-title:focus[b-9gbbvrylkj] { border-bottom-color: var(--vz-primary); }

/* ⛔⛔ 2026-09-04 — QA시트 #68 의 `::deep .jk-rte` 두 줄은 «정본»(wwwroot/app.css 의 .jk-rte)으로
   올라갔다. 여기에 사본을 다시 만들지 마라 — 리치 에디터를 쓰는 화면이 늘면 한쪽만 늙는다. */

/* ── 결재 흐름 시각화 ── */
.flow-viz[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
    padding: 10px;
    margin-bottom: 10px;
    background: var(--vz-light, #f3f4f6);
    border-radius: 6px;
}

.flow-node[b-9gbbvrylkj] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 88px;
    padding: 6px 8px;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color, #e5e7eb);
    border-radius: 6px;
}

.flow-node.parallel[b-9gbbvrylkj] { border-style: dashed; }
.flow-node-header[b-9gbbvrylkj] { font-size: 12px; font-weight: 500; }
.flow-node-parallel-tag[b-9gbbvrylkj] { font-size: 12px; color: var(--vz-primary, #1f6feb); margin-left: 2px; }
.flow-node-label[b-9gbbvrylkj] { font-size: 12px; color: var(--vz-secondary-color, #878a99); }
.flow-node-icon i[b-9gbbvrylkj] { font-size: 18px; color: var(--vz-secondary-color, #878a99); }
.flow-node-avatar[b-9gbbvrylkj] { display: flex; align-items: center; gap: 4px; font-size: 12px; max-width: 140px; }
.flow-node-avatar.empty[b-9gbbvrylkj] { color: var(--vz-secondary-color, #878a99); }
.flow-node-name[b-9gbbvrylkj] { max-width: 110px; }
.flow-arrow i[b-9gbbvrylkj] { font-size: 18px; color: var(--vz-secondary-color, #878a99); }

/* ── 결재선 편집기 (ApprovalLineEditor 포팅) ── */
.line-editor-wrap[b-9gbbvrylkj] { display: flex; flex-direction: column; gap: 8px; }

.line-editor-empty[b-9gbbvrylkj] {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 18px;
    border: 1px dashed var(--vz-border-color, #e5e7eb);
    border-radius: 6px;
    color: var(--vz-secondary-color, #878a99);
}

.line-editor-empty i[b-9gbbvrylkj] { font-size: 28px; }

.order-block[b-9gbbvrylkj] {
    border: 1px solid var(--vz-border-color, #e5e7eb);
    border-radius: 6px;
    padding: 8px 12px;
    background: var(--vz-light, #f3f4f6);
}

/* ── 단계 순서 바꾸기 (QA시트 #71) ──
   ⛔ 여기서 `-webkit-user-drag: none` 을 주지 마라 — 그 한 줄이 draggable="true" 를 «이겨서»
      dragstart 가 아예 안 난다(에러도 경고도 없다, feedback_html5_drag_traps_in_blazor 1번).
   ⛔ 상태 표시 색은 이미 쓰는 토큰에서만 고른다(새 색 금지). */
.order-grip[b-9gbbvrylkj] {
    cursor: grab;
    color: var(--vz-secondary-color, #878a99);
    line-height: 1;
    /* 손잡이 위에서 글자가 잡히면 드래그 대신 «텍스트 선택»이 시작된다. */
    user-select: none;
}

.order-grip:active[b-9gbbvrylkj] { cursor: grabbing; }

.order-block.dragging[b-9gbbvrylkj] { opacity: .5; }

.order-block.drag-over[b-9gbbvrylkj] {
    border-color: var(--vz-primary);
    background: var(--vz-primary-bg-subtle);
}

/* ▲▼ — 마우스가 없어도 순서를 바꿀 수 있어야 한다(키보드·터치). */
.order-move[b-9gbbvrylkj] { display: inline-flex; align-items: center; gap: 2px; }

.order-header[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    padding-bottom: 6px;
    border-bottom: 1px dashed var(--vz-border-color, #e5e7eb);
}

.order-num[b-9gbbvrylkj] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--vz-primary, #1f6feb);
    color: #fff;
    font-size: 12px;
    font-weight: 500;
}

.order-label[b-9gbbvrylkj] { font-size: 12px; color: var(--vz-secondary-color, #878a99); }
.step-row[b-9gbbvrylkj] { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 13px; }

.step-type-badge[b-9gbbvrylkj] {
    display: inline-block;
    padding: 1px 6px;
    font-size: 12px;
    background: var(--vz-secondary-bg-subtle, #eef0f5);
    color: var(--vz-secondary-color, #878a99);
    border-radius: 3px;
}

.step-type-badge.ai[b-9gbbvrylkj] { background: #f0eaff; color: #6a3fc7; }

/* ── 템플릿 드롭다운 ── */
.template-dropdown[b-9gbbvrylkj] { position: relative; }

.template-menu[b-9gbbvrylkj] {
    position: absolute;
    right: 0;
    z-index: 1050;
    min-width: 240px;
    max-height: 320px;
    overflow-y: auto;
}

.template-item[b-9gbbvrylkj] { display: flex; align-items: center; gap: 4px; width: 100%; text-align: left; }
.template-scope[b-9gbbvrylkj] { font-size: 12px; color: var(--vz-secondary-color, #878a99); }

/* ── 액션 바 ──
   ⛔ position: sticky/fixed 로 되돌리지 마라 — 결재선이 짧을 때 빈 공간이 크게 벌어진다
      (원본 1494~1496행). 결재선 «바로 아래»에 붙인다. */
.form-action-bar[b-9gbbvrylkj] {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--vz-border-color, #e5e7eb);
}

/* ── 인라인 핀 메모가 들어간 미리보기 스테이지 (2026-08-31) ────────────────────
   ⛔⛔ 기본 .preview-stage 는 «가운데 정렬 + overflow:hidden» 이다. 도면은 세로가 길어
      그대로 두면 아래쪽이 잘리고, 그 자리에 찍힌 핀은 «보이지도 눌리지도» 않는다.
      에러가 안 나는 종류의 결함이라 여기서 명시적으로 푼다.
   ⛔ 핀·라벨 자체(.dpa-*)는 전역 wwwroot/jk-shell.css 236~260 이다 — 여기서 다시 칠하지 마라.
   ⛔ 스코프 CSS 는 자식 컴포넌트(JkDrawingPinAnnotator)가 그린 노드에 «안 붙는다».
      그래서 이 규칙은 스테이지 «자신»에만 건다(자식은 전역 클래스로 이미 서 있다). */
.preview-stage.has-annotator[b-9gbbvrylkj] {
    display: block;
    align-items: initial;
    justify-content: initial;
    max-height: 520px;
    overflow: auto;
    background: var(--vz-secondary-bg);
}


/* ══ 되살림 (2026-08-31) ══════════════════════════════════════════════
   ⛔⛔ 위 미리보기 구간을 정본에서 이식하면서 «정본에 없는» 규칙까지 같이 지웠다.
      이 클래스들은 정본 쪽에 대응이 없고(문서 메타 요약 · 결재 흐름 양끝 · 버튼 줄) Blazor 가
      자체로 만든 것이라, 정본 <style> 을 훑는 방식으로는 «복원 대상으로 보이지 않는다».
   ⛔ 구간을 통째로 갈아끼울 때는 「마크업이 아직 쓰는 class 인가」를 먼저 대조할 것 —
      지워도 빌드·테스트가 통과하고 화면만 조용히 무스타일이 된다(감사 스크립트가 이걸 잡았다). */

/* ⛔⛔ 2026-09-01 — 이관본이 정본보다 «작게» 적어 놨었다(13px/12px). 사용자 지적으로 정본 값 복원.
   정본 +page.svelte:1990~2029 — title 0.95rem/600 · meta 0.9rem · item 0.9rem(gap 6px).
   ⛔ px 로 되돌리지 마라. 크기를 새로 고르지도 마라 — 정본이 정한 값이다. */
.preview-info-title[b-9gbbvrylkj] {
    font-size: 14px; font-weight: 600; margin-bottom: 4px;
    color: var(--vz-body-color);
}

.preview-info-meta[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 13px;
}

/* ⛔ 크기를 여기서 다시 정하지 않는다 — 정본은 .preview-info-meta 에서 물려받는다. */
.preview-catpath[b-9gbbvrylkj] {
    color: var(--vz-secondary-color, #878a99);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ⛔ 정본은 grid 가 «아니라» flex 다(+page.svelte:2014). auto-fit·minmax 로 두면
   좁은 칸에서 칸이 접혀 「리비전」이 아래 줄로 떨어진다(2026-08-31 지적).
   ⛔ 되돌리지 마라 — 한 줄로 흐르다가 «정말 넘칠 때만» 접히는 것이 정본 동작이다. */
.preview-info-grid[b-9gbbvrylkj] {
    margin-top: 8px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 16px;
    min-width: 0;
}

.preview-info-item[b-9gbbvrylkj] {
    display: flex; align-items: center; gap: 6px; font-size: 13px; min-width: 0;
}

.preview-info-item i[b-9gbbvrylkj] {
    color: var(--vz-secondary-color, #878a99);
    flex-shrink: 0;
}

.preview-info-key[b-9gbbvrylkj] {
    color: var(--vz-secondary-color, #878a99);
}

.preview-info-val[b-9gbbvrylkj] {
    font-weight: 500;
}


/* ⛔ 이관 때 «빠진» 규칙 — 마크업은 쓰는데 정의가 한 번도 없었다(감사에서 발견, 2026-08-31).
   정본 +page.svelte:2239·2362 에 있다. 결재 흐름 양끝 노드와 하단 버튼 줄이다. */

.form-action-left[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.form-action-right[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.form-action-right .btn-lg[b-9gbbvrylkj] {
    font-weight: 600;
    padding: 10px 24px;
    font-size: 14px;
}

.flow-node-start[b-9gbbvrylkj], .flow-node-end[b-9gbbvrylkj] {
    align-items: center;
    justify-content: center;
    background: var(--vz-light);
    min-width: 80px;
}

.flow-node-start .flow-node-icon[b-9gbbvrylkj],
	.flow-node-end .flow-node-icon[b-9gbbvrylkj] {
    width: 32px; height: 32px;
    border-radius: 50%;
    background: var(--vz-primary);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
}

.flow-node-end .flow-node-icon[b-9gbbvrylkj] {
    background: var(--vz-success);
}

/* ⛔⛔ 2026-09-01 — 아이콘 «글리프»가 회색이라 파란/초록 원 위에서 안 보였다.
   위 규칙이 `.flow-node-icon` 에 `color: white` 를 줬지만, 안쪽 <i> 를
   `.flow-node-icon i { color: var(--vz-secondary-color) }`(위 490~509 묶음)가 다시 덮는다.
   ⛔ 그쪽 회색을 지우지 마라 — 흐름 중간 노드(요청자/단계)는 그 회색이 맞다.
      여기서 «원이 있는 두 노드만» 되돌린다. inherit 이라 배경색이 바뀌어도 따라간다. */
.flow-node-start .flow-node-icon i[b-9gbbvrylkj],
.flow-node-end .flow-node-icon i[b-9gbbvrylkj] {
    color: inherit;
}


/* ══ 정본 스타일 이식 (2026-08-31 스타일 감사) ══════════════════════
   마크업은 쓰는데 «어느 CSS 에도 정의가 없던» 클래스들이다 - 화면이 조용히 무스타일이었다.
   출처: JK.AI.Front/src/routes/dms/approvals/request/+page.svelte
   ⛔ 정본에 «없는» 클래스는 이식하지 않았다 - 정본과 동일하게 맞추는 것이 지시다.
   ⛔ 자식 컴포넌트가 그리는 노드는 스코프가 달라 ::deep 이 필요하다(정본의 :global 과 같은 축). */

.preview-info[b-9gbbvrylkj] {
    padding: 14px 4px 12px;
    flex-shrink: 0;
}


/* 폼 머리 — 정본 +page.svelte:2211 이식 (2026-08-31).
   ⛔ 페이지 상단 헤더를 없앤 자리를 이것이 대신한다. 둘을 «같이» 두지 마라. */

/* ⛔ `.split-topbar*` CSS 제거 (2026-08-20) — 상단 스티키 바를 없애면서 죽은 규칙이 됐다.
	   헤더는 `.form-head*` 이 대신한다. */
	.draft-indicator[b-9gbbvrylkj] {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    background: var(--vz-success-bg-subtle, #e8f6ee);
    color: var(--vz-success);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
}

/* ── 폼 헤더 (종전 상단 스티키 바에서 옮겨 옴, 2026-08-20 지시 ⑨) ── */
	.form-head[b-9gbbvrylkj] {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 18px;
}

.form-head-back[b-9gbbvrylkj] {
    flex: 0 0 auto;
}

.form-head-text[b-9gbbvrylkj] {
    min-width: 0; flex: 1 1 auto;
}

.form-head-title[b-9gbbvrylkj] {
    font-size: 1rem; font-weight: 500; line-height: 1.2;
}

.form-head-sub[b-9gbbvrylkj] {
    font-size: 13px;
    color: var(--vz-secondary-color);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Pages/ChangeControl/BomImpactDecision.razor.rz.scp.css */
/* BOM 변경 영향 결정 — 정본 plm/bom-impact/[id]/+page.svelte 의 인라인 style 을 옮긴 것뿐이다. */

/* 정본 `style="cursor: pointer"` — 옵션 카드 전체가 클릭 대상이다. */
.bom-opt[b-dq8aa893cb] { cursor: pointer; }

/* 정본 `style="max-width:200px"` (발효일 입력) */
.bom-eff[b-dq8aa893cb] { max-width: 200px; }
/* /Components/Pages/ChangeControl/EcoDetail.razor.rz.scp.css */
/* 변경지시서 상세 — 정본 plm/eco/[id]/+page.svelte 의 인라인 style 을 옮긴 것뿐이다.
   ⛔ 새 디자인을 만들지 않는다. */

/* 정본 `style="height:6px"` */
.eco-bar[b-77tpyzju22] { height: 6px; }

/* 정본 `style="width:110px"` (영향 등급 열) */
.eco-th-risk[b-77tpyzju22] { width: 110px; }

/* 미이관 안내 한 줄 — 표 아래 보조 문구. 본문보다 작게. */
.eco-note[b-77tpyzju22] { font-size: 12px; }
/* /Components/Pages/ChangeControl/EcrList.razor.rz.scp.css */
/* 변경요청 목록 — 정본 plm/ecr/+page.svelte 의 <style> 블록을 그대로 옮겼다.
   ⛔ 새 디자인을 만들지 않는다. 인라인 style 로 흩어져 있던 것도 여기로 모았다
      (Blazor 스코프 CSS 라 이 컴포넌트 밖으로 새지 않는다). */

/* 툴바 — 검색 / 액션. 좁아지면 검색이 먼저 줄고, 액션은 끝까지 붙어 있는다. */
.ecr-actions[b-ga25znxmwz] { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

.ecr-search[b-ga25znxmwz] {
    display: flex; align-items: center; gap: 8px;
    /* ⛔ `max-width` 를 다시 걸지 마라 — 좌측 칼럼이 이미 좁아(col-lg-5) 상한을 또 걸면
       검색칸 오른쪽에 쓸모없는 빈 공간이 남는다. 줄어들 수 있게 둔다(min-width:0). */
    flex: 1 1 auto; min-width: 0;
    /* ⛔ 배경을 --vz-light 로 두면 페이지 배경과 거의 같아 입력칸이 안 보인다
       (2026-08-08 사용자 지적 "검색창 배경색상은 흰색으로"). */
    background: var(--vz-card-bg, #fff); border: 1px solid var(--vz-border-color);
    border-radius: 20px; padding: 6px 12px; color: var(--vz-secondary-color);
}
.ecr-search:focus-within[b-ga25znxmwz] { border-color: var(--vz-primary); }
.ecr-search i[b-ga25znxmwz] { font-size: 15px; flex-shrink: 0; }
.ecr-search input[b-ga25znxmwz] {
    flex: 1; min-width: 0; border: 0; background: transparent; outline: none;
    font-size: 13px; color: var(--vz-body-color);
}
.ecr-search input[b-ga25znxmwz]::-webkit-search-cancel-button { display: none; }
.ecr-search-clear[b-ga25znxmwz] {
    border: 0; background: transparent; color: var(--vz-secondary-color);
    padding: 0; line-height: 1; cursor: pointer;
}
.ecr-search-clear:hover[b-ga25znxmwz] { color: var(--vz-primary); }

/* 빈 상태 */
.empty-state[b-ga25znxmwz] {
    text-align: center; padding: 60px 20px;
    color: var(--vz-secondary-color);
}
/* ⛔ `>` 다. 자손 선택자였을 때 빈 상태 «안의 버튼 아이콘까지» 3rem 블록이 되어
   「조건 지우고 전체 보기」가 회색 덩어리로 나왔다 (2026-08-17 실측). */
.empty-state > i[b-ga25znxmwz] { font-size: 3rem; margin-bottom: 12px; display: block; }
.empty-state h5[b-ga25znxmwz] { margin-bottom: 4px; }

/* 목록 — 결재함 좌측 리스트와 같은 밀도/스크롤 규칙 */
.cr-list[b-ga25znxmwz] { max-height: calc(100vh - 260px); overflow-y: auto; }

/* 원본이 인라인 style 로 주던 값들 */
.ecr-no[b-ga25znxmwz] { font-size: 13px; color: var(--vz-primary); }
.ecr-title[b-ga25znxmwz] { font-size: 13px; }
.ecr-meta[b-ga25znxmwz] { font-size: 13px; color: var(--vz-tertiary-color); }
.ecr-progress[b-ga25znxmwz] { font-size: 12px; color: var(--vz-tertiary-color); }
.ecr-hint[b-ga25znxmwz] { font-size: 12px; }
.ecr-hint-icon[b-ga25znxmwz] { font-size: 2rem; }

/* ── 작성 모달 (정본 EcrCreateModal.svelte <style>) ── */
.pick-q[b-ga25znxmwz] { font-weight: 500; margin-bottom: 8px; }

.mode-seg[b-ga25znxmwz] {
    display: inline-flex; gap: 0; margin-bottom: 10px;
    border: 1px solid var(--vz-border-color); border-radius: 7px; overflow: hidden;
}
.mode-seg button[b-ga25znxmwz] {
    border: none; background: var(--vz-card-bg, #fff); padding: 5px 16px;
    font-size: 13px; color: var(--vz-secondary-color); cursor: pointer;
}
.mode-seg button.on[b-ga25znxmwz] { background: var(--vz-primary); color: #fff; }

.pick-list[b-ga25znxmwz] {
    display: flex; flex-direction: column; gap: 3px;
    max-height: 190px; overflow-y: auto;
    border: 1px solid var(--vz-border-color); border-radius: 7px; padding: 5px;
}
.pick-row[b-ga25znxmwz] {
    display: flex; align-items: center; gap: 7px; width: 100%;
    border: none; background: none; text-align: left;
    padding: 6px 8px; border-radius: 5px; cursor: pointer; font-size: 13px;
}
.pick-row:hover[b-ga25znxmwz] { background: var(--vz-secondary-bg-subtle, #eef0f5); }
.pick-row.on[b-ga25znxmwz] { background: var(--vz-primary-bg-subtle, #eef0f7); }
.pick-main[b-ga25znxmwz] { font-weight: 500; flex-shrink: 0; }
.pick-sub[b-ga25znxmwz] { color: var(--vz-secondary-color); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-empty[b-ga25znxmwz] { padding: 22px 8px; text-align: center; color: var(--vz-secondary-color); font-size: 13px; }

.picked-row[b-ga25znxmwz] { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.picked-label[b-ga25znxmwz] { font-size: 12px; color: var(--vz-secondary-color); margin-right: 3px; }
.picked-chip[b-ga25znxmwz] {
    display: inline-flex; align-items: center; gap: 3px;
    background: var(--vz-primary-bg-subtle, #eef0f7); color: var(--vz-primary-text-emphasis, #2e3d6b);
    border-radius: 999px; padding: 2px 5px 2px 10px; font-size: 12px;
}
.picked-chip button[b-ga25znxmwz] { border: none; background: none; color: inherit; cursor: pointer; padding: 0 2px; line-height: 1; }

/* ── 모바일 ── */
@media (max-width: 768px) {
    .cr-list[b-ga25znxmwz] { max-height: none; }
}
/* /Components/Pages/DistributionDesk/DistributionDetail.razor.rz.scp.css */
/* 원본 JK.AI.Front/src/routes/dms/distributions/[id]/+page.svelte 의 <style>(287~294행) 그대로.
   ⛔ 값을 «다듬지 않는다» — 디자인은 새로 만들지 않는다. */


.link-label[b-xmvi0a31gu] {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--vz-secondary-color);
    margin-bottom: 0.25rem;
}

.link-row[b-xmvi0a31gu] { display: flex; gap: 0.5rem; align-items: center; }

.link-input[b-xmvi0a31gu] {
    font-family: var(--vz-font-monospace, monospace);
    background: var(--vz-tertiary-bg);
}

.modal-backdrop-custom[b-xmvi0a31gu] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1050;
}

.modal-card[b-xmvi0a31gu] {
    background: var(--vz-secondary-bg);
    padding: 1.25rem;
    border-radius: 8px;
    min-width: 480px;
    max-width: 560px;
}

/* 원본 227행 인라인 style="max-height: 200px; overflow-y: auto" */
.guard-hits[b-xmvi0a31gu] { max-height: 200px; overflow-y: auto; }
/* /Components/Pages/DistributionDesk/DistributionRequestForm.razor.rz.scp.css */
/* 원본 JK.AI.Front/src/routes/dms/distributions/request/+page.svelte 의 <style>(627~657행) 그대로.
   ⛔ 값을 «다듬지 않는다» — 디자인은 새로 만들지 않는다. */


.modal-backdrop-custom[b-rzk4lnh8ng] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1050;
}

.modal-card[b-rzk4lnh8ng] {
    background: var(--vz-secondary-bg);
    padding: 1.25rem;
    border-radius: 8px;
    min-width: 480px;
    max-width: 560px;
}

.doc-list[b-rzk4lnh8ng] { max-height: 220px; overflow-y: auto; }
.doc-row[b-rzk4lnh8ng] { padding: 4px 0; border-bottom: 1px solid var(--vz-border-color, #eee); }
.doc-row:last-child[b-rzk4lnh8ng] { border-bottom: none; }

.autocomplete-dropdown[b-rzk4lnh8ng] {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    max-height: 280px;
    overflow-y: auto;
    z-index: 1055;
    margin-top: 2px;
}

.autocomplete-item[b-rzk4lnh8ng] {
    display: block;
    width: 100%;
    text-align: left;
    padding: 6px 10px;
    background: transparent;
    border: none;
    font-size: 13px;
    cursor: pointer;
}

.autocomplete-item.highlighted[b-rzk4lnh8ng],
.autocomplete-item:hover[b-rzk4lnh8ng] { background: var(--vz-tertiary-bg); }
/* /Components/Pages/Distribution/DistributionAiGuard.razor.rz.scp.css */
/* 원본 ai-guard/+page.svelte 의 <style> 블록(218~220행) 그대로 이식. */

/* /Components/Pages/Distribution/DistributionMonitor.razor.rz.scp.css */
/* 원본 monitor/+page.svelte 의 <style> 블록(308~318행) 그대로 이식.
   ⛔ 디자인을 «새로 만들지 않는다» — 값(폭·색·그림자)을 원본과 같게 둔다. */


.drawer-backdrop[b-lg4h9g1eu1] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 1050;
}

.drawer[b-lg4h9g1eu1] {
    position: fixed;
    right: 0;
    top: 0;
    bottom: 0;
    width: 640px;
    max-width: 90vw;
    background: var(--vz-secondary-bg);
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.1);
    display: flex;
    flex-direction: column;
}

.drawer-head[b-lg4h9g1eu1] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid var(--vz-border-color);
}

.drawer-body[b-lg4h9g1eu1] {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
}

.modal-backdrop-custom[b-lg4h9g1eu1] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1055;
}

.modal-card[b-lg4h9g1eu1] {
    background: var(--vz-secondary-bg);
    padding: 1.25rem;
    border-radius: 8px;
    min-width: 480px;
    max-width: 560px;
}
/* /Components/Pages/Distribution/DistributionPolicy.razor.rz.scp.css */
/* 원본 policy/+page.svelte 의 <style> 블록(263~284행) 그대로 이식.
   ⛔ 디자인을 «새로 만들지 않는다» — 값(색·간격)을 원본과 같게 둔다. */


.sticky-preview[b-jbt9ixfv4q] {
    position: sticky;
    top: 80px;
}

.preview-frame[b-jbt9ixfv4q] {
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    background: linear-gradient(180deg, var(--vz-tertiary-bg) 0%, var(--vz-border-color) 100%);
    padding: 12px;
    display: flex;
    justify-content: center;
}

.preview-svg[b-jbt9ixfv4q] {
    width: 100%;
    max-width: 320px;
    height: auto;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    background: var(--vz-secondary-bg);
}
/* /Components/Pages/Distribution/DistributionRegister.razor.rz.scp.css */
/* 원본 register/+page.svelte 의 <style> 블록(425~455행) 이식.
   ⛔ 디자인을 «새로 만들지 않는다» — 값(색·간격·그림자)을 원본과 같게 둔다.
   ⚠️ .register-row 의 `cursor: pointer` 는 계속 «뺀 채로» 둔다.
      2026-08-30 에 문서 상세 오버레이가 이 셸에 생겼지만, 이 화면은 «행 전체»가 아니라
      «문서명 버튼»만 그것을 연다. 행에 손가락 커서를 되살리면 «눌러도 아무 일이 없는» 자리가
      다시 생긴다 — 행 전체 클릭을 옮기는 날 함께 되돌린다. */


.register-row[b-nau8dfbggv] {
    transition: background-color 0.12s;
}

.register-row:hover[b-nau8dfbggv] {
    background: var(--vz-tertiary-bg);
}

.autocomplete-dropdown[b-nau8dfbggv] {
    position: absolute;
    top: 100%;
    left: 12px;
    right: 12px;
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    max-height: 280px;
    overflow-y: auto;
    z-index: 1055;
    margin-top: 2px;
}

.autocomplete-item[b-nau8dfbggv] {
    display: block;
    width: 100%;
    text-align: left;
    padding: 6px 10px;
    background: transparent;
    border: none;
    font-size: 13px;
    cursor: pointer;
}

.autocomplete-item.highlighted[b-nau8dfbggv],
.autocomplete-item:hover[b-nau8dfbggv] {
    background: var(--vz-tertiary-bg);
}

.card-animate[b-nau8dfbggv] {
    transition: all 0.5s ease;
}

.card-animate:hover[b-nau8dfbggv] {
    transform: translateY(calc(-1.5px));
    box-shadow: 0 5px 10px rgba(30, 32, 37, 0.12);
}

/* 회수 모달 — 원본은 window.prompt() 라 스타일이 없다.
   같은 배치의 배포 모니터링 모달(monitor/+page.svelte 316~317행)과 «같은 값»을 쓴다. */
.modal-backdrop-custom[b-nau8dfbggv] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1055;
}

.modal-card[b-nau8dfbggv] {
    background: var(--vz-secondary-bg);
    padding: 1.25rem;
    border-radius: 8px;
    min-width: 480px;
    max-width: 560px;
}
/* /Components/Pages/Dms.razor.rz.scp.css */
/*
    문서함 AI 필터 칩 — 정본 routes/dms/+page.svelte 의 <style> 블록 그대로.

    ⛔ 여기 있는 이유: 컨테이너(.dms-ai-filters)는 wwwroot/jk-shell.css 에 이미 있는데
       «칩 알맹이»(.filter-chip / .chip-count)는 없다. 정본에서 그 두 규칙만 라우트 파일의
       scoped style 에 있었고, gen-blazor-shell-css.py 가 뽑아 온 것은 컴포넌트 청크뿐이라
       빠졌다. jk-shell.css 는 «생성물»이라 손으로 고치지 않는다 — 화면 옆에 붙여 둔다.

    ⛔ 스코프 CSS 다. 이 규칙은 Dms.razor 가 «직접 그린» 요소에만 붙는다
       (JS·MarkupString 으로 만든 노드에는 안 붙는다 — 공용부 계약 §4-B 함정표).
*/

.filter-chip[b-s5oaibjzta] {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    font-size: 13px;
    border-radius: 999px;
    border: 1px solid var(--vz-border-color);
    background: white;
    color: var(--vz-body-color);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.filter-chip:hover[b-s5oaibjzta] {
    border-color: var(--vz-primary);
}

.filter-chip.active[b-s5oaibjzta] {
    background: var(--vz-primary);
    border-color: var(--vz-primary);
    color: white;
}

.chip-count[b-s5oaibjzta] {
    margin-left: 6px;
    padding: 0 6px;
    font-size: 13px;
    font-weight: 600;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.08);
    color: inherit;
}

.filter-chip.active .chip-count[b-s5oaibjzta] {
    background: rgba(255, 255, 255, 0.22);
}

/* ──────────────────────────────────────────────────────────────────────────
   문서 검색 툴바 — 정본 $lib/components/dms/DmsSearchBar.svelte 의 <style>(144~148행) 그대로.

   ⛔ 여기 있는 이유: 이 세 규칙은 정본에서 Svelte 스코프 «안»에 갇혀 있었다. 그래서
      scripts/gen-blazor-shell-css.py 가 뽑아 온 wwwroot/jk-shell.css 에도, 서빙 global.css 에도
      «0건»이다(2026-08-31 실측). .dms-toolbar 자체(jk-shell.css:589)만 넘어왔다.
   ⛔ 값을 새로 고르지 않았다 — 원본 숫자 그대로다(디자인 표준: 색·크기를 새로 고르지 말 것).
   ⛔ 스코프 CSS 다. Dms.razor 가 «직접 그린» 요소에만 붙는다 — 공유 컴포넌트(카드 그리드·
      상세 오버레이)가 그린 버튼에는 안 붙는다. 그쪽은 그쪽 .razor.css 의 몫이다.
   ────────────────────────────────────────────────────────────────────────── */

/* 정본 :144~147 — 인라인 style(min-width:58px) + .text-muted 로 흉내 내던 것을 되돌린 자리.
   ⛔ font-weight:600 · min-width:44px 가 정본 값이다. */
.toolbar-zoom-label[b-s5oaibjzta] {
    font-size: 13px;
    font-weight: 600;
    min-width: 44px;
    text-align: center;
    color: var(--vz-secondary-color);
}

/* 정본 .toolbar-divider — 줌 그룹 앞뒤로 «2개» 들어간다(DmsSearchBar.svelte:101 · 113). */
.toolbar-divider[b-s5oaibjzta] {
    width: 1px;
    height: 18px;
    background: var(--vz-border-color);
    margin: 0 3px;
}

/* 정본 :148 — Velzon 의 .btn-icon 은 padding:0 이라 아이콘이 사각 박스에 꽉 찬다.
   ⛔⛔ 전역에 풀지 마라. .btn-icon 은 다른 화면도 쓴다 — 정본도 «스코프»로만 덮어썼다.
   ⛔ 스코프 선택자는 `.btn-icon[b-xxxxx]`(0,2,0)라 global.css 의 `.btn-icon`(0,1,0)을 이긴다. */
.btn-icon[b-s5oaibjzta] {
    padding: 0.2rem 0.35rem;
    line-height: 1;
}


/* ══ 정본 스타일 이식 (2026-08-31 DOM 대조) ══════════════════════════════════
   출처: JK.AI.Front/src/lib/components/dms/DmsSearchBar.svelte <style>
   ⛔⛔ 이 규칙들은 정본에서 Svelte «스코프» 안에 있어 jk-shell.css·global.css 에 «0건»이다.
      그래서 이관본이 부트스트랩 조합(.input-group / d-flex gap-1 ms-auto)으로 «흉내»를 냈고,
      간격과 검색 아이콘 위치가 정본과 달랐다. 흉내를 걷어내고 원본 값을 그대로 가져온다. */

.toolbar-count[b-s5oaibjzta] {
    font-size: 13px;
    color: var(--vz-secondary-color);
    white-space: nowrap;
}

.toolbar-spacer[b-s5oaibjzta] { flex: 1; }

.toolbar-actions[b-s5oaibjzta] {
    display: flex;
    align-items: center;
    gap: 3px;
    flex-shrink: 0;
}

/* 검색어가 있을 때 ✕ 가 글자와 겹치지 않게 여백을 준다(search-icon 은 좌측이다). */
.search-box .form-control.has-clear[b-s5oaibjzta] {
    padding-right: 32px;
}

.search-clear-btn[b-s5oaibjzta] {
    position: absolute;
    right: 6px;
    top: 0;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--vz-secondary-color);
    cursor: pointer;
    line-height: 1;
    font-size: 16px;
}

.search-clear-btn:hover[b-s5oaibjzta] {
    color: var(--vz-body-color);
}

/* 정본 +page.svelte <style>:452 — 하단 「표시 N / 전체 M」 글자.
   ⛔ 정본에서 스코프 안이라 jk-shell.css 에 없다. .text-muted 로 흉내 내면 크기가 달라진다(0.85rem). */
.loadmore-count[b-s5oaibjzta] {
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 정본 DmsDropZone.svelte <style>:131~143 — 그리드를 감싸는 세로 플렉스.
   ⛔ height:100% 로 바꾸지 마라. 정본이 2026-05-14 에 그걸로 밟았다 —
      flex 컨테이너 안에서 자식 fallback 으로 동작해 카드 그리드만큼 늘어났고,
      .dms-main 의 overflow:hidden 에 잘려 아래쪽 카드에 스크롤로도 못 갔다.
      flex:1 + min-height:0 만으로 충분하다. */
.dms-dropzone-wrapper[b-s5oaibjzta] {
    position: relative;
    width: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
    flex: 1;
}


/* ══ 「더 불러오기」 줄이 목록 «끝»에 오게 — 2026-09-02 지시 ═══════════════════
   ⛔⛔ 증상: 스크롤을 내려도 버튼이 목록 끝에 있지 않고 스크롤을 따라 움직였다.
      원인은 jk-shell.css 의 `.dms-dropzone-wrapper{flex:1; min-height:0}` 이다 —
      스크롤 주체가 `.dms-content` 인데 래퍼가 «화면 높이»(223px)로 눌리고, 카드는
      overflow:visible 로 그 밖에(8,182px) 그려진다. 다음 형제인 버튼 줄은 «눌린 상자» 바로
      뒤에 놓이므로 카드 한가운데 떠 있게 된다(2026-09-02 실측: 래퍼 ch=223 / sh=8182).
   ⛔ 고칠 축은 «줄여도 되는가»다 — 내용만큼은 차지해야 한다(`0 auto`).
      grow 는 남긴다: 카드가 몇 장뿐일 때도 드롭 영역이 화면을 채워야 한다.
   ⛔ jk-shell.css 를 직접 고치지 마라 — 생성물이다(scripts/gen-blazor-shell-css.py). */
.dms-dropzone-wrapper[b-s5oaibjzta] {
    flex: 1 0 auto;
    min-height: auto;
}

/* QA 09-04 #66 — 업로드 버튼은 폴더가 없어도 «눌린다»(누르면 토스트로 이유를 말한다).
   disabled 로 두면 툴팁도 안 뜨고 「버튼이 없다」로 읽힌다. 흐리게만 한다 — 새 색 없음. */
.jk-upload-needs-folder[b-s5oaibjzta] {
    opacity: 0.6;
}
/* /Components/Pages/DmsBrowseDesk/DmsBrowseTypeChips.razor.rz.scp.css */
/* 원본 $lib/components/shared/DmsTypeChips.svelte 의 <style> 블록 그대로 (43~66행).
   ⛔ 새로 디자인하지 않았다. 이 규칙은 Svelte 스코프 안에 있어서
      wwwroot/jk-shell.css 추출본에 «빠져 있다»(.dms-type-chips 만 추출됨).
   ⛔ .dms-type-chips 자체는 jk-shell.css:628 에 이미 있으므로 여기 다시 쓰지 않는다.
   스타일 축: /dms 의 AI 필터 칩(.filter-chip)과 같은 모양 — 같은 줄에 놓여도 이질감이 없게. */

.filter-chip[b-bao5mehdjo] {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    font-size: 13px;
    border-radius: 999px;
    border: 1px solid var(--vz-border-color);
    background: white;
    color: var(--vz-body-color);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.filter-chip:hover[b-bao5mehdjo] {
    border-color: var(--vz-primary);
}

.filter-chip.active[b-bao5mehdjo] {
    background: var(--vz-primary);
    border-color: var(--vz-primary);
    color: white;
}
/* /Components/Pages/DmsHome/DmsDashboard.razor.rz.scp.css */
/*
    홈(오늘 할 일) 스타일 — 원본 HomeActionQueue.svelte 의 <style> 블록(601~880행)을 그대로 옮겼다.
    수치는 wireframes/home.html + shared.css 를 따른다.

    ⛔⛔ 색은 --vz-* 브리지 토큰만 쓴다. 새 hex 를 고르면 hex 인벤토리 게이트가 잡는다.
    ⛔ 디자인을 «새로 만들지 않는다» — 값 하나도 바꾸지 않았다.
       추가한 것은 .jkia-kpi-nolink 하나뿐이고, 그건 «이 셸에 라우트가 없어 링크를 못 건» 자리를
       클릭 가능한 것처럼 보이지 않게 하는 용도다(원본에는 그런 상태가 없다).
*/

.jkia-h1[b-al03awu4dx] {
    font-size: 22px;
    font-weight: 500;
    color: var(--vz-heading-color);
    margin: 0 0 2px;
}

.jkia-psub[b-al03awu4dx] {
    font-size: 13px;
    color: var(--vz-secondary-color);
    margin: 0 0 16px;
}

.jkia-muted[b-al03awu4dx] {
    font-size: 12px;
    color: var(--vz-secondary-color);
}

.jkia-kpis[b-al03awu4dx] {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 16px;
}

/* PLM 모듈이 꺼진 고객사(견적만 쓰는 곳)에는 「내 작업」 칸이 «없다» — 3칸으로 접는다.
   ⛔ 위 repeat(4,1fr) 을 고치지 마라. 기본은 4칸이고 이건 예외다.
   ⛔ 이 선택자가 .jkia-kpis 하나짜리보다 특정성이 높아 «미디어 쿼리를 이긴다» —
      그래서 아래 두 브레이크포인트에도 같은 modifier 를 다시 적어 두었다(2+1 · 1열). */
.jkia-kpis.jkia-kpis-3[b-al03awu4dx] {
    grid-template-columns: repeat(3, 1fr);
}

.jkia-kpi[b-al03awu4dx] {
    display: block;
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
    padding: 14px 16px;
    text-decoration: none;
    color: var(--vz-body-color);
    transition: border-color 0.15s, box-shadow 0.15s;
}

.jkia-kpi:hover[b-al03awu4dx] {
    border-color: var(--vz-primary);
    box-shadow: 0 3px 12px rgba(var(--vz-primary-rgb), 0.14);
}

/* 이동 대상이 이 셸에 아직 없는 자리 — 눌러도 갈 데가 없으므로 hover 강조를 끈다.
   ⛔ 숨기지 않는다. 숨기면 사용자는 그 건이 «없는 줄» 안다. */
.jkia-kpi-nolink[b-al03awu4dx] {
    cursor: default;
}

.jkia-kpi-nolink:hover[b-al03awu4dx] {
    border-color: var(--vz-border-color);
    box-shadow: none;
}

.jkia-kpi-lab[b-al03awu4dx] {
    display: block;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 라벨 옆 축 표기 — 라벨보다 한 단계 약하게(같은 크기면 라벨이 두 줄처럼 읽힌다) */
.jkia-kpi-axis[b-al03awu4dx] {
    opacity: 0.75;
}

.jkia-kpi-val[b-al03awu4dx] {
    display: block;
    font-size: 26px;
    font-weight: 500;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.jkia-kpi-u[b-al03awu4dx] {
    font-size: 13px;
    font-weight: 400;
    color: var(--vz-secondary-color);
    margin-left: 3px;
}

.jkia-kpi-sub[b-al03awu4dx] {
    display: block;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 권한으로 못 읽은 KPI — 회색 부제와 섞이면 못 보고 지나친다 (PLM-20260813-08).
   ⛔ 새 hex 금지(hex 인벤토리 게이트) — 브리지 토큰만 쓴다. */
.jkia-kpi-sub.jkia-kpi-warn[b-al03awu4dx] {
    color: var(--vz-warning);
    font-weight: 500;
}

.jkia-split[b-al03awu4dx] {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

.jkia-card[b-al03awu4dx] {
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
}

.jkia-mb[b-al03awu4dx] {
    margin-bottom: 14px;
}

.jkia-card-hd[b-al03awu4dx] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 13px;
    font-weight: 500;
}

/* ⛔ 2026-09-04 — .jkia-summary(접이식 헤더)도 함께 지웠다. 이 화면에 <details> 가 남아 있지 않다.
   그 하나뿐인 사용처가 「전사 현황」이었다. */

.jkia-spacer[b-al03awu4dx] {
    flex: 1;
}

.jkia-bd[b-al03awu4dx] {
    padding: 12px 16px;
}

/* ── 작업 큐 행 ── */
.jkia-row[b-al03awu4dx] {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--vz-border-color);
}

.jkia-row:last-child[b-al03awu4dx] {
    border-bottom: none;
}

.jkia-row:hover[b-al03awu4dx] {
    background: var(--vz-tertiary-bg);
}

.jkia-ic[b-al03awu4dx] {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    flex-shrink: 0;
    background: var(--vz-light);
    color: var(--vz-secondary);
}

/* 종류를 색으로만 가르지 않는다 — 아이콘 모양이 1차 구분이고 색은 보조다 */
.jkia-ic-due[b-al03awu4dx] {
    background: var(--vz-danger-bg-subtle);
    color: var(--vz-danger);
}

.jkia-ic-ap[b-al03awu4dx] {
    background: var(--vz-primary-bg-subtle);
    color: var(--vz-primary);
}

.jkia-tx[b-al03awu4dx] {
    min-width: 0;
    flex: 1;
}

.jkia-t1[b-al03awu4dx] {
    display: block;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 프로젝트 큐 — 행 «전체»가 링크다(2026-09-04). 글자색은 본문, 호버에서 제목만 링크색으로. */
a.jkia-row-link[b-al03awu4dx] {
    color: var(--vz-body-color);
    text-decoration: none;
    cursor: pointer;
}

a.jkia-row-link:hover .jkia-t1[b-al03awu4dx] {
    color: var(--vz-primary);
    text-decoration: underline;
}

a.jkia-row-link:focus-visible[b-al03awu4dx] {
    outline: 2px solid var(--vz-primary);
    outline-offset: -2px;
}

.jkia-t1 a[b-al03awu4dx] {
    color: var(--vz-body-color);
    text-decoration: none;
}

.jkia-t1 a:hover[b-al03awu4dx] {
    color: var(--vz-primary);
    text-decoration: underline;
}

.jkia-t2[b-al03awu4dx] {
    display: block;
    font-size: 12px;
    color: var(--vz-secondary-color);
    margin-top: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.jkia-ac[b-al03awu4dx] {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

.jkia-reject[b-al03awu4dx] {
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 10px 16px 12px 60px;
    border-bottom: 1px solid var(--vz-border-color);
    background: var(--vz-tertiary-bg);
}

.jkia-more[b-al03awu4dx] {
    padding: 10px 16px;
    text-align: center;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

.jkia-empty[b-al03awu4dx] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 40px 16px;
    color: var(--vz-secondary-color);
    font-size: 13px;
}

.jkia-empty i[b-al03awu4dx] {
    font-size: 26px;
    color: var(--vz-success);
}

.jkia-empty-sm[b-al03awu4dx] {
    padding: 20px 16px;
}

/* «못 읽었다» 자리 — ⛔ 위 .jkia-empty i 가 아이콘을 초록(success)으로 칠한다.
   그대로 두면 실패가 「다 처리했습니다」처럼 읽힌다(PLM-20260813-08 과 같은 모양의 사고).
   ⛔ 새 hex 금지 — 브리지 토큰만 쓴다. */
.jkia-empty.jkia-empty-warn[b-al03awu4dx],
.jkia-empty.jkia-empty-warn i[b-al03awu4dx] {
    color: var(--vz-warning);
}

/* ── 타임라인 ── */
.jkia-ev[b-al03awu4dx] {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 13px;
}

.jkia-ev:last-child[b-al03awu4dx] {
    border-bottom: none;
}

.jkia-ev-w[b-al03awu4dx] {
    width: 46px;
    flex-shrink: 0;
    color: var(--vz-secondary-color);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

.jkia-ev-n[b-al03awu4dx] {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.jkia-ev-n a[b-al03awu4dx] {
    color: var(--vz-body-color);
    text-decoration: none;
}

.jkia-ev-n a:hover[b-al03awu4dx] {
    color: var(--vz-primary);
    text-decoration: underline;
}

.jkia-dot[b-al03awu4dx] {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--vz-primary);
    flex-shrink: 0;
}

/* ── 바로 가기 칩 ── */
.jkia-chips[b-al03awu4dx] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.jkia-chip[b-al03awu4dx] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 5px 10px;
    border: 1px solid var(--vz-border-color);
    border-radius: 14px;
    font-size: 12px;
    color: var(--vz-body-color);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.jkia-chip:hover[b-al03awu4dx] {
    border-color: var(--vz-primary);
    color: var(--vz-primary);
}

.jkia-chip.jkia-kpi-nolink:hover[b-al03awu4dx] {
    border-color: var(--vz-border-color);
    color: var(--vz-body-color);
}

/* ⛔ 2026-09-04 — 「전사 현황」(.jkia-stats · .jkia-stat-n · .jkia-stat-axis)을 지웠다.
   카드가 사라졌으므로 스타일도 함께 지운다. 되살리려면 화면·서비스부터 되돌려야 한다. */

.jkia-center[b-al03awu4dx] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 40px 16px;
}

.jkia-error i[b-al03awu4dx] {
    font-size: 24px;
    color: var(--vz-danger);
}

.jkia-err-title[b-al03awu4dx] {
    font-size: 14px;
    font-weight: 500;
}

@media (max-width: 1199px) {
    .jkia-split[b-al03awu4dx] {
        grid-template-columns: 1fr;
    }

    .jkia-kpis[b-al03awu4dx] {
        grid-template-columns: repeat(2, 1fr);
    }

    /* 3칸 모드도 2열로 접는다 — 마지막 한 장이 홀로 남는 «2+1» 을 허용한다.
       ⛔ 3칸을 좁은 폭에서 유지하면 숫자(26px)가 라벨과 겹쳐 읽힌다. */
    .jkia-kpis.jkia-kpis-3[b-al03awu4dx] {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 575px) {
    .jkia-kpis[b-al03awu4dx] {
        grid-template-columns: 1fr;
    }

    .jkia-kpis.jkia-kpis-3[b-al03awu4dx] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/DmsInboxDesk/NotifyChannelPrefs.razor.rz.scp.css */
/*
    원본 me/notifications/+page.svelte 의 <style> 블록(190~218행)을 «그대로» 옮긴 것이다.
    ⛔ 값(색·간격·반경)을 새로 고르지 않았다 — 디자인은 새로 만들지 않는다.
    ⛔ Blazor scoped CSS 라 이 컴포넌트에만 붙는다(원본 Svelte <style> 의 스코프와 같은 성질).
       fs-11 · fs-13 은 원본에서도 이 블록이 정의한다(Velzon 기본에 없는 크기라 여기 남긴다).
*/
.ch-card[b-knbtz9m8e8] {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px;
    border: 1px solid var(--vz-border-color);
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.15s ease;
    background: var(--vz-card-bg, #fff);
    margin: 0;
}

.ch-card:hover[b-knbtz9m8e8] {
    border-color: var(--vz-primary, #4f46e5);
    background: #fafbff;
}

.ch-active[b-knbtz9m8e8] {
    border-color: var(--vz-primary, #4f46e5);
    background: #f5f7ff;
    box-shadow: 0 0 0 1px var(--vz-primary, #4f46e5) inset;
}

.ch-disabled[b-knbtz9m8e8] {
    pointer-events: none;
    opacity: 0.6;
}

.ch-blocked[b-knbtz9m8e8] {
    background: var(--vz-tertiary-bg);
    opacity: 0.65;
    cursor: not-allowed;
}

.ch-blocked:hover[b-knbtz9m8e8] {
    border-color: var(--vz-border-color);
    background: var(--vz-tertiary-bg);
}

.ch-block-msg[b-knbtz9m8e8] {
    color: var(--vz-secondary);
    font-style: italic;
}

.ch-toggle[b-knbtz9m8e8] {
    margin-top: 4px;
    flex-shrink: 0;
}

.ch-icon[b-knbtz9m8e8] {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    flex-shrink: 0;
}

.ch-text[b-knbtz9m8e8] {
    flex: 1;
}

.ch-title[b-knbtz9m8e8] {
    font-weight: 500;
    font-size: 14px;
    margin-bottom: 4px;
}

.ch-desc[b-knbtz9m8e8] {
    font-size: 12px;
    color: var(--vz-secondary);
    line-height: 1.5;
}


/* /Components/Pages/DmsSearchDesk/SavedSearches.razor.rz.scp.css */
/*
    원본 +page.svelte 의 <style> 블록(573~706행)을 «그대로» 옮긴 것.
    ⛔ Svelte 의 스코프 스타일 = Blazor 의 CSS 격리(.razor.css). 값을 새로 고르지 않았다.
    ⛔ .sf-modal-backdrop 의 z-index 1080 은 원본 값이다 — 임의로 올리지 마라.
*/

.sf-header[b-6toava7e1x] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 8px 4px 16px;
}

.sf-layout[b-6toava7e1x] {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 16px;
    min-height: calc(100vh - 140px);
}

/* ── 좌측 폴더 목록 ── */
.sf-folder-list[b-6toava7e1x] {
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 10px;
    overflow-y: auto;
    max-height: calc(100vh - 140px);
}

.sf-empty[b-6toava7e1x] {
    text-align: center;
    padding: 60px 20px;
}

.sf-folder-item[b-6toava7e1x] {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--vz-border-color);
    cursor: pointer;
    transition: background 0.15s;
}

.sf-folder-item:last-child[b-6toava7e1x] {
    border-bottom: none;
}

.sf-folder-item:hover[b-6toava7e1x] {
    background: var(--vz-light, #f9fafb);
}

.sf-folder-item.active[b-6toava7e1x] {
    background: var(--vz-primary-bg-subtle, #eef2fb);
    border-left: 3px solid var(--vz-primary);
    padding-left: 11px;
}

.sf-folder-main[b-6toava7e1x] {
    flex: 1;
    min-width: 0;
}

.sf-folder-title[b-6toava7e1x] {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--vz-body-color);
    margin-bottom: 3px;
}

.sf-folder-desc[b-6toava7e1x] {
    font-size: 13px;
    color: var(--vz-secondary-color);
    margin-bottom: 4px;
}

.sf-folder-meta[b-6toava7e1x] {
    display: flex;
    align-items: center;
    gap: 6px;
}

.sf-folder-meta .badge[b-6toava7e1x] {
    font-size: 13px;
}

.sf-folder-actions[b-6toava7e1x] {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex-shrink: 0;
    opacity: 0;
    transition: opacity 0.15s;
}

.sf-folder-item:hover .sf-folder-actions[b-6toava7e1x],
.sf-folder-item.active .sf-folder-actions[b-6toava7e1x] {
    opacity: 1;
}

/* ── 우측 결과 영역 ── */
.sf-result[b-6toava7e1x] {
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.sf-placeholder[b-6toava7e1x] {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 20px;
    text-align: center;
}

.sf-result-header[b-6toava7e1x] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--vz-border-color);
    flex-shrink: 0;
}

.sf-result-title[b-6toava7e1x] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.sf-result-actions[b-6toava7e1x] {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

.sf-result-desc[b-6toava7e1x] {
    padding: 8px 18px;
    font-size: 13px;
    color: var(--vz-secondary-color);
    border-bottom: 1px solid var(--vz-border-color);
}

.sf-grid-wrap[b-6toava7e1x] {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    min-height: 0;
    /* 카드 그리드 마퀴 드래그를 스크롤 전체로 확장 */
    display: flex;
    flex-direction: column;
}

.sf-empty-result[b-6toava7e1x] {
    text-align: center;
    padding: 60px 20px;
}

/* ── 모달 ── */
.sf-modal-backdrop[b-6toava7e1x] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sf-modal[b-6toava7e1x] {
    width: 520px;
    max-width: 92vw;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    border-radius: 12px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.25);
    overflow: hidden;
}

@media (max-width: 992px) {
    .sf-layout[b-6toava7e1x] {
        grid-template-columns: 1fr;
    }

    .sf-folder-list[b-6toava7e1x] {
        max-height: 320px;
    }
}
/* /Components/Pages/DrawingCheck/DrawingChecker.razor.rz.scp.css */
/*
    도면 규격 검증 — 원본 <style>(532~648행) 이식.

    ⛔ 값(색·크기·z-index·blend)을 «고르지» 않았다. 전부 원본 그대로다.
       고치면 핀 위치·겹침 판독이 달라지고, 그건 판정이 달라진 것처럼 보인다.

    ⛔⛔ 이 화면의 오버레이는 «Blazor 가 그린다»(핀·격자·사이드바 전부). 그래서 CSS 격리 스코프가
       그대로 붙는다 — ::deep 이 필요 없다. JS 가 만드는 노드는 «하나도 없다»
       (JS 는 .image-container 의 transform 만 건드린다 — 그 요소도 Blazor 가 그린 것이다).
*/

.hover-bg:hover[b-yhzaqrkk2p] { background: #f3f6f9; }

/* 위반 목록 — 원본 350행 `max-height: 65vh; overflow-y: auto` */
.violation-list[b-yhzaqrkk2p] { max-height: 65vh; overflow-y: auto; }

/* 뷰어 오버레이 */
.viewer-overlay[b-yhzaqrkk2p] {
    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.8); z-index: 9999;
    display: flex; align-items: center; justify-content: center;
}
.viewer-modal[b-yhzaqrkk2p] {
    width: 95vw; height: 92vh; background: #fff;
    border-radius: 8px; overflow: hidden;
    display: flex; flex-direction: column;
    box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}
.viewer-header[b-yhzaqrkk2p] {
    background: #405189; padding: 8px 16px;
    display: flex; align-items: center; justify-content: space-between;
}
.viewer-body[b-yhzaqrkk2p] { flex: 1; display: flex; overflow: hidden; }

/* ⛔ touch-action:none 을 빼면 포인터 드래그 팬이 브라우저 스크롤에 먹힌다. */
.viewer-pdf[b-yhzaqrkk2p] {
    flex: 1; overflow: hidden; background: #e0e0e0;
    display: flex; justify-content: center; align-items: center;
    padding: 0; user-select: none; touch-action: none;
    cursor: grab;
}
.viewer-pdf:active[b-yhzaqrkk2p] { cursor: grabbing; }

/* ⛔⛔ transform-origin 은 center center 다 — JS 의 zoomAtPoint 보정식이 그 전제 위에 서 있다. */
.image-container[b-yhzaqrkk2p] {
    position: relative;
    box-shadow: 0 2px 12px rgba(0,0,0,0.2);
    transition: transform 0.05s ease-out;
    transform-origin: center center;
}
.drawing-image[b-yhzaqrkk2p] {
    display: block;
    max-width: calc(95vw - 320px - 32px);
    max-height: calc(92vh - 50px);
    width: auto; height: auto;
    object-fit: contain;
    background: #fff;
    pointer-events: none; /* 드래그가 이미지에 걸리지 않도록 */
    -webkit-user-drag: none;
}
.marker-overlay[b-yhzaqrkk2p] {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    pointer-events: none;
}

.viewer-sidebar[b-yhzaqrkk2p] {
    width: 320px; border-left: 1px solid #ddd;
    display: flex; flex-direction: column; background: #fff;
}
.viewer-sidebar-body[b-yhzaqrkk2p] { overflow-y: auto; flex: 1; }
.sidebar-item[b-yhzaqrkk2p] { cursor: pointer; transition: background 0.15s; }
.sidebar-item:hover[b-yhzaqrkk2p] { background: #f3f6f9; }
.sidebar-item.active[b-yhzaqrkk2p] { background: #e8eff7; border-left: 3px solid #405189; }
/* 원본 508행의 인라인 style 을 클래스로 옮긴 것뿐이다(값 동일). */
.sidebar-num[b-yhzaqrkk2p] { width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; }

/* 핀 마커 */
.pin-marker[b-yhzaqrkk2p] {
    position: absolute;
    transform: translate(-50%, -50%);
    width: 24px; height: 24px;
    border-radius: 50%;
    color: #fff;
    font-size: 13px;
    font-weight: bold;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    pointer-events: auto;
    border: 2px solid #fff;
    box-shadow: 0 2px 6px rgba(0,0,0,0.4);
    transition: transform 0.15s, box-shadow 0.15s;
    z-index: 5;
}
.pin-marker:hover[b-yhzaqrkk2p] {
    transform: translate(-50%, -50%) scale(1.3);
    box-shadow: 0 3px 12px rgba(0,0,0,0.5);
    z-index: 10;
}
.pin-marker.active[b-yhzaqrkk2p] {
    transform: translate(-50%, -50%) scale(1.4);
    box-shadow: 0 0 0 4px rgba(255,255,255,0.6), 0 4px 16px rgba(0,0,0,0.5);
    z-index: 10;
}

/* Phase 1 진단: 디버그 오버레이 */
.debug-grid-v[b-yhzaqrkk2p] {
    position: absolute; top: 0; bottom: 0;
    width: 1px; background: rgba(255, 0, 0, 0.4);
    pointer-events: none;
}
.debug-grid-h[b-yhzaqrkk2p] {
    position: absolute; left: 0; right: 0;
    height: 1px; background: rgba(255, 0, 0, 0.4);
    pointer-events: none;
}
.debug-grid-label[b-yhzaqrkk2p] {
    position: absolute;
    transform: translate(-50%, -50%);
    font-size: 13px; font-weight: bold;
    color: #fff; background: rgba(0,0,0,0.55);
    padding: 1px 4px; border-radius: 2px;
    pointer-events: none;
}
.debug-badge[b-yhzaqrkk2p] {
    position: absolute;
    transform: translate(calc(-50% + 14px), calc(-50% - 18px));
    font-size: 13px; font-weight: 600;
    color: #fff;
    padding: 2px 5px; border-radius: 3px;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0,0,0,0.4);
    pointer-events: none;
    z-index: 6;
}
/* /Components/Pages/DrawingSearch/DrawingLibrarySearch.razor.rz.scp.css */
/*
    도면 검색 — 원본 인라인 style + <style>(473~485행) 이식.

    ⛔ 값을 «고르지» 않았다. 원본이 인라인으로 박아 둔 크기·색을 클래스로 옮겼을 뿐이다.
    ⛔ 이 화면에는 JS 가 만드는 노드가 «없다» — ::deep 이 필요 없다.
       (collocated JS 는 fetch/SSE 만 하고 DOM 을 만들지 않는다.)
*/

/* 원본 221행 `style="height: 80vh; display:flex; flex-direction:column"` */
.library-card[b-fupv2wjvd0] { height: 80vh; display: flex; flex-direction: column; }
.library-body[b-fupv2wjvd0] { overflow-y: auto; flex: 1; }

.library-count[b-fupv2wjvd0] { font-size: 13px; }
.library-meta[b-fupv2wjvd0] { font-size: 13px; }
.library-icon[b-fupv2wjvd0] { font-size: 18px; }
.library-del[b-fupv2wjvd0] { font-size: 13px; }

/* 원본 287행 — 펼친 파일 헤더의 배경. */
.library-head[b-fupv2wjvd0] { cursor: pointer; background: transparent; }
.library-head.expanded[b-fupv2wjvd0] { background: #f0f4ff; }

/* 원본 311행 — 다장 도면일 때만 목록 배경을 살짝 깐다. */
.library-layouts[b-fupv2wjvd0] { background: transparent; }
.library-layouts.grouped[b-fupv2wjvd0] { background: #fafbff; }

.layout-cell[b-fupv2wjvd0] { width: 70px; }
.layout-thumb[b-fupv2wjvd0] {
    height: 50px; width: 66px; object-fit: contain;
    background: #f5f5f5; cursor: pointer;
}
.layout-no[b-fupv2wjvd0] { font-size: 13px; }
.layout-link[b-fupv2wjvd0] { font-size: 11px; }
.link-work[b-fupv2wjvd0] { color: #6f42c1; }
.link-translate[b-fupv2wjvd0] { color: #0ea5e9; }

/* 업로드 큐 */
.queue-row[b-fupv2wjvd0] { font-size: 13px; }
.queue-spinner[b-fupv2wjvd0] { width: 14px; height: 14px; }
.queue-bar[b-fupv2wjvd0] { height: 4px; }
.queue-count[b-fupv2wjvd0] { font-size: 13px; }
.queue-msg[b-fupv2wjvd0] { font-size: 13px; }

/* 검색 진행 막대 — 원본 383행 `height:6px` */
.search-bar[b-fupv2wjvd0] { height: 6px; }

/* 결과 썸네일 — 원본 411행 `height:60px; background:#f5f5f5` */
.match-thumb[b-fupv2wjvd0] { height: 60px; background: #f5f5f5; }

/* 비교 미리보기 모달 — 원본 <style>(473~485행) */
.compare-overlay[b-fupv2wjvd0] {
    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.8); z-index: 9999;
    display: flex; align-items: center; justify-content: center;
}
.compare-modal[b-fupv2wjvd0] {
    width: 95vw; height: 90vh; background: #fff; border-radius: 8px;
    overflow: hidden; display: flex; flex-direction: column;
}
.compare-header[b-fupv2wjvd0] {
    background: #405189; padding: 10px 16px;
    display: flex; align-items: center; justify-content: space-between;
}
.compare-body[b-fupv2wjvd0] {
    flex: 1; display: flex; gap: 4px; padding: 8px; overflow: hidden; background: #f5f5f5;
}
.compare-pane[b-fupv2wjvd0] {
    flex: 1; display: flex; flex-direction: column; align-items: center;
    overflow: auto; background: #fff; border-radius: 4px; padding: 8px;
}
.compare-pane img[b-fupv2wjvd0] { max-width: 100%; max-height: calc(90vh - 100px); object-fit: contain; }
.compare-label[b-fupv2wjvd0] { font-size: 13px; color: #666; margin-bottom: 4px; }
.compare-name[b-fupv2wjvd0] { font-size: 13px; color: #999; margin-top: 4px; }
/* /Components/Pages/DrawingSearch/DrawingVectorViewer.razor.rz.scp.css */
/*
    도면 뷰어 — 원본 스타일 세 벌.
      ① +page.svelte 의 <style>(290~315행) + CHECKER 상수(13~17행)
      ② SvgPanZoomStage.svelte 의 <style>(70~80행) — .svg-pz-stage
      ③ DrawingMeasureLayer.svelte 의 <style>(372~385행) — .m-*

    ⛔⛔ CSS 격리(scoped)라서 «JS 가 만든 노드»에는 스코프 속성이 붙지 않는다.
       그래서 <svg> 안쪽을 겨냥하는 규칙은 ::deep 으로 뚫는다. 빼면 «조용히» 안 먹는다:
         · non-scaling-stroke 가 안 먹으면 fit 줌에서 선이 사라진다.
         · .m-* 이 안 먹으면 측정선·라벨이 «보이지 않는다»(요소는 있는데 색이 없다).

    ⛔ 값을 고르지 않았다. 색·굵기·크기는 전부 원본 그대로다.
*/

/* 스테이지 — 원본 SvgPanZoomStage(fillParent=false, minHeightOffset=240) */
.svg-pz-stage[b-92pi2st7q8] {
    position: relative;
    width: 100%;
    min-height: 420px;
    height: calc(100vh - 240px);
    overflow: hidden;
    cursor: grab;
    user-select: none;
    /* 원본 CHECKER(13~17행) — 투명 배경을 눈에 보이게 하는 체커보드 */
    background:
        linear-gradient(45deg, #f3f4f6 25%, transparent 25%) 0 0/20px 20px,
        linear-gradient(-45deg, #f3f4f6 25%, transparent 25%) 0 10px/20px 20px,
        linear-gradient(45deg, transparent 75%, #f3f4f6 75%) 10px -10px/20px 20px,
        linear-gradient(-45deg, transparent 75%, #f3f4f6 75%) -10px 0/20px 20px,
        #fff;
}
.svg-pz-stage:active[b-92pi2st7q8] { cursor: grabbing; }

/* JS 가 소유하는 칸 — 스테이지를 꽉 채운다(내부 <svg> 가 position:absolute 로 깔린다). */
.dvv-svg-slot[b-92pi2st7q8] { position: absolute; inset: 0; }
.dvv-svg-slot[b-92pi2st7q8]  .view-svg { position: absolute; inset: 0; }
/* 선은 줌과 무관하게 일정 굵기로 보이도록(=fit 줌에서도 안 사라짐) + 벡터 무손실 */
.dvv-svg-slot[b-92pi2st7q8]  .view-layer path { vector-effect: non-scaling-stroke; }

/* 측정 오버레이 — 원본 DrawingMeasureLayer <style>(372~385행) */
.dvv-svg-slot[b-92pi2st7q8]  .m-line { stroke: #f06548; fill: none; }
.dvv-svg-slot[b-92pi2st7q8]  .m-area { stroke: #f06548; fill: rgba(240,101,72,0.12); }
.dvv-svg-slot[b-92pi2st7q8]  .m-leader { stroke: #f06548; stroke-dasharray: 2 2; opacity: 0.5; }
.dvv-svg-slot[b-92pi2st7q8]  .m-guide { stroke: #f06548; stroke-dasharray: 4 3; fill: none; opacity: 0.7; }
.dvv-svg-slot[b-92pi2st7q8]  .m-end { stroke: #f06548; fill: #fff; }
.dvv-svg-slot[b-92pi2st7q8]  .m-pending { stroke: #f06548; fill: #fff; }
.dvv-svg-slot[b-92pi2st7q8]  .m-label { fill: #842029; dominant-baseline: middle; }
.dvv-svg-slot[b-92pi2st7q8]  .m-label-bg { fill: #fff; stroke: #f06548; opacity: 0.92; }
.dvv-svg-slot[b-92pi2st7q8]  .m-snap { stroke: #0ab39c; fill: none; }
.dvv-svg-slot[b-92pi2st7q8]  .m-snap-fill { stroke: #0ab39c; fill: rgba(10,179,156,0.25); }
.dvv-svg-slot[b-92pi2st7q8]  .m-cursor { fill: #f06548; opacity: 0.6; }
.dvv-svg-slot[b-92pi2st7q8]  .m-del-bg { fill: #f06548; }
.dvv-svg-slot[b-92pi2st7q8]  .m-del-x { fill: #fff; dominant-baseline: middle; }

.stage-msg[b-92pi2st7q8] {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    font-size: 13px; white-space: nowrap;
    z-index: 1;
}

/* 툴바 — 원본 인라인 style 을 클래스로 옮긴 것뿐(값 동일). */
.scale-badge[b-92pi2st7q8] { min-width: 52px; }
.unit-select[b-92pi2st7q8] { width: auto; }

/* 측정 목록 플로팅 패널 — 원본 <style>(300~315행) */
.measure-panel[b-92pi2st7q8] {
    position: absolute; top: 12px; right: 12px; z-index: 5;
    width: 240px; max-height: calc(100% - 24px); display: flex; flex-direction: column;
    background: #fff; border: 1px solid #e9ebec; border-radius: 6px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.08); font-size: 12px;
}
.measure-panel.collapsed[b-92pi2st7q8] { width: auto; }
.mp-head[b-92pi2st7q8] {
    display: flex; align-items: center; gap: 2px; padding: 7px 10px;
    cursor: pointer; border-bottom: 1px solid #f1f3f5; user-select: none;
}
.mp-body[b-92pi2st7q8] { overflow-y: auto; padding: 4px 0; }
.mp-item[b-92pi2st7q8] { display: flex; align-items: center; padding: 4px 10px; line-height: 1.4; }
.mp-item:hover[b-92pi2st7q8] { background: #f8f9fa; }
.mp-val[b-92pi2st7q8] { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* /Components/Pages/EcrDetail/EcrDetailScreen.razor.rz.scp.css */
/* 설계변경 상세 — 원본 `JK.AI.Front/src/routes/plm/ecr/[id]/+page.svelte` 의 <style> 이식.
   ⛔ 디자인을 새로 만들지 않았다. 클래스 이름·값을 그대로 옮겼다.

   ⛔⛔ 원본은 `body.ecr-detail-fullscreen` + JS `fitHeight()` 로 «전체화면»을 만든다.
      이 셸에는 그 body 클래스도 그 JS 도 없다(wwwroot 는 공통 파일이라 열지 않는다).
      그래서 높이를 재지 «않고» 하단 액션 바를 sticky 로 붙였다 — 원본이 지키려던 것은
      「주요 액션(결재 올리기)이 화면 밖으로 잘리지 않는다」이고, sticky 는 그것을 만족한다.
      ⛔ `height: 100vh` 나 `calc(100vh - 133px)` 로 되돌리지 마라. 원본 주석이 그 둘을 모두 금지한다
        (앱 크롬 높이가 서브탭 유무로 달라져서 상수를 박으면 액션 바가 잘린다). */

.chg[b-dipbp2kncr] { display: flex; flex-direction: column; }

/* ── 상단 바 — 번호와 임시저장 표시만. 제목은 본문 첫 줄이 맡는다 ── */
.chg-top[b-dipbp2kncr] {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
}
.chg-top-id[b-dipbp2kncr] { font-size: 14px; }
.chg-top-right[b-dipbp2kncr] { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-left: auto; }

/* ── 본문 — 한 컬럼. 최대폭을 두는 이유: 사유 본문이 1400px 로 늘어나면 읽기 어렵다 ── */
.chg-scroll[b-dipbp2kncr] { padding: 6px 0 16px; }
.chg-wrap[b-dipbp2kncr] { max-width: 980px; margin: 0 auto; }

/* ── 제목 ── */
.subj[b-dipbp2kncr] { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.subj-title[b-dipbp2kncr] {
    font-size: 22px; font-weight: 500; line-height: 1.35;
    margin: 0; color: var(--vz-heading-color);
}
.subj-st[b-dipbp2kncr] { font-weight: 400; }
.subj-by[b-dipbp2kncr] { font-size: 13px; color: var(--vz-secondary-color); margin: 4px 0 14px; }

/* ── 시점 배너 ── */
.banner[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 13px; border-radius: 8px; margin-bottom: 14px;
    font-size: 13px;
}
.banner i[b-dipbp2kncr] { font-size: 16px; flex-shrink: 0; }
.banner-lock[b-dipbp2kncr] { background: var(--vz-warning-bg-subtle, #fef4e4); color: var(--vz-warning-text-emphasis, #a97a1e); }
.banner-void[b-dipbp2kncr] { background: var(--vz-secondary-bg-subtle, #eef0f5); color: var(--vz-secondary-color); }
/* 실패 배너 — 「대기 중」(warning) 과 색을 나눈다. 같은 색이면 두 사실이 한 사실로 읽힌다. */
.banner-fail[b-dipbp2kncr] {
    align-items: flex-start;
    background: var(--vz-danger-bg-subtle, #fde8e4); color: var(--vz-danger-text-emphasis, #a03d2c);
}
.banner-fail .fail-list[b-dipbp2kncr] { margin: 6px 0 0; padding-left: 18px; font-size: 13px; }
.banner-fail .fail-list li[b-dipbp2kncr] { margin-bottom: 2px; }
.banner-fail code[b-dipbp2kncr] { color: inherit; }
.flex-1[b-dipbp2kncr] { flex: 1; }

/* ── 카드 — 세 시점에서 자리가 같다 ── */
.card2[b-dipbp2kncr] {
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 9px;
    margin-bottom: 14px;
}
.card2-alert[b-dipbp2kncr] { border-color: var(--vz-warning); }
.card2-hd[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 7px;
    padding: 11px 15px; border-bottom: 1px solid var(--vz-border-color);
    font-weight: 500; font-size: 14px; color: var(--vz-heading-color);
}
.hd-sub[b-dipbp2kncr] { font-weight: 400; font-size: 13px; color: var(--vz-secondary-color); }
.card2-bd[b-dipbp2kncr] { padding: 14px 15px; }
.card2-sub[b-dipbp2kncr] { font-size: 13px; font-weight: 500; color: var(--vz-secondary-color); margin-bottom: 5px; }
.card2-note[b-dipbp2kncr] { margin: 9px 0 0; font-size: 12px; color: var(--vz-secondary-color); }

/* 시스템이 판정한 결과 — 묻지 않고 알려 준다 */
.auto-verdict[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin-top: 12px; padding: 9px 12px; border-radius: 7px;
    background: var(--vz-primary-bg-subtle, #eef0f7);
    color: var(--vz-primary-text-emphasis, #2e3d6b);
    font-size: 13px; line-height: 1.5;
}
.auto-verdict i[b-dipbp2kncr] { font-size: 16px; flex-shrink: 0; }

.empty-hint[b-dipbp2kncr] {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 26px 20px; color: var(--vz-secondary-color); text-align: center;
}
.empty-hint i[b-dipbp2kncr] { font-size: 2rem; margin-bottom: 6px; }
.empty-hint p[b-dipbp2kncr] { margin: 0; font-size: 13px; line-height: 1.6; }

/* 사유 분류 칩 */
.chipsrow[b-dipbp2kncr] { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 10px; }
.chip[b-dipbp2kncr] {
    border: 1px solid var(--vz-border-color); background: var(--vz-card-bg, #fff);
    border-radius: 999px; padding: 4px 11px; font-size: 13px;
    color: var(--vz-secondary-color); cursor: pointer; transition: all .12s;
}
.chip:hover[b-dipbp2kncr] { border-color: var(--vz-primary); color: var(--vz-primary); }
.chip.on[b-dipbp2kncr] { background: var(--vz-primary); border-color: var(--vz-primary); color: #fff; }

/* 사유 입력 — 2026-08-31 부터 공용 <JkRichEditor>(계약 §2) 다. 높이는 그쪽 MinHeight 가 정한다. */
/* .ecrd-reason-editor 는 2026-08-31 에 <JkRichEditor MinHeight="180px"/> 로 대체됐다 —
   ⛔ 높이를 두 곳에서 정하지 않는다. */

/* 일정 */
.sched-row[b-dipbp2kncr] { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 12px; }
.sched-row > div[b-dipbp2kncr] { min-width: 190px; }
.sched-label[b-dipbp2kncr] { font-size: 13px; color: var(--vz-secondary-color); margin-bottom: 4px; }
.sched-hint[b-dipbp2kncr] { font-size: 12px; color: var(--vz-secondary-color); margin-top: 3px; }

/* 접힘 — 결재중·완료에만 존재한다 */
.fold[b-dipbp2kncr] { margin-top: 14px; border-top: 1px solid var(--vz-border-color); padding-top: 8px; }
.fold-btn[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 5px; width: 100%;
    border: none; background: none; padding: 7px 2px; cursor: pointer;
    font-size: 13px; color: var(--vz-secondary-color); text-align: left;
}
.fold-btn:hover[b-dipbp2kncr] { color: var(--vz-primary); }
.fold-btn i[b-dipbp2kncr] { transition: transform .15s; }
.fold-btn i.rot[b-dipbp2kncr] { transform: rotate(180deg); }
.fold-n[b-dipbp2kncr] {
    font-size: 12px; padding: 0 6px; border-radius: 999px;
    background: var(--vz-secondary-bg-subtle, #eef0f5); color: var(--vz-secondary-color);
}
.fold-bd[b-dipbp2kncr] { padding: 4px 2px 12px; }

/* 반영 상태 */
.sys-row[b-dipbp2kncr] { display: flex; gap: 9px; align-items: flex-start; font-size: 13px; line-height: 1.6; }
.sys-row i[b-dipbp2kncr] { font-size: 18px; flex-shrink: 0; margin-top: 1px; }
.sys-row.ok i[b-dipbp2kncr] { color: var(--vz-success); }
.sys-row.bad i[b-dipbp2kncr] { color: var(--vz-danger); }
.sys-row.wait i[b-dipbp2kncr] { color: var(--vz-warning); }
.sys-err[b-dipbp2kncr] {
    margin-top: 6px; padding: 6px 9px; border-radius: 6px;
    background: var(--vz-secondary-bg-subtle, #eef0f5);
    font-size: 12px; font-family: monospace; word-break: break-all;
    color: var(--vz-secondary-color);
}

/* 결정 내역 — 종결된 결재 단계의 사유·처리시각 (PLM-20260826-07) */
.decisions[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 8px; }
.decision[b-dipbp2kncr] {
    border: 1px solid var(--vz-border-color); border-left: 3px solid var(--vz-success);
    border-radius: 6px; padding: 8px 10px; background: var(--vz-card-bg, #fff);
}
.decision.decision-bad[b-dipbp2kncr] { border-left-color: var(--vz-danger); }
.decision-hd[b-dipbp2kncr] { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.decision-who[b-dipbp2kncr] { color: var(--vz-body-color); font-weight: 500; }
.decision-at[b-dipbp2kncr] { color: var(--vz-secondary-color); font-size: 12px; }
.decision-bd[b-dipbp2kncr] { margin-top: 6px; font-size: 13px; line-height: 1.6; }

/* AI 요약 박스 */
.ai-summary-box[b-dipbp2kncr] {
    display: flex; gap: 10px; padding: 12px 14px;
    background: linear-gradient(135deg, #f0f4ff 0%, #e8f6ee 100%);
    border-radius: 8px; margin-bottom: 14px;
    font-size: 14px; line-height: 1.5;
}
.ai-summary-box i[b-dipbp2kncr] { color: var(--vz-primary); font-size: 20px; flex-shrink: 0; margin-top: 1px; }

/* 영향 분석 — 등급 통계 3칸은 폐기(2026-08-19): 숫자만 있고 "무엇이 왜"가 없어 결재 판단에 쓸모가 없었다. */
.impact-list[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 6px; }
.impact-item[b-dipbp2kncr] {
    display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px;
    background: var(--vz-card-bg, #fff); border-radius: 6px;
    border: 1px solid var(--vz-border-color); font-size: 13px;
}
.impact-item.clickable[b-dipbp2kncr] { cursor: pointer; }
.impact-item.clickable:hover[b-dipbp2kncr] { background: var(--vz-tertiary-bg); }
.impact-badge[b-dipbp2kncr] { flex-shrink: 0; font-weight: 400; }
.impact-item-body[b-dipbp2kncr] { min-width: 0; }
.impact-item-path[b-dipbp2kncr] { font-weight: 500; }
.impact-item-name[b-dipbp2kncr] { margin-left: 6px; color: var(--vz-body-color); font-weight: 400; }
.impact-item-reason[b-dipbp2kncr] { font-size: 13px; color: var(--vz-secondary-color); margin-top: 2px; }
.impact-item-src[b-dipbp2kncr] { font-size: 12px; color: var(--vz-secondary-color); margin-top: 2px; }

/* 사유 — ⛔ 읽기 전용 사유를 «입력창처럼» 보이게 하지 마라 (2026-08-20).
   흰 배경 + 테두리 = 사용자에겐 textarea 다. 완료된 건에서 고칠 수 있다고 오해한다. */
.reason-box[b-dipbp2kncr] {
    padding: 12px 14px; background: var(--vz-body-bg, #f3f4f6);
    border-radius: 8px; font-size: 14px; line-height: 1.6;
    min-height: 60px;
}
.reason-box.has-content[b-dipbp2kncr] { background: var(--vz-body-bg, #f3f4f6); border: 0; }

/* ── 리치 본문 통일 줄간격 — 정본 +page.svelte:2395~2403 의 :global(.ecr-rich-content …) 값 그대로 ──
   ⛔ 정본에서 이 규칙은 컴포넌트 <style> 안에 스코프돼 있다 → global.css 에 0건이다. 안 옮기면 무스타일.
   ⛔⛔ 본문 노드(p·ul·li·hr·table)를 그리는 것은 «자식 컴포넌트» JkRichText 다. 그 노드에는 이 파일의
      스코프 속성(b-…)이 안 붙는다 — ::deep 이 없으면 한 줄도 안 걸린다. */
.ecr-rich-content[b-dipbp2kncr]  p,
.ecr-rich-content[b-dipbp2kncr]  ul,
.ecr-rich-content[b-dipbp2kncr]  ol { margin: 0 0 6px; }
.ecr-rich-content[b-dipbp2kncr]  p:last-child,
.ecr-rich-content[b-dipbp2kncr]  ul:last-child { margin-bottom: 0; }
.ecr-rich-content[b-dipbp2kncr]  li { margin: 2px 0; }
.ecr-rich-content[b-dipbp2kncr]  hr { margin: 8px 0; border-top: 1px dashed var(--vz-border-color); }
.ecr-rich-content[b-dipbp2kncr]  table { margin: 0 0 6px; }

/* 변경 대상 */
.items-list[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 6px; }
.change-item[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 10px; padding: 8px 12px;
    background: var(--vz-body-bg, #f3f4f6); border-radius: 6px;
    transition: background 0.1s;
}
.change-item:hover[b-dipbp2kncr] { background: var(--vz-secondary-bg-subtle, #eef0f5); }
.change-item-body[b-dipbp2kncr] { flex: 1; min-width: 0; font-size: 14px; }

/* 대상 담기 패널 */
.add-item-panel[b-dipbp2kncr] {
    padding: 12px; margin-bottom: 10px;
    background: var(--vz-body-bg, #f3f4f6); border-radius: 8px;
}
.part-search-results[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 4px; max-height: 200px; overflow-y: auto; }
.part-result-item[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 8px; padding: 6px 10px;
    background: var(--vz-card-bg, #fff); border-radius: 4px;
    border: 1px solid var(--vz-border-color);
    cursor: pointer; font-size: 14px; width: 100%; text-align: left;
}
.part-result-item:hover[b-dipbp2kncr] { border-color: var(--vz-primary); }
.part-result-item code[b-dipbp2kncr] { flex-shrink: 0; }
.part-result-item span[b-dipbp2kncr] { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 문서 필터 칩 ── */
.doc-filter-chips[b-dipbp2kncr] { display: flex; flex-wrap: wrap; gap: 4px; }
.doc-chip[b-dipbp2kncr] {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 10px; border-radius: 999px;
    background: var(--vz-body-bg, #f3f4f6);
    border: 1px solid var(--vz-border-color);
    font-size: 13px; font-weight: 500;
    color: var(--vz-secondary-color);
    cursor: pointer; transition: all 0.12s;
}
.doc-chip:hover[b-dipbp2kncr] { background: var(--vz-secondary-bg-subtle, #eef0f5); color: var(--vz-body-color); }
.doc-chip.active[b-dipbp2kncr] { background: var(--vz-primary); color: white; border-color: var(--vz-primary); }
.doc-chip-count[b-dipbp2kncr] {
    display: inline-block; min-width: 18px; padding: 0 5px;
    background: rgba(0, 0, 0, 0.1); border-radius: 999px;
    font-size: 13px; line-height: 14px; text-align: center;
}
.doc-chip.active .doc-chip-count[b-dipbp2kncr] { background: rgba(255, 255, 255, 0.25); }

/* ── 결재선 편집기 (원본 ApprovalLineEditor.svelte 의 <style> 그대로) ── */
.line-editor[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 0.5rem; }
.order-block[b-dipbp2kncr] {
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    background: var(--vz-light);
}
.order-header[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 0.5rem;
    margin-bottom: 0.5rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px dashed var(--vz-border-color);
}
.order-num[b-dipbp2kncr] {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px;
    border-radius: 50%;
    background: var(--vz-primary); color: var(--vz-white);
    font-size: 13px; font-weight: 600;
}
.order-label[b-dipbp2kncr] { font-size: 13px; color: var(--vz-secondary-color); }
.step-row[b-dipbp2kncr] { display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0; font-size: 13px; }
.step-approver[b-dipbp2kncr] { font-weight: 500; }
.step-affil[b-dipbp2kncr] { font-size: 12px; color: var(--vz-secondary-color); }

/* ── 하단 액션 바 — 세 시점에서 **다른 것은 여기뿐이다** ──
   ⛔ 원본은 flex 컨테이너 바닥에 고정한다. 여기서는 sticky 로 같은 목적을 이룬다
      (주요 액션이 화면 밖으로 잘리지 않게). ⛔ 100vh 계산으로 되돌리지 마라. */
.chg-foot[b-dipbp2kncr] {
    position: sticky;
    bottom: 0;
    z-index: 5;
    flex-shrink: 0; display: flex; align-items: center; gap: 16px;
    padding: 11px 16px;
    background: var(--vz-card-bg, #fff);
    border-top: 1px solid var(--vz-border-color);
    box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.04);
}
.foot-note[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    font-size: 12px; color: var(--vz-secondary-color); min-width: 0;
}
.foot-actions[b-dipbp2kncr] { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }

/* 임시저장 표시 */
.draft-indicator[b-dipbp2kncr] {
    display: inline-flex; align-items: center;
    padding: 4px 10px; background: var(--vz-success-bg-subtle, #e8f6ee);
    color: var(--vz-success); border-radius: 999px;
    font-size: 13px; font-weight: 500; white-space: nowrap;
}

/* BOM 트리 */
.bom-tree[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 2px; }
.bom-row[b-dipbp2kncr] {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px; background: var(--vz-card-bg, #fff);
    border-radius: 4px; font-size: 14px;
    border: 1px solid var(--vz-border-color);
}
.bom-level-dot[b-dipbp2kncr] {
    width: 22px; height: 22px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: white; font-size: 13px; font-weight: 500; flex-shrink: 0;
}
.bom-row-body[b-dipbp2kncr] { flex: 1; min-width: 0; }
.bom-row-part[b-dipbp2kncr] { font-weight: 500; }
.bom-row-meta[b-dipbp2kncr] { font-size: 13px; color: var(--vz-secondary-color); margin-top: 1px; }
.bom-part-link[b-dipbp2kncr] { cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.bom-part-link:hover[b-dipbp2kncr] { color: var(--vz-primary); text-decoration-thickness: 2px; }

/* 버전 이력 타임라인 (원본 VersionTimeline.svelte) */
.timeline[b-dipbp2kncr] { display: flex; flex-direction: column; gap: 10px; }
.timeline-item[b-dipbp2kncr] { display: flex; gap: 10px; align-items: flex-start; }
.timeline-dot[b-dipbp2kncr] { width: 10px; height: 10px; border-radius: 50%; margin-top: 6px; flex-shrink: 0; }
.timeline-content[b-dipbp2kncr] { flex: 1; min-width: 0; }

/* 부품 상세 팝업 — 2026-08-31 Components/Shared/PartPreview/JkPartPreviewModal.razor.css 로
   옮겼다(마크업과 같이 간다. 같은 날 팝업 두 벌을 한 벌로 합치면서 그리로 다시 이사했다).
   ⛔ 여기 되돌려 놓지 마라 — CSS 격리는 «컴포넌트»별이라 이 파일에 두면 그 팝업엔 안 먹는다. */

/* 인라인 편집 */
.editable[b-dipbp2kncr] { cursor: pointer; position: relative; }
.editable:hover[b-dipbp2kncr] { background: var(--vz-secondary-bg-subtle, #eef0f5); border-radius: 4px; }
.edit-hint[b-dipbp2kncr] {
    font-size: 13px; color: var(--vz-secondary-color);
    opacity: 0; transition: opacity 0.15s; margin-left: 6px;
}
.editable:hover .edit-hint[b-dipbp2kncr] { opacity: 1; }

/* 유틸 */
.btn-xs[b-dipbp2kncr] { padding: 2px 8px; font-size: 13px; }

/* ── 모바일 최적화 ──
   ⛔ `.split-*`·`.analysis-*` 선택자는 없다 — 그 요소들이 이제 없다.
      죽은 선택자를 남기면 다음 사람이 "모바일은 아직 split 이구나"로 읽는다. */
@media (max-width: 768px) {
    .chg-top[b-dipbp2kncr] { flex-wrap: wrap; gap: 8px; }
    .subj-title[b-dipbp2kncr] { font-size: 18px; }
    .card2-bd[b-dipbp2kncr] { padding: 12px; }
    .sched-row[b-dipbp2kncr] { gap: 10px; }
    .sched-row > div[b-dipbp2kncr] { min-width: 100%; }

    .chg-foot[b-dipbp2kncr] { flex-direction: column; align-items: stretch; gap: 8px; padding: 10px 12px; }
    .foot-note[b-dipbp2kncr] { order: 2; }
    .foot-actions[b-dipbp2kncr] { order: 1; margin-left: 0; flex-wrap: wrap; }
}

/* ── 대상 문서·도면 = 카드 그리드 (2026-08-31 사용자 지시) ─────────────────
   부품은 위 .items-list 그대로 두고, 문서/도면만 이 그리드로 그린다.
   도면은 「그림을 봐야」 무엇인지 알기 때문에 리스트로 되돌리지 말 것. */
.ecrd-doc-grid[b-dipbp2kncr] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
    margin-top: 8px;
}
.ecrd-doc-tile[b-dipbp2kncr] {
    position: relative;
    border: 1px solid var(--vz-border-color, #e9ebec);
    border-radius: 6px;
    background: var(--vz-secondary-bg, #fff);
    overflow: hidden;
}
.ecrd-doc-tile:hover[b-dipbp2kncr] { border-color: var(--vz-primary, #405189); }
.ecrd-doc-thumb[b-dipbp2kncr] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 108px;
    padding: 0;
    border: 0;
    border-bottom: 1px solid var(--vz-border-color, #e9ebec);
    background: var(--vz-light, #f3f6f9);
    cursor: pointer;
}
.ecrd-doc-thumb img[b-dipbp2kncr] { width: 100%; height: 100%; object-fit: contain; }
.ecrd-doc-ext[b-dipbp2kncr],
.ecrd-doc-converting[b-dipbp2kncr] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--vz-secondary-color, #878a99);
}
.ecrd-doc-ext i[b-dipbp2kncr] { font-size: 1.6rem; }
.ecrd-doc-meta[b-dipbp2kncr] { padding: 6px 8px; }
.ecrd-doc-title[b-dipbp2kncr] { font-size: 13px; font-weight: 500; }
.ecrd-doc-badges[b-dipbp2kncr] { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 3px; }
.ecrd-doc-badges .badge[b-dipbp2kncr] { font-size: 12px; }
/* 빼기 버튼은 타일 위에 얹는다 - 메타 줄을 좁히지 않으려는 것이다. */
.ecrd-doc-remove[b-dipbp2kncr] {
    position: absolute;
    top: 4px;
    right: 4px;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 4px;
}
/* /Components/Pages/ErpBom/BomEffectivity.razor.rz.scp.css */
/* 원본 effectivity/+page.svelte 에는 <style> 블록이 «없다».
   여기 있던 것은 confirm(...) 대체 확인 카드(.eff-modal-backdrop/.eff-modal-card)뿐이었고,
   2026-09-03 그 확인창을 공용 확인 모달(JkConfirmService/JkModal)로 옮기면서 규칙도 걷어냈다.
   ⛔ 확인창 스타일을 화면별로 다시 만들지 마라 — 껍데기는 JkModal 한 벌이다. */
/* /Components/Pages/ErpBom/ErpOutbox.razor.rz.scp.css */
/* 원본 outbox/+page.svelte 의 <style> 블록(1048~1082행) 그대로 이식.
   ⛔ 디자인을 «새로 만들지 않는다» — 값(폭·색·테두리)을 원본과 같게 둔다. */

.ring-primary[b-3bs4u34os6] { box-shadow: 0 0 0 2px var(--vz-primary); }

/* 상세 모달 — modal-xl 의 1140px 한계 완화. 와이드 모니터에서 표 가독성 확보.
   ⛔ 원본은 :global() 로 걸었다 — Blazor 는 스코프 CSS 라 ::deep 이 그 자리다.
      다이얼로그가 이 컴포넌트의 마크업 «안»에 있으므로 클래스 선택자만으로도 닿는다. */
.outbox-detail-dialog[b-3bs4u34os6] {
    max-width: min(1600px, 95vw) !important;
}

/* Payload 패널 — 흰 바탕 + 부드러운 보더로 표 가독성 향상 */
.payload-pane[b-3bs4u34os6] {
    background: #fbfcfe;
}

/* Payload 분류 섹션 — 품목/속성/도면/BOM 등 시각 구분 */
.payload-section[b-3bs4u34os6] { margin-bottom: 1rem; }
.payload-section:last-child[b-3bs4u34os6] { margin-bottom: 0; }
.payload-section-title[b-3bs4u34os6] {
    font-size: 13px;
    font-weight: 600;
    color: #344054;
    margin-bottom: 0.55rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid var(--vz-border-color);
}

/* /Components/Pages/GovernanceAdmin/AuditLogBrowser.razor.rz.scp.css */
/* 원본 JK.AI.Front/src/routes/admin/audit/log/+page.svelte 의 <style> 블록.
   ⛔ 2026-09-01 — 원본에 있던 .fs-12·.fs-13 재정의는 제거했다. 이 화면에서만 전역 유틸을
      14.4px 로 키우고 있었고(실측), 그것이 «페이지마다 글자 크기가 다르다» 는 지적의 원인 중 하나다.
   ⛔ 나머지 값은 원본 숫자다 — 색·z-index 를 새로 고르지 않았다. */



.audit-table tbody tr.expanded[b-97plq966kf] { background: var(--vz-tertiary-bg); }

.audit-detail-summary[b-97plq966kf] {
    font-size: 14px;
    line-height: 1.4;
    word-break: break-word;
}

.audit-detail-row td[b-97plq966kf] { border-top: 0; }

.audit-json[b-97plq966kf] {
    font-size: 12px;
    background: var(--vz-secondary-bg);
    padding: 8px;
    border-radius: 4px;
    border: 1px solid var(--vz-border-color);
    white-space: pre-wrap;
    word-break: break-all;
}

.cursor-pointer[b-97plq966kf] { cursor: pointer; }

.autocomplete-dropdown[b-97plq966kf] {
    position: absolute; top: 100%; left: 12px; right: 12px;
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    max-height: 320px; overflow-y: auto;
    z-index: 1055; margin-top: 2px;
}

.autocomplete-item[b-97plq966kf] {
    display: block; width: 100%; text-align: left;
    padding: 6px 10px;
    background: transparent; border: none;
    font-size: 13px; cursor: pointer;
}

.autocomplete-item.highlighted[b-97plq966kf], .autocomplete-item:hover[b-97plq966kf] {
    background: var(--vz-tertiary-bg);
}
/* /Components/Pages/GovernanceAdmin/CategoryPolicies.razor.rz.scp.css */
/* 원본 JK.AI.Front/src/routes/admin/categories/+page.svelte 의 <style> 블록 그대로.
   ⛔ 값을 «고르지» 않았다 — 여백·색 전부 원본 숫자다. */

.cat-tree[b-1znx1onkfm], .cat-tree ul[b-1znx1onkfm] { list-style: none; padding-left: 0; margin: 0; }
.cat-tree ul[b-1znx1onkfm] { padding-left: 1rem; }

.cat-row[b-1znx1onkfm] {
    padding: 0.3rem 0.5rem;
    cursor: pointer;
    border-radius: 4px;
    font-size: 13px;
}

.cat-row:hover[b-1znx1onkfm] { background: var(--vz-light); }

.cat-row.active[b-1znx1onkfm] {
    background: var(--vz-primary-bg-subtle, #dff0fa);
    color: var(--vz-primary);
    font-weight: 600;
}

/* /Components/Pages/GovernanceAdmin/RoleDefinitions.razor.rz.scp.css */
/* 원본 JK.AI.Front/src/routes/admin/permissions/roles/+page.svelte 의 <style> 블록 그대로.
   ⛔ 값을 «고르지» 않았다 — 크기·색·투명도 전부 원본 숫자다. */

/* 활성(파란 배경) 행에서 bg-light 배지가 역할명을 시각적으로 가리는 문제 — outline 스타일로 약화 */
.role-system-badge.is-active[b-6idymqi0qb] {
    background-color: rgba(255, 255, 255, 0.18);
    color: var(--vz-white);
    border: 1px solid rgba(255, 255, 255, 0.55);
}

/* 역할 카드의 편집/삭제 액션 — list-group-item-action(button) 안의 click 전파 차단 + 호버 효과 */
.role-action-btn[b-6idymqi0qb] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 4px;
    color: var(--vz-secondary);
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.role-action-btn:hover[b-6idymqi0qb] {
    background-color: rgba(0, 0, 0, 0.06);
    color: var(--vz-primary);
}

.role-action-btn.role-delete-btn:hover[b-6idymqi0qb] {
    color: var(--vz-danger);
}

.role-action-btn.on-active[b-6idymqi0qb] {
    color: rgba(255, 255, 255, 0.85);
}

.role-action-btn.on-active:hover[b-6idymqi0qb] {
    background-color: rgba(255, 255, 255, 0.18);
    color: var(--vz-white);
}

/* 매트릭스에서 변경된 행 강조 */
tr.row-changed[b-6idymqi0qb] {
    background-color: #fff8e1 !important;
}

/* 원본 RoleFormModal.svelte 의 <style> — z-index 두 줄 그대로. */
.role-modal-backdrop[b-6idymqi0qb] { z-index: 1050; }
.role-modal[b-6idymqi0qb] { z-index: 1055; }
/* /Components/Pages/ImportOps/DrawingTranslate.razor.rz.scp.css */
/*
    다국어 오버레이 — 원본 스타일 두 벌.
      ① +page.svelte 의 <style>(160~168행) — .ov-img · .ov-layer · .ov-text · .stage-msg
      ② SvgPanZoomStage.svelte 의 <style>(70~80행) — .svg-pz-stage

    ⛔⛔ CSS 격리(scoped)라서 «JS 가 만든 노드»(img · 오버레이 span)에는 스코프 속성이 붙지 않는다.
       그래서 ::deep 으로 뚫는다. 빼면 «조용히» 안 먹는다 —
       오버레이 글자가 흰 배경 없이 도면 위에 겹쳐 보이고, 위치도 흐트러진다.

    ⛔ 값을 고르지 않았다. 폰트·색·배경은 원본 그대로다.
*/

.svg-pz-stage[b-62ap53w2g7] {
    position: relative;
    width: 100%;
    min-height: 420px;
    height: calc(100vh - 240px);
    overflow: hidden;
    cursor: grab;
    user-select: none;
    background: #fff;
}
.svg-pz-stage:active[b-62ap53w2g7] { cursor: grabbing; }

/* JS 가 소유하는 칸 — 스테이지를 꽉 채운다(내부 img/레이어가 position:absolute 로 깔린다). */
.dtr-slot[b-62ap53w2g7] { position: absolute; inset: 0; }

.dtr-slot[b-62ap53w2g7]  .ov-img { position: absolute; top: 0; left: 0; will-change: transform; }
.dtr-slot[b-62ap53w2g7]  .ov-layer { position: absolute; top: 0; left: 0; will-change: transform; pointer-events: none; }
.dtr-slot[b-62ap53w2g7]  .ov-text {
    position: absolute;
    background: #fff;
    color: #111;
    line-height: 1;
    padding: 0 1px;
    white-space: nowrap;
    font-family: 'Malgun Gothic', sans-serif;
}

.stage-msg[b-62ap53w2g7] {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    font-size: 13px; white-space: nowrap;
    z-index: 1;
}

/* 툴바 — 원본 인라인 style 을 클래스로 옮긴 것뿐(값 동일). */
.lang-select[b-62ap53w2g7] { width: auto; }
.scale-badge[b-62ap53w2g7] { min-width: 52px; }
/* /Components/Pages/IncomingDesk/DocumentDetailRoute.razor.rz.scp.css */
/* 원본 +page.svelte 의 <style> 블록(85~91행) 그대로.
   ⛔ 값(70vh / 24px)을 «다듬지 않는다» — 실패 안내가 화면 중앙에 서는 축이다. */
.doc-route-state[b-9i8a623o7x] {
    min-height: 70vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

/* 메타 표의 잔글씨 — 받은 배포함과 «같은 값»(원본 incoming 238~241행). */
/* /Components/Pages/IncomingDesk/IncomingDistributions.razor.rz.scp.css */
/* 원본 +page.svelte 의 <style> 블록(238~241행) 그대로.
   ⛔ 원본은 이 클래스 하나뿐이다 — 다른 규칙을 «덧붙이지 않는다». */
/* /Components/Pages/MiscDesk/AdminNotFound.razor.rz.scp.css */
/*
    원본 admin/[...unmatched]/+page.svelte 의 <style>(38~52행) 그대로.
    ⛔ 색은 Velzon CSS 변수를 쓴다 — 값을 새로 고르지 않는다(디자인 표준).
*/

.admin-404[b-a7tq6ca6s9] {
    min-height: 60vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px;
}
.admin-404-code[b-a7tq6ca6s9] {
    font-size: 64px;
    font-weight: 500;
    color: var(--vz-primary);
    line-height: 1.1;
}
.admin-404-msg[b-a7tq6ca6s9] {
    margin: 12px 0 24px;
    color: var(--vz-secondary-color);
    font-size: 15px;
}
/* /Components/Pages/MiscDesk/AgentDocView.razor.rz.scp.css */
/*
    에이전트 산출물 문서 뷰어 — 원본 스타일:
      JK.AI.Front/src/routes/view/[id]/+page.svelte 의 <style>(223~291행).

    ⛔⛔ 원본의 `:global(body) { background: #f5f5f5 }` 는 «옮길 수 없다» —
       Blazor 의 CSS 격리는 컴포넌트 밖(body)에 규칙을 걸지 못한다.
       대신 화면 전체를 감싸는 .vw 판에 같은 색·같은 높이를 준다(PublicQuoteView.razor.css 의 .pq 와 같은 수법).

    ⛔⛔ 원본의 `.document-content :global(h1|h2|table|thead|blockquote …)`(262~277행)은
       `::deep` 으로 옮겼다. 이유가 있다 — 마크다운 HTML 은 «자식 컴포넌트»(<JkRichText>) 안에서 그려지고,
       Blazor 의 격리 CSS 속성은 «이 컴포넌트의 마크업»에만 붙는다. `::deep` 없이 `.document-content h1`
       이라고 쓰면 규칙이 «한 개도» 걸리지 않는다(에러 없이 서식만 사라진다 — 원본의 :global 과 같은 함정).
       ⛔ 값은 원본 그대로다. th 의 font-weight:600 도 원본 값이라 바꾸지 않았다.

    ⛔⛔ 인쇄 규칙을 빼지 마라 — 이 화면의 버튼 둘 중 하나가 「인쇄」다.
       툴바·푸터는 종이에 나오면 안 되고, 본문 폭은 종이에서 전폭이어야 한다.
*/

.vw[b-ktu1sg7y36] {
    min-height: 100vh;
    background: #f5f5f5;
}

.view-loading[b-ktu1sg7y36],
.view-error[b-ktu1sg7y36] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

/* 원본은 아이콘 크기·색을 인라인 style 로 줬다(151행) — 격리 CSS 로 옮긴다. */
.view-error i[b-ktu1sg7y36] {
    font-size: 3rem;
    color: #dc3545;
}

/* 「로그인이 필요합니다」는 오류가 아니다 — 같은 판을 쓰되 색만 중립으로. */
.view-error i.lockico[b-ktu1sg7y36] {
    color: #6c757d;
}

.view-toolbar[b-ktu1sg7y36] {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--vz-secondary-bg);
    border-bottom: 1px solid var(--vz-border-color);
    padding: 8px 24px;
}

.view-container[b-ktu1sg7y36] {
    max-width: 860px;
    margin: 0 auto;
    padding: 32px 24px;
    background: var(--vz-secondary-bg);
    min-height: calc(100vh - 50px);
}

.view-footer[b-ktu1sg7y36] {
    margin-top: 3rem;
}

/* 문서 스타일 — 원본 258~261행 */
.document-content[b-ktu1sg7y36] {
    line-height: 1.8;
    font-size: 14px;
}

/* 마크다운 조각을 감싸는 판. 원본은 {@html …} 이라 감싸는 요소가 없었지만,
   Blazor 는 «자식 컴포넌트»를 여기 넣으므로 ::deep 의 기준점이 필요하다. 서식은 주지 않는다. */
.md-block[b-ktu1sg7y36] {
    display: contents;
}

/* ── 마크다운 렌더 결과 서식 — 원본 262~277행 (:global → ::deep) ────────────── */
.document-content[b-ktu1sg7y36]  h1 { font-size: 1.6rem; border-bottom: 3px solid var(--vz-primary); padding-bottom: 0.5rem; margin-top: 2rem; }
.document-content[b-ktu1sg7y36]  h2 { font-size: 22px; color: var(--vz-primary); border-bottom: 2px solid var(--vz-primary); padding-bottom: 0.4rem; margin-top: 1.5rem; }
.document-content[b-ktu1sg7y36]  h3 { font-size: 18px; color: var(--vz-primary); margin-top: 1.2rem; }
.document-content[b-ktu1sg7y36]  h4 { font-size: 16px; color: var(--vz-body-color); margin-top: 1rem; }
.document-content[b-ktu1sg7y36]  table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: 13px; }
.document-content[b-ktu1sg7y36]  thead { background: var(--vz-primary); color: var(--vz-white); }
.document-content[b-ktu1sg7y36]  th { padding: 0.6rem 0.75rem; font-weight: 600; text-align: left; border: 1px solid var(--vz-primary); }
.document-content[b-ktu1sg7y36]  td { padding: 0.5rem 0.75rem; border: 1px solid var(--vz-border-color); }
.document-content[b-ktu1sg7y36]  tbody tr:nth-child(even) { background: var(--vz-tertiary-bg); }
.document-content[b-ktu1sg7y36]  tbody tr:hover { background: var(--vz-tertiary-bg); }
.document-content[b-ktu1sg7y36]  ul,
.document-content[b-ktu1sg7y36]  ol { padding-left: 1.5rem; margin: 0.5rem 0; }
.document-content[b-ktu1sg7y36]  li { margin-bottom: 0.3rem; }
.document-content[b-ktu1sg7y36]  hr { border: none; border-top: 2px solid var(--vz-border-color); margin: 1.5rem 0; }
.document-content[b-ktu1sg7y36]  code { background: #f1f3f5; padding: 0.15rem 0.4rem; border-radius: 3px; font-size: 0.9em; }
.document-content[b-ktu1sg7y36]  blockquote { border-left: 4px solid var(--vz-primary); padding: 0.5rem 1rem; margin: 1rem 0; background: var(--vz-tertiary-bg); color: var(--vz-body-color); }
.document-content[b-ktu1sg7y36]  strong { color: var(--vz-body-color); }

/* 원본 200행의 인라인 style="max-height: 500px" */
.doc-img[b-ktu1sg7y36] {
    max-height: 500px;
}

/* 인쇄 최적화 — 원본 280~290행 */
@media print {
    .vw[b-ktu1sg7y36] {
        background: var(--vz-secondary-bg);
    }

    .no-print[b-ktu1sg7y36] {
        display: none !important;
    }

    .view-container[b-ktu1sg7y36] {
        max-width: 100%;
        padding: 0;
        margin: 0;
    }

    .doc-img[b-ktu1sg7y36],
    .document-content[b-ktu1sg7y36]  img {
        max-height: 300px !important;
    }

    /* 원본 289행 — 표가 페이지 경계에서 잘리지 않게. */
    .document-content[b-ktu1sg7y36]  table {
        page-break-inside: avoid;
    }
}
/* /Components/Pages/MiscDesk/JkDrawingCompareView.razor.rz.scp.css */
/*
    도면 비교 뷰 — 원본 스타일 두 벌.
      ① DrawingCompareView.svelte 의 <style>(288~330행)
      ② SvgPanZoomStage.svelte 의 <style>(70~80행) — .svg-pz-stage

    ⛔⛔ 2026-08-31 — 이 파일은 «부품과 함께» 움직인다(DrawingRevisionCompare.razor.css 에서 이름만 바뀜).
       CSS 격리는 «같은 이름의 .razor» 에만 스코프 속성을 붙인다. 부품을 다른 파일로 뽑으면서
       이 파일을 두고 가면 스타일이 통째로 빠진다 — 에러 없이, 화면만 무너진다.

    ⛔⛔ CSS 격리(scoped)라서 «JS 가 만든 노드»에는 스코프 속성이 붙지 않는다.
       그래서 SVG 안쪽을 겨냥하는 규칙은 ::deep 로 뚫는다. 빼면 조용히 안 먹는다:
         · non-scaling-stroke 가 안 먹으면 fit 줌에서 선이 사라진다.
         · mix-blend-mode 가 안 먹으면 «겹침이 어두워지지 않아» 비교가 성립하지 않는다.
*/

.svg-pz-stage[b-7tzlwzc7g8] {
    position: relative;
    width: 100%;
    min-height: 420px;
    overflow: hidden;
    cursor: grab;
    user-select: none;
}
.svg-pz-stage:active[b-7tzlwzc7g8] { cursor: grabbing; }

/* JS 가 소유하는 칸 — 스테이지를 꽉 채운다(내부 <svg> 가 position:absolute 로 깔린다). */
.dcv-svg-slot[b-7tzlwzc7g8] { position: absolute; inset: 0; }

.dcv-svg-slot[b-7tzlwzc7g8]  .cmp-svg { position: absolute; inset: 0; isolation: isolate; }
/* 선은 줌과 무관하게 일정 굵기로 보이도록(=fit 줌에서도 안 사라짐) + 벡터 무손실 */
.dcv-svg-slot[b-7tzlwzc7g8]  .cmp-svg path { vector-effect: non-scaling-stroke; }
/* ⛔ 겹침이 어두워지는 축 — 이 한 줄이 「빨강/초록/겹침=공통」을 성립시킨다. */
.dcv-svg-slot[b-7tzlwzc7g8]  .cmp-top { mix-blend-mode: multiply; }

.stage-msg[b-7tzlwzc7g8] {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    font-size: 13px; white-space: nowrap;
    z-index: 1;
}

.swatch[b-7tzlwzc7g8] { display: inline-block; width: 12px; height: 12px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
.sw-red[b-7tzlwzc7g8] { background: #d6336c; }      /* 서버가 기준(삭제분)을 이 색으로 렌더한다 — DrawingController.cs:1497 */
.sw-green[b-7tzlwzc7g8] { background: #128a4f; }    /* 개정(추가분) — 같은 파일 1498행 */
.sw-dark[b-7tzlwzc7g8] { background: #2b2b2b; }
.legend .form-check-label[b-7tzlwzc7g8] { cursor: pointer; }

.diff-panel[b-7tzlwzc7g8] {
    width: 320px;
    flex: 0 0 320px;
    height: calc(100vh - 280px);
    min-height: 420px;
    overflow-y: auto;
    padding: 10px 12px;
    font-size: 12px;
}
.dp-head[b-7tzlwzc7g8] { margin-bottom: 8px; font-size: 13px; }
.dp-sec-title[b-7tzlwzc7g8] { font-weight: 500; margin: 10px 0 4px; font-size: 12px; }
.dp-item[b-7tzlwzc7g8] {
    padding: 3px 6px; border-radius: 4px; margin-bottom: 2px;
    background: #f8f9fa; word-break: break-all; line-height: 1.4;
}
.dp-item .old[b-7tzlwzc7g8] { color: #d6336c; text-decoration: line-through; }
.dp-item .new[b-7tzlwzc7g8] { color: #128a4f; }

/*
    FillParent(모달 임베드) — 정본 DrawingCompareView.svelte:301~304 그대로.
    카드·스테이지·변경목록을 «부모 높이 100%»로 접는다.

    ⛔⛔ 이 네 줄이 빠지면 모달 안에서 스테이지가 calc(100vh - 280px) 로 남아 모달 밖으로 넘친다
       (.dcv-modal-body 가 overflow:hidden 이라 아래쪽이 «잘린 채로» 보인다 — 에러는 안 난다).
    ⛔ .diff-panel 의 height:calc(100vh - 280px) 를 여기서 덮는다. 위 규칙을 지우지 마라 —
       standalone 진입(FillParent=false)이 그 값을 쓴다.
    ⛔ min-height:420px 는 «남겨 둔다»(정본과 같다). 모달이 그보다 낮아지면 스크롤이 생긴다.
*/
.dcv-fill[b-7tzlwzc7g8] { height: 100%; display: flex; flex-direction: column; }
.dcv-fill .dcv-body[b-7tzlwzc7g8] { flex: 1 1 auto; min-height: 0; }
.dcv-fill .dcv-stage-wrap[b-7tzlwzc7g8] { height: 100%; }
.dcv-fill .diff-panel[b-7tzlwzc7g8] { height: 100%; }
/* /Components/Pages/MiscDesk/PrintQuoteView.razor.rz.scp.css */
/*
    견적서 인쇄 — 원본 스타일 두 벌을 합친 것.
      ① routes/print/quote/[id]/+page.svelte 의 <style>(74~98행) — 바깥 판(.pq/.msg/.bar/.sheet)
      ② lib/components/sales/QuoteDocument.svelte 의 <style>(354~482행) 중 «읽기 전용»에
         실제로 걸리는 규칙만. 편집 표시(.editing …)·자동완성(.qd-ac-*)·행 삭제(.qd-x)·
         행 추가(.qd-addrow)는 editable=false 에서 «그려지지 않는» 요소라 옮기지 않았다.

    ⛔ 원본은 `:global(body) { background: #e9ecef }` 로 바탕을 깔았다. Blazor 스코프 CSS 는
       body 를 못 잡으므로 «바깥 판(.pq)에 min-height:100vh + 배경»으로 같은 그림을 만든다
       (PublicQuoteView.razor.css 가 먼저 쓴 방식 — 두 화면이 같아야 인쇄 결과가 같다).

    ⛔⛔ 스코프 CSS 는 «이 컴포넌트가 그린 노드»에만 붙는다. 그래서 양식을 MarkupString·JS 로
       만들지 않았다 — 만들면 스타일«만» 조용히 안 붙고 종이가 무스타일로 나온다(계약서 §4-B).

    ⛔⛔ 인쇄 규칙을 빼지 마라 — 「출력하면 이 양식대로」가 이 화면의 존재 이유다.
       상단 바는 종이에 나오면 안 되고, 표는 페이지 경계에서 행이 잘리면 안 된다.
*/

.pq[b-mjoqwkthc3] { min-height: 100vh; background: #e9ecef; }

.msg[b-mjoqwkthc3] { padding: 40px 20px; text-align: center; color: #6b7280; font-size: 14px; }
.msg.err[b-mjoqwkthc3] { color: #b91c1c; }
.msg.err i[b-mjoqwkthc3] { font-size: 32px; display: block; margin-bottom: 10px; color: #9ca3af; }

.bar[b-mjoqwkthc3] {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 10px 14px; background: #fff; border-bottom: 1px solid #dee2e6;
    position: sticky; top: 0; z-index: 5;
}
.hint[b-mjoqwkthc3] { color: #6b7280; font-size: 12px; margin-right: auto; }
.pbtn[b-mjoqwkthc3] {
    border: 1px solid #cfd4da; background: #fff; border-radius: 5px;
    padding: 5px 12px; font-size: 13px; cursor: pointer;
}
.pbtn.ghost[b-mjoqwkthc3] { color: #6b7280; }
.sheet[b-mjoqwkthc3] { padding: 18px; display: flex; justify-content: center; }
.sheet .qdoc[b-mjoqwkthc3] { box-shadow: 0 1px 8px rgba(0, 0, 0, 0.15); }

/* ── 양식 본체 (A4 폭 190mm — 화면에서 축소돼도 인쇄가 그대로 나오게 mm 를 쓴다) ── */
.qdoc[b-mjoqwkthc3] {
    background: #fff;
    color: #111;
    width: 190mm;
    max-width: 100%;
    margin: 0 auto;
    padding: 10mm 10mm 12mm;
    font-size: 13px;
    line-height: 1.5;
    box-sizing: border-box;
}
.qd-title[b-mjoqwkthc3] {
    text-align: center;
    font-size: 26px;
    font-weight: 500;      /* ⛔ 700 금지 — 앱 전역 규칙(폰트 ≤500) */
    letter-spacing: 8px;
    margin: 0 0 14px;
}
.qd-head[b-mjoqwkthc3] { display: flex; gap: 16px; align-items: flex-start; }
.qd-to[b-mjoqwkthc3], .qd-us[b-mjoqwkthc3] { flex: 1 1 0; min-width: 0; }
.qd-us[b-mjoqwkthc3] { border-left: 1px solid #e5e7eb; padding-left: 14px; }
.qd-to-name[b-mjoqwkthc3], .qd-us-name[b-mjoqwkthc3] { font-size: 15px; font-weight: 500; margin-bottom: 4px; }
.qd-gwiha[b-mjoqwkthc3] { font-size: 12px; color: #555; }
.qd-line[b-mjoqwkthc3] { display: flex; gap: 6px; font-size: 12px; }
.qd-lbl[b-mjoqwkthc3] { color: #6b7280; min-width: 56px; flex: 0 0 auto; }
.qd-val[b-mjoqwkthc3] { flex: 1 1 auto; min-width: 0; }
.qd-lead[b-mjoqwkthc3] { margin: 14px 0 10px; }
.qd-subject[b-mjoqwkthc3] { display: flex; gap: 8px; margin-bottom: 6px; }

.qd-table[b-mjoqwkthc3] { width: 100%; border-collapse: collapse; margin-top: 4px; }
.qd-table th[b-mjoqwkthc3], .qd-table td[b-mjoqwkthc3] { border: 1px solid #d1d5db; padding: 4px 6px; font-size: 12px; }
.qd-table thead th[b-mjoqwkthc3] { background: #f3f4f6; font-weight: 500; text-align: center; }
.qd-table td.c[b-mjoqwkthc3] { text-align: center; }
.qd-table td.r[b-mjoqwkthc3] { text-align: right; }
.qd-table td.empty[b-mjoqwkthc3] { color: #9ca3af; padding: 14px; }

.qd-sum[b-mjoqwkthc3] { margin: 8px 0 0 auto; border-collapse: collapse; }
.qd-sum th[b-mjoqwkthc3], .qd-sum td[b-mjoqwkthc3] { border: 1px solid #d1d5db; padding: 4px 10px; font-size: 12px; }
.qd-sum th[b-mjoqwkthc3] { background: #f3f4f6; font-weight: 500; text-align: left; min-width: 110px; }
.qd-sum td[b-mjoqwkthc3] { min-width: 130px; }
.qd-sum tr.grand th[b-mjoqwkthc3], .qd-sum tr.grand td[b-mjoqwkthc3] { background: #eef2ff; font-size: 13px; }

.qd-notes[b-mjoqwkthc3] { margin-top: 14px; }
.qd-notes-hd[b-mjoqwkthc3] { font-weight: 500; margin-bottom: 4px; }
.qd-notes ol[b-mjoqwkthc3] { margin: 0; padding-left: 18px; }
.qd-notes li[b-mjoqwkthc3] { font-size: 12px; }

.qd-footer[b-mjoqwkthc3] { margin-top: 14px; text-align: center; font-size: 11px; color: #6b7280; }

@media print {
    .pq[b-mjoqwkthc3] { background: #fff; }
    .bar[b-mjoqwkthc3] { display: none !important; }
    .sheet[b-mjoqwkthc3] { padding: 0; display: block; }
    .sheet .qdoc[b-mjoqwkthc3] { box-shadow: none; }
    .qdoc[b-mjoqwkthc3] { width: auto; padding: 0; }
    .qd-table tr[b-mjoqwkthc3] { break-inside: avoid; page-break-inside: avoid; }
    .qd-table thead[b-mjoqwkthc3] { display: table-header-group; }   /* 여러 장이면 머리행 반복 */
}
/* /Components/Pages/MiscDesk/PublicDistributionView.razor.rz.scp.css */
/*
    배포 비로그인 링크 — 원본 스타일 그대로:
      JK.AI.Front/src/routes/d/[token]/+page.svelte 의 <style>(163~204행).

    ⛔ 공개 화면이다 — 사내 레이아웃 밖. 값은 로그인 화면과 같은 톤(13px 본문, font-weight 500 이하)이다.
       ⛔ 색·크기를 새로 고르지 마라(디자인 표준). 원본 값에서 한 글자도 바꾸지 않았다.

    ⛔ 원본은 Svelte 스코프 스타일이라 클래스 이름이 짧다(.pd/.dl/.kv…). Blazor CSS 격리도 같은
       범위라 이름을 늘리지 않았다 — 원본과 대조하기 쉬운 쪽을 택했다.
*/

.pd[b-lury4bris7] {
    min-height: 100vh;
    background: #eef1f5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 32px 16px;
    font-size: 13px;
    color: #1f2f3e;
}

.card[b-lury4bris7] {
    width: 100%;
    max-width: 460px;
    background: #fff;
    border: 1px solid #e3e7ec;
    border-radius: 12px;
    padding: 28px 28px 24px;
}

.card.wide[b-lury4bris7] {
    max-width: 560px;
}

.brand[b-lury4bris7] {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 22px;
}

.logo[b-lury4bris7] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: #1b5cc2;
    color: #fff;
    font-weight: 500;
    font-size: 13px;
}

.name[b-lury4bris7] {
    color: #6b7785;
    font-size: 12px;
}

.title[b-lury4bris7] {
    font-size: 18px;
    font-weight: 500;
    line-height: 1.4;
    margin: 0 0 6px;
    display: flex;
    gap: 8px;
    align-items: flex-start;
    overflow-wrap: anywhere;
}

.title i[b-lury4bris7] {
    color: #c0392b;
    font-size: 20px;
    flex: 0 0 auto;
}

.title .ri-folder-zip-line[b-lury4bris7] {
    color: #1b5cc2;
}

.to[b-lury4bris7] {
    color: #6b7785;
    margin-bottom: 18px;
}

.to b[b-lury4bris7] {
    font-weight: 500;
    color: #1f2f3e;
}

.kv[b-lury4bris7] {
    display: grid;
    grid-template-columns: 72px 1fr;
    row-gap: 8px;
    column-gap: 12px;
    margin: 0 0 20px;
    padding: 14px;
    border: 1px solid #e3e7ec;
    border-radius: 8px;
    background: #f8fafc;
}

.kv dt[b-lury4bris7] {
    color: #6b7785;
}

.kv dd[b-lury4bris7] {
    margin: 0;
}

.sub2[b-lury4bris7] {
    color: #6b7785;
    margin-left: 4px;
}

.dl[b-lury4bris7] {
    width: 100%;
    border: 0;
    border-radius: 8px;
    padding: 12px;
    background: #1b5cc2;
    color: #fff;
    font-size: 14px;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    cursor: pointer;
}

.dl:disabled[b-lury4bris7] {
    opacity: 0.6;
    cursor: default;
}

.dl:hover:not(:disabled)[b-lury4bris7] {
    background: #174fa8;
}

.note[b-lury4bris7] {
    margin-top: 12px;
    color: #6b7785;
    font-size: 12px;
    line-height: 1.5;
    display: flex;
    gap: 6px;
    align-items: flex-start;
}

.note.warn[b-lury4bris7] {
    color: #8a5a00;
}

.block[b-lury4bris7] {
    display: flex;
    gap: 10px;
    align-items: center;
    padding: 14px;
    border-radius: 8px;
    background: #fff4f2;
    border: 1px solid #f3d1cb;
    color: #8a2b1d;
}

.block i[b-lury4bris7] {
    font-size: 20px;
}

.msg[b-lury4bris7] {
    padding: 32px 0;
    text-align: center;
    color: #6b7785;
}

.msg.err i[b-lury4bris7] {
    font-size: 28px;
    display: block;
    margin-bottom: 8px;
    color: #c0392b;
}

/* 한도 초과 — ⛔ .err(빨강)과 «다른 색»이어야 한다. 링크가 죽은 것이 아니라 잠시 제한된 것이다.
   같은 색을 쓰면 사용자가 재발급을 요청하게 된다(.note.warn 과 같은 앰버 계열로 맞췄다). */
.msg.wait i[b-lury4bris7] {
    font-size: 28px;
    display: block;
    margin-bottom: 8px;
    color: #8a5a00;
}

.msg .sub[b-lury4bris7] {
    font-size: 12px;
    margin-top: 6px;
}

.foot[b-lury4bris7] {
    margin-top: 18px;
    color: #98a3ae;
    font-size: 12px;
}

/* ── 파일 목록 (원본 192~203행) ── */
.files[b-lury4bris7] {
    list-style: none;
    margin: 16px 0 0;
    padding: 0;
    border: 1px solid #e3e7ec;
    border-radius: 8px;
    overflow: hidden;
}

.files li[b-lury4bris7] {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-top: 1px solid #e3e7ec;
}

.files li:first-child[b-lury4bris7] {
    border-top: 0;
}

.fi[b-lury4bris7] {
    color: #c0392b;
    font-size: 18px;
    flex: 0 0 auto;
}

.fmain[b-lury4bris7] {
    flex: 1 1 auto;
    min-width: 0;
}

.fname[b-lury4bris7] {
    font-size: 13px;
    color: #1f2f3e;
    overflow-wrap: anywhere;
}

.fmeta[b-lury4bris7] {
    font-size: 12px;
    color: #6b7785;
    margin-top: 2px;
}

.fbad[b-lury4bris7] {
    color: #8a2b1d;
}

.fbtn[b-lury4bris7] {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: 1px solid #d6dbe1;
    background: #fff;
    border-radius: 6px;
    color: #1b5cc2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.fbtn:disabled[b-lury4bris7] {
    color: #b0b8c1;
    cursor: default;
}

.fbtn:hover:not(:disabled)[b-lury4bris7] {
    background: #f0f5fc;
}
/* /Components/Pages/MiscDesk/PublicQuoteLayout.razor.rz.scp.css */
/*
    ⛔⛔ 2026-09-03 (QA #42 · 견적서 출력 화면 맨 아래 「오류가 발생했습니다 · 새로 고침」)
       원인은 «회로 오류»가 아니라 «스타일이 안 붙은 것»이었다.
       `#blazor-error-ui` 를 display:none 으로 감추는 규칙은 Layout/MainLayout.razor.css 한 곳에만
       있는데, 그건 «스코프 CSS» 라 `#blazor-error-ui[b-hll8fnlub6]` 로 컴파일된다
       (실측: obj/…/scopedcss/bundle/JK.AI.Blazor.styles.css:242 — MainLayout 한 곳뿐).
       PublicQuoteLayout 이 그린 같은 이름의 div 에는 «다른 스코프»가 붙으므로 그 규칙이 안 걸리고,
       결국 오류가 없는데도 문서 흐름에 그대로 남아 화면 맨 아래에 보이고 인쇄 2페이지에도 찍혔다.
       wwwroot 에 전역 `#blazor-error-ui` 정의는 0건이다(2026-09-03 실측).

    ⛔ 공통 파일(MainLayout.razor.css)로 풀지 마라 — 스코프 CSS 는 원래 남의 컴포넌트에 안 붙는 것이
       계약이다. 마크업을 «가진 쪽»이 규칙도 갖는다.
    ⛔ 마크업(PublicQuoteLayout.razor 의 div)을 지워서 풀지도 마라 — 회로가 끊겼을 때
       고객 화면이 아무 말도 하지 않게 된다(그 div 의 존재 이유).
    ⚠️ 같은 결함이 Pages/AccountDesk/AuthPageLayout.razor 에도 있다(그쪽도 .razor.css 가 없다).
       이번 묶음 밖이라 손대지 않고 보고만 했다.
*/

#blazor-error-ui[b-xzytmpuvh7] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-xzytmpuvh7] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

/* ⛔ 이 레이아웃은 «종이로 나가는» 화면(/print/quote/{id})이 쓴다.
     진짜 회로 오류가 났더라도 그 배너가 견적서에 인쇄되면 안 된다 —
     화면에서는 보이고, 인쇄에서만 빠진다. */
@media print {
    #blazor-error-ui[b-xzytmpuvh7] {
        display: none !important;
    }
}
/* /Components/Pages/MiscDesk/PublicQuoteView.razor.rz.scp.css */
/*
    견적서 공개 열람 — 원본 스타일 두 벌을 합친 것.
      ① routes/quote/[token]/+page.svelte 의 <style>(84~101행) — 바깥 판(.pq/.msg/.bar/.sheet)
      ② lib/components/sales/QuoteDocument.svelte 의 <style>(354~482행) 중 «읽기 전용»에
         실제로 걸리는 규칙만. 편집 표시(.editing …)·자동완성(.qd-ac-*)·행 삭제(.qd-x)·
         행 추가(.qd-addrow)는 editable=false 에서 «그려지지 않는» 요소라 옮기지 않았다.

    ⛔ Svelte 는 두 컴포넌트로 나뉘어 있었고 페이지가 `:global(.qdoc)` 로 그림자를 줬다.
       Blazor 에서는 한 컴포넌트에 합쳤으므로 CSS 격리 범위가 같아 `::deep` 이 필요 없다.

    ⛔⛔ 인쇄 규칙을 빼지 마라 — 「출력하면 이 양식대로」가 이 문서의 요구다.
       상단 바는 종이에 나오면 안 되고, 표는 페이지 경계에서 행이 잘리면 안 된다.
*/

.pq[b-iik5727ydk] { min-height: 100vh; background: #e9ecef; }

.msg[b-iik5727ydk] { padding: 64px 20px; text-align: center; color: #6b7280; font-size: 14px; }
.msg.err i[b-iik5727ydk] { font-size: 32px; display: block; margin-bottom: 10px; color: #9ca3af; }
.msg .sub[b-iik5727ydk] { font-size: 12px; margin-top: 6px; color: #9ca3af; }

.bar[b-iik5727ydk] {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 16px; background: #fff; border-bottom: 1px solid #dee2e6;
}
.who[b-iik5727ydk] { font-size: 13px; color: #6b7280; margin-right: auto; }
.pbtn[b-iik5727ydk] {
    border: 1px solid #cfd4da; background: #fff; border-radius: 5px;
    padding: 5px 12px; font-size: 13px; cursor: pointer;
}
.sheet[b-iik5727ydk] { padding: 18px; display: flex; justify-content: center; }
.sheet .qdoc[b-iik5727ydk] { box-shadow: 0 1px 8px rgba(0, 0, 0, 0.15); }

/* ── 양식 본체 (A4 폭 190mm — 화면에서 축소돼도 인쇄가 그대로 나오게 mm 를 쓴다) ── */
.qdoc[b-iik5727ydk] {
    background: #fff;
    color: #111;
    width: 190mm;
    max-width: 100%;
    margin: 0 auto;
    padding: 10mm 10mm 12mm;
    font-size: 13px;
    line-height: 1.5;
    box-sizing: border-box;
}
.qd-title[b-iik5727ydk] {
    text-align: center;
    font-size: 26px;
    font-weight: 500;      /* ⛔ 700 금지 — 앱 전역 규칙(폰트 ≤500) */
    letter-spacing: 8px;
    margin: 0 0 14px;
}
.qd-head[b-iik5727ydk] { display: flex; gap: 16px; align-items: flex-start; }
.qd-to[b-iik5727ydk], .qd-us[b-iik5727ydk] { flex: 1 1 0; min-width: 0; }
.qd-us[b-iik5727ydk] { border-left: 1px solid #e5e7eb; padding-left: 14px; }
.qd-to-name[b-iik5727ydk], .qd-us-name[b-iik5727ydk] { font-size: 15px; font-weight: 500; margin-bottom: 4px; }
.qd-gwiha[b-iik5727ydk] { font-size: 12px; color: #555; }
.qd-line[b-iik5727ydk] { display: flex; gap: 6px; font-size: 12px; }
.qd-lbl[b-iik5727ydk] { color: #6b7280; min-width: 56px; flex: 0 0 auto; }
.qd-val[b-iik5727ydk] { flex: 1 1 auto; min-width: 0; }
.qd-lead[b-iik5727ydk] { margin: 14px 0 10px; }
.qd-subject[b-iik5727ydk] { display: flex; gap: 8px; margin-bottom: 6px; }

.qd-table[b-iik5727ydk] { width: 100%; border-collapse: collapse; margin-top: 4px; }
.qd-table th[b-iik5727ydk], .qd-table td[b-iik5727ydk] { border: 1px solid #d1d5db; padding: 4px 6px; font-size: 12px; }
.qd-table thead th[b-iik5727ydk] { background: #f3f4f6; font-weight: 500; text-align: center; }
.qd-table td.c[b-iik5727ydk] { text-align: center; }
.qd-table td.r[b-iik5727ydk] { text-align: right; }
.qd-table td.empty[b-iik5727ydk] { color: #9ca3af; padding: 14px; }

.qd-sum[b-iik5727ydk] { margin: 8px 0 0 auto; border-collapse: collapse; }
.qd-sum th[b-iik5727ydk], .qd-sum td[b-iik5727ydk] { border: 1px solid #d1d5db; padding: 4px 10px; font-size: 12px; }
.qd-sum th[b-iik5727ydk] { background: #f3f4f6; font-weight: 500; text-align: left; min-width: 110px; }
.qd-sum td[b-iik5727ydk] { min-width: 130px; }
.qd-sum tr.grand th[b-iik5727ydk], .qd-sum tr.grand td[b-iik5727ydk] { background: #eef2ff; font-size: 13px; }

.qd-notes[b-iik5727ydk] { margin-top: 14px; }
.qd-notes-hd[b-iik5727ydk] { font-weight: 500; margin-bottom: 4px; }
.qd-notes ol[b-iik5727ydk] { margin: 0; padding-left: 18px; }
.qd-notes li[b-iik5727ydk] { font-size: 12px; }

.qd-footer[b-iik5727ydk] { margin-top: 14px; text-align: center; font-size: 11px; color: #6b7280; }

@media print {
    .pq[b-iik5727ydk] { background: #fff; }
    .bar[b-iik5727ydk] { display: none !important; }
    .sheet[b-iik5727ydk] { padding: 0; display: block; }
    .sheet .qdoc[b-iik5727ydk] { box-shadow: none; }
    .qdoc[b-iik5727ydk] { width: auto; padding: 0; }
    .qd-table tr[b-iik5727ydk] { break-inside: avoid; page-break-inside: avoid; }
    .qd-table thead[b-iik5727ydk] { display: table-header-group; }   /* 여러 장이면 머리행 반복 */
}
/* /Components/Pages/MyWork/MyWorkBoard.razor.rz.scp.css */
/*
    내 작업 — 이 화면에서만 쓰는 CSS. Blazor CSS 격리(collocation)라 이 컴포넌트 밖으로 새지 않는다.

    ⛔ 새로 «디자인한» 값이 하나도 없다. 둘 다 기존 프론트의 컴파일 산출물에서 그대로 옮겼다:
      ① .mw-search  — 원본 +page.svelte 의 <style> 블록(결재함 .inbox-search 와 같은 수치).
                      ⛔ 배경은 흰색이어야 입력칸이 보인다 — --vz-light 는 페이지 배경과 거의 같아
                         2026-08-08 에 "검색칸을 못 찾겠다"는 지적이 나왔다.
      ② (삭제됨) .segtabs — 여기에 사본이 있었다. 2026-08-30 통합에서 «지웠다».
                      ⛔ 「global.css 에 없다」는 실측이 «다른 파일»을 잰 것이었다:
                         JK.AI.Web/wwwroot/... 는 08-29 셸 CSS 이관 «이전»의 배포본이라 0건이지만,
                         이 셸이 실제로 서빙하는 것은 JK.AI.Web/bin/Debug/net8.0/wwwroot 쪽이고
                         거기 global.css 에는 .segtabs 규칙이 있다(실측 14건, 부품 상세에서 렌더 확인).
                      ⛔ 같은 클래스를 두 벌 두면 한쪽만 늙는다 — 사본이 아니라 정본을 쓴다.
*/

/* ── 검색 (원본 +page.svelte <style>) ─────────────────────────────────── */
.mw-search[b-iy3ld8tf6t] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 180px;
    min-width: 150px;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 20px;
    padding: 5px 12px;
    color: var(--vz-secondary-color);
}

.mw-search:focus-within[b-iy3ld8tf6t] {
    border-color: var(--vz-primary);
}

.mw-search input[b-iy3ld8tf6t] {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    outline: none;
    font-size: 13px;
    color: var(--vz-body-color);
}

.mw-search input[b-iy3ld8tf6t]::-webkit-search-cancel-button {
    display: none;
}

.mw-search-clear[b-iy3ld8tf6t] {
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    padding: 0;
    line-height: 1;
    cursor: pointer;
}

.mw-search-clear:hover[b-iy3ld8tf6t] {
    color: var(--vz-primary);
}

/* ── 세그먼트 탭 (SegTabs.svelte 청크에서 해시만 제거) ─────────────────── */











/* ══ 정본 스타일 이식 (2026-08-31 스타일 감사) ══════════════════════
   마크업은 쓰는데 «어느 CSS 에도 정의가 없던» 클래스들이다 - 화면이 조용히 무스타일이었다.
   출처: JK.AI.Front/src/lib/components/plm/SimilarPartPanel.svelte
   ⛔ 정본에 «없는» 클래스는 이식하지 않았다 - 정본과 동일하게 맞추는 것이 지시다.
   ⛔ 자식 컴포넌트가 그리는 노드는 스코프가 달라 ::deep 이 필요하다(정본의 :global 과 같은 축). */

.min-w-0[b-iy3ld8tf6t] {
    min-width: 0;
}
/* /Components/Pages/NotFound.razor.rz.scp.css */
/* 전역 404. ⛔ 이 화면의 요소는 전부 렌더 트리가 만든다(JS·MarkupString 없음) → 스코프 CSS 가 먹는다. */
.jk-nf[b-7bhz2ijhl7] {
    max-width: 480px;
    margin: 8vh auto 0;
    text-align: center;
    padding: 0 16px;
}

.jk-nf-ic[b-7bhz2ijhl7] {
    font-size: 44px;
    color: #ced4da;
    line-height: 1;
}

.jk-nf-title[b-7bhz2ijhl7] {
    margin: 14px 0 8px;
    font-size: 22px;   /* 디자인 표준 h1 */
    font-weight: 500;
}

.jk-nf-desc[b-7bhz2ijhl7] {
    font-size: 13px;   /* 디자인 표준 본문 */
    color: #878a99;
    line-height: 1.7;
    margin-bottom: 20px;
}

.jk-nf-actions[b-7bhz2ijhl7] {
    display: flex;
    justify-content: center;
    gap: 6px;
    flex-wrap: wrap;
}
/* /Components/Pages/OrderDetail/OrderDetailView.razor.rz.scp.css */
/* 원본 sales/orders/[id]/+page.svelte 의 <style>(1716~1727행) 그대로. */

.modal-backdrop-custom[b-clwmxnvh6p] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1050;
}

.readonly-html[b-clwmxnvh6p] {
    padding: 8px 12px;
    border: 1px solid var(--vz-border-color);
    background: var(--vz-tertiary-bg);
    border-radius: 6px;
    min-height: 40px;
}


/* ══ 헤더 위험도 카드 ══════════════════════════════════════════════════
   출처: JK.AI.Front/src/lib/components/sales/SalesOrderRiskCard.svelte 의 <style>(114~134행).
   ⛔ 정본이 Svelte 스코프 안에 두고 있어 global.css 에 0건이다 — 안 옮기면 무스타일이다.
   ⛔ 값을 손보지 않았다(padding 6px 12px · font-size 0.9rem · background #f8f9fc · gap 0.4rem 0.6rem). */

.risk-card[b-clwmxnvh6p] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.6rem;
    padding: 6px 12px;
    font-size: 13px;
    background: #f8f9fc;
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
}

.metric[b-clwmxnvh6p] {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    transition: color 0.12s;
}

.metric:hover[b-clwmxnvh6p] {
    color: var(--vz-primary);
}

.sep[b-clwmxnvh6p] {
    color: #c5c8d0;
}

/* 출처: JK.AI.Front/src/lib/components/common/CurrentSnapshotNotice.svelte 의 <style>(39~45행).
   ⛔ compact 분기만 쓴다 — .snapshot-notice(비compact)는 이 화면이 그리지 않아 옮기지 않았다. */
.snapshot-notice-compact[b-clwmxnvh6p] {
    display: inline-flex;
    align-items: center;
    font-size: 12px;
    color: var(--vz-secondary-color);
    cursor: help;
}


/* ══ 정본 스타일 이식 (2026-08-31 스타일 감사) ══════════════════════
   마크업은 쓰는데 «어느 CSS 에도 정의가 없던» 클래스들이다 - 화면이 조용히 무스타일이었다.
   출처: JK.AI.Front/src/lib/components/sales/SalesOrderScheduleCalendar.svelte
   ⛔ 정본에 «없는» 클래스는 이식하지 않았다 - 정본과 동일하게 맞추는 것이 지시다.
   ⛔ 자식 컴포넌트가 그리는 노드는 스코프가 달라 ::deep 이 필요하다(정본의 :global 과 같은 축). */

/* 툴바 */
	.sc-bar[b-clwmxnvh6p] {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;
}

.sc-cell[b-clwmxnvh6p] {
    background: var(--vz-card-bg, #fff); min-height: 5.25rem; padding: 0.2rem 0.25rem;
    display: flex; flex-direction: column; gap: 0.1rem; overflow: hidden;
}

.sc-cell.outside[b-clwmxnvh6p] {
    background: var(--vz-secondary-bg);
}

.sc-cell.outside .sc-date[b-clwmxnvh6p] {
    opacity: 0.45;
}

.sc-cell.today[b-clwmxnvh6p] {
    box-shadow: inset 0 0 0 2px var(--vz-primary);
}

.sc-cell.picked[b-clwmxnvh6p] {
    box-shadow: inset 0 0 0 2px var(--vz-info);
}

.sc-head.sun[b-clwmxnvh6p], .sc-date.sun[b-clwmxnvh6p] {
    color: var(--vz-danger);
}

.sc-head.sat[b-clwmxnvh6p], .sc-date.sat[b-clwmxnvh6p] {
    color: var(--vz-primary);
}

.sc-date[b-clwmxnvh6p] {
    font-size: 11px; color: var(--vz-secondary-color); line-height: 1.2;
}

/* 날짜 클릭 시 상세 */
	.sc-day[b-clwmxnvh6p], .sc-undated[b-clwmxnvh6p] {
    margin-top: 0.5rem; border: 1px solid var(--vz-border-color); border-radius: 0.5rem;
    background: var(--vz-secondary-bg); padding: 0.5rem 0.625rem;
}

.sc-day-item[b-clwmxnvh6p] {
    width: 100%; display: flex; align-items: center; gap: 0.4rem; text-align: left;
    border: 0; background: none; padding: 0.25rem 0.15rem; border-radius: 0.25rem;
}

.sc-day-item:hover[b-clwmxnvh6p] {
    background: var(--vz-tertiary-bg);
}

.sc-day-list[b-clwmxnvh6p] {
    list-style: none; margin: 0; padding: 0;
}

.sc-day-meta[b-clwmxnvh6p] {
    margin-left: auto; display: inline-flex; align-items: center; gap: 0.35rem; font-size: 11px; color: var(--vz-secondary-color); white-space: nowrap;
}

.sc-day-meta .badge[b-clwmxnvh6p] {
    font-weight: 500;
}

.sc-day-prj[b-clwmxnvh6p] {
    font-size: 11px; color: var(--vz-primary);
}

.sc-day-title[b-clwmxnvh6p] {
    font-size: 12px; color: var(--vz-body-color); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* 달력 격자 */
	.sc-grid[b-clwmxnvh6p] {
    display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
    border: 1px solid var(--vz-border-color); border-radius: 0.5rem; overflow: hidden;
    background: var(--vz-border-color); gap: 1px;
}

.sc-head[b-clwmxnvh6p] {
    background: var(--vz-secondary-bg); text-align: center; padding: 0.25rem 0;
    font-size: 11px; color: var(--vz-secondary-color);
}

.sc-item[b-clwmxnvh6p] {
    border: 0; border-left: 3px solid var(--vz-border-color); border-radius: 0.2rem;
    padding: 0.05rem 0.25rem; font-size: 11px; line-height: 1.3;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
    color: var(--vz-body-color); text-align: left; display: block; width: 100%;
}

.sc-item:hover[b-clwmxnvh6p] {
    filter: brightness(0.95);
}

/* 기간 작업의 중간 날짜는 제목을 비운다 — 막대만 남아 기간으로 읽힌다.
	   ⛔ display:none 이 아니라 visibility:hidden — 글자 높이를 유지해야 칸마다 막대 높이가 어긋나지 않는다. */
	.sc-item:not(.labeled) .sc-item-txt[b-clwmxnvh6p] {
    visibility: hidden;
}

/* ⛔ text-overflow 도 함께 꺼야 한다 — 말줄임표는 **부모가** 그리므로 span 을 숨겨도 「…」만 남는다
	   (2026-08-22 실측: 이어지는 칸이 전부 「…」로 보였다). */
	.sc-item:not(.labeled)[b-clwmxnvh6p] {
    text-overflow: clip;
}

/* 이어지는 칸은 좌우 라운드를 죽여 한 줄로 보이게 */
	.sc-item:not(.start)[b-clwmxnvh6p] {
    border-left-width: 0; border-top-left-radius: 0; border-bottom-left-radius: 0;
}

.sc-item:not(.end)[b-clwmxnvh6p] {
    border-top-right-radius: 0; border-bottom-right-radius: 0;
}

.sc-more[b-clwmxnvh6p] {
    font-size: 11px; color: var(--vz-secondary-color); padding-left: 0.15rem;
}
/* /Components/Pages/Organization/OrgAdmin.razor.rz.scp.css */
/* 원본 +page.svelte 의 <style> 블록(831~845행) 그대로. ⛔ 색·크기를 새로 고르지 않았다. */
.org-ctx-menu[b-v9zaxirncx] {
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    min-width: 180px;
    padding: 4px 0;
}

.org-ctx-item[b-v9zaxirncx] {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 6px 14px;
    border: none;
    background: none;
    font-size: 13px;
    color: var(--vz-body-color);
    cursor: pointer;
    text-align: left;
}

.org-ctx-item:hover[b-v9zaxirncx] { background: var(--vz-tertiary-bg); color: var(--vz-primary); }
.org-ctx-danger:hover[b-v9zaxirncx] { background: #fff0f0; color: var(--vz-danger); }

.role-item[b-v9zaxirncx] { cursor: pointer; border: 1px solid transparent; transition: all 0.15s; }
.role-item:hover[b-v9zaxirncx] { background: var(--vz-tertiary-bg); border-color: var(--vz-border-color); }
.role-active[b-v9zaxirncx] { background: #f0f4ff; border-color: #c8d8ff; }
.role-active:hover[b-v9zaxirncx] { background: #e4ecff; }
/* /Components/Pages/Organization/OrgTree.razor.rz.scp.css */
/* 원본 OrgTree.svelte 의 <style> 블록(78~99행) 그대로. ⛔ 값을 새로 고르지 않았다. */
.org-node[b-uzfws9e29s] { user-select: none; }

.org-item[b-uzfws9e29s] {
    display: flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    color: var(--vz-body-color);
    transition: all 0.12s;
}

.org-item:hover[b-uzfws9e29s] { background: rgba(64, 81, 137, 0.06); }
.org-item.active[b-uzfws9e29s] { background: var(--vz-primary); color: var(--vz-white); }

.org-name[b-uzfws9e29s] { flex: 1; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.org-count[b-uzfws9e29s] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    border-radius: 9px;
    font-size: 13px;
    font-weight: 600;
    padding: 0 4px;
    background: rgba(64, 81, 137, 0.12);
    color: var(--vz-primary);
}

.org-item.active .org-count[b-uzfws9e29s] { background: rgba(255, 255, 255, 0.25); color: var(--vz-white); }

.org-rename-input[b-uzfws9e29s] {
    flex: 1;
    border: 1px solid var(--vz-primary);
    border-radius: 3px;
    padding: 1px 6px;
    font-size: 13px;
    font-weight: 500;
    outline: none;
    background: var(--vz-secondary-bg);
    color: var(--vz-body-color);
}
/* /Components/Pages/PartDetail/JkPartHistoryTimeline.razor.rz.scp.css */
/*
    「변경 이력 · 타임라인」 스타일 — 정본 HistoryTimeline.svelte 의 <style> 블록 그대로.

    ⛔⛔ 왜 클래스 이름을 ph-timeline-* 로 바꿨나 (지우지 마라 — 다음 사람이 되돌린다):
       jk-shell.css 에 정본과 «같은 이름»의 규칙이 두 벌 있다.
         ① 153~162행 — 이 타임라인에서 추출된 것(.timeline-container / .timeline-item / .timeline-dot …)
         ② 263~266행 — «다른 화면»의 타임라인(.timeline 안쪽용)
       ②가 뒤에 있어서 .timeline-item 의 padding 과 .timeline-dot 의 크기·위치를 덮는다.
       정본 이름을 그대로 쓰면 점이 1rem 으로 줄고 들여쓰기가 사라진다 — «에러 없이 모양만» 틀린다.
       그래서 이름을 갈라 두고, 스타일은 이 스코프 CSS 가 갖는다.

    ⛔ 스코프 CSS 는 JS·MarkupString 이 만든 자식에는 안 붙는다. 이 컴포넌트는 전부
       Razor 가 그리므로 해당 없다 — 여기에 JS 로 노드를 만들지 마라.
*/

.ph-timeline[b-oh81s0jvie] {
    position: relative;
    padding-left: 30px;
    width: 100%;
    box-sizing: border-box;
}

.ph-timeline[b-oh81s0jvie]::before {
    content: '';
    position: absolute;
    left: 12px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--vz-tertiary-bg);
}

.ph-timeline-item[b-oh81s0jvie] {
    position: relative;
    padding: 8px 8px 16px 24px;
    transition: background 0.15s;
    border-radius: 6px;
    margin-left: -8px;
    /* 부모 폭 전체 사용 — block default 가 어떤 ancestor 영향으로 잘릴 때 안전망(정본 주석). */
    width: auto;
    box-sizing: border-box;
    display: block;
}

.ph-timeline-item.clickable[b-oh81s0jvie] { cursor: pointer; }
.ph-timeline-item.clickable:hover[b-oh81s0jvie] { background: rgba(64, 81, 137, 0.04); }

.ph-timeline-dot[b-oh81s0jvie] {
    position: absolute;
    left: -22px;
    top: 10px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}

.ph-timeline-content[b-oh81s0jvie] {
    min-width: 0;
    width: 100%;
    display: block;
}

/* 좁은 폭(사이드패널 ~360px)에서도 라벨/시간/사용자가 줄바꿈되도록. flex-wrap + min-width:0. */
.ph-timeline-meta[b-oh81s0jvie] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    min-width: 0;
}

.ph-timeline-meta > span[b-oh81s0jvie] { min-width: 0; }

.ph-timeline-item.milestone[b-oh81s0jvie] { background: rgba(255, 193, 7, 0.04); }
.ph-timeline-dot.milestone-dot[b-oh81s0jvie] { box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.4); }
/* /Components/Pages/PartDetail/PartDetailPage.razor.rz.scp.css */


/* ══ 확정 결재 «결재선» — 2026-09-01 지시(다단계) ═══════════════════════════
   ⛔ 순서가 곧 의미다. 한 줄에 한 단계씩 «세로»로 쌓는다 — 칩을 옆으로 늘어놓으면
      줄바꿈에서 순서가 눈에 안 들어온다. */
.appr-steps[b-izgvc1hz24] {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.appr-step[b-izgvc1hz24] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    font-size: 13px;
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    background: var(--vz-card-bg, #fff);
}

.appr-step-n[b-izgvc1hz24] {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--vz-primary);
    color: var(--vz-white);
    font-size: 12px;
    font-weight: 600;
}

.appr-step-name[b-izgvc1hz24] {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Pages/Partners/PartnerCompanies.razor.rz.scp.css */
/* 원본 companies/+page.svelte 의 <style> 블록 그대로 (457~484행).
   ⛔ 디자인을 새로 만들지 않는다 — 옮기는 것이다. */

.modal-backdrop-custom[b-tv48hm8nu1] {
    position: fixed; inset: 0; background: rgba(0,0,0,0.45);
    display: flex; align-items: center; justify-content: center; z-index: 1055;
}

.modal-card[b-tv48hm8nu1] {
    background: var(--vz-secondary-bg); border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    min-width: 600px; max-width: 720px; width: 100%; margin: 1rem;
    display: flex; flex-direction: column; max-height: 92vh;
}

.modal-header-custom[b-tv48hm8nu1] {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 20px;
    border-bottom: 1px solid var(--vz-border-color);
}

.modal-body-custom[b-tv48hm8nu1] { padding: 20px; overflow-y: auto; flex: 1; }

.modal-footer-custom[b-tv48hm8nu1] {
    padding: 12px 20px;
    border-top: 1px solid var(--vz-border-color);
    text-align: right; display: flex; gap: 8px; justify-content: flex-end;
}

.card-animate[b-tv48hm8nu1] { transition: all 0.4s ease; }
.card-animate:hover[b-tv48hm8nu1] { transform: translateY(-2px); box-shadow: 0 5px 10px rgba(30,32,37,0.12); }

.autocomplete-dropdown[b-tv48hm8nu1] {
    position: absolute; top: 100%; left: 12px; right: 12px;
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    max-height: 280px; overflow-y: auto;
    z-index: 1080; margin-top: 2px;
}

.autocomplete-item[b-tv48hm8nu1] {
    display: block; width: 100%; text-align: left;
    padding: 6px 10px;
    background: transparent; border: none;
    font-size: 13px; cursor: pointer;
}

.autocomplete-item.highlighted[b-tv48hm8nu1], .autocomplete-item:hover[b-tv48hm8nu1] {
    background: var(--vz-tertiary-bg);
}
/* /Components/Pages/Partners/PartnerUsers.razor.rz.scp.css */
/* 원본 users/+page.svelte 의 <style> 블록 그대로 (556~587행).
   ⛔ 디자인을 새로 만들지 않는다 — 옮기는 것이다. */

.modal-backdrop-custom[b-c2mx1a325d] {
    position: fixed; inset: 0; background: rgba(0,0,0,0.45);
    display: flex; align-items: center; justify-content: center; z-index: 1055;
}

.modal-card[b-c2mx1a325d] {
    background: var(--vz-secondary-bg); border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    min-width: 600px; max-width: 720px; width: 100%; margin: 1rem;
    display: flex; flex-direction: column; max-height: 92vh;
}

.modal-header-custom[b-c2mx1a325d] {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 20px;
    border-bottom: 1px solid var(--vz-border-color);
}

.modal-body-custom[b-c2mx1a325d] { padding: 20px; overflow-y: auto; flex: 1; }

.modal-footer-custom[b-c2mx1a325d] {
    padding: 12px 20px;
    border-top: 1px solid var(--vz-border-color);
    text-align: right; display: flex; gap: 8px; justify-content: flex-end;
}

/* 임시 비밀번호 모달 — 확인 버튼으로만 닫힌다(배경 클릭으로 닫으면 비번을 못 보고 지나친다) */
.temp-pw-card[b-c2mx1a325d] { min-width: 420px; max-width: 520px; }

.card-animate[b-c2mx1a325d] { transition: all 0.4s ease; }
.card-animate:hover[b-c2mx1a325d] { transform: translateY(-2px); box-shadow: 0 5px 10px rgba(30,32,37,0.12); }

.avatar-xs .avatar-title[b-c2mx1a325d] { font-weight: 600; font-size: 12px; }
/* /Components/Pages/Pms/ProjectCalendar.razor.rz.scp.css */
/* PMS 프로젝트 캘린더 — scoped.
   ⛔ 값은 간트(ProjectGantt.razor.css)와 프로젝트 상세 패널(ProjectDetailPage.razor.css)에서 쓰던
      그 축(sticky 라벨 열 · 절대위치 막대 · Velzon 토큰)이다. 새 색·새 반경을 고르지 않는다(요구사항 §9). */

/* ── 필터 ──────────────────────────────────────────────────────────────── */
.pms-select[b-v4p3shxlmi] { width: auto; min-width: 9rem; }
.pms-select-year[b-v4p3shxlmi] { min-width: 7rem; }
.pms-search[b-v4p3shxlmi] { width: 15rem; }
/* 기간 직접 입력 — 날짜 두 칸이 셀렉트만큼 넓어지면 필터 줄이 두 줄로 접힌다. */
.pms-date[b-v4p3shxlmi] { width: 8.5rem; }
.pms-daterange input:disabled[b-v4p3shxlmi] { background: var(--vz-tertiary-bg); }

.pms-legend-group[b-v4p3shxlmi] { font-weight: 500; color: var(--vz-body-color); }
.pms-legend-sep[b-v4p3shxlmi] { width: 1px; height: 14px; background: var(--vz-border-color); }
/* 예정 기간(계획선) 범례 — 막대와 «같은 모양»(점선 테두리). */
.pms-legend-planned[b-v4p3shxlmi] { display: inline-block; width: 18px; height: 9px; border: 1px dashed var(--vz-secondary-color); border-radius: 2px; }

/* ── 범례 ──────────────────────────────────────────────────────────────── */
.pms-legend[b-v4p3shxlmi] {
    display: flex; align-items: center; flex-wrap: wrap; gap: 14px;
    padding: 8px 14px;
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 12px; color: var(--vz-secondary-color);
}
.pms-legend-item[b-v4p3shxlmi] { display: inline-flex; align-items: center; gap: 5px; }
.pms-dot[b-v4p3shxlmi] { display: inline-block; width: 9px; height: 9px; border-radius: 50%; }
.pms-legend-gate[b-v4p3shxlmi] { color: var(--vz-primary); font-size: 11px; }
.pms-legend-ms[b-v4p3shxlmi] { color: var(--vz-secondary-color); font-size: 11px; }
.pms-legend-today[b-v4p3shxlmi] { display: inline-block; width: 2px; height: 12px; background: var(--vz-primary); }

/* ── 타임라인 표 ───────────────────────────────────────────────────────── */
/* §9 — 프로젝트가 많아지면 가로·세로 «둘 다» 스크롤. 헤더 행은 위에, 라벨 열은 왼쪽에 붙는다. */
.pms-scroll[b-v4p3shxlmi] { overflow: auto; max-height: calc(100vh - 330px); min-height: 240px; }
.pms-header[b-v4p3shxlmi] { position: sticky; top: 0; z-index: 6; }
.pms-header .pms-label[b-v4p3shxlmi] { z-index: 7; }
.pms-table[b-v4p3shxlmi] { width: max-content; min-width: 100%; position: relative; }

/* 격자·오늘선 «한 겹» — 행마다 찍지 않는다(2026-09-02 「버벅임」 수정).
   행마다 두면 요소 수가 행수 × 눈금수로 곱해진다(200행 × 40눈금 = 8,000개).
   ⛔ z-index 를 주지 마라 — 새 쌓임 맥락이 생기면 오늘선(z 2)이 막대(z 1) 아래로 내려간다.
   left 는 .pms-label 폭과 «같은 값»이어야 한다(둘이 어긋나면 격자가 통째로 밀린다). */
.pms-gridlines[b-v4p3shxlmi] {
    position: absolute;
    top: 0; bottom: 0; left: 240px; right: 0;
    pointer-events: none;
}

.pms-row[b-v4p3shxlmi] {
    display: flex;
    border-bottom: 1px solid var(--vz-border-color);
    min-height: 64px;
}
.pms-header[b-v4p3shxlmi] { min-height: 34px; background: var(--vz-tertiary-bg); font-weight: 500; }

/* 라벨 열 — 가로 스크롤 시 고정(간트와 같은 규칙). */
.pms-label[b-v4p3shxlmi] {
    width: 240px; min-width: 240px;
    padding: 8px 12px;
    border-right: 1px solid var(--vz-border-color);
    position: sticky; left: 0; z-index: 4;
    background: var(--vz-secondary-bg);
}
.pms-header .pms-label[b-v4p3shxlmi] { background: var(--vz-tertiary-bg); display: flex; align-items: center; }
.pms-no[b-v4p3shxlmi] { font-size: 12px; line-height: 1.2; }
.pms-name[b-v4p3shxlmi] { font-size: 13px; font-weight: 500; margin: 2px 0; }
.pms-meta[b-v4p3shxlmi] { display: flex; align-items: center; gap: 8px; font-size: 12px; white-space: nowrap; }
.pms-meta .badge[b-v4p3shxlmi] { font-weight: 500; }
.pms-meta-sep[b-v4p3shxlmi] { color: var(--vz-secondary-color); }
.pms-no .badge[b-v4p3shxlmi] { font-size: 10px; vertical-align: middle; }
/* §4 행 펼치기 — 라벨 오른쪽 끝의 작은 화살표. 행 클릭(드로어)과 «분리»된 버튼이다(stopPropagation). */
.pms-expand[b-v4p3shxlmi] {
    border: 0; background: transparent; padding: 0 2px; line-height: 1;
    color: var(--vz-secondary-color); cursor: pointer; font-size: 14px;
}
.pms-expand:hover[b-v4p3shxlmi], .pms-expand.on[b-v4p3shxlmi] { color: var(--vz-primary); }

/* 트랙 — 절대위치 자식들의 기준. ⛔ overflow:hidden 을 주지 마라 — 마일스톤 라벨이 오른쪽 끝에서 잘린다.
   대신 스크롤 컨테이너(.pms-scroll)가 넘침을 맡는다. */
.pms-track[b-v4p3shxlmi] {
    flex: 1 0 auto; min-width: 720px;
    position: relative;
}
.pms-header .pms-track[b-v4p3shxlmi] { overflow: hidden; }

/* 프로젝트 행 — 클릭 대상임을 «누르기 전에» 알린다. */
.pms-project[b-v4p3shxlmi] { cursor: pointer; transition: background-color .12s ease; }
.pms-project:hover[b-v4p3shxlmi] { background: var(--vz-light-bg-subtle); }
.pms-project:hover .pms-label[b-v4p3shxlmi] { background: var(--vz-light-bg-subtle); }
.pms-project.selected[b-v4p3shxlmi] { background: var(--vz-primary-bg-subtle); }
.pms-project.selected .pms-label[b-v4p3shxlmi] { background: var(--vz-primary-bg-subtle); box-shadow: inset 3px 0 0 var(--vz-primary); }
.pms-project:focus-visible[b-v4p3shxlmi] { outline: 2px solid var(--vz-primary); outline-offset: -2px; }

/* 눈금 */
.pms-tick[b-v4p3shxlmi] {
    position: absolute; top: 9px;
    font-size: 12px; font-weight: 400; color: var(--vz-secondary-color);
    transform: translateX(-50%); white-space: nowrap;
}
.pms-tick.major[b-v4p3shxlmi] { color: var(--vz-body-color); font-weight: 500; }
/* 첫 눈금은 가운데 정렬하면 왼쪽으로 반이 잘린다(실측: 「2025.10」이 「5.10」으로 보였다) — 간트의 .month-marker.first 규칙. */
.pms-tick.first[b-v4p3shxlmi] { transform: none; }
.pms-grid[b-v4p3shxlmi] { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--vz-border-color); opacity: .55; }
.pms-grid.major[b-v4p3shxlmi] { opacity: 1; }

/* 오늘 기준선 — 간트와 같은 primary 2px. */
.pms-today[b-v4p3shxlmi] { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--vz-primary); z-index: 2; transform: translateX(-1px); }
.pms-today-tag[b-v4p3shxlmi] {
    position: absolute; top: 6px;
    transform: translateX(-50%);
    padding: 1px 6px; border-radius: 9px;
    background: var(--vz-primary); color: #fff;
    font-size: 11px; font-weight: 500; line-height: 16px;
    z-index: 3;
}

/* 막대 — 옅은 «계획» 바탕 위에 진행률만큼 «채움». 색은 상태 토큰 4종뿐. */
.pms-bar[b-v4p3shxlmi] {
    position: absolute; top: 12px; height: 20px;
    border-radius: .25rem;
    overflow: hidden;
    z-index: 1;
}
.pms-bar-fill[b-v4p3shxlmi] { position: absolute; top: 0; bottom: 0; left: 0; }
/* §2 예정 기간 — 실제 막대 «뒤»에 점선 상자로 깐다(간트 .gantt-bar-planned 와 같은 모양). */
.pms-bar-planned[b-v4p3shxlmi] {
    position: absolute; top: 10px; height: 24px;
    border: 1px dashed var(--vz-secondary-color);
    border-radius: .25rem;
    background: rgba(64, 81, 137, .06);
    z-index: 0;
}
/* 진행률 글자 — 바탕 위 한 겹(본문색) + 채움 폭만큼 잘라낸 한 겹(채움 대비색).
   둘은 «같은 자리»에 겹쳐 있고, 위 겹만 .pms-bar-clip 이 채움 폭으로 자른다. */
.pms-bar-text[b-v4p3shxlmi] {
    position: absolute; top: 0; left: 0; z-index: 1;
    padding: 0 8px;
    font-size: 12px; font-weight: 500; line-height: 20px; white-space: nowrap;
    color: var(--vz-body-color);
}
.pms-bar-clip[b-v4p3shxlmi] {
    position: absolute; top: 0; left: 0; bottom: 0;
    overflow: hidden; z-index: 2;
    pointer-events: none;
}
.pms-bar-primary[b-v4p3shxlmi]   { background: var(--vz-primary-bg-subtle); }
.pms-bar-primary   .pms-bar-fill[b-v4p3shxlmi] { background: var(--vz-primary); }
.pms-bar-success[b-v4p3shxlmi]   { background: var(--vz-success-bg-subtle); }
.pms-bar-success   .pms-bar-fill[b-v4p3shxlmi] { background: var(--vz-success); }
.pms-bar-danger[b-v4p3shxlmi]    { background: var(--vz-danger-bg-subtle); }
.pms-bar-danger    .pms-bar-fill[b-v4p3shxlmi] { background: var(--vz-danger); }
.pms-bar-secondary[b-v4p3shxlmi] { background: var(--vz-tertiary-bg); border: 1px dashed var(--vz-border-color); }
.pms-bar-secondary .pms-bar-fill[b-v4p3shxlmi] { background: var(--vz-secondary-color); }
/* 채움 위 글자색 — «흰색». 사용자가 「검은색이라 안 보인다」고 한 그 칸이다.
   ⛔⛔ 값은 «브라우저에서 실측한» 토큰이다(2026-09-02, getComputedStyle). Velzon 기본값(#405189·#0ab39c·
      #f06548·#878a99)을 보고 고르면 틀린다 — 이 앱은 JK 디자인 토큰으로 «전부 덮어썼고» 네 채움이 다 어둡다:
        primary   #1a6fc4 : 흰 5.10 : 1 / 본문색 2.68 : 1
        success   #256e39 : 흰 6.23 : 1 / 본문색 2.20 : 1
        danger    #b3243a : 흰 6.50 : 1 / 본문색 2.11 : 1
        secondary #646a72 : 흰 5.46 : 1 / 본문색 2.51 : 1
      넷 다 흰색이 이긴다(본문색 #1f2f3e 은 전부 3:1 미만). 「색마다 다르게」 고를 이유가 없다.
   ⛔ mix-blend-mode 로 때우지 않는다 — 예전 규칙은 normal 로 눌러져 있어 «아무 일도» 하지 않았다.
   ⛔ 바탕(subtle) 위 겹은 본문색 그대로다 — 진행률 0% 라도 글자가 읽혀야 한다. */
.pms-bar-clip .pms-bar-text[b-v4p3shxlmi] { color: #fff; }

/* Gate / Milestone — 막대 «아래» 줄. Gate 는 primary, Milestone 은 secondary, 지연은 danger, 완료는 success. */
.pms-ms[b-v4p3shxlmi] {
    position: absolute; top: 36px;
    transform: translateX(-50%);
    display: inline-flex; align-items: center; gap: 3px;
    font-size: 11px; line-height: 1; white-space: nowrap;
    color: var(--vz-secondary-color);
    z-index: 2;
}
.pms-ms-mark[b-v4p3shxlmi] { font-size: 11px; }
/* 앞 라벨과 «실제로 겹칠 때만» 한 줄 아래로 내린다 — 줄 배치는 PmsCalendarService.LaneAssign 이 정한다.
   ⛔ 예전엔 「홀수 번째」를 무조건 내렸다 — 겹치지 않아도 두 줄이 됐다(2026-09-02 지시로 수정). */
.pms-ms.alt[b-v4p3shxlmi] { top: 49px; }
/* 색은 마크업의 text-{색} 유틸이 정한다(Gate 상태 4종 = 프로젝트와 같은 토큰, 다른 축). 여기는 «굵기»만. */
.pms-ms.gate[b-v4p3shxlmi] { font-weight: 500; }
.pms-ms.overdue[b-v4p3shxlmi] { font-weight: 600; }
.pms-ms.overdue .pms-ms-mark[b-v4p3shxlmi] { font-size: 12px; }
.pms-ms-label[b-v4p3shxlmi] { max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.pms-ms-date[b-v4p3shxlmi] { margin-left: 4px; font-weight: 400; opacity: .8; }

/* ── 드로어 (부트스트랩 offcanvas 를 «켠 채»로 그린다 — JS 없이) ───────── */
/* ⛔ 겹침 순서는 app.css 하단 표를 따른다 — 모달 층 2000. 부트스트랩 기본(1045)은 셸 아래로 간다. */
.pms-drawer[b-v4p3shxlmi] {
    visibility: visible;
    z-index: 2000;
    width: 380px;
    border-left: 1px solid var(--vz-border-color);
}
.pms-drawer-backdrop[b-v4p3shxlmi] { z-index: 1990; }
.pms-drawer .offcanvas-header[b-v4p3shxlmi] { border-bottom: 1px solid var(--vz-border-color); }

.pms-dl[b-v4p3shxlmi] { margin: 0; }
.pms-dl dt[b-v4p3shxlmi] { font-size: 12px; font-weight: 500; color: var(--vz-secondary-color); margin-top: 12px; }
.pms-dl dd[b-v4p3shxlmi] { margin: 3px 0 0; font-size: 13px; }
.pms-dl dd .pms-dot[b-v4p3shxlmi] { margin-right: 6px; vertical-align: middle; }
.pms-ms-list li[b-v4p3shxlmi] { padding: 3px 0; font-size: 13px; }


/* 표시 상한 안내 행 — 잘린 건수를 «화면에서» 밝힌다(조용히 자르면 데이터가 없는 줄 안다). */
.pms-more[b-v4p3shxlmi] { min-height: 40px; background: var(--vz-tertiary-bg); }
.pms-more .pms-label[b-v4p3shxlmi] { background: var(--vz-tertiary-bg); display: flex; align-items: center; }
.pms-more-track[b-v4p3shxlmi] { display: flex; align-items: center; padding: 0 12px; font-size: 12px; color: var(--vz-secondary-color); }

/* ── §4 펼친 행 — 단계별 진행상황 (기획 → 설계 → 검증 → 시험양산 → 양산) ─── */
.pms-phase-row[b-v4p3shxlmi] { min-height: 40px; background: var(--vz-tertiary-bg); }
.pms-phase-row .pms-label[b-v4p3shxlmi] { background: var(--vz-tertiary-bg); display: flex; align-items: center; }
.pms-phase-track[b-v4p3shxlmi] { display: flex; align-items: center; padding: 0 12px; }
.pms-phases[b-v4p3shxlmi] { display: flex; align-items: center; gap: 4px; font-size: 12px; }
.pms-phase[b-v4p3shxlmi] { display: inline-flex; align-items: center; gap: 4px; color: var(--vz-secondary-color); }
.pms-phase.done[b-v4p3shxlmi] { color: var(--vz-success); }
.pms-phase.active[b-v4p3shxlmi] { color: var(--vz-primary); font-weight: 500; }
.pms-phase-mark[b-v4p3shxlmi] { font-size: 14px; line-height: 1; }
.pms-phase-arrow[b-v4p3shxlmi] { color: var(--vz-border-color); margin-left: 4px; font-size: 14px; line-height: 1; }

/* ── §6 다음 Gate 강조 — 드로어 ───────────────────────────────────────── */
.pms-next-gate[b-v4p3shxlmi] {
    padding: 8px 12px; border-radius: 6px;
    background: var(--vz-primary-bg-subtle); border-left: 3px solid var(--vz-primary);
}
.pms-next-gate.delayed[b-v4p3shxlmi] { background: var(--vz-danger-bg-subtle); border-left-color: var(--vz-danger); }
.pms-next-gate-name[b-v4p3shxlmi] { font-weight: 500; color: var(--vz-primary); }
.pms-next-gate.delayed .pms-next-gate-name[b-v4p3shxlmi] { color: var(--vz-danger); }
.pms-next-gate-date[b-v4p3shxlmi] { font-size: 13px; color: var(--vz-body-color); margin-top: 2px; }
.pms-next-gate-d[b-v4p3shxlmi] { font-size: 13px; font-weight: 500; color: var(--vz-primary); }
.pms-next-gate.delayed .pms-next-gate-d[b-v4p3shxlmi] { color: var(--vz-danger); }
.pms-ms-list .badge[b-v4p3shxlmi] { font-size: 10px; }
/* /Components/Pages/Pms/ProjectDashboard.razor.rz.scp.css */
/*
    프로젝트 대시보드 스코프 CSS.

    ⛔ 색을 새로 고르지 않았다 — 전부 Velzon CSS 변수(--vz-*) 다.
    ⛔ .fs-11/.fs-12 같은 유틸리티를 «재정의하지 않는다». 화면별 CSS 가 전역을 이겨서
       다른 화면까지 글자 크기가 갈리는 사고가 있었다(feedback_velzon_fs_utility_tokens_all_same).
       필요한 크기는 이 화면 전용 class 로만 준다.
    ⛔ 카드 머리는 규약 값이다: 배경 #f5faff · 아래 1px --vz-border-color · 제목은 본문색 500.
*/

/* ── 카드 머리 (전사 규약) ───────────────────────────────────────────────── */
.card-header[b-1glon3xpk2] {
    background-color: #f5faff;
    border-bottom: 1px solid var(--vz-border-color);
    padding: .6rem .9rem;
}

.card-header .card-title[b-1glon3xpk2] {
    font-size: 13px;
    font-weight: 500;
    color: var(--vz-body-color);
}

/* 본문 기준 13px — 이 화면 안에서만. */
.page-content[b-1glon3xpk2] {
    font-size: 13px;
}

.pms-note[b-1glon3xpk2] {
    font-size: 12px;
    line-height: 1.5;
}

.pms-pm-select[b-1glon3xpk2] {
    min-width: 190px;
}

/* 기간 입력 — 날짜 피커 아이콘까지 들어갈 최소 폭. 값이 잘리면 직접 입력이 불가능해진다. */
.pms-date[b-1glon3xpk2] {
    width: 150px;
    font-size: 13px;
}

/* ── KPI 8칸 한 줄 ───────────────────────────────────────────────────────
   bootstrap 12칸은 8 로 나뉘지 않는다 — grid 로 직접 8칸을 만든다.
   좁아지면 4칸 → 2칸으로 접는다(한 줄 규칙은 넓은 화면의 것이다). */
.kpi-strip[b-1glon3xpk2] {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    gap: .75rem;
}

@media (max-width: 1599.98px) {
    .kpi-strip[b-1glon3xpk2] {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (max-width: 767.98px) {
    .kpi-strip[b-1glon3xpk2] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.kpi-tile .card-body[b-1glon3xpk2] {
    padding: .7rem .8rem;
}

.kpi-label[b-1glon3xpk2] {
    font-size: 12px;
    font-weight: 500;
    color: var(--vz-secondary-color);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kpi-value[b-1glon3xpk2] {
    font-size: 24px;
    font-weight: 500;
    line-height: 1.2;
}

.kpi-sub[b-1glon3xpk2] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── 라이프사이클 파이프라인 (순수 CSS 화살표) ───────────────────────────
   ⛔ clip-path 로 깎기 때문에 왼쪽에 «파인 만큼» 겹쳐 놓아야 틈이 안 생긴다(margin-left 음수). */
.stage-flow[b-1glon3xpk2] {
    display: flex;
    align-items: stretch;
    overflow-x: auto;
    padding: 2px 0;
}

.stage-chevron[b-1glon3xpk2] {
    flex: 1 1 0;
    min-width: 92px;
    padding: .5rem .5rem .5rem 1.2rem;
    text-align: center;
    clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%, 14px 50%);
    background-color: var(--vz-light);
    color: var(--vz-secondary-color);
    margin-left: -12px;
}

.stage-chevron:first-child[b-1glon3xpk2] {
    margin-left: 0;
    clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%);
}

.stage-chevron.on[b-1glon3xpk2] {
    background-color: var(--vz-primary);
    color: var(--vz-white);
}

.stage-name[b-1glon3xpk2] {
    font-size: 12px;
    line-height: 1.3;
    white-space: nowrap;
}

.stage-count[b-1glon3xpk2] {
    font-size: 17px;
    font-weight: 500;
    line-height: 1.3;
}

/* ── 12주 게이트·납기 격자 ──────────────────────────────────────────────── */
.week-grid[b-1glon3xpk2] {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 4px;
    align-items: end;
}

@media (max-width: 991.98px) {
    .week-grid[b-1glon3xpk2] {
        grid-template-columns: repeat(6, minmax(0, 1fr));
    }
}

.week-cell[b-1glon3xpk2] {
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    padding: 6px 4px;
    text-align: center;
    background-color: var(--vz-secondary-bg);
}

.week-bars[b-1glon3xpk2] {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 3px;
    height: 42px;
}

.week-bar[b-1glon3xpk2] {
    width: 10px;
    border-radius: 2px 2px 0 0;
}

.week-bar.gate[b-1glon3xpk2] {
    background-color: var(--vz-primary);
}

.week-bar.due[b-1glon3xpk2] {
    background-color: var(--vz-danger);
}

.week-label[b-1glon3xpk2] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    margin-top: 4px;
}

.week-count[b-1glon3xpk2] {
    font-size: 12px;
    font-weight: 500;
}

/* 표 글자도 본문 기준으로 — Velzon 기본이 더 크다. */
.table > :not(caption) > * > *[b-1glon3xpk2] {
    padding: .45rem .6rem;
}
/* /Components/Pages/Pms/ProjectTasks.razor.rz.scp.css */
/* PMS 프로젝트 Task — 목록·보드·간트·캘린더·통합 View (scoped).
   ⛔ 값은 Velzon 토큰과 프로젝트 캘린더(ProjectCalendar.razor.css)의 그 축이다. 새 색·새 반경을 고르지 않는다(§20). */

.tk-meta[b-onqjh5w9kb] { font-size: 13px; display: inline-flex; align-items: center; gap: 6px; }
.tk-select[b-onqjh5w9kb] { width: auto; min-width: 9rem; }
.tk-filter[b-onqjh5w9kb] { background: var(--vz-tertiary-bg); }
.tk-table tbody tr[b-onqjh5w9kb] { cursor: pointer; }

/* ── 보드 ────────────────────────────────────────────────────────────────── */
.tk-board[b-onqjh5w9kb] { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; padding: 12px; }
.tk-board.compact[b-onqjh5w9kb] { gap: 8px; padding: 8px; }
.tk-col[b-onqjh5w9kb] { background: var(--vz-tertiary-bg); border-radius: 6px; padding: 8px; min-height: 120px; }
.tk-col-head[b-onqjh5w9kb] { display: flex; align-items: center; gap: 6px; font-weight: 500; font-size: 13px; margin-bottom: 8px; }
.tk-dot[b-onqjh5w9kb] { display: inline-block; width: 8px; height: 8px; border-radius: 50%; }
.tk-card[b-onqjh5w9kb] {
    background: var(--vz-secondary-bg); border: 1px solid var(--vz-border-color); border-radius: 6px;
    padding: 6px 8px; margin-bottom: 6px; cursor: pointer; font-size: 13px;
}
.tk-card:hover[b-onqjh5w9kb] { border-color: var(--vz-primary); }
.tk-card-name[b-onqjh5w9kb] { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tk-card-meta[b-onqjh5w9kb] { display: flex; align-items: center; gap: 4px; color: var(--vz-secondary-color); font-size: 12px; }
.tk-board.compact .tk-card[b-onqjh5w9kb] { padding: 4px 6px; margin-bottom: 4px; font-size: 12px; }

/* ── 간트 (프로젝트 캘린더와 같은 축) ─────────────────────────────────────── */
.tk-gantt[b-onqjh5w9kb] { overflow-x: auto; }
.tk-g-row[b-onqjh5w9kb] { display: flex; border-bottom: 1px solid var(--vz-border-color); min-height: 38px; }
.tk-g-row[role=button][b-onqjh5w9kb] { cursor: pointer; }
.tk-g-row[role=button]:hover[b-onqjh5w9kb] { background: var(--vz-light-bg-subtle); }
.tk-g-head[b-onqjh5w9kb] { background: var(--vz-tertiary-bg); min-height: 30px; font-weight: 500; }
.tk-g-label[b-onqjh5w9kb] {
    width: 220px; min-width: 220px; padding: 8px 12px; font-size: 13px;
    border-right: 1px solid var(--vz-border-color);
    position: sticky; left: 0; z-index: 2; background: var(--vz-secondary-bg);
}
.tk-g-head .tk-g-label[b-onqjh5w9kb] { background: var(--vz-tertiary-bg); }
.tk-gantt.compact .tk-g-label[b-onqjh5w9kb] { width: 150px; min-width: 150px; padding: 6px 8px; font-size: 12px; }
.tk-g-track[b-onqjh5w9kb] { flex: 1 0 auto; min-width: 480px; position: relative; }
.tk-g-tick[b-onqjh5w9kb] { position: absolute; top: 7px; font-size: 12px; color: var(--vz-secondary-color); transform: translateX(-50%); white-space: nowrap; }
.tk-g-tick.first[b-onqjh5w9kb] { transform: none; }
.tk-g-grid[b-onqjh5w9kb] { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--vz-border-color); opacity: .6; }
.tk-g-today[b-onqjh5w9kb] { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--vz-primary); z-index: 1; }
.tk-g-today-tag[b-onqjh5w9kb] { position: absolute; top: 5px; transform: translateX(-50%); padding: 1px 6px; border-radius: 9px; background: var(--vz-primary); color: #fff; font-size: 11px; line-height: 16px; z-index: 2; }
.tk-g-bar[b-onqjh5w9kb] { position: absolute; top: 9px; height: 20px; border-radius: .25rem; overflow: hidden; z-index: 1; }
.tk-g-fill[b-onqjh5w9kb] { position: absolute; inset: 0 auto 0 0; }
.tk-g-text[b-onqjh5w9kb] { position: relative; z-index: 1; display: block; padding: 0 6px; font-size: 12px; line-height: 20px; color: var(--vz-body-color); }
.tk-g-bar-primary[b-onqjh5w9kb]   { background: var(--vz-primary-bg-subtle); }   .tk-g-bar-primary .tk-g-fill[b-onqjh5w9kb]   { background: var(--vz-primary); }
.tk-g-bar-success[b-onqjh5w9kb]   { background: var(--vz-success-bg-subtle); }   .tk-g-bar-success .tk-g-fill[b-onqjh5w9kb]   { background: var(--vz-success); }
.tk-g-bar-danger[b-onqjh5w9kb]    { background: var(--vz-danger-bg-subtle); }    .tk-g-bar-danger .tk-g-fill[b-onqjh5w9kb]    { background: var(--vz-danger); }
.tk-g-bar-secondary[b-onqjh5w9kb] { background: var(--vz-tertiary-bg); border: 1px dashed var(--vz-border-color); } .tk-g-bar-secondary .tk-g-fill[b-onqjh5w9kb] { background: var(--vz-secondary-color); }

/* ── 캘린더 ──────────────────────────────────────────────────────────────── */
.tk-cal-head[b-onqjh5w9kb] { display: flex; align-items: center; gap: 14px; padding: 10px 14px; border-bottom: 1px solid var(--vz-border-color); }

/* 주간 — 7열 격자. 여러 날짜 Task 는 «한 Bar»(§14): grid-column span. dense 로 빈칸을 채워 줄을 아낀다. */
.tk-week[b-onqjh5w9kb] {
    display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-auto-flow: row dense;
    gap: 4px 0; padding: 0 0 12px; min-height: 200px;
}
.tk-week-day[b-onqjh5w9kb] {
    display: flex; align-items: center; gap: 4px; padding: 8px 10px; font-size: 13px;
    border-bottom: 1px solid var(--vz-border-color); background: var(--vz-tertiary-bg);
}
.tk-week-day.weekend[b-onqjh5w9kb] { color: var(--vz-secondary-color); }
/* §12 오늘 — primary 밑줄 + 배지 하나. 배경을 통째로 칠하지 않는다. */
.tk-week-day.today[b-onqjh5w9kb] { box-shadow: inset 0 -2px 0 var(--vz-primary); color: var(--vz-primary); font-weight: 500; }
.tk-week-dow[b-onqjh5w9kb] { font-weight: 500; }
.tk-week-empty[b-onqjh5w9kb] { grid-column: 1 / 8; text-align: center; padding: 24px 0; }
.tk-bar[b-onqjh5w9kb] {
    margin: 0 4px; padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer;
    display: flex; align-items: center; gap: 6px; min-width: 0; border-left: 3px solid transparent;
}
.tk-bar-name[b-onqjh5w9kb] { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tk-bar-meta[b-onqjh5w9kb] { color: var(--vz-secondary-color); white-space: nowrap; }
.tk-bar-primary[b-onqjh5w9kb]   { background: var(--vz-primary-bg-subtle);   border-left-color: var(--vz-primary); }
.tk-bar-success[b-onqjh5w9kb]   { background: var(--vz-success-bg-subtle);   border-left-color: var(--vz-success); }
.tk-bar-danger[b-onqjh5w9kb]    { background: var(--vz-danger-bg-subtle);    border-left-color: var(--vz-danger); }
.tk-bar-secondary[b-onqjh5w9kb] { background: var(--vz-tertiary-bg);         border-left-color: var(--vz-secondary-color); }
.tk-bar.cont-l[b-onqjh5w9kb] { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: 0; }
.tk-bar.cont-r[b-onqjh5w9kb] { border-top-right-radius: 0; border-bottom-right-radius: 0; margin-right: 0; }
.tk-week.compact[b-onqjh5w9kb] { min-height: 120px; }
.tk-week.compact .tk-week-day[b-onqjh5w9kb] { padding: 5px 6px; font-size: 12px; }
.tk-week.compact .tk-bar[b-onqjh5w9kb] { padding: 2px 6px; font-size: 11px; }

/* 월간 — 6×7. 칸마다 3건 + «+N more»(§15). */
.tk-month[b-onqjh5w9kb] { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--vz-border-color); }
.tk-month-dow[b-onqjh5w9kb] { padding: 6px 8px; font-size: 12px; font-weight: 500; background: var(--vz-tertiary-bg); border-bottom: 1px solid var(--vz-border-color); }
.tk-month-cell[b-onqjh5w9kb] { min-height: 96px; padding: 4px 6px; border-right: 1px solid var(--vz-border-color); border-bottom: 1px solid var(--vz-border-color); font-size: 12px; }
.tk-month-cell.other[b-onqjh5w9kb] { background: var(--vz-light-bg-subtle); color: var(--vz-secondary-color); }
.tk-month-cell.today .tk-month-num[b-onqjh5w9kb] { color: var(--vz-primary); font-weight: 500; }
.tk-month-cell.today[b-onqjh5w9kb] { box-shadow: inset 0 2px 0 var(--vz-primary); }
.tk-month-num[b-onqjh5w9kb] { margin-bottom: 4px; }
.tk-chip[b-onqjh5w9kb] { padding: 1px 6px; margin-bottom: 2px; border-radius: 3px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-left: 2px solid transparent; }
.tk-chip-primary[b-onqjh5w9kb]   { background: var(--vz-primary-bg-subtle); border-left-color: var(--vz-primary); }
.tk-chip-success[b-onqjh5w9kb]   { background: var(--vz-success-bg-subtle); border-left-color: var(--vz-success); }
.tk-chip-danger[b-onqjh5w9kb]    { background: var(--vz-danger-bg-subtle);  border-left-color: var(--vz-danger); }
.tk-chip-secondary[b-onqjh5w9kb] { background: var(--vz-tertiary-bg);       border-left-color: var(--vz-secondary-color); }
.tk-more[b-onqjh5w9kb] { color: var(--vz-secondary-color); font-size: 11px; padding-left: 4px; }

/* ── 통합 View — 2×2 (§5.2) ──────────────────────────────────────────────── */
.tk-ov[b-onqjh5w9kb] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; padding: 12px; }
.tk-ov-card[b-onqjh5w9kb] { display: flex; flex-direction: column; min-height: 260px; }
.tk-ov-body[b-onqjh5w9kb] { flex: 1 1 auto; overflow: auto; max-height: 320px; }
@media (max-width: 991.98px) { .tk-ov[b-onqjh5w9kb] { grid-template-columns: 1fr; } }

/* 전체화면 Overlay (§7) — 모달 층(2000). 셸 위를 «전부» 덮는다. */
.tk-fs[b-onqjh5w9kb] {
    position: fixed; inset: 0; z-index: 2000;
    background: var(--vz-body-bg); display: flex; flex-direction: column; outline: none;
}
.tk-fs-head[b-onqjh5w9kb] { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 20px; border-bottom: 1px solid var(--vz-border-color); background: var(--vz-secondary-bg); }
.tk-fs-filter[b-onqjh5w9kb] { padding: 8px 20px; border-bottom: 1px solid var(--vz-border-color); background: var(--vz-tertiary-bg); }
.tk-fs-body[b-onqjh5w9kb] { flex: 1 1 auto; overflow: auto; }
.tk-fs .tk-ov[b-onqjh5w9kb] { height: 100%; grid-template-rows: repeat(2, minmax(0, 1fr)); }
.tk-fs .tk-ov-card[b-onqjh5w9kb] { min-height: 0; }
.tk-fs .tk-ov-body[b-onqjh5w9kb] { max-height: none; }

/* ── Task Drawer (§16) ───────────────────────────────────────────────────── */
.tk-drawer[b-onqjh5w9kb] { visibility: visible; z-index: 2100; width: 360px; border-left: 1px solid var(--vz-border-color); }
.tk-drawer-backdrop[b-onqjh5w9kb] { z-index: 2090; }
.tk-drawer .offcanvas-header[b-onqjh5w9kb] { border-bottom: 1px solid var(--vz-border-color); }
.tk-dl[b-onqjh5w9kb] { margin: 0; }
.tk-dl dt[b-onqjh5w9kb] { font-size: 12px; font-weight: 500; color: var(--vz-secondary-color); margin-top: 10px; }
.tk-dl dd[b-onqjh5w9kb] { margin: 2px 0 0; font-size: 13px; }
/* /Components/Pages/ProjectDetail/ProjectDetailPage.razor.rz.scp.css */
/*
   프로젝트 상세 — 원본 [id]/+page.svelte <style> 블록(1810~2071행) 중 «이 화면에 남은 것»만 옮겼다.

   ⛔ 값을 새로 고르지 않았다. 색은 전부 Velzon CSS 변수(--vz-*)이고 픽셀도 원본 그대로다.
   ⛔ 옮기지 않은 블록과 이유:
      · .wbs-gantt / .gantt-* / .bar-*      — 간트는 별도 화면(B16)이고 이 화면엔 그 마크업이 없다.
      · .assignee-picker / .assignee-menu   — details/summary 다중 담당자 피커를 옮기지 않았다(select 로 대체).
      · .ctx-overlay / .ctx-menu / .ctx-item — 고정 위치 우클릭 메뉴 대신 «행 안 액션 줄»로 옮겼다.
      · .deliv-card / .dms-deliv-card / .deliv-preview / .deliv-badges
                                            — 원본에도 «구» 표기가 붙은 죽은 스타일이다(카드는 DmsCardGrid 가 그린다).
      · .sf-tabs / .sf-tab                  — 원본은 ProjectSubFolderTabs 컴포넌트 안에 scoped 로 있었다.
                                              그 컴포넌트를 옮기지 않아 여기로 가져왔다(값은 그대로).
*/

/* QA#189: disabled 버튼 커서 — Bootstrap 이 pointer-events:none 을 걸어 cursor 가 안 먹으므로 복원 */
.member-add-btn:disabled[b-3kdp7i6zkc] {
    cursor: not-allowed;
    pointer-events: auto;
}

/* 참여자 추가줄 (2026-09-01 지시) — «필요한 만큼만» 차지한다.
   예전에는 col-md-5/4/3 으로 12칸을 다 썼서 검색칸·셀렉트·버튼이 화면 끝까지 늘어졌다.
   ⛔ 포인트를 새로 고르지 않았다 — 크기는 전부 rem 계산값이고 색은 하나도 안 넣었다. */
.member-add[b-3kdp7i6zkc] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
}

.member-add-pick[b-3kdp7i6zkc] {
    position: relative;
    flex: 0 1 17rem;
    min-width: 12rem;
}

.member-add-role[b-3kdp7i6zkc] {
    flex: 0 0 8.5rem;
}

/* ⛔ 후보 목록은 «띄우는» 것이다. 흐름에 두면 그만큼 버튼이 아래로 밀리고
   목록이 떠드는 순간 표가 통째로 출렁거린다. */
.member-add-list[b-3kdp7i6zkc] {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 5;
    margin-top: 0.125rem;
    max-height: 12.5rem;
    overflow-y: auto;
    box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.12);
}

.member-add-picked[b-3kdp7i6zkc] {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding-bottom: 0.25rem;
}

/* 게이트 체크리스트 — 슬롯 row */
.deliv-checklist .list-group-item:hover[b-3kdp7i6zkc] {
    background-color: rgba(64, 81, 137, 0.04);
}

/* Phase Stepper — 원 + 커넥터 */
.phase-stepper[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.phase-item[b-3kdp7i6zkc] {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    cursor: pointer;
    padding: .75rem;
    border-radius: .5rem;
    transition: all .15s;
    border: 1px solid transparent;
}

.phase-item:hover[b-3kdp7i6zkc] {
    background-color: rgba(64, 81, 137, .05);
}

.phase-item.selected[b-3kdp7i6zkc] {
    background-color: rgba(64, 81, 137, .08);
    border-color: var(--vz-primary);
}

.phase-circle[b-3kdp7i6zkc] {
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: 22px;
    transition: background-color .15s, color .15s;
}

/* 플레이 삼각형 optical centering — 삼각형의 무게중심이 왼쪽이라 살짝 오른쪽으로 미세 이동 */
.phase-circle-active[b-3kdp7i6zkc] >  .ri-play-fill {
    transform: translateX(1.5px);
}

/* Active 미선택 시 미세한 외부 pulse ring — 선택되면 pulse 제거(solid fill 로만 표현) */
.phase-circle-active:not(.phase-circle-selected)[b-3kdp7i6zkc] {
    animation: phase-pulse-b-3kdp7i6zkc 1.8s ease-in-out infinite;
}

@keyframes phase-pulse-b-3kdp7i6zkc {
    0%, 100% { box-shadow: 0 0 0 0 rgba(10, 179, 156, .45); }
    70% { box-shadow: 0 0 0 8px rgba(10, 179, 156, 0); }
}

.phase-info[b-3kdp7i6zkc] {
    min-width: 0;
}

.phase-connector[b-3kdp7i6zkc] {
    width: 2px;
    height: 14px;
    background-color: var(--vz-border-color);
    margin-left: calc(.75rem + 21px);
}

/* 산출물 chip 배치 (작업 표의 산출물 칸) */
.deliv-chips[b-3kdp7i6zkc] {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
}

.deliv-chips .badge[b-3kdp7i6zkc] {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 표 인라인 입력 — 원본 .wbs-inline (그리드 셀 편집기의 «평소엔 투명» 규칙) */
.wbs-inline[b-3kdp7i6zkc] {
    font-size: 13px;
    padding: .2rem .4rem;
    background-color: transparent;
    border-color: transparent;
}

.wbs-inline:hover[b-3kdp7i6zkc], .wbs-inline:focus[b-3kdp7i6zkc] {
    background-color: var(--vz-secondary-bg);
    border-color: #ced4da;
}

/* 상태별 select border 색상 */
.status-select-secondary[b-3kdp7i6zkc] { border-left: 3px solid var(--vz-secondary) !important; }
.status-select-info[b-3kdp7i6zkc]      { border-left: 3px solid var(--vz-info) !important; }
.status-select-warning[b-3kdp7i6zkc]   { border-left: 3px solid var(--vz-warning) !important; }
.status-select-success[b-3kdp7i6zkc]   { border-left: 3px solid var(--vz-success) !important; }
.status-select-danger[b-3kdp7i6zkc]    { border-left: 3px solid var(--vz-danger) !important; }

/* 세로 타임라인 */
.timeline-v[b-3kdp7i6zkc] {
    position: relative;
    padding-left: 1.5rem;
}

.timeline-v[b-3kdp7i6zkc]::before {
    content: '';
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 6px;
    width: 2px;
    background-color: var(--vz-tertiary-bg);
}

.tl-item[b-3kdp7i6zkc] {
    position: relative;
    padding: .5rem 0 .75rem 0;
}

.tl-dot[b-3kdp7i6zkc] {
    position: absolute;
    left: -1.5rem;
    top: .9rem;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background-color: var(--vz-primary);
    border: 2px solid var(--vz-secondary-bg);
    box-shadow: 0 0 0 2px var(--vz-border-color);
}

.tl-content[b-3kdp7i6zkc] {
    padding-left: .25rem;
}

/* 서브폴더 탭 — 원본 ProjectSubFolderTabs.svelte 79~104행 */
.sf-tabs[b-3kdp7i6zkc] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 0;
}

.sf-tab[b-3kdp7i6zkc] {
    border: 1px solid #e5e7eb;
    background: var(--vz-secondary-bg);
    color: #374151;
    padding: 5px 12px;
    border-radius: 6px;
    font-size: 13px;
    cursor: pointer;
}

.sf-tab.active[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
    color: var(--vz-primary);
    background: rgba(64, 81, 137, .08);
}

.sf-count[b-3kdp7i6zkc] {
    margin-left: 6px;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* ══ 작업 보드 (2026-09-01) ══════════════════════════════════════════════════
   Plane 의 «칸반 칸 + 속성 칩 카드» 배치 아이디어를 참조해 이 리포에서 새로 쓴 것이다.
   ⛔⛔ Plane(AGPL-3.0) · OpenProject(GPL-3.0) 의 CSS 는 한 줄도 옮기지 않았다.
   ⛔ 색·크기를 새로 고르지 않았다 — 전부 Velzon 토큰(--vz-*)과 본문 13px 기준이다. */
.kb-board[b-3kdp7i6zkc] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    overflow-x: auto;
    padding-bottom: 0.5rem;
}

.kb-col[b-3kdp7i6zkc] {
    flex: 0 0 15.5rem;
    max-width: 15.5rem;
    max-height: 34rem;
    display: flex;
    flex-direction: column;
    background: var(--vz-tertiary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 0.5rem;
}

/* 드롭 대상 강조 — 어느 칸에 놓이는지 «놓기 전에» 보여야 한다. */
.kb-col.kb-over[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
    box-shadow: 0 0 0 2px rgba(var(--vz-primary-rgb), 0.18);
}

.kb-head[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 0.625rem;
    border-bottom: 1px solid var(--vz-border-color);
}

.kb-dot[b-3kdp7i6zkc] {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    flex: 0 0 auto;
}

.kb-title[b-3kdp7i6zkc] {
    font-size: 12px;
    font-weight: 500;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.kb-n[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    background: var(--vz-body-bg);
    border-radius: 0.75rem;
    padding: 0 0.375rem;
}

.kb-add[b-3kdp7i6zkc] {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    line-height: 1;
    padding: 0.125rem 0.25rem;
    border-radius: 0.25rem;
}

.kb-add:hover:not(:disabled)[b-3kdp7i6zkc] {
    background: var(--vz-body-bg);
    color: var(--vz-primary);
}

.kb-body[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding: 0.5rem;
    min-height: 4rem;
    overflow-y: auto;
}

/* ⛔ 카드는 «흰 종이»다(2026-09-01 지시). --vz-body-bg 는 셸 바닥색(연회색)이라
   칸 배경(--vz-tertiary-bg)과 붙어 카드 경계가 흐려졌다. 카드 토큰을 쓴다 — 다크 테마도 이 토큰이 진다. */
.kb-card[b-3kdp7i6zkc] {
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 0.375rem;
    padding: 0.5rem;
    cursor: pointer;
}

.kb-card:hover[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
}

/* ⛔ 끌고 있는 카드의 표시는 «class» 로 준다. style 로 주면 회로가 다시 그릴 때 지워진다. */
.kb-card.kb-dragging[b-3kdp7i6zkc] {
    opacity: 0.45;
}

.kb-card-top[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-bottom: 0.25rem;
}

.kb-id[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
}

.kb-card-title[b-3kdp7i6zkc] {
    font-size: 12px;
    line-height: 1.35;
    word-break: break-all;
}

.kb-card-foot[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.375rem;
}

.kb-chip[b-3kdp7i6zkc] {
    font-size: 11px;
    font-weight: 400;
    display: inline-flex;
    align-items: center;
    gap: 0.1875rem;
}

/* ⛔ 이니셜은 한글 2자다 — 22px 원 안에 들어가려면 10px 가 한계다.
   11px 로 올렸더니 글자가 원 밖으로 번졌다(2026-09-01 스크린샷 확인). */
.kb-ava[b-3kdp7i6zkc] {
    width: 1.375rem;
    height: 1.375rem;
    border-radius: 50%;
    background: var(--vz-primary);
    color: #fff;
    font-size: 10px;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.kb-empty[b-3kdp7i6zkc] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    text-align: center;
    padding: 1rem 0.5rem;
    border: 1px dashed var(--vz-border-color);
    border-radius: 0.375rem;
}

.kb-quick[b-3kdp7i6zkc] {
    margin-bottom: 0.25rem;
}

/* ══ 작업 패키지 목록 + 상세 패널 (2026-09-01) ══════════════════════════════
   OpenProject work packages 의 «표 구조와 분할 상세» 아이디어만 참조했다.
   ⛔⛔ OpenProject(GPL-3.0) 의 CSS 는 한 줄도 옮기지 않았다.
   ⛔ 색·크기를 새로 고르지 않았다 — Velzon 토큰(--vz-*)과 본문 13px 기준이다. */
.wp-split[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.wp-main[b-3kdp7i6zkc] {
    min-width: 0;
}

/* 목록에서만 «옆»에 붙인다. 좁으면 위아래로 떨어져야 표가 짓눌리지 않는다. */
@media (min-width: 1400px) {
    .wp-split-side[b-3kdp7i6zkc] {
        flex-direction: row;
        align-items: flex-start;
    }

    .wp-split-side .wp-main[b-3kdp7i6zkc] {
        flex: 1 1 auto;
    }

    .wp-split-side .wp-side[b-3kdp7i6zkc] {
        flex: 0 0 25rem;
        max-width: 25rem;
    }
}

.wp-wrap[b-3kdp7i6zkc] {
    max-height: calc(100vh - 15rem);
    overflow-y: auto;
}

.wp-table[b-3kdp7i6zkc] {
    font-size: 12px;
}

.wp-table thead th[b-3kdp7i6zkc] {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--vz-tertiary-bg);
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--vz-secondary-color);
    white-space: nowrap;
}

.wp-c-id[b-3kdp7i6zkc] { width: 4.5rem; }
.wp-c-type[b-3kdp7i6zkc] { width: 4.5rem; }
.wp-c-status[b-3kdp7i6zkc] { width: 6.5rem; }
.wp-c-pri[b-3kdp7i6zkc] { width: 5.5rem; }
.wp-c-asgn[b-3kdp7i6zkc] { width: 9rem; }
.wp-c-date[b-3kdp7i6zkc] { width: 6.25rem; }

/* 숫자 폭을 고정한다 — ID·날짜 열이 행마다 들쭉날쭉하면 훑어보기 어렵다. */
.wp-c-id[b-3kdp7i6zkc],
.wp-c-date[b-3kdp7i6zkc] {
    font-variant-numeric: tabular-nums;
}

.wp-row[b-3kdp7i6zkc] {
    cursor: pointer;
}

.wp-row:hover > td[b-3kdp7i6zkc] {
    background: var(--vz-tertiary-bg);
}

/* 선택된 행 — 오른쪽 패널이 «무엇을» 보여 주는지 눈으로 이어져야 한다. */
.wp-row.wp-on > td[b-3kdp7i6zkc] {
    background: rgba(var(--vz-primary-rgb), 0.10);
}

.wp-row-phase > td[b-3kdp7i6zkc] {
    background: rgba(var(--vz-primary-rgb), 0.04);
}

.wp-row-phase.wp-on > td[b-3kdp7i6zkc] {
    background: rgba(var(--vz-primary-rgb), 0.12);
}

.wp-row-empty > td[b-3kdp7i6zkc] {
    background: transparent;
}

.wp-caret[b-3kdp7i6zkc] {
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    line-height: 1;
    padding: 0 0.25rem 0 0;
}

.wp-caret:hover[b-3kdp7i6zkc] {
    color: var(--vz-primary);
}

.wp-indent[b-3kdp7i6zkc] {
    display: inline-block;
    width: 1.5rem;
}

.wp-subject[b-3kdp7i6zkc] {
    vertical-align: middle;
}

.wp-subcount[b-3kdp7i6zkc] {
    margin-left: 0.375rem;
    font-size: 11px;
    color: var(--vz-secondary-color);
}

/* 유형 — 배지가 아니라 «색 글자»다. 행마다 배지를 두면 밀도가 무너진다. */
.wp-type[b-3kdp7i6zkc] {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
}

.wp-type-phase[b-3kdp7i6zkc] { color: var(--vz-primary); }
.wp-type-task[b-3kdp7i6zkc] { color: var(--vz-info); }

.wp-dot[b-3kdp7i6zkc] {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    margin-right: 0.375rem;
}

.wp-newrow > td[b-3kdp7i6zkc] {
    background: var(--vz-tertiary-bg);
}

.wp-new-title[b-3kdp7i6zkc] {
    max-width: 18rem;
}

/* ── 상세 패널 ─────────────────────────────────────────────────────────── */
.wp-side[b-3kdp7i6zkc] {
    border: 1px solid var(--vz-border-color);
    border-radius: 0.5rem;
    background: var(--vz-body-bg);
}

.wp-panel-head[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.625rem;
    border-bottom: 1px solid var(--vz-border-color);
}

.wp-panel-head .btn-close[b-3kdp7i6zkc] {
    margin-left: auto;
}

/* ⛔ 2026-09-01 지시 — 패널에 스크롤이 «되도록 안 생기게» 화면 높이에 맞춰 늘린다.
     고정 34rem 이면 큰 화면에서도 내용이 잘려 스크롤이 났다. */
.wp-panel-body[b-3kdp7i6zkc] {
    padding: 0.75rem;
    max-height: calc(100vh - 15rem);
    overflow-y: auto;
}

/* 제목 줄 — 오른쪽 끝에 삭제 버튼이 붙는다. */
.wp-title-row[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.wp-title-row .wp-title[b-3kdp7i6zkc] {
    flex: 1 1 auto;
    min-width: 0;
}

.wp-crumb[b-3kdp7i6zkc] {
    font-size: 12px;
    color: var(--vz-secondary-color);
}

.wp-title[b-3kdp7i6zkc] {
    margin: 0.25rem 0;
    font-size: 1rem;
}

.wp-meta[b-3kdp7i6zkc] {
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 11px;
    color: var(--vz-secondary-color);
}

.wp-sec[b-3kdp7i6zkc] {
    margin-bottom: 1rem;
}

.wp-sec-h[b-3kdp7i6zkc] {
    margin-bottom: 0.375rem;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--vz-secondary-color);
}

.wp-activity[b-3kdp7i6zkc] {
    list-style: none;
    margin: 0 0 0.75rem;
    padding: 0;
}

.wp-activity li[b-3kdp7i6zkc] {
    display: flex;
    gap: 0.5rem;
    padding: 0.375rem 0;
}

.wp-act-dot[b-3kdp7i6zkc] {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    margin-top: 0.375rem;
    flex: 0 0 auto;
}

.wp-act-t[b-3kdp7i6zkc] { font-size: 12px; }
.wp-act-m[b-3kdp7i6zkc] { font-size: 11px; color: var(--vz-secondary-color); }

.wp-dl[b-3kdp7i6zkc] {
    display: grid;
    grid-template-columns: 6rem 1fr;
    gap: 0.375rem 0.75rem;
    margin: 0 0 0.75rem;
    font-size: 12px;
}

.wp-dl dt[b-3kdp7i6zkc] {
    font-weight: 500;
    color: var(--vz-secondary-color);
}

.wp-dl dd[b-3kdp7i6zkc] { margin: 0; }

.wp-rel-list[b-3kdp7i6zkc],
.wp-watchers[b-3kdp7i6zkc] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.wp-rel-list li[b-3kdp7i6zkc],
.wp-watchers li[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0;
    font-size: 12px;
}

/* ── 산출물 드롭존 (2026-09-01) ─────────────────────────────────────────── */
.pd-drop[b-3kdp7i6zkc] {
    border: 1px dashed var(--vz-border-color);
    border-radius: 0.5rem;
    padding: 0.625rem 0.75rem;
    transition: border-color 0.12s, background 0.12s;
}

/* ⛔ 이 클래스는 JS 가 붙였다 뗀다. style 이 아니라 class 라서 회로 재렌더가 지우지 않는다. */
.pd-drop.pd-drop-over[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
    background: rgba(var(--vz-primary-rgb), 0.06);
}

.pd-drop-hint[b-3kdp7i6zkc] {
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 단계 행의 «작업 추가» — 스페이스 단축키를 눈에 보이게 만드는 짝이다. */
.wp-inline-add[b-3kdp7i6zkc] {
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    line-height: 1;
    padding: 0 0.25rem;
    margin-left: 0.25rem;
    border-radius: 0.25rem;
}

.wp-inline-add:hover:not(:disabled)[b-3kdp7i6zkc] {
    background: var(--vz-body-bg);
    color: var(--vz-primary);
}

/* 행에 포커스가 갔다는 표시 — 스페이스가 먹는 자리를 알려 준다. */
.wp-row-phase:focus-visible[b-3kdp7i6zkc] {
    outline: 2px solid var(--vz-primary);
    outline-offset: -2px;
}

/* ── UI 점검에서 나온 보완 (2026-09-01) ──────────────────────────────────
   ⛔ 색·크기를 새로 고르지 않았다. 빠져 있던 «상태 표현»만 채운다. */

/* 아이콘 버튼도 누를 수 있게 «보여야» 한다 — <button> 기본 커서는 화살표다. */
.wp-caret[b-3kdp7i6zkc],
.wp-inline-add[b-3kdp7i6zkc],
.kb-add[b-3kdp7i6zkc] {
    cursor: pointer;
}

/* 못 누르는 것은 못 누르게 «보인다». 색만 같으면 눌러 보고서야 안다. */
.wp-inline-add:disabled[b-3kdp7i6zkc],
.kb-add:disabled[b-3kdp7i6zkc] {
    opacity: 0.45;
    cursor: not-allowed;
}

/* 키보드로 고른 행이 어디인지 보여야 한다. */
.wp-row:focus-visible[b-3kdp7i6zkc],
.kb-card:focus-visible[b-3kdp7i6zkc] {
    outline: 2px solid var(--vz-primary);
    outline-offset: -2px;
}

/* 움직임을 줄여 달라고 한 사용자에게는 전환을 끈다. */
@media (prefers-reduced-motion: reduce) {
    .pd-drop[b-3kdp7i6zkc],
    .kb-card[b-3kdp7i6zkc],
    .wp-row[b-3kdp7i6zkc] {
        transition: none !important;
    }
}

/* ══ 산출물 좌우 분할 (2026-09-01) ══════════════════════════════════════
   왼쪽 = 단계별 슬롯(계획), 오른쪽 = 파일 풀(실물). 파일을 슬롯으로 끌어다 놓는다.
   ⛔ 1400px 미만에서는 위아래로 쌓는다 — 작업 탭(.wp-split-side)이 쓰는 «같은» 기준점이다.
      두 칸을 억지로 붙여 두면 양쪽 다 못 읽는다. */
.dv-split[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-items: stretch;
}

.dv-split > .card[b-3kdp7i6zkc] {
    margin-bottom: 0;
}

@media (min-width: 1400px) {
    .dv-split[b-3kdp7i6zkc] {
        flex-direction: row;
    }

    /* ⛔ 2026-09-01 지시로 좁혔다(55% → 42%). 왼쪽은 «제목+상태»만 읽으면 되고,
         오른쪽 파일 칸은 썸네일이 한 줄에 더 들어가야 고르기 쉽다. */
    .dv-left[b-3kdp7i6zkc] {
        flex: 0 0 42%;
        max-width: 42%;
    }

    .dv-right[b-3kdp7i6zkc] {
        flex: 1 1 auto;
        min-width: 0;
    }
}

/* 드롭 대상 — 놓을 수 있는 자리를 «놓기 전에» 보여 준다. */
.deliv-slot-row[b-3kdp7i6zkc] {
    transition: background 0.12s, box-shadow 0.12s;
}

.deliv-slot-row.deliv-slot-over[b-3kdp7i6zkc] {
    background: rgba(var(--vz-primary-rgb), 0.10);
    box-shadow: inset 0 0 0 2px var(--vz-primary);
}

@media (prefers-reduced-motion: reduce) {
    .deliv-slot-row[b-3kdp7i6zkc] {
        transition: none !important;
    }
}

/* ⛔⛔ 공용 카드는 jk-shell.css:8 에서 `-webkit-user-drag: none` 이다(마퀴 선택 때문).
     그 한 줄이 «draggable="true" 를 무력화»한다 — 속성만 켜면 Chromium 이 드래그를 시작조차
     하지 않는다(2026-09-01 실측: dragstart 가 아예 안 났고 mousedown 만 났다).
   ⛔ 정본(jk-shell.css)을 고치지 마라 — 문서함·수주 등 다른 화면의 마퀴 선택이 깨진다.
     이 칸 안에서만 되돌린다. ::deep 이 필요한 이유는 카드가 «남의 컴포넌트» 마크업이라
     스코프 속성이 안 붙기 때문이다. */
#pd-file-pane[b-3kdp7i6zkc]  .dms-card {
    -webkit-user-drag: element;
}

/* ══ 정보 탭 (2026-09-02) ═══════════════════════════════════════════════════
   왼쪽 = 정보(프로젝트·수주·수행), 오른쪽 = 단계별 진행 상황(게이트 화살표 + 선택 게이트 패널).
   ⛔ 색·크기는 Velzon 토큰(--vz-*)과 본문 13px 기준이다. 새 값을 고르지 않는다. */
.pi-split[b-3kdp7i6zkc] {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 1rem;
    align-items: start;
}

.pi-split.pi-split-single[b-3kdp7i6zkc] {
    grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 1199.98px) {
    .pi-split[b-3kdp7i6zkc] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.pi-card[b-3kdp7i6zkc] {
    margin-bottom: 1rem;
}

.pi-right .pi-card[b-3kdp7i6zkc] {
    position: sticky;
    top: 0.5rem;
}

/* 카드 머리 색 띠 — 카드마다 «무슨 정보인지» 색으로 갈린다. */
.pi-head[b-3kdp7i6zkc] {
    border-bottom: 1px solid var(--vz-border-color);
}

.pi-head > .d-flex[b-3kdp7i6zkc] { width: 100%; }

/* 2026-09-02 지시(2차) — 카드마다 다른 색을 «쓰지 않는다». 알록달록하면 전문성이 떨어진다. 한 색(primary 톤)으로 통일. */
/* 2026-09-02(3차) 지시 — 머리 배경은 #f5faff 로 «고정». 제목·옆 글자는 본문색(500)으로 또렷하게, 버튼은 primary 한 종류. */
.pi-head-primary[b-3kdp7i6zkc], .pi-head-success[b-3kdp7i6zkc], .pi-head-info[b-3kdp7i6zkc], .pi-head-warning[b-3kdp7i6zkc] {
    background: #f5faff;
    border-bottom-color: var(--vz-border-color);
    min-height: 3rem;
    display: flex;
    align-items: center;
}
.pi-head .fw-medium[b-3kdp7i6zkc] { color: var(--vz-body-color); }
.pi-head .fw-medium > i[b-3kdp7i6zkc] { color: var(--vz-primary); }

.pi-head-side[b-3kdp7i6zkc] {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--vz-body-color);
    white-space: nowrap;
}

/* 라벨-값 2열 — 라벨 폭을 고정해야 값이 세로로 정렬된다. */
.pi-dl[b-3kdp7i6zkc] {
    display: grid;
    grid-template-columns: 7.5rem minmax(0, 1fr);
    column-gap: 0.75rem;
    row-gap: 0.45rem;
    margin: 0;
    font-size: 13px;
}

.pi-dl dt[b-3kdp7i6zkc] {
    font-weight: 500;
    color: var(--vz-secondary-color);
}

.pi-dl dd[b-3kdp7i6zkc] {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

.pi-progress[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.pi-prog-row[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.pi-prog-row .progress[b-3kdp7i6zkc] {
    height: 6px;
}

.pi-prog-label[b-3kdp7i6zkc] {
    width: 3rem;
    color: var(--vz-secondary-color);
}

.pi-prog-n[b-3kdp7i6zkc] {
    width: 6.5rem;
    text-align: right;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

.pi-desc[b-3kdp7i6zkc] {
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--vz-border-color);
}

.pi-desc-title[b-3kdp7i6zkc],
.pi-sub-title[b-3kdp7i6zkc] {
    font-size: 12px;
    font-weight: 500;
    color: var(--vz-secondary-color);
    margin-bottom: 0.35rem;
}

.pi-sub[b-3kdp7i6zkc] {
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--vz-border-color);
}

.pi-table[b-3kdp7i6zkc] {
    font-size: 12.5px;
}

.pi-table th[b-3kdp7i6zkc] {
    font-weight: 500;
    color: var(--vz-secondary-color);
}

/* 현황 타일 — 숫자가 먼저 읽히고, 0 이 아니면 색이 든다. 누르면 그 자리로 간다. */
.pi-tiles[b-3kdp7i6zkc] {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.5rem;
}

@media (max-width: 575.98px) {
    .pi-tiles[b-3kdp7i6zkc] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.pi-tile[b-3kdp7i6zkc] {
    border: 1px solid var(--vz-border-color);
    border-radius: 0.5rem;
    background: var(--vz-secondary-bg);
    padding: 0.5rem 0.4rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    cursor: pointer;
    text-align: center;
}

.pi-tile:hover[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
}

.pi-tile-n[b-3kdp7i6zkc] {
    font-size: 18px;
    font-weight: 500;
    line-height: 1.1;
}

.pi-tile-l[b-3kdp7i6zkc] {
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

.pi-tile-danger .pi-tile-n[b-3kdp7i6zkc] { color: var(--vz-danger); }
.pi-tile-warning .pi-tile-n[b-3kdp7i6zkc] { color: var(--vz-warning); }

.pi-members[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.pi-member[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 13px;
    min-width: 0;
}

.pi-member-name[b-3kdp7i6zkc] {
    font-weight: 500;
}

/* ── 게이트 화살표 스테퍼 — >기획>설계>검증> ─────────────────────────────── */
.gate-flow[b-3kdp7i6zkc] {
    display: flex;
    gap: 3px;
    overflow-x: auto;
    padding: 2px 0 6px;
}

.gate-step[b-3kdp7i6zkc] {
    position: relative;
    flex: 1 1 0;
    min-width: 7.5rem;
    border: 0;
    margin: 0;
    padding: 0.45rem 1rem 0.45rem 1.35rem;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    text-align: left;
    font-size: 13px;
    line-height: 1.2;
    background: var(--vz-tertiary-bg);
    color: var(--vz-secondary-color);
    clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%, 13px 50%);
    cursor: pointer;
    transition: filter 0.12s;
}

.gate-step:first-child[b-3kdp7i6zkc] {
    clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%);
    padding-left: 0.85rem;
    border-radius: 0.375rem 0 0 0.375rem;
}

.gate-step:last-child[b-3kdp7i6zkc] {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 13px 50%);
    border-radius: 0 0.375rem 0.375rem 0;
}

.gate-step:first-child:last-child[b-3kdp7i6zkc] {
    clip-path: none;
    border-radius: 0.375rem;
}

.gate-step:hover[b-3kdp7i6zkc] {
    filter: brightness(0.96);
}

.gate-step:focus-visible[b-3kdp7i6zkc] {
    outline: 2px solid var(--vz-primary);
    outline-offset: -2px;
}

.gate-step-icon[b-3kdp7i6zkc] {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    background: rgba(255, 255, 255, 0.7);
    font-size: 13px;
}

.gate-step-text[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.gate-step-label[b-3kdp7i6zkc] {
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gate-step-sub[b-3kdp7i6zkc] {
    font-size: 11px;
    opacity: 0.85;
    white-space: nowrap;
}

/* 상태 색 — 통과·진행=success(정본 PhaseStatusIcon) · 검토=warning · 실패=danger · 대기=secondary */
.gate-success[b-3kdp7i6zkc] { background: var(--vz-success-bg-subtle); color: var(--vz-success); }
.gate-warning[b-3kdp7i6zkc] { background: var(--vz-warning-bg-subtle); color: var(--vz-warning); }
.gate-danger[b-3kdp7i6zkc] { background: var(--vz-danger-bg-subtle); color: var(--vz-danger); }
.gate-secondary[b-3kdp7i6zkc] { background: var(--vz-tertiary-bg); color: var(--vz-secondary-color); }

/* 선택된 게이트 — 그 상태 색으로 «채운다». clip-path 가 그림자를 잘라 채움으로만 표현한다. */
.gate-step.on[b-3kdp7i6zkc] { color: #fff; }
.gate-step.on .gate-step-icon[b-3kdp7i6zkc] { background: rgba(255, 255, 255, 0.25); }
.gate-step.on.gate-success[b-3kdp7i6zkc] { background: var(--vz-success); }
.gate-step.on.gate-warning[b-3kdp7i6zkc] { background: var(--vz-warning); }
.gate-step.on.gate-danger[b-3kdp7i6zkc] { background: var(--vz-danger); }
.gate-step.on.gate-secondary[b-3kdp7i6zkc] { background: var(--vz-secondary); }

.gate-panel[b-3kdp7i6zkc] {
    margin-top: 0.75rem;
    border: 1px solid var(--vz-border-color);
    border-radius: 0.5rem;
    padding: 0.75rem;
    background: var(--vz-secondary-bg);
}

.gate-panel-head h6[b-3kdp7i6zkc] {
    font-size: 15px;
}

.gate-delivs[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.gate-deliv[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--vz-border-color);
    border-left-width: 4px;
    border-radius: 0.375rem;
    font-size: 13px;
}

.gate-hist-detail[b-3kdp7i6zkc] {
    white-space: pre-wrap;
}

.gate-memo[b-3kdp7i6zkc] {
    font-size: 13px;
    resize: vertical;
}

/* ══ 산출물 두 칸 «구분» (2026-09-02) ═══════════════════════════════════════ */
.dv-head[b-3kdp7i6zkc] {
    border-bottom: 1px solid var(--vz-border-color);
}

/* 2026-09-02 지시(2차) — 두 칸 머리도 한 색. 구분은 아이콘·제목·부제가 한다. */
.dv-head-slot[b-3kdp7i6zkc], .dv-head-file[b-3kdp7i6zkc] { background: #f5faff; border-bottom-color: var(--vz-border-color); min-height: 3rem; }
.dv-head-slot .dv-head-ic[b-3kdp7i6zkc], .dv-head-file .dv-head-ic[b-3kdp7i6zkc] { background: var(--vz-primary); }

.dv-head-ic[b-3kdp7i6zkc] {
    width: 30px;
    height: 30px;
    border-radius: 0.4rem;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    flex: 0 0 auto;
}

.dv-head-sub[b-3kdp7i6zkc] {
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

/* 상태 요약 띠 */
.dv-summary[b-3kdp7i6zkc] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    padding: 0.45rem 0.75rem;
    margin-bottom: 0.6rem;
    border: 1px solid var(--vz-border-color);
    border-radius: 0.375rem;
    background: var(--vz-tertiary-bg);
    font-size: 12.5px;
    color: var(--vz-secondary-color);
}

.dv-sum[b-3kdp7i6zkc] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.dv-sum b[b-3kdp7i6zkc] {
    color: var(--vz-body-color);
    font-weight: 500;
}

.dv-sum-success i[b-3kdp7i6zkc] { color: var(--vz-success); }
.dv-sum-info i[b-3kdp7i6zkc] { color: var(--vz-info); }
.dv-sum-danger[b-3kdp7i6zkc] { color: var(--vz-danger); }
.dv-sum-danger b[b-3kdp7i6zkc] { color: var(--vz-danger); }

/* 연결 파일 칸 — 썸네일 + 파일명 + 메타. 버튼이라 키보드로도 연다. */
.dv-file[b-3kdp7i6zkc] {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    flex: 1 1 14rem;
    max-width: 19rem;
    min-width: 0;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--vz-border-color);
    border-radius: 0.4rem;
    background: var(--vz-secondary-bg);
    text-align: left;
    color: var(--vz-body-color);
    cursor: pointer;
}

button.dv-file:hover[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
}

button.dv-file:hover .dv-file-name[b-3kdp7i6zkc] {
    color: var(--vz-primary);
}

.dv-file-empty[b-3kdp7i6zkc] {
    cursor: default;
    border-style: dashed;
    background: transparent;
}

/* 2026-09-02 지시 — 「파일 미연결」 칸이 곧 「파일 선택」 버튼이다(옆 버튼을 없앴다).
   ⛔ .dv-file-empty 가 cursor:default 라 «뒤에» 와야 이긴다. 순서를 바꾸면 눌러도 커서가 안 바뀐다. */
button.dv-file-pick[b-3kdp7i6zkc] { cursor: pointer; }
button.dv-file-pick:hover[b-3kdp7i6zkc] {
    border-style: solid;
    border-color: var(--vz-primary);
    background: var(--vz-primary-bg-subtle);
}
button.dv-file-pick:hover .dv-file-name[b-3kdp7i6zkc] { color: var(--vz-primary); }
button.dv-file-pick:focus-visible[b-3kdp7i6zkc] { outline: 2px solid var(--vz-primary); outline-offset: 1px; }

.dv-file-missing .dv-file-name[b-3kdp7i6zkc] {
    color: var(--vz-danger);
}

.dv-thumb[b-3kdp7i6zkc] {
    width: 40px;
    height: 40px;
    border-radius: 0.3rem;
    object-fit: cover;
    border: 1px solid var(--vz-border-color);
    background: var(--vz-tertiary-bg);
    flex: 0 0 auto;
}

.dv-thumb-ic[b-3kdp7i6zkc] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    color: var(--vz-secondary-color);
}

.dv-file-text[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.dv-file-name[b-3kdp7i6zkc] {
    font-size: 12.5px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dv-file-meta[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dv-file-meta > span + span[b-3kdp7i6zkc] { margin-left: 2px; }

@media (max-width: 1399.98px) {
    .dv-file[b-3kdp7i6zkc] { flex-basis: 16rem; }
}

/* 편집 모달(JkModal) — 머리 옆 프로젝트 번호·제목 */
.pd-edit-sub[b-3kdp7i6zkc] {
    font-size: 12.5px;
    color: var(--vz-secondary-color);
    max-width: 24rem;
}

.dv-head-prog[b-3kdp7i6zkc] {
    width: 7rem;
    height: 5px;
    margin-top: 3px;
}

/* 슬롯 행 — 왼쪽 색 띠 = 상태. 번호·유형 상자·제목·메타 순. */
/* 2026-09-02 지시(2차) — 행 앞의 색 띠를 «없앤다». 상태는 배지가 말한다. (게이트 패널 .gate-deliv 도 같은 규칙) */
.gate-deliv[b-3kdp7i6zkc] { border-left-width: 1px; }

.dv-no[b-3kdp7i6zkc] {
    width: 1.4rem;
    font-size: 11px;
    color: var(--vz-secondary-color);
    text-align: right;
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
}

.dv-type[b-3kdp7i6zkc] {
    width: 34px;
    height: 34px;
    border-radius: 0.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    flex: 0 0 auto;
    background: var(--vz-tertiary-bg);
    color: var(--vz-secondary-color);
}

/* 제목 칸은 «먼저» 폭을 잡고, 파일 칸이 줄어든다 — 제목이 글자 단위로 꺾이면 읽을 수 없다(3차 실측). */
.dv-slot-main[b-3kdp7i6zkc] {
    flex: 1 1 12rem;
    min-width: 9rem;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dv-slot-title > .fw-medium[b-3kdp7i6zkc] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.dv-slot-title[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
}

.dv-req[b-3kdp7i6zkc] {
    font-size: 10px;
    font-weight: 500;
}

.dv-slot-meta[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12px;
    min-width: 0;
    flex-wrap: wrap;
}

.dv-file-chip[b-3kdp7i6zkc] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    max-width: 18rem;
    padding: 1px 8px;
    border: 1px solid rgba(var(--vz-success-rgb), 0.35);
    border-radius: 999px;
    background: var(--vz-success-bg-subtle);
    color: var(--vz-success);
    font-size: 12px;
    cursor: pointer;
}

.dv-file-chip:hover[b-3kdp7i6zkc] {
    border-color: var(--vz-success);
}

.dv-unlinked[b-3kdp7i6zkc] {
    font-size: 11.5px;
}

/* 오른쪽 버튼 묶음은 줄을 «안 바꾼다» — 좁으면 제목 쪽이 줄어든다. */
.dv-slot > .ms-auto[b-3kdp7i6zkc] {
    flex: 0 0 auto;
}

.dv-slot > .ms-auto .btn[b-3kdp7i6zkc] {
    white-space: nowrap;
}

/* ══ 작업 보드 — 폭을 «끝까지» (2026-09-02) ═══════════════════════════════
   칸 수가 적으면 폭을 나눠 채우고, 많으면(담당자별) 가로 스크롤이 난다. */
.kb-board[b-3kdp7i6zkc] {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(13rem, 1fr);
    align-items: start;
}

.kb-col[b-3kdp7i6zkc] {
    flex: none;
    max-width: none;
    min-width: 0;
}

.kb-late-hint[b-3kdp7i6zkc] {
    color: var(--vz-danger);
    font-size: 14px;
    margin-left: auto;
    padding: 0 0.25rem;
}

.kb-board-compact[b-3kdp7i6zkc] {
    padding: 0.5rem;
    gap: 0.5rem;
    grid-auto-columns: minmax(10rem, 1fr);
}

.kb-board-compact .kb-col[b-3kdp7i6zkc] {
    max-height: none;
}

.kb-board-compact .kb-card[b-3kdp7i6zkc] {
    padding: 0.35rem 0.5rem;
}

/* ══ 작업 달력 (2026-09-02) ═══════════════════════════════════════════════ */
.cal-head[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    flex-wrap: wrap;
    margin-bottom: 0.6rem;
}

.cal-week[b-3kdp7i6zkc] {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    border: 1px solid var(--vz-border-color);
    border-radius: 0.5rem;
    overflow: hidden;
    background: var(--vz-secondary-bg);
}

.cal-day-head[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.45rem 0.55rem;
    font-size: 13px;
    background: var(--vz-tertiary-bg);
    border-bottom: 1px solid var(--vz-border-color);
    border-right: 1px solid var(--vz-border-color);
}

.cal-day-head:nth-child(7)[b-3kdp7i6zkc] {
    border-right: 0;
}

.cal-day-head.weekend[b-3kdp7i6zkc] {
    color: var(--vz-secondary-color);
}

.cal-day-head.today[b-3kdp7i6zkc] {
    box-shadow: inset 0 -2px 0 var(--vz-primary);
    color: var(--vz-primary);
    font-weight: 500;
}

.cal-dow[b-3kdp7i6zkc] {
    font-weight: 500;
}

.cal-day-n[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
}

.cal-day[b-3kdp7i6zkc] {
    min-height: 16rem;
    padding: 0.4rem;
    border-right: 1px solid var(--vz-border-color);
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.cal-day:last-child[b-3kdp7i6zkc] {
    border-right: 0;
}

.cal-day.weekend[b-3kdp7i6zkc] {
    background: var(--vz-light-bg-subtle);
}

.cal-day.today[b-3kdp7i6zkc] {
    background: rgba(var(--vz-primary-rgb), 0.04);
}

.cal-week.compact .cal-day[b-3kdp7i6zkc] {
    min-height: 8rem;
    padding: 0.25rem;
    gap: 0.25rem;
}

.cal-week.compact .cal-day-head[b-3kdp7i6zkc] {
    padding: 0.3rem 0.4rem;
    font-size: 12px;
}

.cal-empty[b-3kdp7i6zkc] {
    color: var(--vz-border-color);
    text-align: center;
    padding-top: 0.5rem;
}

.cal-more[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    padding-left: 0.25rem;
}

/* ── 날짜 클릭 → 그 날의 전체 일정 (2026-09-03 QA #62) ─────────────────────
   ⛔ 「+N more」는 이제 «버튼»이다. 버튼 기본 껍데기를 벗겨 옛 모양을 그대로 유지한다. */
.cal-more-btn[b-3kdp7i6zkc] {
    display: block;
    width: 100%;
    border: 0;
    background: transparent;
    text-align: left;
    cursor: pointer;
    padding: 0 0 0 0.25rem;
    font: inherit;
    font-size: 11px;
}

.cal-more-btn:hover[b-3kdp7i6zkc] {
    color: var(--vz-primary);
    text-decoration: underline;
}

.cal-day-open[b-3kdp7i6zkc] {
    border: 0;
    background: transparent;
    padding: 0;
    margin: 0;
    color: inherit;
    font: inherit;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    cursor: pointer;
}

.cal-day-open:hover[b-3kdp7i6zkc] {
    color: var(--vz-primary);
    text-decoration: underline;
}

/* 날짜별 전체 일정 모달 목록 */
.cal-day-list[b-3kdp7i6zkc] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.cal-day-item[b-3kdp7i6zkc] {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--vz-border-color);
    border-radius: 0.375rem;
    background: var(--vz-secondary-bg);
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.cal-day-item:hover[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
    background: rgba(var(--vz-primary-rgb), 0.04);
}

.cal-day-item.cal-late[b-3kdp7i6zkc] {
    border-left: 3px solid var(--vz-danger);
}

.cal-day-bar[b-3kdp7i6zkc] {
    width: 3px;
    align-self: stretch;
    border-radius: 2px;
    flex: 0 0 auto;
}

.cal-day-item-main[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.cal-day-item-title[b-3kdp7i6zkc] {
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cal-day-item-sub[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cal-day-item-pct[b-3kdp7i6zkc] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    min-width: 2.5rem;
    text-align: right;
}

/* 카드 — 왼쪽 띠 = 상태. 흰 종이 위에 선다(보드 카드와 같은 축). */
.cal-card[b-3kdp7i6zkc] {
    border: 1px solid var(--vz-border-color);
    border-left: 3px solid var(--vz-warning);
    border-radius: 0.375rem;
    background: var(--vz-secondary-bg);
    padding: 0.35rem 0.45rem;
    font-size: 12px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.cal-card:hover[b-3kdp7i6zkc] {
    border-color: var(--vz-primary);
}

.cal-card.cal-on[b-3kdp7i6zkc] {
    box-shadow: 0 0 0 2px rgba(var(--vz-primary-rgb), 0.35);
}

.cal-card-success[b-3kdp7i6zkc] { border-left-color: var(--vz-success); }
.cal-card-info[b-3kdp7i6zkc] { border-left-color: var(--vz-info); }
.cal-card-danger[b-3kdp7i6zkc] { border-left-color: var(--vz-danger); }
.cal-card-secondary[b-3kdp7i6zkc] { border-left-color: var(--vz-secondary); }
.cal-card.cal-late[b-3kdp7i6zkc] { background: var(--vz-danger-bg-subtle); border-left-color: var(--vz-danger); }

.cal-card-title[b-3kdp7i6zkc] {
    font-weight: 500;
    font-size: 12.5px;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

.cal-ic-start[b-3kdp7i6zkc] {
    color: var(--vz-primary);
    margin-right: 1px;
}

.cal-card-meta[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    min-width: 0;
    color: var(--vz-secondary-color);
}

.cal-card-meta .badge[b-3kdp7i6zkc] {
    font-size: 10px;
}

.cal-card-meta .kb-ava[b-3kdp7i6zkc] {
    width: 18px;
    height: 18px;
    font-size: 9px;
}

.cal-mark[b-3kdp7i6zkc] {
    font-size: 10px;
    font-weight: 500;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--vz-primary-bg-subtle);
    color: var(--vz-primary);
}

.cal-mark-end[b-3kdp7i6zkc] {
    background: var(--vz-warning-bg-subtle);
    color: var(--vz-warning);
}

.cal-mark-late[b-3kdp7i6zkc] {
    background: var(--vz-danger);
    color: #fff;
}

.cal-prog[b-3kdp7i6zkc] {
    height: 4px;
}

.cal-card-span[b-3kdp7i6zkc] {
    font-size: 11px;
}

/* 월간 */
.cal-month[b-3kdp7i6zkc] {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    border: 1px solid var(--vz-border-color);
    border-radius: 0.5rem;
    overflow: hidden;
    background: var(--vz-secondary-bg);
}

.cal-month-dow[b-3kdp7i6zkc] {
    padding: 0.4rem 0.5rem;
    font-size: 12px;
    font-weight: 500;
    background: var(--vz-tertiary-bg);
    border-bottom: 1px solid var(--vz-border-color);
}

.cal-month-dow.weekend[b-3kdp7i6zkc] {
    color: var(--vz-secondary-color);
}

.cal-month-cell[b-3kdp7i6zkc] {
    min-height: 6.5rem;
    padding: 0.25rem 0.35rem;
    border-right: 1px solid var(--vz-border-color);
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 12px;
    min-width: 0;
}

.cal-month-cell:nth-child(7n + 7)[b-3kdp7i6zkc] {
    border-right: 0;
}

.cal-month-cell.other[b-3kdp7i6zkc] {
    background: var(--vz-light-bg-subtle);
    color: var(--vz-secondary-color);
}

.cal-month-cell.today[b-3kdp7i6zkc] {
    box-shadow: inset 0 2px 0 var(--vz-primary);
}

.cal-month-cell.today .cal-month-num[b-3kdp7i6zkc] {
    color: var(--vz-primary);
    font-weight: 500;
}

.cal-month-num[b-3kdp7i6zkc] {
    margin-bottom: 0.2rem;
}

.cal-chip[b-3kdp7i6zkc] {
    padding: 1px 6px;
    margin-bottom: 2px;
    border-radius: 3px;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-left: 2px solid var(--vz-warning);
    background: var(--vz-warning-bg-subtle);
}

.cal-chip-success[b-3kdp7i6zkc] { background: var(--vz-success-bg-subtle); border-left-color: var(--vz-success); }
.cal-chip-info[b-3kdp7i6zkc] { background: var(--vz-info-bg-subtle); border-left-color: var(--vz-info); }
.cal-chip-danger[b-3kdp7i6zkc] { background: var(--vz-danger-bg-subtle); border-left-color: var(--vz-danger); }
.cal-chip-secondary[b-3kdp7i6zkc] { background: var(--vz-tertiary-bg); border-left-color: var(--vz-secondary); }
.cal-chip.cal-late[b-3kdp7i6zkc] { background: var(--vz-danger-bg-subtle); border-left-color: var(--vz-danger); }

/* ══ 통합뷰 — 전체화면 2×2 (2026-09-02) ═══════════════════════════════════
   모달 층(2000). 셸 위를 «전부» 덮는다. z-index 표는 feedback_blazor_modal_shell_and_zindex_layers. */
.pd-ov[b-3kdp7i6zkc] {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: var(--vz-body-bg);
    display: flex;
    flex-direction: column;
    outline: none;
}

.pd-ov-head[b-3kdp7i6zkc] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 1.25rem;
    border-bottom: 1px solid var(--vz-border-color);
    background: var(--vz-secondary-bg);
}

.pd-ov-grid[b-3kdp7i6zkc] {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    gap: 0.75rem;
    padding: 0.75rem;
}

/* 3분할 — 왼쪽 목록, 오른쪽은 위 달력 / 아래 간트. */
.pd-ov-right[b-3kdp7i6zkc] {
    display: grid;
    grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.75rem;
    min-height: 0;
}

@media (max-width: 991.98px) {
    .pd-ov[b-3kdp7i6zkc] {
        overflow: auto;
    }

    .pd-ov-grid[b-3kdp7i6zkc] {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: none;
        grid-auto-rows: minmax(18rem, auto);
    }

    .pd-ov-right[b-3kdp7i6zkc] {
        grid-template-rows: none;
        grid-auto-rows: minmax(18rem, auto);
    }
}

.pd-ov-card[b-3kdp7i6zkc] {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.pd-ov-body[b-3kdp7i6zkc] {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

/* 통합뷰 안의 간트는 자기 카드·여백을 접는다(Embedded) — 여기서는 스크롤만 준다. */
.pd-ov-gantt[b-3kdp7i6zkc]  .card {
    margin-bottom: 0;
    border: 0;
    box-shadow: none;
}
/* /Components/Pages/Projects/ProjectGate.razor.rz.scp.css */
/* 게이트 검토 (2026-09-02 3차) — 카드 머리 #f5faff(프로젝트 상세와 같은 축) · 산출물 체크리스트 행.
   ⛔ 색·크기는 Velzon 토큰과 본문 13px 기준. 상세 화면(.dv-*)과 같은 모양을 «따로» 갖는다 — 스코프 CSS 라 공유가 안 된다. */
.gt-head[b-dpdg68m3c1] {
    background: #f5faff;
    border-bottom: 1px solid var(--vz-border-color);
    min-height: 3rem;
    display: flex;
    align-items: center;
}

.gt-head > .d-flex[b-dpdg68m3c1] { width: 100%; }

.gt-head-ic[b-dpdg68m3c1] {
    width: 30px;
    height: 30px;
    border-radius: 0.4rem;
    background: var(--vz-primary);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    flex: 0 0 auto;
}

.gt-head-sub[b-dpdg68m3c1] {
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

.gt-head-side[b-dpdg68m3c1] {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--vz-body-color);
    white-space: nowrap;
}

.gt-stat[b-dpdg68m3c1] { text-align: center; }
.gt-prog[b-dpdg68m3c1] { min-width: 12rem; }

/* 체크리스트 행 */
.gt-list[b-dpdg68m3c1] { display: flex; flex-direction: column; }

.gt-row[b-dpdg68m3c1] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    border-bottom: 1px solid var(--vz-border-color);
    font-size: 13px;
}

.gt-row:last-child[b-dpdg68m3c1] { border-bottom: 0; }
.gt-row:hover[b-dpdg68m3c1] { background: rgba(64, 81, 137, 0.03); }
.gt-row-missing[b-dpdg68m3c1] { background: var(--vz-danger-bg-subtle); }
.gt-row-missing:hover[b-dpdg68m3c1] { background: var(--vz-danger-bg-subtle); }

.gt-no[b-dpdg68m3c1] {
    width: 1.4rem;
    font-size: 11px;
    color: var(--vz-secondary-color);
    text-align: right;
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
}

.gt-type[b-dpdg68m3c1] {
    width: 34px;
    height: 34px;
    border-radius: 0.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    flex: 0 0 auto;
    background: var(--vz-tertiary-bg);
    color: var(--vz-secondary-color);
}

.gt-main[b-dpdg68m3c1] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.gt-title[b-dpdg68m3c1] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.gt-badge[b-dpdg68m3c1] { font-size: 10px; font-weight: 500; }

.gt-meta[b-dpdg68m3c1] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 연결 파일 — 썸네일 + 파일명 + 메타 */
.gt-file[b-dpdg68m3c1] {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    flex: 0 1 22rem;
    min-width: 0;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--vz-border-color);
    border-radius: 0.4rem;
    background: var(--vz-secondary-bg);
    text-align: left;
    color: var(--vz-body-color);
    cursor: pointer;
}

button.gt-file:hover[b-dpdg68m3c1] { border-color: var(--vz-primary); }
button.gt-file:hover .gt-file-name[b-dpdg68m3c1] { color: var(--vz-primary); }

.gt-file-empty[b-dpdg68m3c1] { cursor: default; border-style: dashed; background: transparent; }
.gt-file-missing .gt-file-name[b-dpdg68m3c1] { color: var(--vz-danger); }

.gt-thumb[b-dpdg68m3c1] {
    width: 40px;
    height: 40px;
    border-radius: 0.3rem;
    object-fit: cover;
    border: 1px solid var(--vz-border-color);
    background: var(--vz-tertiary-bg);
    flex: 0 0 auto;
}

.gt-thumb-ic[b-dpdg68m3c1] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    color: var(--vz-secondary-color);
}

.gt-file-text[b-dpdg68m3c1] { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }

.gt-file-name[b-dpdg68m3c1] {
    font-size: 12.5px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gt-file-meta[b-dpdg68m3c1] {
    font-size: 11px;
    color: var(--vz-secondary-color);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gt-file-meta > span + span[b-dpdg68m3c1] { margin-left: 2px; }

@media (max-width: 767.98px) {
    .gt-row[b-dpdg68m3c1] { flex-wrap: wrap; }
    .gt-file[b-dpdg68m3c1] { flex-basis: 100%; }
}
/* /Components/Pages/Projects/Projects.razor.rz.scp.css */
/*
    원본 +page.svelte 의 <style> 블록(1,043~1,063행)을 그대로 옮긴 것이다.
    ⛔ 값을 새로 고르지 않았다 — 색은 전부 Velzon CSS 변수(--vz-*)를 그대로 쓴다.
    ⛔ Blazor 스코프 CSS 라 이 컴포넌트가 그린 요소에만 붙는다(원본 Svelte 스코프와 같은 범위).
*/

.project-card[b-qbrutqg33b] {
    cursor: pointer;
    transition: box-shadow .15s, transform .15s;
}

.project-card:hover[b-qbrutqg33b] {
    box-shadow: 0 .5rem 1rem rgba(64, 81, 137, .12);
    transform: translateY(-2px);
}

.phase-bar[b-qbrutqg33b] {
    height: 6px;
}

.phase-step[b-qbrutqg33b] {
    height: 100%;
    border-radius: 3px;
    background-color: var(--vz-tertiary-bg);
}

.phase-step.done[b-qbrutqg33b] {
    background-color: var(--vz-success);
}

.phase-step.current[b-qbrutqg33b] {
    background-color: var(--vz-primary);
}

/* 자동완성 active 항목 — 내부 text-primary / text-muted 가 파란 배경에 묻히지 않게 흰색 계열로 override.
   원본은 :global() 로 뺐다(Svelte 스코프가 자식 요소에 안 붙어서). Blazor 는 ::deep 이 그 자리다. */
.list-group-item-action.active[b-qbrutqg33b]  code.text-primary,
.list-group-item-action.active[b-qbrutqg33b]  .text-primary {
    color: var(--vz-white) !important;
}

.list-group-item-action.active[b-qbrutqg33b]  .text-muted {
    color: rgba(255, 255, 255, .85) !important;
}
/* /Components/Pages/QuoteImport/QuoteDetailPage.razor.rz.scp.css */
/* 원본 sales/quotes/[id]/+page.svelte 의 <style>(633~637행) 그대로.
   ⛔ 값(inset · rgba · z-index)을 새로 고르지 않는다 — 원본이 못박아 둔 백드롭이다. */
.modal-backdrop-custom[b-oo8vj51udn] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1050;
}


/* ══ 모달 머리/몸통 구분 — 2026-09-02 지시 ════════════════════════════════════
   ⛔⛔ Velzon 테마가 `--vz-modal-header-border-width: 0` 과 `.modal-header{padding-bottom:0}` 로
      머리 밑줄을 «지워» 둬서 제목과 본문이 한 덩어리로 붙어 보였다(2026-09-02 실측).
   ⛔ 값은 모달 표준 껍데기(JkModal .jk-modal-head/.jk-modal-foot)와 같다 — 새로 고르지 마라.
   ⛔ 이 규칙은 scoped 다(이 화면의 마크업에만 붙는다). 전역 .modal-header 를 고치지 마라 —
      다른 화면 수십 개의 모양이 한꺼번에 바뀐다. */
/* ⛔ 선택자를 줄이지 마라 — Velzon 에 `.modal-dialog:not(.modal-dialog-scrollable) .modal-header
   { padding-bottom: 0 }`(특이도 0,3,0)가 있어 `.modal-header` 하나로는 여백이 «안 붙는다»
   (2026-09-02 실측: 밑줄만 붙고 padding-bottom 은 0 이었다). */
.modal-dialog .modal-header[b-oo8vj51udn] {
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--vz-border-color);
}

.modal-footer[b-oo8vj51udn] {
    border-top: 1px solid var(--vz-border-color);
}
/* /Components/Pages/QuoteImport/QuoteDocumentPanel.razor.rz.scp.css */
/*
    견적서 문서 패널 — 원본 스타일 두 벌.
      ① lib/components/sales/QuoteDocumentPanel.svelte <style>(276~297행) — 바깥 판(.qdp-*)
      ② lib/components/sales/QuoteDocument.svelte <style>(354~482행) 중 이 화면이 실제로 그리는 것.

    ⛔⛔ 「종이 위에 놓인 양식」이라는 그림을 잃지 마라 — 그게 보여야 사람이 인쇄 결과를 예상한다
       (원본 291행 주석). 회색 판(.qdp-paper) + 흰 종이(.qdoc) + 그림자가 그 장치다.

    ⛔ 편집칸(.qd-inp)은 «양식 글자처럼» 보여야 한다. 폼 컨트롤 테두리를 그대로 두면
       견적서가 입력 폼으로 보이고, 「출력하면 이 양식대로」라는 약속이 화면에서부터 깨진다.
       ⇒ 테두리 없음 + 점선 밑줄. 포커스에서만 또렷해진다.

    ⛔ 항목 그리드(JkEditableGrid)는 «자기 스코프»의 CSS 를 갖는다 — 여기서 그 안쪽을 건드리려면
       ::deep 가 필요하다. 지금은 바깥 여백만 잡는다. ⛔ 그리드 내부 표를 여기서 다시 칠하지 마라
       (공용 부품이 바뀌면 이 화면만 조용히 어긋난다).
*/

.qdp[b-m3ueil7a6a] { display: flex; flex-direction: column; height: 100%; }

.qdp-bar[b-m3ueil7a6a] {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    padding: 8px 10px; border-bottom: 1px solid var(--vz-border-color);
    background: var(--vz-tertiary-bg);
}
.qdp-state[b-m3ueil7a6a] { font-size: 12px; }
.qdp-sm[b-m3ueil7a6a] { font-size: 12px; }
.qdp-xs[b-m3ueil7a6a] { font-size: 12px; }

.qdp-share[b-m3ueil7a6a] {
    padding: 8px 10px; border-bottom: 1px solid var(--vz-border-color);
    background: var(--vz-body-bg, #f8f9fa);
}
.qdp-share-tbl[b-m3ueil7a6a] { font-size: 12px; }

/* 종이 느낌 — 양식이 흰 종이 위에 있다는 것이 보여야 인쇄 결과를 예상할 수 있다. */
.qdp-paper[b-m3ueil7a6a] {
    flex: 1 1 auto; overflow: auto; padding: 14px;
    /* 종이를 «올려 둔 책상». 앱 UI 라 Velzon 토큰을 쓴다(2026-09-02 팔레트 정리). */
    background: var(--vz-light);
}

/* ── 양식 본체 (A4 폭 190mm) ─────────────────────────────────────────────── */
/* ⛔⛔ 여기 «안»의 흰 바탕(#fff)과 검은 잉크(#111)는 토큰으로 바꾸지 마라 — 이건 화면이 아니라
   «인쇄되는 종이»다. 다크 모드에서 배경이 검어지면 인쇄 결과와 화면이 갈린다.
   ⛔ 나머지(테두리·라벨·보조 글자)는 2026-09-02 에 Velzon 토큰으로 정리했다 —
      종전 값(#6b7280·#d1d5db·#4f46e5·#eef2ff…)은 Velzon 이 아니라 «다른 템플릿»의 팔레트였다. */
.qdoc[b-m3ueil7a6a] {
    background: #fff;
    color: #111;
    width: 190mm;
    max-width: 100%;
    margin: 0 auto;
    padding: 10mm 10mm 12mm;
    font-size: 13px;
    line-height: 1.5;
    box-sizing: border-box;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12);
}

.qd-title[b-m3ueil7a6a] {
    display: block;
    width: 100%;
    text-align: center;
    font-size: 26px;
    font-weight: 500;      /* ⛔ 700 금지 — 앱 전역 규칙(폰트 ≤500) */
    letter-spacing: 8px;
    margin: 0 0 14px;
}

.qd-head[b-m3ueil7a6a] { display: flex; gap: 16px; align-items: flex-start; }
.qd-to[b-m3ueil7a6a], .qd-us[b-m3ueil7a6a] { flex: 1 1 0; min-width: 0; }
.qd-us[b-m3ueil7a6a] { border-left: 1px solid var(--vz-border-color); padding-left: 14px; }
.qd-to-name[b-m3ueil7a6a], .qd-us-name[b-m3ueil7a6a] { font-size: 15px; font-weight: 500; margin-bottom: 4px; }
.qd-us-name[b-m3ueil7a6a] { display: block; width: 100%; }
.qd-gwiha[b-m3ueil7a6a] { font-size: 12px; color: var(--vz-secondary-color); }
.qd-line[b-m3ueil7a6a] { display: flex; gap: 6px; font-size: 12px; align-items: center; }
.qd-lbl[b-m3ueil7a6a] { color: var(--vz-secondary-color); min-width: 56px; flex: 0 0 auto; }
.qd-val[b-m3ueil7a6a] { flex: 1 1 auto; min-width: 0; }
.qd-lead[b-m3ueil7a6a] { margin: 14px 0 10px; display: block; width: 100%; }
.qd-subject[b-m3ueil7a6a] { display: flex; gap: 8px; margin-bottom: 6px; }

.qd-items[b-m3ueil7a6a] { margin-top: 4px; }

.qd-sum[b-m3ueil7a6a] { margin: 8px 0 0 auto; border-collapse: collapse; }
.qd-sum th[b-m3ueil7a6a], .qd-sum td[b-m3ueil7a6a] { border: 1px solid var(--vz-border-color); padding: 4px 10px; font-size: 12px; }
.qd-sum th[b-m3ueil7a6a] { background: var(--vz-tertiary-bg); font-weight: 500; text-align: left; min-width: 110px; }
.qd-sum td[b-m3ueil7a6a] { min-width: 130px; }
.qd-sum td.r[b-m3ueil7a6a] { text-align: right; }
.qd-sum tr.grand th[b-m3ueil7a6a], .qd-sum tr.grand td[b-m3ueil7a6a] { background: var(--vz-primary-bg-subtle); font-size: 13px; }

.qd-notes[b-m3ueil7a6a] { margin-top: 14px; }
.qd-notes-hd[b-m3ueil7a6a] { font-weight: 500; margin-bottom: 4px; display: flex; align-items: center; gap: 6px; }
.qd-notes ol[b-m3ueil7a6a] { margin: 0; padding-left: 18px; }
.qd-notes li[b-m3ueil7a6a] { font-size: 12px; display: flex; align-items: center; gap: 4px; }
.qd-note[b-m3ueil7a6a] { flex: 1 1 auto; min-width: 0; }

.qd-footer[b-m3ueil7a6a] { margin-top: 14px; text-align: center; font-size: 11px; color: var(--vz-secondary-color); display: block; width: 100%; }

/* ── 편집칸 ──────────────────────────────────────────────────────────────── */
.qd-inp[b-m3ueil7a6a] {
    border: 0;
    border-bottom: 1px dashed var(--vz-border-color);
    background: transparent;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    padding: 1px 2px;
    border-radius: 0;
    /* ⛔ 최소 크기를 준다 — 빈 칸이 0폭이 되면 클릭 대상이 사라진다(2026-08-21 지적). */
    min-width: 40px;
}
.qd-inp:focus[b-m3ueil7a6a] {
    outline: 0;
    border-bottom-color: var(--vz-primary);
    background: var(--vz-light-bg-subtle);
}
.qd-inp:disabled[b-m3ueil7a6a] { border-bottom-color: transparent; color: inherit; }

textarea.qd-inp[b-m3ueil7a6a] { resize: vertical; }

/* 비고 삭제 — 원본 .qd-x */
.qd-x[b-m3ueil7a6a] {
    border: 0; background: transparent; color: var(--vz-secondary-color); cursor: pointer;
    font-size: 14px; line-height: 1; padding: 0 4px;
}
.qd-x:hover[b-m3ueil7a6a] { color: var(--vz-danger); }

/* 비고 추가 — 원본 .qd-mini */
.qd-mini[b-m3ueil7a6a] {
    border: 1px dashed var(--vz-primary-border-subtle); background: transparent; color: var(--vz-primary);
    cursor: pointer; font-size: 12px; border-radius: 4px; padding: 0 8px; line-height: 1.6;
}
/* /Components/Pages/RagChat/RagConversation.razor.rz.scp.css */


/* ══ 정본 스타일 이식 (2026-08-31 스타일 감사) ══════════════════════
   마크업은 쓰는데 «어느 CSS 에도 정의가 없던» 클래스들이다 - 화면이 조용히 무스타일이었다.
   출처: JK.AI.Front/src/routes/rag/chat/+page.svelte
   ⛔ 정본에 «없는» 클래스는 이식하지 않았다 - 정본과 동일하게 맞추는 것이 지시다.
   ⛔ 자식 컴포넌트가 그리는 노드는 스코프가 달라 ::deep 이 필요하다(정본의 :global 과 같은 축). */

.session-item[b-kwc5vmwgul] {
    cursor: pointer;
    transition: background 0.15s;
}

.session-item:hover[b-kwc5vmwgul] {
    background: var(--vz-tertiary-bg);
}

.session-item.active[b-kwc5vmwgul] {
    background: #e8eff7;
    border-left: 3px solid var(--vz-primary) !important;
}

/* ══ 답변 각주 [n] (2026-09-05 RAG P0-2) ═══════════════════════════════
   ⛔ 색·크기를 새로 고르지 않았다 - 링크색은 테마 변수, 크기는 본문(13px) 그대로다.
   ⛔ 점수(score)는 그리지 않는다. 내부 혼합 점수라 「84% 정확」으로 오인된다. */

.rag-cite[b-kwc5vmwgul] {
    color: var(--vz-link-color);
    text-decoration: none;
    white-space: nowrap;
}

.rag-cite:hover[b-kwc5vmwgul] {
    text-decoration: underline;
}

/* 매핑된 DMS 문서가 없는 각주 - 누를 곳이 없으니 링크처럼 보이지 않게 한다. */
.rag-cite-plain[b-kwc5vmwgul] {
    color: var(--vz-secondary-color);
    cursor: default;
}
/* /Components/Pages/RagFiles/RagDocuments.razor.rz.scp.css */
/* 미리보기 모달 — 원본 rag/files/+page.svelte 347~368행의 <style> 블록 그대로.
   ⛔ 원본은 Svelte 스코프 CSS 라 그대로 복사하면 전역으로 샌다.
      Blazor 의 collocated .razor.css(스코프 CSS)로 옮겨 «같은 범위»를 유지한다.
   ⛔ 색은 새로 고르지 않는다 — var(--vz-*) 는 기존 global.css(Velzon)의 토큰이다. */

.preview-overlay[b-apjxm7r9hr] {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.7);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.preview-modal[b-apjxm7r9hr] {
    width: 90vw;
    height: 90vh;
    background: var(--vz-secondary-bg);
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 8px 32px rgba(0,0,0,0.3);
}

.preview-header[b-apjxm7r9hr] {
    background: var(--vz-primary);
    padding: 10px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}

.preview-body[b-apjxm7r9hr] {
    flex: 1;
    overflow: hidden;
}

.preview-body iframe[b-apjxm7r9hr] {
    border: none;
}
/* /Components/Pages/SalesCreate/ProjectGantt.razor.rz.scp.css */
/*
    원본 JK.AI.Front/src/routes/plm/projects/[id]/gantt/+page.svelte 의 <style> 블록(444~565행)을
    «클래스명·값 그대로» 옮긴 것이다. ⛔ 색·간격을 새로 고르지 않았다.
    ⛔ Svelte 의 컴포넌트 스코프 CSS ↔ Blazor CSS isolation 으로 «역할이 같다» — 전역으로 올리지 마라.
*/

/* No.135: 가로 스크롤 영역 — 트랙이 뷰포트보다 넓으면 좌우로 스크롤 */
.gantt-scroll[b-qpqvtaipdl] { overflow-x: auto; }
.gantt-table[b-qpqvtaipdl] { border-top: 1px solid var(--vz-border-color); width: max-content; min-width: 100%; }
.gantt-row[b-qpqvtaipdl] { display: flex; border-bottom: 1px solid var(--vz-border-color); min-height: 44px; }
.gantt-header[b-qpqvtaipdl] { background-color: var(--vz-tertiary-bg); min-height: 32px; font-weight: 600; }
.gantt-tasks-header[b-qpqvtaipdl] { background-color: #f1f3f5; }
.gantt-label[b-qpqvtaipdl] {
    width: 180px; min-width: 180px;
    padding: .4rem .75rem;
    border-right: 1px solid var(--vz-border-color);
    /* 가로 스크롤 시에도 단계/태스크 이름 열은 고정 */
    position: sticky; left: 0; z-index: 4;
    background-color: var(--vz-secondary-bg);
}
/* 헤더/그룹 행 라벨은 해당 행 배경색과 동일하게 (sticky 가 트랙 위를 덮으므로) */
.gantt-header .gantt-label[b-qpqvtaipdl] { background-color: var(--vz-tertiary-bg); }
.gantt-tasks-header .gantt-label[b-qpqvtaipdl] { background-color: #f1f3f5; }
.gantt-phase-group-header .gantt-label[b-qpqvtaipdl] { background-color: var(--vz-tertiary-bg); }
.gantt-track[b-qpqvtaipdl] {
    /* 트랙 최소 폭 = 일수 비례 픽셀(--track-w, 인라인 주입).
       화면이 넓으면 grow 로 채우고, 좁으면 min-width 가 가로 스크롤을 만든다. */
    flex: 1 0 auto; min-width: var(--track-w, 1000px);
    position: relative; overflow: hidden;
}
.month-marker[b-qpqvtaipdl] {
    position: absolute; top: 6px; font-size: 13px; color: #8d9298;
    transform: translateX(-50%);
    white-space: nowrap;
}
.month-marker.first[b-qpqvtaipdl] { transform: none; left: 4px !important; }
.month-marker.last[b-qpqvtaipdl]  { transform: translateX(-100%); }
.month-grid[b-qpqvtaipdl] {
    position: absolute; top: 0; bottom: 0;
    width: 1px; background-color: #f1f3f5;
}
.gantt-bar[b-qpqvtaipdl] {
    position: absolute; top: 10px; height: 22px;
    border-radius: .25rem;
}
.gantt-bar-planned[b-qpqvtaipdl] {
    background-color: rgba(64,81,137,.08);
    border: 1px dashed;
    top: 9px; height: 24px;
}
.gantt-bar-actual[b-qpqvtaipdl] {
    opacity: .9;
    display: flex; align-items: center; padding: 0 .5rem;
    color: white; font-size: 13px; font-weight: 500;
}
.gantt-bar-label[b-qpqvtaipdl] { white-space: nowrap; overflow: hidden; }
.gantt-today-line[b-qpqvtaipdl] {
    position: absolute; top: 0; bottom: 0;
    width: 2px; background-color: var(--vz-primary);
    z-index: 2;
}
.gantt-predicted-line[b-qpqvtaipdl] {
    position: absolute; top: 0; bottom: 0;
    width: 2px; background-color: var(--vz-danger);
    z-index: 2;
}
.task-marker[b-qpqvtaipdl] {
    position: absolute; top: 12px;
    color: #8d9298; font-size: 13px;
    transform: translateX(-50%);
    z-index: 1;
}
.task-marker.done[b-qpqvtaipdl] { color: var(--vz-success); }
.task-marker.overdue[b-qpqvtaipdl] { color: var(--vz-danger); }

/* Phase 그룹 헤더 (접기/펼치기) */
.gantt-phase-group-header[b-qpqvtaipdl] {
    background-color: var(--vz-tertiary-bg);
    cursor: pointer;
    min-height: 36px;
    user-select: none;
}
.gantt-phase-group-header:hover[b-qpqvtaipdl] { background-color: #f1f3f5; }
.gantt-phase-group-header .gantt-label[b-qpqvtaipdl] { padding-top: .55rem; }
.gantt-toggle-icon[b-qpqvtaipdl] {
    font-size: 1rem; vertical-align: middle;
    margin-right: 2px; color: var(--vz-secondary-color);
}

/* Task 행 (들여쓰기) */
.gantt-task-row[b-qpqvtaipdl] { min-height: 40px; }
.gantt-label-indent[b-qpqvtaipdl] { padding-left: 1.75rem; }

/* Task 막대 */
.gantt-bar-task-planned[b-qpqvtaipdl] {
    background-color: rgba(64, 81, 137, .06);
    border: 1px dashed;
    top: 10px; height: 20px;
}
.gantt-bar-task-actual[b-qpqvtaipdl] {
    top: 10px; height: 20px;
    opacity: .9;
    overflow: hidden;
}
.gantt-bar-task-actual.overdue[b-qpqvtaipdl] {
    box-shadow: 0 0 0 1px var(--vz-danger) inset;
}
.gantt-bar-task-progress[b-qpqvtaipdl] {
    position: absolute; left: 0; top: 0; bottom: 0;
    background-color: rgba(255, 255, 255, .35);
    border-right: 1px solid rgba(255, 255, 255, .8);
}
.legend-box[b-qpqvtaipdl] {
    display: inline-block; width: 12px; height: 12px;
    border-radius: 2px; margin-right: 4px; vertical-align: middle;
}
.legend-line[b-qpqvtaipdl] {
    display: inline-block; width: 2px; height: 12px;
    margin-right: 4px; vertical-align: middle;
}
.legend-bar[b-qpqvtaipdl] {
    display: inline-block; width: 24px; height: 10px;
    border-radius: 2px; margin-right: 4px; vertical-align: middle;
}
.legend-bar-planned[b-qpqvtaipdl] {
    background-color: rgba(64, 81, 137, .06);
    border: 1px dashed var(--vz-primary);
}
/* /Components/Pages/SalesCreate/QuoteCreate.razor.rz.scp.css */
/* 견적 작성 화면 scoped CSS — 2026-09-02 신설. */


/* ══ 모달 머리/몸통 구분 — 2026-09-02 지시 ════════════════════════════════════
   ⛔⛔ Velzon 테마가 `--vz-modal-header-border-width: 0` 과 `.modal-header{padding-bottom:0}` 로
      머리 밑줄을 «지워» 둬서 제목과 본문이 한 덩어리로 붙어 보였다(2026-09-02 실측).
   ⛔ 값은 모달 표준 껍데기(JkModal .jk-modal-head/.jk-modal-foot)와 같다 — 새로 고르지 마라.
   ⛔ 이 규칙은 scoped 다(이 화면의 마크업에만 붙는다). 전역 .modal-header 를 고치지 마라 —
      다른 화면 수십 개의 모양이 한꺼번에 바뀐다. */
/* ⛔ 선택자를 줄이지 마라 — Velzon 에 `.modal-dialog:not(.modal-dialog-scrollable) .modal-header
   { padding-bottom: 0 }`(특이도 0,3,0)가 있어 `.modal-header` 하나로는 여백이 «안 붙는다»
   (2026-09-02 실측: 밑줄만 붙고 padding-bottom 은 0 이었다). */
.modal-dialog .modal-header[b-bcf958nbpc] {
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--vz-border-color);
}

.modal-footer[b-bcf958nbpc] {
    border-top: 1px solid var(--vz-border-color);
}
/* /Components/Pages/SalesDesk/Customers.razor.rz.scp.css */
/* 정본 스타일 이식 — JK.AI.Front/src/routes/sales/customers/+page.svelte 의 <style>(325~332행)과
   lib/components/grid/CustomerGrid.svelte 의 <style>(683~686행).

   ⛔⛔ 이 규칙들은 정본에서 Svelte «스코프» 안에 있어 global.css 에 «0건»이다.
      셸이 global.css 를 링크해도 따라오지 않는다 — 그래서 화면이 조용히 무스타일이었다.
   ⛔ .sales-customers-page 는 장식이 아니다. 이게 없으면 카드가 안 늘어나 그리드가 짧아진다.
      정본이 :global() 로 한정한 이유도 같다(다른 페이지 카드까지 커지는 부작용). */

.sales-customers-page > .card[b-xxn9p71xft] {
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 180px);
}

/* ⛔ .grid-area 는 wwwroot/app.css 로 옮겼다 — 그리드를 쓰는 화면이 여럿이라 화면마다 베끼지 않는다. */


/* ══ 모달 머리/몸통 구분 — 2026-09-02 지시 ════════════════════════════════════
   ⛔⛔ Velzon 테마가 `--vz-modal-header-border-width: 0` 과 `.modal-header{padding-bottom:0}` 로
      머리 밑줄을 «지워» 둬서 제목과 본문이 한 덩어리로 붙어 보였다(2026-09-02 실측).
   ⛔ 값은 모달 표준 껍데기(JkModal .jk-modal-head/.jk-modal-foot)와 같다 — 새로 고르지 마라.
   ⛔ 이 규칙은 scoped 다(이 화면의 마크업에만 붙는다). 전역 .modal-header 를 고치지 마라 —
      다른 화면 수십 개의 모양이 한꺼번에 바뀐다. */
/* ⛔ 선택자를 줄이지 마라 — Velzon 에 `.modal-dialog:not(.modal-dialog-scrollable) .modal-header
   { padding-bottom: 0 }`(특이도 0,3,0)가 있어 `.modal-header` 하나로는 여백이 «안 붙는다»
   (2026-09-02 실측: 밑줄만 붙고 padding-bottom 은 0 이었다). */
.modal-dialog .modal-header[b-xxn9p71xft] {
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--vz-border-color);
}

.modal-footer[b-xxn9p71xft] {
    border-top: 1px solid var(--vz-border-color);
}
/* /Components/Pages/SalesDesk/Quotes.razor.rz.scp.css */
/* 원본 두 파일의 <style> 에서 «이 화면이 실제로 쓰는 것»만 옮겼다.
   ⛔ 죽은 CSS 를 남기지 않는다(원본 주석의 규칙) — 드로어/리사이저/모달 높이 규칙은
      상세(QuoteDetailDrawer)를 옮기지 않았으므로 함께 빠졌다. */

/* +page.svelte 406~410행 — 목록 카드를 감싸는 세로 플렉스.
   ⛔ .master-pane 의 flex:1 1 auto 가 «기댈 곳»이 이 컨테이너다. 빼면 카드가 안 늘어나
      그리드가 뷰포트를 못 채운다(2026-08-31 정본 대조에서 빠져 있었다). */
.master-detail[b-et0z3dqorm] {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* +page.svelte 411행 — 목록 카드는 세로로 늘어난다. */
.master-pane[b-et0z3dqorm] {
    flex: 1 1 auto;
    min-height: 240px;
    display: flex;
    flex-direction: column;
    /* 439~441행 — 목록 카드는 깔끔한 흰색 유지(대비). */
    background: var(--vz-secondary-bg);
}

/* 443~448행 — 검색 아이콘을 입력 안쪽 왼쪽에 겹쳐 놓는다. */
.search-box[b-et0z3dqorm] {
    position: relative;
}

.search-box .search[b-et0z3dqorm] {
    padding-left: 2rem;
}

.search-box .search-icon[b-et0z3dqorm] {
    position: absolute;
    left: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--vz-gray-500);
}

/* QuoteGrid.svelte 1022~1027행 — 목록 하단 조작 안내 줄. */
.hint-bar[b-et0z3dqorm] {
    font-size: 13px;
    background: var(--vz-tertiary-bg);
    color: var(--vz-secondary-color);
    padding: 2px 12px;
}

/* 412행 — 카드 본문(그리드 자리)이 남는 높이를 먹는다. ::deep 은 그리드가 자식 컴포넌트라서다. */
.master-pane[b-et0z3dqorm]  .card-body.p-0 {
    flex: 1 1 auto;
    min-height: 0;
}

/* ⛔ .quote-list-grid 는 «자식 컴포넌트»(JkAgGrid)가 그리는 노드라 스코프가 다르다 —
     그래서 여기 두지 않고 wwwroot/app.css 에 뒀다(.quote-grid 와 같은 사정). */

/* 정본 QuoteGrid.svelte <style>:1025~1035 — 임시 행 안내 줄(그리드 아래). */
.phantom-guide[b-et0z3dqorm] {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 16px;
    background: linear-gradient(90deg, #fff8dc 0%, #fffbe6 100%);
    border-top: 2px solid var(--vz-warning);
    border-bottom: 1px solid #eee2b3;
    font-size: 14px;
    color: #6b5200;
}

/* ⭐ 2026-09-03 (QA #38) — 이 띠가 그리드 «위»로 올라갔다(안내가 가리키는 맨 윗줄 바로 옆).
   ⛔ 위에 있으면 굵은 선이 «머리»에 와야 아래 표와 이어져 보인다 — 두께를 아래로 옮긴다.
      값은 종전과 같은 두 선(2px warning / 1px #eee2b3)을 위아래만 바꾼 것이다. 새로 고르지 마라. */
.phantom-guide-top[b-et0z3dqorm] {
    border-top: 1px solid #eee2b3;
    border-bottom: 2px solid var(--vz-warning);
}


/* ══ 견적 상세 드로어 — 정본 QuoteActionBar / QuoteBasicPanel / QuoteActivityPanel <style> 이식
   ⛔⛔ 정본에서 Svelte 스코프 안이라 global.css 에 «0건»이다 — 클래스 이름만 맞춰서는 모양이 안 나온다.
   ⛔ 값(액션바 그라데이션·점 크기·연결선 40px)을 새로 고르지 마라. 정본 그대로다. */

.quote-action-bar[b-et0z3dqorm] {
    padding: 10px 16px;
    background: linear-gradient(180deg, #eef1f6 0%, #e5e9f0 100%);
    border-bottom: 1px solid #d8dce3;
    min-height: 52px;
}

.quote-action-bar .min-w-0[b-et0z3dqorm] { min-width: 0; }

/* ⛔ `pb-2` 를 빼지 마라 — 종전 정본에서 탭 버튼 밑변이 컨텐츠 경계선에 붙어 한 덩어리로 보였다. */
.drawer-tabs[b-et0z3dqorm] {
    border-bottom: 1px solid var(--vz-border-color, #e6eaef);
    background: var(--vz-card-bg, #fff);
}

.basic-panel[b-et0z3dqorm] { padding: 12px 16px; }

.basic-panel-footer[b-et0z3dqorm] {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--vz-border-color);
}

.readonly-html[b-et0z3dqorm] {
    padding: 8px 12px;
    border: 1px solid var(--vz-border-color);
    background: var(--vz-tertiary-bg);
    border-radius: 6px;
    min-height: 60px;
}

/* ── 활동 탭 ─────────────────────────────────────────────────────────────── */
.activity-panel[b-et0z3dqorm] { padding: 12px 16px; }

.summary-card[b-et0z3dqorm] {
    padding: 10px 14px;
    background: #f8f9fb;
    border: 1px solid #eef0f3;
    border-radius: 8px;
}

.summary-label[b-et0z3dqorm] { font-size: 12px; color: var(--vz-secondary-color); margin-bottom: 2px; }
.summary-value[b-et0z3dqorm] { font-weight: 500; color: var(--vz-body-color); }

.activity-section[b-et0z3dqorm] { margin-bottom: 16px; }
.section-title[b-et0z3dqorm] { font-weight: 500; margin-bottom: 6px; color: var(--vz-body-color); font-size: 13px; }

.status-flow[b-et0z3dqorm] { display: flex; align-items: center; gap: 0; flex-wrap: nowrap; }
.status-step[b-et0z3dqorm] { display: flex; align-items: center; gap: 6px; padding: 4px 10px; }

/* ⛔ 미도달 단계의 점 — 테두리와 «같은 색»을 채우면 링이 사라져 평평해진다. 면은 한 단계 밝게. */
.status-dot[b-et0z3dqorm] {
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--vz-light); border: 2px solid var(--vz-border-color);
    transition: all 0.2s;
}

.status-step.past .status-dot[b-et0z3dqorm] { background: var(--vz-success); border-color: var(--vz-success); }
.status-step.current .status-dot[b-et0z3dqorm] {
    background: var(--vz-primary); border-color: var(--vz-primary);
    box-shadow: 0 0 0 3px rgba(64, 81, 137, 0.2);
}

.status-label[b-et0z3dqorm] { font-size: 13px; color: var(--vz-secondary-color); }
.status-step.past .status-label[b-et0z3dqorm] { color: var(--vz-success); }
.status-step.current .status-label[b-et0z3dqorm] { color: var(--vz-primary); font-weight: 500; }

.status-connector[b-et0z3dqorm] { width: 40px; height: 2px; background: var(--vz-border-color); }
.status-connector.past[b-et0z3dqorm] { background: var(--vz-success); }

.reason-box[b-et0z3dqorm] {
    padding: 10px 14px;
    background: rgba(240, 101, 72, 0.08);
    border-left: 3px solid var(--vz-danger);
    border-radius: 4px;
    white-space: pre-wrap;
    font-size: 13px;
}

.memo-box[b-et0z3dqorm] {
    padding: 10px 14px;
    background: var(--vz-tertiary-bg);
    border: 1px solid #eef0f3;
    border-radius: 4px;
    white-space: pre-wrap;
    font-size: 13px;
}


/* ══ 모달 머리/몸통 구분 — 2026-09-02 지시 ════════════════════════════════════
   ⛔⛔ Velzon 테마가 `--vz-modal-header-border-width: 0` 과 `.modal-header{padding-bottom:0}` 로
      머리 밑줄을 «지워» 둬서 제목과 본문이 한 덩어리로 붙어 보였다(2026-09-02 실측).
   ⛔ 값은 모달 표준 껍데기(JkModal .jk-modal-head/.jk-modal-foot)와 같다 — 새로 고르지 마라.
   ⛔ 이 규칙은 scoped 다(이 화면의 마크업에만 붙는다). 전역 .modal-header 를 고치지 마라 —
      다른 화면 수십 개의 모양이 한꺼번에 바뀐다. */
/* ⛔ 선택자를 줄이지 마라 — Velzon 에 `.modal-dialog:not(.modal-dialog-scrollable) .modal-header
   { padding-bottom: 0 }`(특이도 0,3,0)가 있어 `.modal-header` 하나로는 여백이 «안 붙는다»
   (2026-09-02 실측: 밑줄만 붙고 padding-bottom 은 0 이었다). */
.modal-dialog .modal-header[b-et0z3dqorm] {
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--vz-border-color);
}

.modal-footer[b-et0z3dqorm] {
    border-top: 1px solid var(--vz-border-color);
}


/* ══ 탭 줄 ↔ 표 사이 여백 — 2026-09-02 지시 ══════════════════════════════════
   ⛔ 「신규 견적·새로고침」 액션 줄이 사이에서 여백 노릇을 하고 있었다. 줄을 없애자
      탭과 표머리가 맞닿았다. 여백을 «몸통»이 갖게 한다.
   ⛔ `.card-header` 쪽을 고치려 하지 마라 — 마크업의 `pb-0` 이 부트스트랩 유틸(!important)이다. */
.quote-list-body[b-et0z3dqorm] {
    padding-top: 0.75rem !important;
}
/* /Components/Pages/SalesOrders/Executive.razor.rz.scp.css */
/* 원본 sales/executive/+page.svelte 의 <style>(585~593행) 그대로.
   축 표기 — 라벨보다 한 단 낮게. 홈 `.jkia-kpi-axis` 와 같은 역할. */

.kpi-axis[b-fb3cv7r445] {
    font-size: 11px;
    font-weight: 400;
    opacity: 0.8;
    white-space: nowrap;
}
/* /Components/Pages/SalesOrders/Orders.razor.rz.scp.css */
/* 원본 sales/orders/+page.svelte 의 <style>(386~398행)에서 «이 화면이 실제로 쓰는 것»만 옮겼다.
   ⛔ 죽은 CSS 를 남기지 않는다 — 원본 주석의 `.nav-link` 오버라이드는 SegTabs 전환으로 이미 죽었다. */

.search-box[b-0fzco6sxbd] {
    position: relative;
}

.search-box .search[b-0fzco6sxbd] {
    padding-left: 2rem;
}

.search-box .search-icon[b-0fzco6sxbd] {
    position: absolute;
    left: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--vz-gray-500);
}

/* 검색어 지우기(×) — 입력칸 안 오른쪽. 입력 padding 을 건드리지 않으려 겹쳐 놓는다. */
.search-box .search-clear[b-0fzco6sxbd] {
    position: absolute;
    right: 0.35rem;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    line-height: 1;
    padding: 2px 4px;
    color: var(--vz-gray-500);
    cursor: pointer;
}

.search-box .search-clear:hover[b-0fzco6sxbd] {
    color: var(--vz-body-color);
}
/* /Components/Pages/SalesOrders/ShipmentDetailView.razor.rz.scp.css */
/* 원본 sales/shipments/[id]/+page.svelte 의 <style>(401~406행) 그대로. */

.modal-backdrop-custom[b-w6pqptevc1] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1050;
}
/* /Components/Pages/SystemSettings/EmailSettings.razor.rz.scp.css */
/* 원본 email/+page.svelte 의 <style> 블록(178~181행)에 있던 .fs-12 재정의를 제거했다(2026-09-01 지시).
   그 규칙이 전역 유틸(.fs-12 = 12px)을 «이 화면에서만» 14.4px 로 키우고 있었다 — 브라우저로 실측했다.
   ⛔ 같은 클래스가 화면마다 다른 크기가 되면 «페이지마다 글자가 다르다» 는 말이 나온다. 다시 넣지 마라. */
/* /Components/Pages/SystemSettings/GeneralSettings.razor.rz.scp.css */
/* 원본 general/+page.svelte 의 <style> 블록(510~531행) 그대로 이식.
   ⛔ 디자인을 «새로 만들지 않는다» — 값(색·간격)을 원본과 같게 둔다. */

.key-help-box[b-uhlkpbi3ux] {
    background: #f8f9fc;
    border: 1px solid #e3e6f0;
    border-left: 3px solid #4a90e2;
    border-radius: 4px;
}

.key-help-table[b-uhlkpbi3ux] {
    font-size: 12px;
    background: white;
}

.key-help-table thead th[b-uhlkpbi3ux] {
    font-size: 12px;
    font-weight: 500;
    background: #f1f3f5;
    padding: 4px 8px;
}

.key-help-table tbody td[b-uhlkpbi3ux] {
    padding: 5px 8px;
    vertical-align: top;
}

.key-help-table tbody tr.current[b-uhlkpbi3ux] {
    background: #fff3cd;
}

.key-help-table tbody tr.current code[b-uhlkpbi3ux] {
    font-weight: 600;
}

.key-help-row > td[b-uhlkpbi3ux] {
    background: transparent !important;
}
/* /Components/Pages/Traceability/AdminBomSettings.razor.rz.scp.css */
/* 원본 PreparingPlaceholder.svelte 의 <style> 블록 그대로. */
.placeholder-wrap[b-675b91ypma] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 60vh;
    color: var(--vz-secondary-color);
}

.placeholder-icon[b-675b91ypma] {
    font-size: 4rem;
    opacity: 0.4;
    margin-bottom: 1rem;
}
/* /Components/Pages/Traceability/PartRevTrace.razor.rz.scp.css */
/* 원본 +page.svelte 의 <style> 블록 그대로. 첨부 도면 행이 클릭 대상임을 보이는 커서. */
.doc-row[b-5u1zdwsbsq] { cursor: pointer; }
/* /Components/Shared/CardGrid/JkDialog.razor.rz.scp.css */
/* 공용 모달 — 2026-09-01 야간 17회차 fix (PLM-20260901-16 · -17).
   ⛔ 값은 «새로 디자인한 것이 아니라» 종전 JkDmsBulkActionBar.razor.css / JkDmsCardContextMenu.razor.css
      의 .jk-dialog* 를 그대로 옮긴 것이다. 모양이 바뀌면 그건 이 fix 의 스코프 밖이다.
   ⛔ 격리 CSS 라 마크업이 이 컴포넌트로 옮겨 온 이상 규칙도 여기 있어야 한다. */

.jk-dialog-backdrop[b-kj94kao2vp] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .45);
    display: flex;
    align-items: center;
    justify-content: center;
    /* ⛔⛔ 2026-09-02 지적(「confirm 창이 모달 창 뒤에 숨는다」) — 종전 1080 은 이 부품이
       «우클릭 메뉴/일괄 액션바»에서만 쓰이던 시절의 값이다. 지금은 파일 상세 오버레이
       (.detail-overlay = 2050)와 카테고리 피커(.picker-backdrop = 2080) «위»에서도 뜬다.
       app.css 의 겹침 순서표가 정한 자리는 「메뉴가 여는 작은 대화상자 = 2200」이다.
       ⛔ 숫자를 여기서 새로 고르지 마라 — 표(app.css 하단)를 보고 그 층을 쓴다. */
    z-index: 2200;
    /* ⛔⛔ 2026-09-01 야간 17회차 fix 후속 — 마크업에 `picker-backdrop` 을 «기능 때문에» 함께 달았다
       (JkDmsCardGrid.razor.js INTERACTIVE_SELECTOR 에 걸려야 이 안의 클릭이 「선택 해제」로 읽히지 않는다).
       그런데 jk-shell.css:506 의 전역 `.picker-backdrop` 에 blur(2px) 가 있어 «모양»까지 따라온다.
       나머지 선언(position·background·z-index·flex)은 위 격리 규칙이 명시도에서 이기지만
       backdrop-filter 는 여기 없어서 그대로 먹는다 — 그래서 여기서 되돌린다.
       ⛔ 이 fix 는 동작만 고친다. 딤 배경의 모양이 달라지면 그건 회귀다. */
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

.jk-dialog[b-kj94kao2vp] {
    background: var(--vz-card-bg, #fff);
    border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .2);
    width: 100%;
    max-width: 520px;
    margin: 1rem;
    display: flex;
    flex-direction: column;
}

/* 포커스 받을 것이 하나도 없을 때 대화상자 자신이 포커스를 받는다(JkDialog.razor.js focusFirst).
   ⛔ 그때 테두리가 안 보이면 「어디에 있는지 모르는 포커스」가 된다. */
.jk-dialog:focus-visible[b-kj94kao2vp] {
    outline: 2px solid var(--vz-primary, #0ea5e9);
    outline-offset: 2px;
}

.jk-dialog-head[b-kj94kao2vp] {
    padding: 10px 14px;
    font-weight: 600;
    font-size: 13px;
    background: var(--vz-primary-bg-subtle, #dff0fa);
    border-bottom: 1px solid var(--vz-border-color);
    border-radius: 8px 8px 0 0;
}

.jk-dialog-body[b-kj94kao2vp] { padding: 14px; }

.jk-dialog-tree-body[b-kj94kao2vp] {
    max-height: 50vh;
    overflow-y: auto;
    padding: 6px;
}

.jk-dialog-foot[b-kj94kao2vp] {
    padding: 10px 14px;
    border-top: 1px solid var(--vz-border-color);
    display: flex;
    justify-content: flex-end;
    gap: 6px;
}
/* /Components/Shared/CardGrid/JkDmsBulkActionBar.razor.rz.scp.css */
/* 하단 일괄 액션바 — 정본 DmsBulkActionBar.svelte 의 <style> 그대로.
   ⛔ QA시트 #42: 전체폭 바가 아니라 «내용 폭 pill» 이다(화면 하단 중앙에 떠 있음).
      전체폭으로 되돌리면 좌측 사이드바를 덮고, AI 패널이 열릴 때 중앙정렬이 좌측으로 밀린다. */

.bulk-action-bar[b-1fvsdpefv1] {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1040;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 12px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .15);
    padding: 10px 20px;
    max-width: calc(100vw - 32px);
    transition: transform .2s ease;
}

.bulk-bar-inner[b-1fvsdpefv1] {
    display: flex;
    align-items: center;
    gap: 16px;
}

.bulk-count[b-1fvsdpefv1] {
    font-size: 13px;
    font-weight: 500;
    color: var(--vz-primary);
    white-space: nowrap;
}

.bulk-actions[b-1fvsdpefv1] {
    display: flex;
    gap: 8px;
}

/* 권한으로 막힌 버튼 — 2026-09-01 야간 17회차 fix (PLM-20260901-22 ①).
   ⛔⛔ `disabled` 를 쓰지 않는다. disabled 는 탭 순서에서 빠지고 focus() 도 못 받아
      사유(title)를 «마우스 없이는 영영 못 읽는» 상태가 된다. 그래서 aria-disabled 로 바꾸고
      «보이는 표시»만 여기서 준다 — 실제 차단은 핸들러(BlockedBy)와 서비스 게이트가 한다.
   ⛔ pointer-events:none 을 주지 마라 — 그러면 클릭이 안 잡혀 «사유 안내»도 못 띄운다. */
.jk-act-blocked[b-1fvsdpefv1] {
    opacity: .55;
    cursor: not-allowed;
}

/* ⛔ 2026-09-03 — 삭제 «확인»은 공용 확인 모달(JkConfirmService)로 갔다. 이 파일에 남은
     대화상자 스타일은 없다(이동 대화상자도 <JkDialog> 의 격리 CSS 를 탄다).
   ⛔ 2026-09-01 — .jk-dialog* / .jk-bulk-notice 규칙을 여기서 걷어냈다.
     · 대화상자 마크업은 공용 <JkDialog> 로 옮겼다(격리 CSS 라 규칙도 JkDialog.razor.css 로 함께 간다).
       손으로 backdrop 을 그리면 role·이름·포커스 트랩이 또 빠진다 — 그게 PLM-20260901-16/-17 이었다.
     · 인라인 알림(.jk-bulk-notice)은 공용 토스트(JkToastHost)로 대체했다. pointer-events:none 에
       4초 자동 소멸, aria-live 도 없어 «결과가 있었는지»를 사용자도 검증자도 알 수 없었다
       (PLM-20260901-20 「아무 말도 안 한다」). */
/* /Components/Shared/CardGrid/JkDmsCardContextMenu.razor.rz.scp.css */
/* 우클릭 메뉴가 여는 «작은 대화상자» — 이름 변경(입력) · 폴더 고르기(목록) · PLM Sync 안내(링크).
   ⛔ alert()/prompt() 를 쓰지 않는다(전사 규칙) — 그 자리를 대신하는 최소 UI 다.
   ⛔⛔ 「예/아니오」 두 버튼짜리 «확인»은 여기 없다. 2026-09-03 지시로 공용 확인 모달
      (JkConfirmService + JkConfirmHost)이 받는다 — 도면 연결 해제가 그 자리였다.
      확인창을 이 CSS 위에 다시 지으면 Enter/Esc·포커스 복귀가 또 빠진다.
   ⛔ 메뉴 자체(.context-menu / .dropdown-item)의 스타일은 wwwroot/jk-shell.css 에 이미 있다. */

.jk-dialog-backdrop[b-pw8dv3jxrz] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .45);
    display: flex;
    align-items: center;
    justify-content: center;
    /* ⛔ 이 대화상자는 «우클릭 메뉴가» 여는 것이라 메뉴(2101)보다 위여야 한다.
       모달(2000) 안에서 메뉴를 열 수 있으므로 1080 으로는 모달 뒤로 깔린다(2026-09-01). */
    z-index: 2200;
}

.jk-dialog[b-pw8dv3jxrz] {
    background: var(--vz-card-bg, #fff);
    border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .2);
    width: 100%;
    max-width: 420px;
    margin: 1rem;
    display: flex;
    flex-direction: column;
}

.jk-dialog-head[b-pw8dv3jxrz] {
    padding: 10px 14px;
    font-weight: 600;
    font-size: 13px;
    background: var(--vz-primary-bg-subtle, #dff0fa);
    border-bottom: 1px solid var(--vz-border-color);
    border-radius: 8px 8px 0 0;
}

.jk-dialog-body[b-pw8dv3jxrz] { padding: 14px; }

.jk-dialog-foot[b-pw8dv3jxrz] {
    padding: 10px 14px;
    border-top: 1px solid var(--vz-border-color);
    display: flex;
    justify-content: flex-end;
    gap: 6px;
}

/* 카테고리 고르기 — 정본 DmsCategoryPickerModal.svelte <style>(150~174행) 값 «그대로».
   ⛔ 정본에서 스코프 안이라 global.css 에 «0건»이다. 폭·z-index·높이를 새로 고르지 마라.
   ⛔ .card / .card-header / .card-body / .card-footer 는 Velzon 전역 규칙을 그대로 탄다 —
      여기서 다시 정의하지 않는다(정본도 정의하지 않는다). */
/* ⛔⛔ 같은 이름이 «전역»(wwwroot/jk-shell.css:506~507)에도 있다 — 그건 정본의 «파일 피커»
      (DmsDocPicker.svelte) 것인데 추출본이 전역으로 풀어 놓은 것이다. 정본에서는 스코프가 달라
      서로 안 닿지만 여기서는 닿는다. 스코프 선택자(.picker-dialog[b-...])가 특정성으로 이기므로
      «내가 적은 속성»은 안전하고, 안 적은 속성만 전역 값이 샌다. 그래서 아래 두 줄을 «일부러» 적는다:
        · height: auto  ← 전역이 82vh 를 준다(안 적으면 대화상자가 화면 높이만큼 늘어난다)
        · backdrop-filter: none ← 전역이 blur(2px) 를 준다(정본 카테고리 피커에는 없다) */
.picker-backdrop[b-pw8dv3jxrz] {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1090;
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

.picker-dialog[b-pw8dv3jxrz] {
    width: 460px;
    max-width: 90vw;
    height: auto;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}

/* ⛔ 트리가 길어도 대화상자가 화면을 넘지 않게 — 스크롤은 «트리»가 진다(정본과 같다). */
.category-tree[b-pw8dv3jxrz] {
    max-height: 420px;
    overflow-y: auto;
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    padding: 4px 0;
}

/* ⛔ .jk-pick-* 규칙은 2026-08-31 에 JkDmsPickerTree.razor.css 로 «옮겼다».
      여기 두면 CSS 격리 때문에 한 줄도 안 걸린다 — 그 노드를 그리는 것은 이 컴포넌트가 아니라
      JkDmsPickerTree 라서다(scope 속성이 다르다). 되돌리지 마라. */
/* 동작 결과 알림은 «공용 토스트 큐»(JkToastService, 공용부 계약 §1)가 그린다.
   ⛔⛔ 여기 있던 .jk-action-notice(고정 배치 .alert)를 되살리지 마라 — 2026-08-30 실측에서
      그 상자가 사라지지 않아 아래 메뉴 항목이 영영 안 눌렸다. 자동 소멸은 큐의 책임이다. */

/* ⛔ .sim-backdrop / .sim-dialog 는 wwwroot/app.css 로 옮겼다 —
      이 모달 껍데기를 «두 곳»이 쓴다(카드 우클릭 모달 + /dms/similar 라우트).
      화면 스코프 CSS 로 두면 라우트 쪽에 한 줄도 안 걸린다. 되돌리지 마라. */

/* ⛔ .sim-header / .sim-body / .sim-footer 규칙은 «여기 두면 안 된다» — 그 element 를 그리는 것은
      이 컴포넌트가 아니라 JkSimilarDrawingsPanel 이라 CSS 격리 scope 가 달라 한 줄도 안 걸린다.
      정본 값 그대로 JkSimilarDrawingsPanel.razor.css 에 있다. 되돌리지 마라. */
/* /Components/Shared/CardGrid/JkDmsCardGrid.razor.rz.scp.css */
/* 카드 그리드 자체의 배치는 wwwroot/jk-shell.css(.dms-grid / .dms-grid-wrapper / .empty-state)에 있다.
   여기에는 «드롭 업로드를 켰을 때만» 필요한 한 줄만 둔다.

   ⛔⛔ 드롭존을 새 <div> 로 감싸지 않은 이유가 이것이다. 정본의 .dms-dropzone-wrapper 는
      flex:1 + min-height:0 이라, 그 래퍼를 임베디드 그리드(수주·프로젝트 상세)에까지 무조건
      씌우면 높이 계산이 조용히 달라진다. 오버레이가 필요로 하는 것은 «위치 기준»뿐이므로
      이미 있는 컨테이너에 position:relative 만 얹는다. */

.jk-dropzone[b-vrmscvo36h] {
    position: relative;
}
/* /Components/Shared/CardGrid/JkDmsCardTile.razor.rz.scp.css */
/* 카드 «호버 상태» 두 가지 — 정본에서는 JS 상태였다(DmsCard.svelte: hovering · scaled).
   ⛔⛔ 회로로 올리지 않는 이유: 카드 100장이면 마우스가 지날 때마다 왕복이 100번 생긴다.
      정본과 결과가 같은 것만 CSS 로 옮겼다.
   ⛔ jk-shell.css 는 생성물이라 고치지 않는다 — 그래서 «동반 CSS»(격리 스타일)로 둔다. */

/* ① 체크박스: 정본은 hover || selected 일 때만 «렌더»했다. 여기서는 항상 렌더하고 보이기만 가른다. */
.card-checkbox[b-v6xv3rogw1] {
    display: none;
    /* ⛔⛔ 2026-09-03 QA #35 — 감싸는 div 가 «인라인 정렬 여백»만큼 체크박스보다 크다(아래 4px 쯤).
       그 죽은 띠를 누르면 이벤트가 카드로 흘러 카드 클릭(= 단일 선택)이 되고 이전 선택이 통째로 풀린다.
       상자를 입력칸에 딱 맞춰 그 틈을 없앤다(카드 클릭 규칙 자체는 건드리지 않는다). */
    line-height: 0;
    font-size: 0;
}

.dms-card:hover .card-checkbox[b-v6xv3rogw1],
.dms-card.selected .card-checkbox[b-v6xv3rogw1] {
    display: block;
}

/* ② 확대: 여기서 하지 않는다 — JkDmsCardGrid.razor.js 가 500ms 뒤 .scaled 를 «붙인다»
      (정본 DmsCard.svelte:143~150 의 hoverTimer 와 같은 축). 스타일은 jk-shell.css:11
      `.dms-card.scaled` 하나뿐이다.

   ⛔⛔ 종전에는 여기서 «.dms-card:hover 에 transform scale 1.05 + transition-delay .5s» 로
      흉내를 냈다. 겉보기 결과는 비슷하지만 축이 다르다 — 마퀴 드래그를 시작해도 마우스가
      카드 위에 있는 한 :hover 가 유지되어 확대가 «안 풀린다». 확대된 카드는 실제 사각형이
      1.05배라 마퀴 히트 판정(getBoundingClientRect)이 어긋나 이웃 카드가 함께 잡힌다.
      JS 는 mousedown 에서 확대를 먼저 되돌린다 — 그 판단을 CSS 로는 표현할 수 없다.
   ⛔ 되돌리려거든 그 함정부터 다시 읽어라. 값(scale 1.05 / z-index 10 / 그림자)은
      jk-shell.css 의 .dms-card.scaled 가 단일 진실원이다. */
/* /Components/Shared/CardGrid/JkDmsDropOverlay.razor.rz.scp.css */
/* 드롭 하이라이트 · 업로드 진행 — 정본 DmsDropZone.svelte <style> 의 값 그대로.

   ⛔ wwwroot/jk-shell.css 에 옮겨진 `.dms-drop-overlay` 를 쓰지 않는다. 그쪽은
      `animation: svelte-14aywcs-dropFadeIn` 을 참조하는데 «그 @keyframes 가 같이 옮겨지지 않았다»
      (jk-shell.css:591·629 — 이름만 남고 정의가 없다). 참조가 없는 애니메이션은 에러 없이
      그냥 «아무 일도 안 한다» — 여기서는 정의까지 들고 온다.
   ⛔ 색·반경·그림자 값을 새로 고르지 마라(전사 디자인 표준). 정본 값을 그대로 옮긴 것이다. */

.jk-drop-overlay[b-ppkmngvsi6] {
    position: absolute;
    inset: 0;
    z-index: 1050;
    background: rgba(64, 81, 137, .12);
    border: 3px dashed var(--vz-primary);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    animation: jkDropFadeIn-b-ppkmngvsi6 .15s ease;
}

@keyframes jkDropFadeIn-b-ppkmngvsi6 {
    from { opacity: 0; }
    to { opacity: 1; }
}

.jk-drop-overlay-content[b-ppkmngvsi6] {
    text-align: center;
    color: var(--vz-body-color);
    padding: 2rem;
    background: var(--vz-card-bg, #fff);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, .15);
}

.jk-drop-icon[b-ppkmngvsi6] {
    font-size: 3rem;
    color: var(--vz-primary);
}

/* 진행 표시 — 우하단 고정.
   ⛔⛔ pointer-events:none 이다. 고정 배치 상자가 클릭을 가로막으면 그 아래를 «영영 못 누른다»
      (2026-08-30 실측: 우클릭 메뉴 알림이 같은 사고를 냈다). */
.jk-upload-progress[b-ppkmngvsi6] {
    pointer-events: none;
    position: fixed;
    right: 16px;
    bottom: 64px;
    z-index: 1200;
    width: 320px;
    max-width: calc(100vw - 32px);
    padding: 10px 12px;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, .15);
    font-size: 13px;
}

.jk-upload-head[b-ppkmngvsi6] {
    display: flex;
    align-items: center;
    min-width: 0;
}

/* ⛔ 파일명이 길면 상자가 화면 밖으로 늘어난다 — 잘라 준다. */
.jk-upload-name[b-ppkmngvsi6] {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Shared/CardGrid/JkDmsPickerTree.razor.rz.scp.css */
/* 카테고리 선택 트리 — 정본 DmsCategoryPickerNode.svelte <style>(62~98행) 값 «그대로».
   ⛔ 정본에서 이 규칙들은 Svelte 스코프 안이라 global.css 추출본에 «0건»이다. 값을 새로 고르지 마라.

   ⛔⛔ 이 파일이 «없어서» 이 트리는 무스타일로 떠 있었다(2026-08-31 실측).
   Blazor 의 CSS 격리는 «컴포넌트 단위»다. 규칙이 소비처(JkDmsCardContextMenu.razor.css)에 있으면
   그 소비처의 scope 속성이 붙은 요소에만 걸리는데, 노드를 그리는 것은 «이 컴포넌트»라
   scope 가 달라 한 줄도 적용되지 않는다. 에러도 경고도 없다 — 모양만 틀린다. */

.category-node[b-azfbmfr82f] {
    display: flex;
    align-items: center;
    padding: 5px 8px;
    cursor: pointer;
    font-size: 13px;
    user-select: none;
}

.category-node:hover:not(.disabled)[b-azfbmfr82f] {
    background: var(--vz-tertiary-bg);
}

.category-node.selected[b-azfbmfr82f] {
    background: var(--vz-primary-bg-subtle, #e0e7ff);
    /* ⛔ 정본은 600 이다. 전사 규칙(폰트 굵기 ≤ 500)에 맞춰 500 으로 «일부러» 낮춘 한 줄이다. */
    font-weight: 500;
}

.category-node.disabled[b-azfbmfr82f] {
    color: var(--vz-secondary-color);
    cursor: not-allowed;
    opacity: 0.6;
}

.tree-toggle[b-azfbmfr82f] {
    background: none;
    border: none;
    padding: 0 2px;
    color: var(--vz-secondary-color);
    cursor: pointer;
}

.tree-toggle-placeholder[b-azfbmfr82f] {
    display: inline-block;
    width: 18px;
}

.node-name[b-azfbmfr82f] {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ⛔ 정본에 없는 «건수 배지» — 사이드바 트리와 같은 정보를 그 자리에 둔 것이다.
      이름이 늘어나야 배지가 오른쪽으로 밀린다(.node-name flex:1 이 그 역할). */
.jk-pick-count[b-azfbmfr82f] {
    margin-left: auto;
    font-size: 13px;
    color: var(--vz-secondary-color);
    background: var(--vz-light);
    padding: 0 5px;
    border-radius: 8px;
}
/* /Components/Shared/Confirm/JkConfirmHost.razor.rz.scp.css */
/* 확인·알림 모달 표시대 — 껍데기(JkModal)의 값은 그대로, «다른 모달 위»에 뜨는 것만 여기서 정한다.
   이 셸의 판들: JkModal 백드롭 2000 · 토스트 2000 · .detail-overlay 2050 · .picker-backdrop 2080 ·
   .approval-detail-backdrop 2100 · .edit-confirm-backdrop 2110 · .jk-dialog-backdrop 2200.
   확인창은 «그 전부 위»여야 한다 — 어느 판 안에서 삭제를 물어도 뒤로 숨으면 안 된다(2026-09-03 실측 표). */
.jk-confirm-host[b-dnq0stmdis]  .jk-modal-backdrop {
    z-index: 2210;
}

.jk-confirm-host[b-dnq0stmdis]  .jk-confirm-msg {
    white-space: pre-line;
    word-break: break-word;
    font-size: 13px;
    line-height: 1.55;
}

.jk-confirm-host[b-dnq0stmdis]  .jk-confirm-detail {
    margin-top: 6px;
    white-space: pre-line;
    word-break: break-word;
    font-size: 12px;
    color: var(--vz-secondary-color, #878a99);
}

.jk-confirm-host[b-dnq0stmdis]  .jk-confirm-body {
    margin-top: 10px;
}

/* 기본 버튼은 «포커스가 보여야» 한다 — Enter 가 무엇을 누를지 눈으로 알 수 있게. */
.jk-confirm-host[b-dnq0stmdis]  .jk-modal-foot button:focus-visible {
    outline: 2px solid var(--vz-primary, #405189);
    outline-offset: 2px;
}
/* /Components/Shared/DetailOverlay/JkDmsDetailOverlay.razor.rz.scp.css */
/* 파일 상세 오버레이의 «자기 것»만. 본체 모양(.detail-*)은 wwwroot/jk-shell.css 에 추출돼 있다 —
   여기서 다시 정의하지 마라(클래스 이름을 바꾸면 스타일이 조용히 사라진다). */

/* ══ 복사 대상 카테고리 고르기 — 2026-09-02 ═══════════════════════════════════
   ⛔⛔ 이 판은 «전역» .picker-backdrop/.picker-dialog(jk-shell.css:514~515)를 탄다.
      그건 정본의 «파일 피커»(DmsDocPicker) 값이라 height:82vh + blur 가 딸려 온다 —
      카테고리 피커에는 둘 다 맞지 않는다. 우클릭 메뉴의 같은 판(JkDmsCardContextMenu.razor.css:72)
      이 이미 같은 이유로 값을 다시 적고 있다. «같은 값»을 쓴다 — 두 판이 달라 보이면 그게 회귀다.
   ⛔ 값을 새로 고르지 마라. */
.picker-dialog[b-80rqmlz6wl] {
    width: 460px;
    max-width: 90vw;
    height: auto;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}

.picker-backdrop[b-80rqmlz6wl] {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

/* ⛔⛔ 2026-09-02 지적(「카테고리가 길면 아래가 안 보인다」) — 스크롤을 «트리»가 진다.
   전역 .picker-dialog 에 overflow:hidden 이 있어, 트리가 스스로 스크롤하지 않으면
   넘친 카테고리는 «그냥 잘린다»(스크롤바도 안 생긴다). 우클릭 메뉴 쪽과 같은 규칙이다. */
.category-tree[b-80rqmlz6wl] {
    max-height: 420px;
    overflow-y: auto;
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    padding: 4px 0;
}
/* /Components/Shared/DetailOverlay/JkViz3dBomNode.razor.rz.scp.css */
/* 정본: Viz3dBomNode.svelte <style> (110~136행) — 값 그대로 옮겼다.
   ⛔ Blazor 스코프 CSS 라 부모(JkViz3dPanel)의 규칙이 여기까지 오지 않는다 —
      노드 행 스타일은 이 파일이 «원본»이다. 부모 쪽에는 트리 컨테이너/목록만 남긴다.
      (정본도 같은 이유로 두 파일에 나눠 뒀다.) */

.v3-tree-list[b-a1ec7vam6o] { list-style: none; margin: 0; padding: 0; }

.v3-node[b-a1ec7vam6o] { display: flex; align-items: center; }
/* 선택 표시 = 연한 배경 + 왼쪽 강조선. 앱의 .jk-sel 과 같은 언어다. */
.v3-node.sel[b-a1ec7vam6o] { background: var(--vz-primary-bg-subtle, #eaf2fb); box-shadow: inset 3px 0 0 var(--vz-primary, #1a6fc4); }

.v3-caret[b-a1ec7vam6o],
.v3-caret-spacer[b-a1ec7vam6o] {
    flex: 0 0 20px; width: 20px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: var(--vz-secondary, #5d6a78);
    cursor: pointer; padding: 0;
}
.v3-caret-spacer[b-a1ec7vam6o] { cursor: default; }

.v3-node-btn[b-a1ec7vam6o] {
    flex: 1 1 auto; min-width: 0;
    display: flex; align-items: center; gap: 5px;
    border: 0; background: transparent; text-align: left;
    padding: 4px 6px 4px 0; font-size: 12px; color: var(--vz-body-color, #1f2f3e); cursor: pointer;
}
.v3-node-btn:hover[b-a1ec7vam6o] { color: var(--vz-primary, #1a6fc4); }

/* ⛔ 부모 목록이 min-width:max-content 라 여기서 줄이지 않는다 — 깊은 노드도 이름이 다 보이고
   패널을 넘치면 트리가 가로로 스크롤된다(잘라서 감추지 않는다). */
.v3-node-name[b-a1ec7vam6o] { white-space: nowrap; }

/* 수량 — 배지가 아니라 «값»이다. 눈에 띄되 배지들과 구분되게 단색 텍스트로 둔다. */
.v3-qty[b-a1ec7vam6o] { flex: 0 0 auto; font-size: 11px; font-weight: 500; color: var(--vz-secondary, #5d6a78); }

.v3-badge[b-a1ec7vam6o] { flex: 0 0 auto; font-size: 11px; padding: 0 4px; border-radius: 8px; background: var(--vz-warning-bg-subtle, #fdf3e3); color: var(--vz-warning, #b26a00); }
/* 이관됨 = 완료 상태라 success. 「3D 없음」(주의)과 색으로도 갈린다. */
.v3-badge-ok[b-a1ec7vam6o] { background: var(--vz-success-bg-subtle, #e8f6ee); color: var(--vz-success, #0ab39c); }
/* 문서 없음 = 정상 상태일 수 있다(구매품). 경고색을 쓰지 않는다. */
.v3-badge-mute[b-a1ec7vam6o] { background: var(--vz-light, #f3f6f9); color: var(--vz-tertiary-color, #878a99); }
/* /Components/Shared/DetailOverlay/JkViz3dPanel.razor.rz.scp.css */
/* 정본: Viz3dPanel.svelte <style> (1092~1231행) — 값 그대로 옮겼다.
   ⛔ 새 디자인을 짓지 않았다. 색·간격은 전부 앱 토큰(--vz-*)이다.
   ⛔ 노드 «행» 스타일은 여기 없다 — JkViz3dBomNode.razor.css 가 원본이다(스코프가 안 미친다).
   ⛔ 이 파일은 «JS 가 만든 자식»에 닿지 않는다. 다행히 이 패널에는 그런 자식이 없다
      (iframe 내부는 벤더의 jk-theme.css 가 맡는다). ::deep 을 쓸 자리가 없다. */

.v3-wrap[b-kxa73b8xt5] {
    position: relative; display: flex; flex-direction: column;
    width: 100%; height: 100%; background: var(--vz-card-bg, #fff);
}

/* 툴바 — 앱의 세그먼트 언어를 따르되 아이콘 밀도가 높아 자체 클래스를 쓴다. */
.v3-toolbar[b-kxa73b8xt5] {
    flex: 0 0 auto;
    display: flex; align-items: center; gap: 2px;
    padding: 6px 8px;
    border-bottom: 1px solid var(--vz-border-color, #e6eaef);
    background: var(--vz-card-bg, #fff);
    overflow-x: auto; white-space: nowrap;
}
.v3-btn[b-kxa73b8xt5] {
    border: 1px solid transparent; background: transparent;
    border-radius: 6px; padding: 4px 7px;
    font-size: 13px; line-height: 1.2; color: var(--vz-secondary, #5d6a78);
    cursor: pointer; flex: 0 0 auto;
}
.v3-btn-text[b-kxa73b8xt5] { min-width: 30px; }
.v3-btn:hover:not(:disabled)[b-kxa73b8xt5] { background: var(--vz-light, #f3f6f9); color: var(--vz-primary, #1a6fc4); }
.v3-btn.on[b-kxa73b8xt5] { background: var(--vz-primary-bg-subtle, #eaf2fb); color: var(--vz-primary, #1a6fc4); border-color: var(--vz-primary-border-subtle, #cfe2f7); }
/* ⛔ 로딩 중 비활성은 «형태로도» 보여야 한다 — 색만 흐리면 「왜 안 눌리지」가 된다. */
.v3-btn:disabled[b-kxa73b8xt5] { opacity: 0.4; cursor: not-allowed; }

.v3-select[b-kxa73b8xt5] { font-size: 13px; padding: 3px 6px; border: 1px solid var(--vz-border-color, #e6eaef); border-radius: 6px; background: #fff; }
.v3-select:disabled[b-kxa73b8xt5] { opacity: 0.4; cursor: not-allowed; }

.v3-sep[b-kxa73b8xt5] { width: 1px; height: 16px; background: var(--vz-border-color, #e6eaef); margin: 0 4px; flex: 0 0 auto; }
.v3-label[b-kxa73b8xt5] { font-size: 12px; color: var(--vz-tertiary-color, #878a99); margin-right: 2px; }
.v3-status[b-kxa73b8xt5] { font-size: 12px; color: var(--vz-secondary-color, #5d6a78); display: flex; align-items: center; }
/* 브리지 오류 — 정본에는 그리는 자리가 없었다(담아만 뒀다). 작게, 그러나 «말한다». */
.v3-status-warn[b-kxa73b8xt5] { color: var(--vz-warning, #b26a00); }

.v3-body[b-kxa73b8xt5] { flex: 1 1 auto; display: flex; min-height: 0; }

/* ── BOM 트리 ─────────────────────────────────────────────────────────── */
.v3-tree[b-kxa73b8xt5] {
    flex: 0 0 220px; width: 220px;
    border-right: 1px solid var(--vz-border-color, #e6eaef);
    background: var(--vz-card-bg, #fff);
    /* 머리(제목+이관 버튼)는 고정, 목록만 스크롤한다. ⛔ 통째로 overflow 를 주면
       가로 스크롤 시 머리가 옆으로 밀려 나간다(sticky top 은 세로만 잡는다). */
    display: flex; flex-direction: column; min-height: 0; overflow: hidden;
}
.v3-tree-head[b-kxa73b8xt5] {
    flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
    padding: 6px 8px 6px 10px; font-size: 12px; font-weight: 500;
    color: var(--vz-tertiary-color, #878a99);
    border-bottom: 1px solid var(--vz-border-color, #e6eaef); background: inherit;
}
.v3-tree-title[b-kxa73b8xt5] { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v3-tree-act[b-kxa73b8xt5] {
    flex: 0 0 auto; display: inline-flex; align-items: center; gap: 3px;
    border: 1px solid var(--vz-primary-border-subtle, #cfe2f7); border-radius: 6px;
    background: var(--vz-primary-bg-subtle, #eaf2fb); color: var(--vz-primary, #1a6fc4);
    font-size: 11px; font-weight: 400; padding: 2px 6px; cursor: pointer;
    white-space: nowrap; text-decoration: none;
}
.v3-tree-act:hover[b-kxa73b8xt5] { background: var(--vz-primary, #1a6fc4); color: #fff; }
/* ⛔ 깊은 노드에서 이름이 잘리지 않게 목록은 «내용 폭»을 갖고, 넘치면 가로로 스크롤한다. */
.v3-tree-scroll[b-kxa73b8xt5] { flex: 1 1 auto; min-height: 0; overflow: auto; }
.v3-tree-msg[b-kxa73b8xt5] { padding: 12px 10px; font-size: 12px; color: var(--vz-secondary-color, #5d6a78); }
.v3-sel-msg[b-kxa73b8xt5] { padding: 8px 10px; font-size: 11px; background: var(--vz-warning-bg-subtle, #fdf3e3); color: var(--vz-warning, #b26a00); position: sticky; left: 0; }
.v3-tree-list[b-kxa73b8xt5] { list-style: none; margin: 0; padding: 0; min-width: max-content; }

/* ── 뷰어 ─────────────────────────────────────────────────────────────── */
.v3-view[b-kxa73b8xt5] { flex: 1 1 auto; min-width: 0; position: relative; }
.v3-frame[b-kxa73b8xt5] { width: 100%; height: 100%; border: none; display: block; }
.v3-hint[b-kxa73b8xt5] { position: absolute; left: 8px; bottom: 8px; font-size: 12px; color: var(--vz-secondary-color, #5d6a78); background: rgba(255, 255, 255, 0.9); padding: 3px 8px; border-radius: 6px; }

/* ── 파트 상세 모달 ──────────────────────────────────────────────────────
   뷰어 «안»에 겹치는 작은 모달이다(오버레이 안이라 Bootstrap modal 을 쓰지 않는다). */
.v3-modal-backdrop[b-kxa73b8xt5] { position: absolute; inset: 0; background: rgba(31, 47, 62, 0.35); z-index: 5; }
.v3-modal[b-kxa73b8xt5] {
    position: absolute; z-index: 6; top: 50%; left: 50%; transform: translate(-50%, -50%);
    /* ⛔ 폭은 «패널 안»에서 최대한 넓게. 속성 이름이 길어 좁은 폭에서는 값이 다음 줄로 넘어간다.
       calc(100% - 24px) 가 함께 걸려 있어 패널이 좁아도 뷰어 밖으로 나가지 않는다 —
       고정폭으로 바꾸지 마라. */
    width: min(1040px, calc(100% - 24px));
    background: #fff; border-radius: 10px; border: 1px solid var(--vz-border-color, #e6eaef);
    box-shadow: 0 12px 32px rgba(31, 47, 62, 0.18); overflow: hidden;
}
/* ⛔ 드래그로 옮긴 뒤에는 JS 가 transform:none + left/top 을 «인라인으로» 쓴다.
   여기에 .moved 클래스를 다시 만들지 마라 — 좌표 주인이 둘이 된다. */
.v3-modal-head[b-kxa73b8xt5] {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 10px 12px; border-bottom: 1px solid var(--vz-border-color, #e6eaef);
    font-weight: 500; font-size: 14px;
    /* ⛔ cursor:move 로 «잡을 수 있다»는 걸 보여준다 — 안 그러면 아무도 못 찾는다. */
    cursor: move; user-select: none;
}
/* ⛔⛔ 좌: 이미지 / 우: 상세정보. 오른쪽이 남는 폭을 다 먹는다.
   minmax(0,1fr) 이어야 긴 값이 열을 밀지 않는다(1fr 만 쓰면 최소 콘텐츠 폭이 바닥이 된다).
   ⛔ 스크롤은 «오른쪽 열»이 한다 — 바깥이 스크롤되면 이미지가 같이 밀려 올라가
      「보면서 비교」가 안 된다(2단으로 만든 이유가 사라진다). */
.v3-modal-body[b-kxa73b8xt5] {
    padding: 12px; display: grid; gap: 14px; align-items: start;
    /* ⛔ 이미지 열을 «고정폭으로 두지 마라». 모달 폭이 패널에 갇혀 좁아지면 상세가 안 보인다. */
    grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
    max-height: min(72vh, 620px); overflow: hidden;
}
/* 썸네일이 없으면 1단 — 빈 왼쪽 칸을 남기지 않는다. */
.v3-modal-body.only-info[b-kxa73b8xt5] { grid-template-columns: minmax(0, 1fr); }
.v3-modal-info[b-kxa73b8xt5] { min-width: 0; max-height: min(72vh, 620px); overflow-y: auto; padding-right: 2px; }
.v3-thumb[b-kxa73b8xt5] {
    margin: 0; border: 1px solid var(--vz-border-color, #e6eaef); border-radius: 8px;
    background: var(--vz-tertiary-bg, #f7f8fa); overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    height: min(58vh, 460px);
}
.v3-thumb img[b-kxa73b8xt5] { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

.v3-attr-head[b-kxa73b8xt5] { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; color: var(--vz-secondary-color, #5d6a78); margin: 4px 0 6px; padding-top: 8px; border-top: 1px solid var(--vz-border-color, #e6eaef); }
.v3-attr-msg[b-kxa73b8xt5] { font-size: 12px; color: var(--vz-tertiary-color, #878a99); padding: 2px 0 8px; }
.v3-attr-toggle[b-kxa73b8xt5] { border: 0; background: transparent; padding: 2px 0 6px; font-size: 12px; color: var(--vz-secondary-color, #5d6a78); cursor: pointer; display: flex; align-items: center; gap: 4px; }
.v3-attr-toggle:hover[b-kxa73b8xt5] { color: var(--vz-primary, #1a6fc4); }

.v3-modal-foot[b-kxa73b8xt5] { display: flex; justify-content: flex-end; gap: 6px; padding: 10px 12px; border-top: 1px solid var(--vz-border-color, #e6eaef); }

/* ⛔⛔ 이름 열 «고정폭» + 값 열 유동(minmax(0,1fr)). `1fr` 만 쓰면 최소 콘텐츠 폭이 바닥이 되어
   긴 값이 열을 밀어내고 이름과 겹쳐 보인다 — 실제 신고(「속성이름, 값이 겹치거나」)의 원인.
   ⛔ 두 칸 모두 min-width:0 + nowrap + ellipsis 여야 말줄임이 실제로 걸린다. 전체 값은 title 로. */
.v3-dl[b-kxa73b8xt5] { display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 6px 10px; margin: 0 0 10px; font-size: 13px; }
.v3-dl dt[b-kxa73b8xt5],
.v3-dl dd[b-kxa73b8xt5] { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v3-dl dt[b-kxa73b8xt5] { color: var(--vz-secondary-color, #5d6a78); font-weight: 400; }
.v3-dl dd[b-kxa73b8xt5] { margin: 0; color: var(--vz-body-color, #1f2f3e); }
/* ⛔⛔ 반드시 `.v3-dl.v3-dl-attr` 로 «특이도 2»를 줘야 한다. `.v3-dl-attr` 하나만 쓰면
   위 `.v3-dl` 규칙과 같은 특이도라 선언 순서로 갈린다(정본에서 한 번 이 함정에 빠졌다). */
.v3-dl.v3-dl-attr[b-kxa73b8xt5] { grid-template-columns: clamp(110px, 42%, 240px) minmax(0, 1fr); }

@media (max-width: 768px) {
    .v3-tree[b-kxa73b8xt5] { flex-basis: 160px; width: 160px; }
    /* 좁으면 2단을 포기하고 쌓는다 — 좁은 열이 남으면 값 칸이 다시 두 줄로 넘어간다. */
    .v3-modal-body[b-kxa73b8xt5] { grid-template-columns: minmax(0, 1fr); max-height: min(72vh, 620px); overflow-y: auto; }
    .v3-modal-info[b-kxa73b8xt5] { max-height: none; overflow: visible; }
    .v3-thumb[b-kxa73b8xt5] { height: 200px; }
}
/* /Components/Shared/DmsAiPanel/JkDmsAiPanel.razor.rz.scp.css */
/*
    문서함 AI 패널 — 정본 DmsAiPanel.svelte 의 <style>(700~757행) 중 «아직 없는 것»만.

    ⛔⛔ 여기서 다시 만들지 않는 것 — wwwroot/jk-shell.css 에 «이미» 있다(594~597 · 622행):
       .dms-ai-panel · .dms-ai-panel-inner · .dms-search-list · .dms-search-item(:hover)
       두 벌이 되면 어느 쪽이 이기는지 로드 순서에 달린다.

    ⛔ ::deep 을 쓰는 이유 — 스코프 CSS 는 «이 컴포넌트가 그린 요소»에만 b-xxx 속성을 붙인다.
       #aiPanelChat 안의 자손 선택자는 그대로 두면 자손에 속성이 없어 안 걸린다.
*/

/* QA시트 #5 — 입력창 2줄 확대. resize 손잡이를 숨기고 줄바꿈은 Shift+Enter 로만.
   ⛔ 정본의 계산식 그대로다. rows="2" 만으로는 부트스트랩 line-height 가 이겨 한 줄로 눌린다. */
.ai-question-input[b-fh2vrf1lo2] {
    resize: none;
    line-height: 1.45;
    min-height: calc(1.45em * 2 + 12px);
}

/* ⛔⛔ QA시트 #13 — 대화 내용 텍스트 드래그 선택 허용.
   조상(.dms-layout.dragging · 카드 그리드)이 user-select:none 을 걸어 두는 구간이 있어
   그걸 «무력화»하는 것이 이 규칙의 목적이다. 빼면 답변을 복사할 수 없다. */
#aiPanelChat[b-fh2vrf1lo2],
#aiPanelChat[b-fh2vrf1lo2]  * {
    user-select: text;
    -webkit-user-select: text;
}

#aiPanelChat[b-fh2vrf1lo2]  .table {
    font-size: 13px;
}

#aiPanelChat[b-fh2vrf1lo2]  img {
    max-width: 100%;
    height: auto;
}

#aiPanelChat[b-fh2vrf1lo2]  pre {
    font-size: 13px;
    background: var(--vz-tertiary-bg);
    padding: 8px;
    border-radius: 4px;
    overflow-x: auto;
}

#aiPanelChat[b-fh2vrf1lo2]  code {
    font-size: 13px;
}

/* ⛔ 마크다운 렌더러가 «없다» — 답변을 원문 그대로 그린다(주입 경로를 만들지 않으려는 결정).
   그래서 최소한 줄바꿈·목록의 들여쓰기는 살려 준다. JkDetailAiTab 이 내린 것과 같은 처리다.
   ⭐ 렌더러가 붙으면 이 규칙과 마크업 두 곳(msg-user · msg-assistant)만 바꾸면 된다. */
.ai-msg-text[b-fh2vrf1lo2] {
    white-space: pre-wrap;
    word-break: break-word;
}
/* /Components/Shared/DmsSidebar/JkDmsCategoryPermissionModal.razor.rz.scp.css */
/* 카테고리 권한 모달 — 정본 DmsCategoryTree.svelte 의 <style> 블록(648~675행) 값 그대로.
   ⛔ 정본도 Svelte 스코프 스타일이라 전역에 없다. 여기(격리 CSS)가 같은 자리다.
   ⛔ 값을 새로 고르지 마라(폭 720px · z-index 1060 · 배경 45% 는 정본 값이다). */

.perm-modal-backdrop[b-d99jve16r3] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1060;
}

/* 부서 선택은 권한 모달 «위»에 뜬다 — 같은 z-index 면 뒤에 깔려 못 누른다. */
.perm-modal-backdrop-2[b-d99jve16r3] { z-index: 1070; }

.perm-modal-card[b-d99jve16r3] {
    background: var(--vz-secondary-bg);
    border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    width: 100%;
    max-width: 720px;
    margin: 1rem;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
}

.perm-modal-header[b-d99jve16r3] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background: var(--vz-primary-bg-subtle, #dff0fa);
    border-bottom: 1px solid var(--vz-border-color);
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
}

.perm-modal-body[b-d99jve16r3] {
    padding: 16px;
    overflow-y: auto;
    flex: 1;
}

.perm-modal-footer[b-d99jve16r3] {
    padding: 10px 16px;
    border-top: 1px solid var(--vz-border-color);
    text-align: right;
}

/* 대상 칸은 읽기 전용이지만 «눌러서 피커를 여는» 입력이다 — 커서로 그걸 알린다(정본 인라인 style). */
.perm-subject-input[b-d99jve16r3] {
    cursor: pointer;
    background: var(--vz-secondary-bg);
}
/* /Components/Shared/DmsSidebar/JkDmsCategoryTree.razor.rz.scp.css */
/* 카테고리 트리 스타일 — 정본 DmsCategoryTree.svelte 의 <style> 블록 그대로.
   ⛔ 값(패딩·글자 크기·색)을 다시 고르지 마라. 사이드바와 같은 리듬이어야 한다. */

.tree-node[b-0u5m5fqup6] {
    display: flex; align-items: center; gap: 4px;
    padding: 4px 8px; font-size: 13px; cursor: pointer;
    transition: background 0.12s; user-select: none;
    border-radius: 4px; margin: 1px 4px;
}

.tree-node:hover[b-0u5m5fqup6] { background: var(--vz-light); }

.tree-node.active[b-0u5m5fqup6] {
    background: var(--vz-primary-bg-subtle, #dff0fa);
    color: var(--vz-primary);
    font-weight: 600;
}

.tree-toggle[b-0u5m5fqup6] {
    width: 16px; height: 16px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0; font-size: 13px;
    color: var(--vz-secondary-color); border-radius: 3px;
}

.tree-toggle:hover[b-0u5m5fqup6] { background: var(--vz-border-color); }
.tree-toggle-placeholder[b-0u5m5fqup6] { width: 16px; flex-shrink: 0; }
.tree-label[b-0u5m5fqup6] { flex: 1; min-width: 0; }

.tree-count[b-0u5m5fqup6] {
    font-size: 13px; color: var(--vz-secondary-color);
    background: var(--vz-light); padding: 0 5px; border-radius: 8px; flex-shrink: 0;
}

.tree-inline-input[b-0u5m5fqup6] {
    flex: 1; min-width: 0; border: 1px solid var(--vz-primary);
    border-radius: 3px; padding: 1px 6px; font-size: 13px; outline: none; background: white;
}

.tree-add-input[b-0u5m5fqup6] {
    display: flex; align-items: center; gap: 4px; padding: 3px 8px; margin: 1px 4px;
}

/* 「+ 새 폴더」 점선 행 — 실제 폴더 행과 헷갈리지 않게 점선 + 흐린 글자. */
.tree-add-row[b-0u5m5fqup6] {
    display: flex; align-items: center; gap: 4px;
    width: calc(100% - 8px); margin: 1px 4px; padding: 3px 8px;
    font-size: 13px; text-align: left; cursor: pointer;
    color: var(--vz-secondary-color);
    background: none;
    border: 1px dashed var(--vz-border-color);
    border-radius: 4px;
}

.tree-add-row:hover[b-0u5m5fqup6] { color: var(--vz-primary); border-color: var(--vz-primary); }

/* 작업 폴더 배지 — 이름 오른쪽 작은 아이콘. 카운트 배지보다 앞에 온다. */
.tree-workspace-badge[b-0u5m5fqup6] { flex-shrink: 0; font-size: 12px; color: var(--vz-warning); }
/* /Components/Shared/DmsSidebar/JkDmsDeptPickerNode.razor.rz.scp.css */
/* 부서 선택 트리 — 정본 OrgTree.svelte 의 노드 스타일 자리.
   ⛔ 격리 CSS 는 «이 컴포넌트가 그린 요소»에만 붙는다. 그래서 부모(권한 모달)가 아니라 여기 둔다. */

.dept-node[b-azos678nza] {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 5px 8px;
    margin: 1px 4px;
    font-size: 13px;
    cursor: pointer;
    border-radius: 4px;
    user-select: none;
    transition: background 0.12s;
}

.dept-node:hover[b-azos678nza] { background: var(--vz-light); }

.dept-toggle[b-azos678nza] {
    width: 16px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 13px;
    color: var(--vz-secondary-color);
    border-radius: 3px;
}

.dept-toggle:hover[b-azos678nza] { background: var(--vz-border-color); }
.dept-toggle-placeholder[b-azos678nza] { width: 16px; flex-shrink: 0; }

.dept-code[b-azos678nza] {
    margin-left: auto;
    font-size: 12px;
    color: var(--vz-text-muted);
    flex-shrink: 0;
}
/* /Components/Shared/DmsSidebar/JkDmsSidebar.razor.rz.scp.css */
/* DMS 사이드바 스타일 — 정본 DmsSidebar.svelte 의 <style> 블록을 그대로 옮긴 것.
   ⛔ 정본도 Svelte 스코프 스타일이라 전역에 없다. 여기(격리 CSS)가 같은 자리다.
   ⛔ jk-shell.css(생성물)에는 .dms-sidebar / .dms-sidebar-wrapper 만 있다 — 나머지는 여기. */

.dms-sidebar[b-g7tsrenawy] {
    height: 100%;
    overflow-y: auto;
    padding: 0.5rem 0;
}

/* ⛔ 상단 요약 카드(핀·체크아웃·결재 3칸)는 2026-09-04 지시로 제거했다 — 아래 섹션 머리글과 중복이었다. */

.sidebar-section[b-g7tsrenawy] { margin-bottom: 2px; }

.sidebar-section-header[b-g7tsrenawy] {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0.4rem 0.75rem;
    border: none;
    background: none;
    font-size: 13px;
    font-weight: 600;
    color: var(--vz-body-color);
    cursor: pointer;
    transition: background 0.15s;
}

.sidebar-section-header:hover[b-g7tsrenawy] { background: var(--vz-light); }

/* 축 표기 — 라벨보다 한 단 낮게. 홈 KPI 의 .jkia-kpi-axis 와 같은 역할. */
.sidebar-axis[b-g7tsrenawy] {
    font-size: 12px;
    font-weight: 400;
    color: var(--vz-text-muted);
}

.sidebar-list[b-g7tsrenawy] { list-style: none; padding: 0; margin: 0; }

.sidebar-item[b-g7tsrenawy] {
    display: flex;
    align-items: center;
    padding: 0.3rem 0.75rem 0.3rem 1.5rem;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s;
    user-select: none;
}

.sidebar-item:hover[b-g7tsrenawy] { background: var(--vz-light); }

/* QA시트 #12 — 핀 항목 hover 시 우측 해제 버튼 노출 */
.sidebar-item-action[b-g7tsrenawy] {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    padding: 0 2px;
    line-height: 1;
    visibility: hidden;
    flex-shrink: 0;
}

.sidebar-item-actionable:hover .sidebar-item-action[b-g7tsrenawy] { visibility: visible; }
.sidebar-item-action:hover[b-g7tsrenawy] { color: var(--vz-danger); }

.sidebar-item.active[b-g7tsrenawy] {
    background: var(--vz-primary-bg-subtle, #dff0fa);
    color: var(--vz-primary);
    font-weight: 600;
}

.sidebar-tree[b-g7tsrenawy] { padding: 2px 0; }

.tree-node-all[b-g7tsrenawy] {
    display: flex; align-items: center; gap: 4px;
    padding: 5px 12px; margin: 1px 4px;
    font-size: 13px; cursor: pointer;
    border-radius: 4px; user-select: none;
    transition: background 0.12s;
}

.tree-node-all:hover[b-g7tsrenawy] { background: var(--vz-light); }

.tree-node-all.active[b-g7tsrenawy] {
    background: var(--vz-primary-bg-subtle, #dff0fa);
    color: var(--vz-primary);
    font-weight: 600;
}

.sidebar-divider[b-g7tsrenawy] { margin: 0.5rem 0.75rem; border-color: var(--vz-border-color); }


/* 「전체 문서」 우클릭 메뉴 — 트리의 .tree-ctx-menu 와 같은 룩앤필 */
.root-ctx-menu[b-g7tsrenawy] {
    position: fixed;
    z-index: 1055;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    min-width: 200px;
    padding: 4px 0;
}

.root-ctx-item[b-g7tsrenawy] {
    display: flex; align-items: center;
    width: 100%;
    padding: 6px 12px;
    font-size: 13px;
    background: transparent;
    border: none;
    text-align: left;
    cursor: pointer;
    color: var(--vz-body-color);
}

.root-ctx-item:hover[b-g7tsrenawy] { background: var(--vz-light); }

/* 트리 노드 우클릭 메뉴 — 정본 DmsCategoryTree.svelte 의 것과 같은 값.
   ⛔ 이 컴포넌트가 «유일하게» 그리므로(재귀 레벨이 아니라) 여기 둔다. */
.tree-ctx-menu[b-g7tsrenawy] {
    position: fixed; z-index: 1100;
    background: var(--vz-card-bg, #fff); border: 1px solid var(--vz-border-color);
    border-radius: 6px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    padding: 4px 0; min-width: 180px;
}

.tree-ctx-item[b-g7tsrenawy] {
    display: flex; align-items: center; width: 100%;
    padding: 6px 14px; border: none; background: none;
    font-size: 13px; cursor: pointer; text-align: left;
}

.tree-ctx-item:hover[b-g7tsrenawy] { background: var(--vz-light); }
.tree-ctx-divider[b-g7tsrenawy] { height: 1px; background: var(--vz-border-color); margin: 3px 0; }

/* 메뉴 바깥 클릭으로 닫기 — 정본은 svelte:window on:click 이 맡는다.
   ⛔ 회로에 window 리스너를 붙이는 대신 투명 백드롭을 쓴다(같은 결과, 왕복 없음). */
.jk-ctx-backdrop[b-g7tsrenawy] {
    position: fixed;
    inset: 0;
    z-index: 1050;
    background: transparent;
}

/* 체크아웃 취소 확인은 «공용 확인 모달»(JkConfirmService)이 그린다 — 2026-09-03 지시.
   ⛔ .sidebar-confirm / -text / -actions 규칙은 그때 지웠다. 인라인 확인 줄을 다시 만들지 마라
      (여기 목록은 폭이 좁아 두 버튼이 접혔고, 키보드로는 닿지도 않았다). */
/* /Components/Shared/DocPicker/JkDocPickerModal.razor.rz.scp.css */
/* 파일 선택 공용 모달 — 정본 DmsDocPicker.svelte <style> 이식본.
   ⛔⛔ 값은 정본 그대로다(920×620 · 트리 180px). 새로 고르지 마라.
   ⛔ 정본에서 Svelte 스코프 안이라 global.css 에 «0건»이다 — 그래서 여기 collocated 로 둔다.
   ⛔ 트리 노드(.category-node …)는 «자식 컴포넌트»(JkDmsPickerTree)가 그린다. 그 파일엔 .razor.css 가
      없어 스코프 속성이 안 붙는다 — ::deep 으로 닿는다(공용부 계약 §4-B). */

/* ⛔⛔ 2026-09-01 — 백드롭·판·머리·바닥은 «표준 셸»(Shared/Modal/JkModal)이 그린다.
   그 값들이 여기서 그리로 옮겨 갔다(이 모달의 모양이 곧 앱 기준이 됐다).
   ⛔ 여기에 .doc-picker-backdrop / .doc-picker-modal / .doc-picker-header / .doc-picker-footer 를
      다시 만들지 마라 — 기준이 두 벌이 되면 기준이 아니다.

   남은 것은 «이 모달 안쪽»만이다: 검색줄 내용물 · 트리 자리 · 목록 자리 · 고른 파일 칩. */

/* 검색줄 — 바깥 여백·아래 실선은 표준 셸(.jk-modal-subhead)이 이미 준다. 여기서는 «줄 안»만 잡는다. */
.doc-picker-search[b-18odcykjw9] {
    display: flex; align-items: center; gap: 6px;
    width: 100%; min-width: 0;
    color: var(--vz-secondary-color); font-size: 13px;
}
.doc-picker-search input[b-18odcykjw9] { font-size: 13px; min-width: 0; }
.doc-picker-body[b-18odcykjw9] { flex: 1; display: flex; overflow: hidden; }
.doc-picker-tree[b-18odcykjw9] {
    width: 180px; min-width: 160px;
    border-right: 1px solid var(--vz-border-color);
    overflow-y: auto; padding: 6px 0;
    overscroll-behavior: contain;
}
/* ⛔⛔ 트리 노드를 그리는 것은 «자식 컴포넌트»(JkDmsPickerTree)이고,
     그 컴포넌트는 «자기 CSS 파일»을 갖고 있다(.jk-pick-node / .jk-pick-count / .on).
     그러니 여기서 노드 모양을 다시 정의하지 마라 — 두 벌이 되면 한쪽만 늙는다.
   ⛔ 정본의 .picker-tree-* 이름으로 베껴 두면 «한 줄도 안 걸린다»(클래스가 아예 없다).
     여기서는 트리가 앉는 «자리»(폭·스크롤)만 잡는다. */
/* 이 화면이 직접 그리는 「전체」 노드도 자식과 «같은 클래스»를 쓴다 - 그래야 한 줄로 보인다. */
.jk-pick-node[b-18odcykjw9] {
    display: flex; align-items: center; gap: 4px;
    padding: 4px 8px; margin: 1px 0; font-size: 13px;
    border-radius: 4px; cursor: pointer; user-select: none;
}
.jk-pick-node:hover[b-18odcykjw9] { background: var(--vz-light); }
.jk-pick-node.on[b-18odcykjw9] { background: var(--vz-primary-bg-subtle, #dff0fa); color: var(--vz-primary); font-weight: 500; }

.doc-picker-list[b-18odcykjw9] { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.doc-picker-list-body[b-18odcykjw9] {
    flex: 1; overflow-y: auto; padding: 4px 0;
    overscroll-behavior: contain;
}
/* ⛔ 행 목록(.doc-picker-item)은 «없어졌다» — 2026-09-01 지시로 카드 그리드가 대신한다.
   ⛔ 바닥줄(.doc-picker-footer)도 표준 셸의 Footer 가 준다. 둘 다 되살리지 마라. */


/* ══ 고른 파일 목록 — 2026-09-01 지시 ════════════════════════════════════════
   ⛔ 폴더를 옮겨도 «여기»는 남는다. 목록 영역과 푸터 사이에 둔다. */
/* ⛔ 칩 줄이 앉는 «상자»(테두리·배경·최대 높이)는 표준 셸의 PreFooter 가 준다. 여기서는 안쪽만. */
.doc-picker-picked-head[b-18odcykjw9] {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 13px; color: var(--vz-secondary-color); margin-bottom: 4px;
}

.doc-picker-picked-body[b-18odcykjw9] { display: flex; flex-wrap: wrap; gap: 4px; }

.doc-picker-chip[b-18odcykjw9] {
    display: inline-flex; align-items: center; gap: 4px;
    max-width: 240px;
    padding: 2px 6px;
    font-size: 13px;
    border: 1px solid var(--vz-border-color);
    border-radius: 12px;
    background: var(--vz-card-bg, #fff);
}

/* ⛔ 2026-09-01 신설 — 「전체 선택」 머리줄. */
.doc-picker-list-head[b-18odcykjw9] {
    padding: 6px 12px;
    border-bottom: 1px solid var(--vz-border-color);
    background: var(--vz-light);
    font-size: 13px;
    flex-shrink: 0;
}

/* ⛔ 검색 결과에만 그리는 폴더 경로(A - B - C). 줄이 길어지지 않게 한 줄로 자른다. */
.doc-picker-path[b-18odcykjw9] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.doc-picker-search .upload-btn[b-18odcykjw9] { flex-shrink: 0; white-space: nowrap; padding: 4px 12px; }

/* ⛔⛔ 트리 노드는 자식 컴포넌트가 그린다 — 스코프 속성이 안 붙어 ::deep 없이는 못 닿는다. */
.doc-picker-tree[b-18odcykjw9]  .category-node {
    display: flex; align-items: center; gap: 4px;
    padding: 5px 10px; font-size: 13px;
    cursor: pointer; user-select: none; border-radius: 4px; margin: 1px 4px;
}

.doc-picker-tree[b-18odcykjw9]  .category-node:hover { background: var(--vz-light); }

.doc-picker-tree[b-18odcykjw9]  .category-node.selected {
    background: var(--vz-primary-bg-subtle, #dff0fa);
    color: var(--vz-primary); font-weight: 500;
}

.doc-picker-tree[b-18odcykjw9]  .tree-toggle,
.doc-picker-tree[b-18odcykjw9]  .tree-toggle-placeholder {
    width: 14px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
    background: none; border: 0; padding: 0; color: var(--vz-secondary-color);
}

.doc-picker-tree[b-18odcykjw9]  .node-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.doc-picker-tree[b-18odcykjw9]  .jk-pick-count {
    font-size: 12px; color: var(--vz-secondary-color); background: var(--vz-tertiary-bg);
    padding: 0 4px; border-radius: 8px; flex-shrink: 0;
}

/* 「전체」 줄 — 트리 노드와 «같은 모양»이어야 한다(한 줄만 달라 보이면 안 된다). */
.jk-pick-node[b-18odcykjw9] {
    display: flex; align-items: center; gap: 4px;
    padding: 5px 10px; font-size: 13px;
    cursor: pointer; user-select: none; border-radius: 4px; margin: 1px 4px;
}

.jk-pick-node:hover[b-18odcykjw9] { background: var(--vz-light); }
.jk-pick-node.on[b-18odcykjw9] { background: var(--vz-primary-bg-subtle, #dff0fa); color: var(--vz-primary); font-weight: 500; }
/* /Components/Shared/Grid/JkEditableGrid.razor.rz.scp.css */
/* ⛔⛔ 2026-09-02 지적(「input 을 고르려는데 테이블이 잡혀 테두리가 생긴다」) —
   칸을 겨냥해 누르다 조금만 끌면 브라우저가 표를 «텍스트 선택»해 파랗게 칠했다(실측: user-select auto).
   표는 스프레드시트처럼 다루는 물건이라 셀 텍스트를 끌어 잡을 이유가 없다.
   ⛔ 입력칸 «안»은 다시 켠다 — 거기서는 글자를 끌어 고치는 게 정상이다. */
.jk-grid[b-jnk1oxuahj] {
    outline: none;
    user-select: none;
    -webkit-user-select: none;
}

.jk-grid-tbl[b-jnk1oxuahj] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.jk-grid-tbl th[b-jnk1oxuahj] {
    padding: 7px 8px;
    text-align: left;
    font-weight: 500;
    color: var(--vz-secondary-color);
    background: var(--vz-tertiary-bg);
    border-bottom: 1px solid var(--vz-border-color, #e9ebec);
    white-space: nowrap;
}

.jk-grid-tbl td[b-jnk1oxuahj] {
    padding: 5px 8px;
    border-bottom: 1px solid var(--vz-border-color, #f0f2f5);
    vertical-align: middle;
}

.jk-grid-tbl .ta-r[b-jnk1oxuahj] { text-align: right; }

/* 편집 가능한 칸임을 «누르기 전에» 알린다 — 눌러 봐야 아는 표는 편집 가능한 줄 모른다. */
.jk-grid-tbl td.is-editable[b-jnk1oxuahj] { cursor: text; }
.jk-grid-tbl td.is-editable:hover[b-jnk1oxuahj] {
    background: var(--vz-light-bg-subtle);
    box-shadow: inset 0 0 0 1px var(--vz-primary-border-subtle);
}

.jk-grid-in[b-jnk1oxuahj] {
    width: 100%;
    border: 1px solid var(--vz-primary);
    border-radius: 3px;
    padding: 2px 4px;
    font-size: 13px;
    outline: none;
    color: var(--vz-body-color);
    background: var(--vz-secondary-bg);
    /* 표 전체는 선택을 껐지만 입력칸 안에서는 켠다. */
    user-select: text;
    -webkit-user-select: text;
}

.jk-grid-empty[b-jnk1oxuahj] {
    padding: 24px 8px;
    text-align: center;
    color: var(--vz-secondary-color);
}

.jk-grid-actions[b-jnk1oxuahj] { width: 36px; text-align: center; }

.jk-grid-del[b-jnk1oxuahj] {
    border: 0;
    background: transparent;
    color: var(--vz-secondary-color);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
}
.jk-grid-del:hover[b-jnk1oxuahj] { color: var(--vz-danger); }

.jk-grid-bar[b-jnk1oxuahj] {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 0 0;
}

.jk-grid-hint[b-jnk1oxuahj] { color: var(--vz-secondary-color); font-size: 12px; margin-left: auto; }


/* ══ 자동완성 목록 — 2026-09-02 지시 ══════════════════════════════════════════
   ⛔ 목록을 표의 «흐름»에 두면 뜰 때마다 행 높이가 늘었다 줄었다 한다 — absolute 로 띄운다.
   ⛔ 부모(<td>)에 position:relative 가 없으면 판이 페이지 좌상단으로 날아간다. 함께 준다.
   ⛔ 겹침은 «표 안»에서만 겨루면 된다(모달 z-index 층과 무관) — 10 이면 충분하다. */
.jk-grid-sug-wrap[b-jnk1oxuahj] {
    position: relative;
    display: block;
}

.jk-grid-sug[b-jnk1oxuahj] {
    user-select: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 10;
    min-width: 100%;
    max-width: 420px;
    max-height: 240px;
    overflow-y: auto;
    margin: 2px 0 0;
    padding: 4px 0;
    list-style: none;
    background: var(--vz-card-bg, #fff);
    border: 1px solid var(--vz-border-color, #e9ebec);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}

.jk-grid-sug-item[b-jnk1oxuahj] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 10px;
    cursor: pointer;
    white-space: nowrap;
}

.jk-grid-sug-item:hover[b-jnk1oxuahj],
.jk-grid-sug-item.on[b-jnk1oxuahj] {
    background: var(--vz-tertiary-bg, #f3f6f9);
}

.jk-grid-sug-label[b-jnk1oxuahj] { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* 품번·규격 같은 보조 문구. ⛔ 라벨과 같은 색이면 무엇이 «고르는 값»인지 안 갈린다. */
.jk-grid-sug-hint[b-jnk1oxuahj] { color: var(--vz-secondary-color, #878a99); font-size: 12px; }
/* /Components/Shared/Modal/JkModal.razor.rz.scp.css */
/* 모달 표준 껍데기 — 값의 출처는 정본 DmsDocPicker.svelte <style> 다(문서 검색 모달).
   ⛔⛔ 2026-09-01 지시로 이것이 «앱의 기준»이 됐다. 새 모달이 자기 백드롭·판을 다시 그리지 않는다.
   ⛔ 값(폭·높이·반경·그림자·여백)을 새로 고르지 마라. 화면마다 조금씩 다르면 그게 곧 «다른 앱»이다. */

.jk-modal-backdrop[b-9xj3mx3wa2] {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    /* 모달 위에서 굴린 휠이 «뒤 페이지»를 밀지 않게. */
    overscroll-behavior: contain;
}

.jk-modal-panel[b-9xj3mx3wa2] {
    background: var(--vz-card-bg, #fff);
    border-radius: 10px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
    /* ⛔ 폭·높이는 인라인 style 로 온다(파라미터). 여기 값은 «한계»만 잡는다. */
    max-width: 94vw;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
    /* 판에 포커스를 주므로 브라우저 기본 외곽선이 뜬다 — 모양이 흔들려 끈다(백드롭이 이미 초점을 말한다). */
    outline: none;
}

.jk-modal-head[b-9xj3mx3wa2] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--vz-border-color);
    flex-shrink: 0;
}

/* 제목이 길어도 닫기 버튼을 밀어내지 않는다. */
.jk-modal-head h6[b-9xj3mx3wa2] {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jk-modal-subhead[b-9xj3mx3wa2] {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 16px;
    border-bottom: 1px solid var(--vz-border-color);
    color: var(--vz-secondary-color);
    font-size: 13px;
    flex-shrink: 0;
}

/* ⛔ 스크롤은 «몸통만» 한다. 머리·바닥이 함께 밀리면 확인 버튼을 찾으러 스크롤해야 한다. */
.jk-modal-body[b-9xj3mx3wa2] {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 16px;
}

/* 목록을 «가장자리까지» 붙이는 모달(문서 검색 등)은 몸통 여백을 끈다. */
.jk-modal-body.p0[b-9xj3mx3wa2] {
    padding: 0;
    display: flex;
    overflow: hidden;
}

.jk-modal-prefooter[b-9xj3mx3wa2] {
    border-top: 1px solid var(--vz-border-color);
    background: var(--vz-light);
    padding: 6px 16px 8px;
    max-height: 118px;
    overflow-y: auto;
    flex-shrink: 0;
}

.jk-modal-foot[b-9xj3mx3wa2] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 16px;
    border-top: 1px solid var(--vz-border-color);
    flex-shrink: 0;
}
/* /Components/Shared/OrderPreview/JkOrderPreviewModal.razor.rz.scp.css */
/* 수주 미리보기 모달 — scoped.
   ⛔ 값은 앱 표준을 그대로 쓴다: 카드 헤더 배경 #f5faff(2026-09-02 지시), 본문 13px.
      새 색·새 반경을 고르지 않는다. */

.jkop-card[b-hb7y02xytx] { border: 1px solid var(--vz-border-color); box-shadow: none; }

/* ⛔ 헤더 배경은 «픽스»다 — 화면마다 다른 색을 고르지 마라(2026-09-02 지시). */
.jkop-head[b-hb7y02xytx] {
    background: #f5faff;
    padding: 8px 14px;
    border-bottom: 1px solid var(--vz-border-color);
}
.jkop-head h6[b-hb7y02xytx] { font-size: 13px; font-weight: 500; }
.jkop-count[b-hb7y02xytx] { font-size: 12px; }

.jkop-dl[b-hb7y02xytx] { font-size: 13px; }
.jkop-dl .jkop-k[b-hb7y02xytx] {
    display: block;
    font-size: 12px;
    color: var(--vz-secondary-color);
}
.jkop-dl .jkop-v[b-hb7y02xytx] {
    display: block;
    color: var(--vz-body-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jkop-table[b-hb7y02xytx] { font-size: 13px; }
.jkop-table thead th[b-hb7y02xytx] {
    background: var(--vz-tertiary-bg);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
}
.jkop-table td[b-hb7y02xytx] { max-width: 0; }
/* /Components/Shared/OrgPicker/JkOrgPicker.razor.rz.scp.css */
/* 정본 스타일 이식 — OrgPickerModal.svelte <style>(159~182행) + OrgTree.svelte <style>(78~99행).

   ⛔⛔ 정본에서 Svelte «스코프» 안이라 global.css 에 «0건»이다. 껍데기(모달·리스트그룹·배지)는
      부트스트랩이 그리지만, 아래 다섯(.all-users-item · .org-node · .org-item · .org-name · .org-count)은
      여기 없으면 무스타일이 된다.
   ⛔ 자체 클래스(jk-orgp-*)로 다시 만들지 마라 — 2026-08-31 대조에서 정본과 클래스 40종이
      어긋나 있었다(같은 화면인데 DOM 이 통째로 달랐다). */

.all-users-item[b-v551tevptd] {
    display: flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    color: var(--vz-body-color);
    transition: all 0.12s;
    margin-bottom: 4px;
}

.all-users-item:hover[b-v551tevptd] {
    background: rgba(64, 81, 137, 0.06);
}

.all-users-item.active[b-v551tevptd] {
    background: var(--vz-primary);
    color: var(--vz-white);
}

.all-users-item.active .org-count[b-v551tevptd] {
    background: rgba(255, 255, 255, 0.25);
    color: var(--vz-white);
}

/* ── 조직도 트리 (정본 OrgTree.svelte) ─────────────────────────────────────── */

.org-node[b-v551tevptd] {
    user-select: none;
}

.org-item[b-v551tevptd] {
    display: flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    color: var(--vz-body-color);
    transition: all 0.12s;
}

.org-item:hover[b-v551tevptd] {
    background: rgba(64, 81, 137, 0.06);
}

.org-item.active[b-v551tevptd] {
    background: var(--vz-primary);
    color: var(--vz-white);
}

.org-item.active .org-count[b-v551tevptd] {
    background: rgba(255, 255, 255, 0.25);
    color: var(--vz-white);
}

/* ⛔ .org-name 은 «남는 폭을 먹고» 넘치면 말줄임이다 — 부서명이 길면 트리가 옆으로 밀린다. */
.org-name[b-v551tevptd] {
    flex: 1;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.org-count[b-v551tevptd] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    border-radius: 9px;
    font-size: 13px;
    font-weight: 600;
    padding: 0 4px;
    background: rgba(64, 81, 137, 0.12);
    color: var(--vz-primary);
}


/* ══ 고른 차례 번호 — 2026-09-01 지시 「순서도 표시」 ═══════════════════════════
   결재선에서는 «고른 차례»가 곧 결재 단계 순서다. 번호가 없으면 무엇을 먼저 골랐는지 알 수 없다.
   ⛔ 고르지 않은 줄에도 «자리»를 남긴다(빈 원) — 안 그리면 고를 때마다 줄이 좌우로 흔들린다. */
.org-pick-n[b-v551tevptd] {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    color: transparent;
    border: 1px dashed var(--vz-border-color);
}

.org-pick-n.on[b-v551tevptd] {
    color: var(--vz-white, #fff);
    background: var(--vz-primary);
    border: 0;
}
/* /Components/Shared/PartPreview/JkPartPreviewModal.razor.rz.scp.css */
/* 부품 미리보기 팝업 — 2026-08-31 에 Pages/EcrDetail/EcrPartPreviewModal.razor.css 에서
   «마크업과 함께» 옮겼다(그 전에는 EcrDetailScreen.razor.css 310~312행에 있었다).

   ⛔ 마크업만 옮기고 CSS 를 두고 오면 스코프가 갈려 팝업이 스타일 없이 뜬다(조용한 실패).
   ⛔⛔ 실제로 그 사고가 나 있었다: 합치기 전 Pages/Traceability/JkPartPreviewModal.razor 에는
      이 파일이 «아예 없어서» .pvw-section/.pvw-title/.pvw-label 이 전부 무스타일이었다.
      CSS 격리는 «컴포넌트»별이라 옆 컴포넌트의 .razor.css 는 절대 안 먹는다. */
.pvw-section[b-uag8a5r0df] { margin-bottom: 16px; }
.pvw-title[b-uag8a5r0df] { font-size: 13px; font-weight: 500; color: var(--vz-body-color); margin-bottom: 6px; }
.pvw-label[b-uag8a5r0df] { font-size: 13px; color: var(--vz-secondary-color); white-space: nowrap; width: 70px; }
/* /Components/Shared/PartRelease/JkPartReleaseContent.razor.rz.scp.css */
/* 확정 내용 구획 — 기본정보 · 부품속성 · 파일 · BOM 넷을 같은 리듬으로 쌓는다.
   ⛔ 각 구획을 카드로 감싸지 마라 — 이 부품은 «이미 카드/모달 안»에 들어간다(카드 안 카드가 된다).
   ⛔ 2026-09-01 — 종전에 결재함 화면 CSS 에 같은 규칙이 있었다. 부품으로 올리면서 여기로 옮겼다.
      화면 쪽에 사본을 만들지 마라(한쪽만 늙는다). */

.jk-rel-sec[b-a5ijvhrc1l] {
    padding-top: 0.6rem;
    margin-top: 0.6rem;
    border-top: 1px solid var(--vz-border-color);
}

.jk-rel-sec:first-of-type[b-a5ijvhrc1l] {
    padding-top: 0;
    margin-top: 0;
    border-top: 0;
}

.jk-rel-head[b-a5ijvhrc1l] {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 13px;
    font-weight: 500;
    color: var(--vz-body-color);
    margin-bottom: 0.4rem;
}

/* 건수 — 「0건인지 못 읽은 것인지」를 사람이 바로 알게 늘 그린다. */
.jk-rel-n[b-a5ijvhrc1l] {
    font-size: 12px;
    color: var(--vz-secondary-color);
    background: var(--vz-tertiary-bg);
    border-radius: 8px;
    padding: 0 6px;
}

/* ══ 기본정보 — 라벨/값 «격자» (2026-09-01 지시) ═══════════════════════════════
   ⛔⛔ 종전엔 부트스트랩 row/col 이라 줄마다 나눔이 달랐고(6+6 · 4+4+4 · 6+6) 라벨이 어긋나 보였다.
      여기서는 라벨 열 폭을 격자가 «자동으로 맞춘다» — 항목이 늘어도 어긋나지 않는다.
   ⛔ 라벨 폭을 px 로 박지 마라. 「ERP 품목코드」처럼 긴 라벨이 잘린다.

   좁으면 한 쌍(라벨|값), 넓으면 두 쌍이 나란히.
   ⛔⛔ 기준은 «뷰포트»가 아니라 «이 구획의 폭»이다(container query) — 이 부품은 넓은 모달(920px)과
      좁은 결재함 오른쪽 칸에 «둘 다» 들어간다. @media 로 재면 좁은 칸에서 네 열이 되어 뭉갠다.
   ⛔ 컨테이너 쿼리를 못 쓰는 브라우저에서는 «한 쌍»으로 남는다 — 좁아 보일 뿐 열은 여전히 맞는다. */
.jk-rel-sec[b-a5ijvhrc1l] {
    container-type: inline-size;
}

.jk-rel-kv[b-a5ijvhrc1l] {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: 12px;
    row-gap: 6px;
    align-items: baseline;
    margin: 0;
}

.jk-rel-kv dt[b-a5ijvhrc1l] {
    font-size: 12px;
    font-weight: 400;
    color: var(--vz-secondary-color);
    white-space: nowrap;
}

.jk-rel-kv dd[b-a5ijvhrc1l] {
    margin: 0;
    min-width: 0;
    font-size: 13px;
    color: var(--vz-body-color);
}

@container (min-width: 560px) {
    .jk-rel-kv[b-a5ijvhrc1l] {
        grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr);
        column-gap: 16px;
    }
}

.jk-rel-k[b-a5ijvhrc1l] {
    font-size: 12px;
    color: var(--vz-secondary-color);
}

.jk-rel-v[b-a5ijvhrc1l] {
    font-size: 13px;
    color: var(--vz-body-color);
}

.jk-rel-empty[b-a5ijvhrc1l] {
    font-size: 13px;
    color: var(--vz-secondary-color);
}
/* /Components/Shared/ProjectPreview/JkProjectPreviewModal.razor.rz.scp.css */
/* 프로젝트 미리보기 모달 — scoped.
   ⛔ 카드 헤더 배경 #f5faff 는 2026-09-02 지시로 «픽스»다. 본문 13px.
   ⛔ 단계 화살표는 프로젝트 상세 「정보」 탭의 그 모양이다 — 새로 고르지 않는다. */

.jkpp-card[b-w5vbdthkd6] { border: 1px solid var(--vz-border-color); box-shadow: none; }

.jkpp-head[b-w5vbdthkd6] {
    background: #f5faff;
    padding: 8px 14px;
    border-bottom: 1px solid var(--vz-border-color);
}
.jkpp-head h6[b-w5vbdthkd6] { font-size: 13px; font-weight: 500; }
.jkpp-count[b-w5vbdthkd6] { font-size: 12px; }

.jkpp-dl[b-w5vbdthkd6] { font-size: 13px; }
.jkpp-dl .jkpp-k[b-w5vbdthkd6] { display: block; font-size: 12px; color: var(--vz-secondary-color); }
.jkpp-dl .jkpp-v[b-w5vbdthkd6] {
    display: block;
    color: var(--vz-body-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── 단계 흐름 — >기획>설계>검증> 모양. 칸이 서로 물리도록 음수 여백 + clip-path. ── */
.jkpp-flow[b-w5vbdthkd6] { display: flex; align-items: stretch; flex-wrap: wrap; gap: 0; }

.jkpp-step[b-w5vbdthkd6] {
    flex: 1 1 0;
    min-width: 96px;
    padding: 7px 10px 7px 20px;
    margin-right: -10px;
    clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 50%, calc(100% - 11px) 100%, 0 100%, 11px 50%);
    background: var(--vz-tertiary-bg);
    color: var(--vz-secondary-color);
    text-align: center;
    line-height: 1.3;
}
.jkpp-step:last-child[b-w5vbdthkd6] { margin-right: 0; }

.jkpp-step-name[b-w5vbdthkd6] { display: block; font-size: 13px; font-weight: 500; }
.jkpp-step-sub[b-w5vbdthkd6] { display: block; font-size: 11px; opacity: .85; }

/* 색은 Velzon 토큰뿐이다 — 새 색을 고르지 않는다. */
.jkpp-step.done[b-w5vbdthkd6] { background: var(--vz-success-bg-subtle); color: var(--vz-success); }
.jkpp-step.active[b-w5vbdthkd6] { background: var(--vz-primary); color: #fff; }
.jkpp-step.review[b-w5vbdthkd6] { background: var(--vz-warning-bg-subtle); color: var(--vz-warning); }
.jkpp-step.failed[b-w5vbdthkd6] { background: var(--vz-danger-bg-subtle); color: var(--vz-danger); }

.jkpp-chips[b-w5vbdthkd6] { display: flex; flex-wrap: wrap; gap: 6px; }
.jkpp-chips .badge[b-w5vbdthkd6] { font-size: 12px; font-weight: 500; }

.jkpp-members[b-w5vbdthkd6] { font-size: 13px; max-height: 132px; overflow-y: auto; }
.jkpp-members li[b-w5vbdthkd6] { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.jkpp-mrole[b-w5vbdthkd6] { margin-left: auto; font-size: 12px; color: var(--vz-secondary-color); }
/* /Components/Shared/RelationGraph/JkRelationGraphHost.razor.rz.scp.css */
/*
    관계 탐색(온톨로지) 모달 호스트 — «쌓임 순서»만 다룬다.

    ⛔⛔ 이 파일이 없으면 파일 상세에서 「온톨로지 보기」가 «열렸는데 안 보인다»(조용히 깨진다).
       실측 값: jk-shell.css 의 .detail-overlay 는 z-index 2050, JkModal 표준 백드롭은 2000이다.
       즉 파일 상세 위에서 이 모달을 띄우면 «상세 뒤»로 들어가 화면에 나타나지 않는다.
       ⛔ JkModal 의 2000 을 올려서 고치지 마라 — 그건 앱의 모든 모달을 함께 올리는 일이다.
          이 호스트 «하나»만 올린다(상세 오버레이 위에서 뜨는 것이 이 모달의 정의다).

    ⛔ 값은 2100 — .detail-overlay(2050)과 그 위 팝업(.annotation-input-popup 2055)보다 크고,
       임의로 크게 잡지 않았다. 새 값을 고르지 말고 이 근거를 갱신해라.

    ⛔ ::deep 은 «이 컴포넌트가 직접 쓴 요소»에만 스코프 속성이 붙는다는 사실에 기댄다.
       그래서 .razor 의 감싸는 div 가 필요하다 — 지우면 이 규칙이 통째로 죽는다.
*/
.jk-relgraph-host[b-aa6pxtqy29]  .jk-modal-backdrop {
    z-index: 2100;
}

/* 그래프 모달 «위»에 뜨는 상세 넷(파일·부품·수주·프로젝트).
   ⛔⛔ 2100 그대로 두면 그래프 모달과 «같은 층»이라 DOM 순서에 기대게 된다 — 한 층 위로 못박는다.
   ⛔ 파일 상세는 JkModal 이 아니라 .detail-overlay(전역 2050)라 «따로» 올려야 한다.
      둘 다 안 올리면 눌러도 아무것도 안 뜨는 것처럼 보인다(에러 없음). */
.jk-relgraph-host[b-aa6pxtqy29]  .jk-relgraph-detail .jk-modal-backdrop { z-index: 2150; }
.jk-relgraph-host[b-aa6pxtqy29]  .jk-relgraph-detail .detail-overlay { z-index: 2150; }
/* /Components/Shared/RelationGraph/JkRelationGraphView.razor.rz.scp.css */
/*
    관계 탐색(온톨로지) 그래프 본문 — 부품 스코프 CSS.

    ⛔⛔ 2026-09-02 — `Components/Pages/Traceability/RelationExplorer.razor.css` 에서 «통째로» 옮겨 왔다.
       스코프 CSS 는 컴포넌트 경계를 넘지 않는다 — 마크업이 JkRelationGraphView 로 옮겨 갔으므로
       규칙도 여기 있어야 한다. 화면 쪽에 다시 만들지 마라(그러면 모달에서만 스타일이 빠진다).
       ⛔ 시작점 바(.rex-fbar/.rex-cands …)도 «이 부품»이 그린다(ShowStartPicker) — 그래서 여기 있다.

    ⛔⛔ 정본은 `Components/Pages/Pms/ProjectOntology.razor.css` 다 — 값을 «그대로» 옮겼고
       클래스 접두만 onto- → rex- 로 바꿨다. 색·크기를 «새로 고르지» 마라.
       본문 13px · 카드 머리 배경 #f5faff + 아래 1px 경계 · 종류색은 RelationExplorerService 가 정본이다.

    ⛔ .fs-11/12/13/14 같은 Velzon 유틸리티를 여기서 재정의하지 않는다
       (화면 스코프가 전역을 이겨 다른 화면이 조용히 바뀐다).

    ⛔ SVG 안의 글자 크기는 여기서만 정한다 — SVG 텍스트는 1:1 로 그려져 px 가 화면 px 그대로다.
       9~10px 대는 실제 화면에서 읽히지 않아 정본이 전부 올려 둔 값이다(11.5~14).
*/

/* ── 카드 ─────────────────────────────────────────────────────── */
.rex-card[b-oblhd6xf0d] {
    font-size: 13px;
}

.rex-head[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    background: #f5faff;
    border-bottom: 1px solid var(--vz-border-color);
}

.rex-title[b-oblhd6xf0d] {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
}

.rex-hint[b-oblhd6xf0d] {
    font-size: 12px;
    font-weight: 400;
    color: var(--vz-secondary-color);
}

.rex-head-right[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ── 시작점 줄 ────────────────────────────────────────────────── */
.rex-fbar[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.rex-fl[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--vz-secondary-color);
}

.rex-kind[b-oblhd6xf0d] {
    width: 128px;
    flex: 0 0 auto;
}

.rex-q[b-oblhd6xf0d] {
    width: 280px;
    flex: 0 0 auto;
}

.rex-btn[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* ── 이동 경로 ────────────────────────────────────────────────── */
/* ── 이동 경로 줄 ────────────────────────────────────────────────
   ⛔⛔ 2026-09-02 지시(「뒤로·이동 경로·파일명 정렬이 이상하다」).
      원인은 «높이가 서로 달라서»였다: 버튼과 알약이 padding 만 맞춰져 있고 높이가 없어,
      글꼴·아이콘 크기 차이만큼 각자 다른 높이가 되어 한 줄에서 위아래로 흔들렸다.
   ⛔ 그래서 항목마다 «같은 높이(26px)»를 못박는다. gap·정렬만 고쳐서는 다시 어긋난다.
   ⛔ 역할도 갈랐다 — 뒤로는 «동작»이라 칸막이(.rex-crumb-div) 뒤에 두고, 알약은 «경로»만 담는다. */
.rex-crumbs[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin: 0 0 12px;
    min-height: 26px;
}

/* 시작점 바가 있는 «화면»에서는 그 바 아래에 붙으므로 위 여백이 필요하다. */
.rex-fbar + .rex-crumbs[b-oblhd6xf0d] { margin-top: 12px; }

.rex-cl[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    height: 26px;
    font-size: 12px;
    font-weight: 500;
    color: var(--vz-secondary-color);
    margin-right: 1px;
}

.rex-sep[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    height: 26px;
    color: var(--vz-border-color);
}

/* 뒤로 — 경로 알약과 «다르게» 보여야 한다(동작이지 경로가 아니다). */
.rex-back[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    background: var(--vz-tertiary-bg);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--vz-body-color);
    cursor: pointer;
    white-space: nowrap;
}

.rex-back:hover:not(:disabled)[b-oblhd6xf0d] { border-color: #2f8de6; color: #2f8de6; }
.rex-back:disabled[b-oblhd6xf0d] { opacity: .45; cursor: default; }

.rex-crumb-div[b-oblhd6xf0d] {
    width: 1px;
    height: 16px;
    background: var(--vz-border-color);
    margin: 0 2px;
}

.rex-cb[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    max-width: 20rem;
    padding: 0 10px;
    border: 1px solid var(--vz-border-color);
    border-radius: 14px;
    background: #fff;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1;
    color: var(--vz-body-color);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rex-cb:hover[b-oblhd6xf0d] {
    border-color: #2f8de6;
    color: #2f8de6;
}

.rex-cb.cur[b-oblhd6xf0d] {
    background: #e9f2fe;
    border-color: #2f8de6;
    color: #1f6feb;
}

/* ── 후보 목록 ────────────────────────────────────────────────── */
.rex-cands[b-oblhd6xf0d] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 12px;
    max-height: 296px;
    overflow-y: auto;
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
    padding: 6px;
    background: linear-gradient(180deg, #fbfdff, #fff);
}

.rex-cand[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 9px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    text-align: left;
    font-size: 12.5px;
    font-weight: 400;
    color: var(--vz-body-color);
    cursor: pointer;
}

.rex-cand:hover[b-oblhd6xf0d] {
    background: #eef5ff;
}

.rex-cand b[b-oblhd6xf0d] {
    font-weight: 500;
    flex: 0 0 auto;
}

.rex-cdot[b-oblhd6xf0d] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
}

.rex-ctitle[b-oblhd6xf0d] {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--vz-secondary-color);
}

.rex-csub[b-oblhd6xf0d] {
    flex: 0 0 auto;
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

/* ── 상태 표시 ────────────────────────────────────────────────── */
.rex-loading[b-oblhd6xf0d],
.rex-empty[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-content: center;
    padding: 34px 12px;
    font-size: 13px;
    color: var(--vz-secondary-color);
}

/* ── 뷰 토글 ──────────────────────────────────────────────────── */
.rex-seg[b-oblhd6xf0d] {
    display: inline-flex;
    border: 1px solid var(--vz-border-color);
    border-radius: 7px;
    overflow: hidden;
    background: #fff;
}

.rex-seg button[b-oblhd6xf0d] {
    border: 0;
    background: transparent;
    padding: 4px 12px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--vz-secondary-color);
    cursor: pointer;
}

.rex-seg button + button[b-oblhd6xf0d] {
    border-left: 1px solid var(--vz-border-color);
}

.rex-seg button.on[b-oblhd6xf0d] {
    background: #e9f2fe;
    color: #1f6feb;
}

/* ── 계보 네트워크 ────────────────────────────────────────────── */
.rex-twrap[b-oblhd6xf0d] {
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    background: linear-gradient(180deg, #fbfdff, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
}

.rex-tsvg[b-oblhd6xf0d] {
    display: block;
}

.rex-tn[b-oblhd6xf0d] {
    cursor: pointer;
}

.rex-tn:focus[b-oblhd6xf0d] {
    outline: none;
}

.rex-tn rect[b-oblhd6xf0d] {
    transition: 0.12s;
}

.rex-tn:hover rect[b-oblhd6xf0d] {
    stroke-width: 2.6;
}

.rex-tcol[b-oblhd6xf0d] {
    font-size: 12px;
    font-weight: 500;
    fill: var(--vz-secondary-color);
    letter-spacing: 0.3px;
}

.rex-tval[b-oblhd6xf0d] {
    font-size: 13.5px;
    font-weight: 500;
    fill: var(--vz-body-color);
}

.rex-tsub[b-oblhd6xf0d] {
    font-size: 11.5px;
    font-weight: 500;
}

.rex-tbadge[b-oblhd6xf0d] {
    font-size: 10.5px;
    font-weight: 500;
}

/* BOM 수량 — 엣지 위에 얹는 글자. 선과 겹치므로 배경 없이 작게. */
.rex-tqty[b-oblhd6xf0d] {
    font-size: 11px;
    font-weight: 500;
}

/* ── 아이콘·요약 (영향 분석 머리가 쓴다) ─────────────────────── */
.rex-selico[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    font-size: 15px;
    flex: 0 0 auto;
}

.rex-selinfo[b-oblhd6xf0d] {
    display: flex;
    flex-direction: column;
    min-width: 180px;
    flex: 1 1 auto;
}

.rex-selinfo b[b-oblhd6xf0d] {
    font-size: 13px;
    font-weight: 500;
}

.rex-selinfo small[b-oblhd6xf0d] {
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

/* ── 영향 분석 패널 ───────────────────────────────────────────── */
.rex-impact[b-oblhd6xf0d] {
    margin-top: 16px;
    border: 1px solid var(--vz-border-color);
    border-radius: 10px;
    overflow: hidden;
}

.rex-impacthead[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: #f5faff;
    border-bottom: 1px solid var(--vz-border-color);
}

.rex-tiles[b-oblhd6xf0d] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(214px, 1fr));
    gap: 1px;
    background: var(--vz-border-color);
}

.rex-tile[b-oblhd6xf0d] {
    padding: 10px 12px 12px;
    background: #fff;
}

.rex-tilehead[b-oblhd6xf0d] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.rex-tilelbl[b-oblhd6xf0d] {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--vz-body-color);
}

.rex-tilenum[b-oblhd6xf0d] {
    font-size: 20px;
    font-weight: 500;
    color: #1f6feb;
}

.rex-tilenote[b-oblhd6xf0d] {
    margin-top: 1px;
    font-size: 11.5px;
    font-weight: 400;
    color: var(--vz-secondary-color);
}

.rex-tileempty[b-oblhd6xf0d] {
    margin-top: 8px;
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

.rex-tilelist[b-oblhd6xf0d] {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.rex-tilelist li[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    overflow: hidden;
}

.rex-tilelist a[b-oblhd6xf0d],
.rex-tilebtn[b-oblhd6xf0d] {
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    border: 0;
    padding: 0;
    background: transparent;
    font-size: 12px;
    font-weight: 500;
    color: #1f6feb;
    text-align: left;
    cursor: pointer;
}

.rex-tilelist a:hover[b-oblhd6xf0d],
.rex-tilebtn:hover[b-oblhd6xf0d] {
    text-decoration: underline;
}

.rex-tilebadge[b-oblhd6xf0d] {
    flex: 0 0 auto;
    padding: 1px 7px;
    border: 1px solid var(--vz-border-color);
    border-radius: 10px;
    font-size: 10.5px;
    font-weight: 500;
    color: var(--vz-secondary-color);
}

.rex-tilemore[b-oblhd6xf0d] {
    margin-top: 6px;
    font-size: 11.5px;
    color: var(--vz-secondary-color);
}

/* ── 관계망 ───────────────────────────────────────────────────── */
.rex-gwrap[b-oblhd6xf0d] {
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    background: linear-gradient(180deg, #fbfdff, #fff);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
}

.rex-graph[b-oblhd6xf0d] {
    display: block;
    width: 100%;
    height: auto;
}

.rex-ring[b-oblhd6xf0d] {
    fill: none;
    stroke: #e3e9f0;
    stroke-width: 1;
    stroke-dasharray: 3 5;
}

.rex-ringl[b-oblhd6xf0d] {
    font-size: 11px;
    font-weight: 500;
    fill: #a6aeb8;
}

.rex-medge[b-oblhd6xf0d] {
    stroke-width: 1.4;
    stroke-opacity: 0.55;
}

.rex-medge.thin[b-oblhd6xf0d] {
    stroke-width: 0.9;
    stroke-opacity: 0.3;
    stroke-dasharray: 3 4;
}

.rex-mnode[b-oblhd6xf0d] {
    cursor: pointer;
}

.rex-mnode:focus[b-oblhd6xf0d] {
    outline: none;
}

.rex-mlbl[b-oblhd6xf0d] {
    font-size: 11.5px;
    font-weight: 500;
    fill: var(--vz-body-color);
}

.rex-mlbl.rootlbl[b-oblhd6xf0d] {
    font-size: 13px;
}

/* ── 범례 ─────────────────────────────────────────────────────── */
.rex-legend[b-oblhd6xf0d] {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 10px;
}

.rex-key[b-oblhd6xf0d] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--vz-secondary-color);
}

.rex-key i[b-oblhd6xf0d] {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
}

/* 카드 안 [상세] 버튼 — 카드 클릭(=토폴로지 이동)과 «다른 동작»이라 눈에 보여야 한다(2026-09-02 지시).
   ⛔ 색은 카드 테두리와 같은 계열을 쓰지 않는다 — 배지와 헷갈린다. 중립 회색 + hover 에서 primary. */
.rex-tdetail[b-oblhd6xf0d] { cursor: pointer; }
.rex-tdetail rect[b-oblhd6xf0d] {
    fill: #fff;
    stroke: var(--vz-border-color);
    stroke-width: 1;
}
.rex-tdetail text[b-oblhd6xf0d] {
    font-size: 10.5px;
    font-weight: 500;
    fill: var(--vz-secondary-color);
}
.rex-tdetail:hover rect[b-oblhd6xf0d] { stroke: #2f8de6; fill: #e9f2fe; }
.rex-tdetail:hover text[b-oblhd6xf0d] { fill: #1f6feb; }
/* /Components/Shared/SimilarDrawings/JkSimilarDrawingsPanel.razor.rz.scp.css */
/* 원본 스타일 그대로 옮긴 것 — ⛔ 새로 디자인하지 않았다.
   출처 둘:
     · $lib/components/shared/SimilarDrawingsModal.svelte 의 <style>(766~1180행) 중 이 화면이 쓰는 규칙
     · routes/dms/similar/+page.svelte 의 <style>(.similar-fallback)
   ⛔ 이 규칙들은 Svelte 스코프 안에 있어서 wwwroot/jk-shell.css 추출본에 «없다»
      (추출 대상이 DmsCardGrid · DmsContextMenu · DmsDetailOverlay · dms-* · detail-* 였다).
   ⛔ 모달 껍데기(.sim-backdrop/.sim-dialog)는 «여기 없다» — 그건 모달을 여는 쪽
      (JkDmsCardContextMenu.razor.css)이 그린다. 라우트(/dms/similar)는 껍데기 없이 이 패널만 쓴다. */

/* 원본 similar/+page.svelte:63~71 */
.similar-fallback[b-a3g01q6c7h] {
    min-height: 60vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px;
}

/* ── 머리·기준 도면·바닥 (2026-08-31 정본 대조로 이식) ─────────────────────────
   ⛔ 값은 정본 <style> 그대로다. 여기 있던 옛 Bootstrap card 껍데기는 «다시 지은» 것이었다.
   ⛔ 모달(.sim-dialog)의 세로 배치가 이 세 규칙에 걸려 있다 — .sim-body 만 늘어나고 스스로 스크롤한다.
      (.sim-dialog 자체는 소비처인 JkDmsCardContextMenu.razor.css 에 있다 — 그 파일이 그 element 를 그린다.) */

/* SimilarDrawingsModal.svelte:794~810 */
.sim-header[b-a3g01q6c7h] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--vz-border-color);
}

.sim-title[b-a3g01q6c7h] {
    font-size: 1rem;
    font-weight: 600;
    color: var(--vz-heading-color);
}

.sim-subtitle[b-a3g01q6c7h] {
    font-size: 13px;
    color: var(--vz-secondary-color);
}

/* ⛔ 정본이 «자기 스코프 안에서» 정의한 유틸이다 — Velzon 전역에는 없다. 빠지면 긴 제목이 헤더를 밀어낸다. */
.min-w-0[b-a3g01q6c7h] {
    min-width: 0;
}

/* :812~857 — 기준 도면 요약(목록 모드) */
.sim-base[b-a3g01q6c7h] {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 18px;
    background: var(--vz-tertiary-bg);
    border-bottom: 1px solid var(--vz-border-color);
}

.sim-base-thumb[b-a3g01q6c7h] {
    flex-shrink: 0;
    width: 72px;
    height: 54px;
    border-radius: 6px;
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.sim-base-thumb img[b-a3g01q6c7h] {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.sim-base-title[b-a3g01q6c7h] {
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 2px;
}

.sim-base-info[b-a3g01q6c7h] {
    font-size: 13px;
}

/* SimilarDrawingsModal.svelte:859~884 */
.sim-body[b-a3g01q6c7h] {
    /* ⛔ flex-grow/overflow-y 두 줄이 모달의 «높이 계약»이다. 빼면 .sim-dialog(overflow:hidden)가
          내용을 잘라 버린다 — 스크롤이 아니라 «안 보임»이 된다. */
    flex-grow: 1;
    overflow-y: auto;
    padding: 16px 18px;
    min-height: 240px;
}

.sim-loading[b-a3g01q6c7h],
.sim-empty[b-a3g01q6c7h] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 280px;
    text-align: center;
}

.sim-result-header[b-a3g01q6c7h] {
    margin-bottom: 12px;
}

.sim-grid[b-a3g01q6c7h] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
}

/* :886~938 */
.sim-card[b-a3g01q6c7h] {
    background: var(--vz-secondary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
    display: flex;
    flex-direction: column;
    position: relative;
}

.sim-card:hover[b-a3g01q6c7h] {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
    border-color: var(--vz-primary);
}

.sim-card.selected[b-a3g01q6c7h] {
    border-color: var(--vz-primary);
    box-shadow: 0 0 0 2px var(--vz-primary);
}

.sim-card-check[b-a3g01q6c7h] {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 3;
    width: 22px;
    height: 22px;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--vz-border-color);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.12s;
}

.sim-card-check:hover[b-a3g01q6c7h] {
    background: var(--vz-secondary-bg);
    border-color: var(--vz-primary);
}

.sim-card-check.disabled[b-a3g01q6c7h] {
    opacity: 0.4;
    cursor: not-allowed;
}

.sim-card-check input[b-a3g01q6c7h] {
    width: 14px;
    height: 14px;
    margin: 0;
    cursor: inherit;
}

.sim-card-check span[b-a3g01q6c7h] {
    display: none;
}

/* :940~972 */
.sim-card-thumb[b-a3g01q6c7h] {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--vz-tertiary-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.sim-card-thumb img[b-a3g01q6c7h] {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.sim-card-icon[b-a3g01q6c7h] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.sim-card-similarity[b-a3g01q6c7h] {
    position: absolute;
    top: 6px;
    right: 6px;
    font-size: 13px;
    font-weight: 700;
    padding: 4px 8px;
}

/* :973~1011 — 2026-05-21 카드 제목 영역 여백 표준(상하 12~14 · line-height 1.45 · meta 8) */
.sim-card-body[b-a3g01q6c7h] {
    padding: 12px 12px 14px;
}

.sim-card-title[b-a3g01q6c7h] {
    font-size: 13px;
    font-weight: 500;
    line-height: 1.45;
    color: var(--vz-heading-color);
    margin-bottom: 8px;
}

.sim-card-meta[b-a3g01q6c7h] {
    font-size: 13px;
    line-height: 1.45;
    margin-bottom: 8px;
}

.sim-card-bar[b-a3g01q6c7h] {
    height: 3px;
    background: var(--vz-tertiary-bg);
    border-radius: 2px;
    overflow: hidden;
}

.sim-card-bar-fill[b-a3g01q6c7h] {
    height: 100%;
    background: linear-gradient(90deg, var(--vz-info), var(--vz-primary));
    transition: width 0.2s;
}

.sim-card-dl[b-a3g01q6c7h] {
    color: var(--vz-secondary-color);
    text-decoration: none;
    padding: 2px 4px;
    border-radius: 4px;
    line-height: 1;
}

.sim-card-dl:hover[b-a3g01q6c7h] {
    color: var(--vz-primary);
    background: var(--vz-tertiary-bg);
}

/* :1013~1021 — 바닥글. ⛔ 왼쪽·오른쪽 두 덩어리를 space-between 이 벌린다(정본과 같다). */
.sim-footer[b-a3g01q6c7h] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 18px;
    border-top: 1px solid var(--vz-border-color);
    background: var(--vz-card-bg, #fff);
}

/* :1047~1104 — 비교 뷰 (줌/팬 관련 규칙은 그 기능을 안 옮겨서 제외했다) */
.sim-compare-thumbs[b-a3g01q6c7h] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 12px;
}

.sim-compare-col[b-a3g01q6c7h] {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.sim-compare-label[b-a3g01q6c7h] {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    min-width: 0;
}

.sim-compare-label .text-truncate[b-a3g01q6c7h] {
    min-width: 0;
}

.sim-compare-thumb[b-a3g01q6c7h] {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--vz-tertiary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.sim-compare-thumb img[b-a3g01q6c7h] {
    width: 100%;
    height: 100%;
    object-fit: contain;
    /* ⛔⛔ 두 축이 «다른 element» 에서 온다 — 줌은 회로가 바깥 래퍼에, 팬은 JS 가 안쪽에 쓴다.
       한 element 의 style 에 몰면 회로 렌더가 JS 값을 지운다(SimilarDrawings.razor.js 머리말). */
    transform: translate(var(--sim-pan-x, 0%), var(--sim-pan-y, 0%)) scale(var(--sim-zoom, 1));
    transform-origin: center center;
    /* 드래그 중 브라우저 기본 이미지 끌기가 끼어들지 않게 한다. */
    -webkit-user-drag: none;
    user-select: none;
}

/* 정본 :467~480 의 줌 툴바. */
.sim-zoom-toolbar[b-a3g01q6c7h] {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.sim-zoom-toolbar .zoom-label[b-a3g01q6c7h] {
    min-width: 52px;
    text-align: center;
    font-size: 12px;
    color: var(--vz-secondary-color);
}

/* 확대 상태에서만 잡아끌 수 있다 — 커서로 그 사실을 말한다(정본 .panning). */
.sim-compare-zoom.sim-pannable .sim-compare-thumb[b-a3g01q6c7h] {
    cursor: grab;
}

.sim-compare-thumbs[data-panning] .sim-compare-thumb[b-a3g01q6c7h] {
    cursor: grabbing;
}

/* :1109~1172 — 속성 비교표 */
.sim-compare-attrs[b-a3g01q6c7h] {
    background: var(--vz-tertiary-bg);
    border: 1px solid var(--vz-border-color);
    border-radius: 8px;
    padding: 12px 14px;
}

.sim-compare-attrs-title[b-a3g01q6c7h] {
    font-size: 13px;
    font-weight: 600;
    color: var(--vz-heading-color);
    margin-bottom: 8px;
}

.sim-compare-table[b-a3g01q6c7h] {
    font-size: 13px;
}

.sim-compare-table th[b-a3g01q6c7h] {
    font-size: 13px;
    font-weight: 600;
    color: var(--vz-secondary-color);
    background: var(--vz-tertiary-bg);
    border-bottom: 1px solid var(--vz-border-color);
}

.sim-compare-table td[b-a3g01q6c7h] {
    vertical-align: middle;
    border-bottom: 1px solid rgba(0, 0, 0, 0.04);
}

.sim-compare-table .sim-attr-label[b-a3g01q6c7h] {
    position: sticky;
    left: 0;
    background: var(--vz-tertiary-bg);
    z-index: 2;
    width: 120px;
    white-space: nowrap;
}

.sim-compare-table thead th.sim-attr-label[b-a3g01q6c7h] {
    z-index: 3;
}

.sim-compare-table .sim-target-th[b-a3g01q6c7h] {
    min-width: 110px;
    max-width: 200px;
}

.sim-compare-table .sim-match-th[b-a3g01q6c7h] {
    width: 56px;
}

.sim-compare-table tr.row-all-same td[b-a3g01q6c7h] {
    background: rgba(40, 167, 69, 0.05);
}

.sim-compare-table td.cmp-same[b-a3g01q6c7h] {
    background: rgba(40, 167, 69, 0.08);
}

.sim-compare-table td.cmp-diff[b-a3g01q6c7h] {
    background: rgba(220, 53, 69, 0.08);
    font-weight: 600;
}

.sim-compare-table td.cmp-missing[b-a3g01q6c7h] {
    background: rgba(0, 0, 0, 0.02);
    color: var(--vz-secondary-color);
}
/* /Components/Shared/Toast/JkToastHost.razor.rz.scp.css */
/* ⛔⛔ 컨테이너는 «클릭을 통과»시킨다. 이걸 지우면 토스트가 떠 있는 동안
   그 아래 버튼이 안 눌린다(2026-08-30 실제 결함). 알맹이만 pointer-events 를 되돌린다. */
.jk-toast-host[b-bqvwk8mthm] {
    position: fixed;
    right: 16px;
    bottom: 16px;
    /* ⛔⛔ 2026-09-03 QA #58/#16 — 종전 2000 은 «모달과 같은 칸»이었다. 토스트 호스트는 MainLayout
       머리(40행)에서 먼저 그려지므로 같은 값이면 뒤에 그려지는 모달이 이긴다. 실제로
       .detail-overlay(jk-shell.css:346 = 2050) · JkModal(2000) · 확인창(2210) 뒤로 깔려,
       모달 안에서 낸 안내가 «아무것도 안 뜬 것»으로 보였다(「결재 요청 작성 클릭 무반응」).
       ⛔ 토스트는 항상 맨 위다 — app.css 「겹침 순서」 목록의 마지막 칸(2400)을 쓴다.
       ⛔ 이 값을 내리려면 그 목록부터 고쳐라. */
    z-index: 2400;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: min(420px, calc(100vw - 32px));
    pointer-events: none;
}

.jk-toast[b-bqvwk8mthm] {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 6px;
    border: 1px solid var(--vz-border-color, #e9ebec);
    border-left-width: 3px;
    background: #fff;
    box-shadow: 0 4px 16px rgba(30, 32, 37, .14);
    font-size: 13px;
    line-height: 1.45;
    animation: jk-toast-in-b-bqvwk8mthm .16s ease-out;
}

@keyframes jk-toast-in-b-bqvwk8mthm {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .jk-toast[b-bqvwk8mthm] { animation: none; }
}

.jk-toast-ic[b-bqvwk8mthm]     { font-size: 16px; line-height: 1.2; flex: 0 0 auto; }
.jk-toast-body[b-bqvwk8mthm]   { flex: 1 1 auto; min-width: 0; }
.jk-toast-msg[b-bqvwk8mthm]    { font-weight: 500; word-break: break-word; }
.jk-toast-detail[b-bqvwk8mthm] { margin-top: 2px; font-size: 12px; color: #878a99; word-break: break-word; }

.jk-toast-x[b-bqvwk8mthm] {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: #878a99;
    cursor: pointer;
    padding: 0 2px;
    font-size: 15px;
    line-height: 1.2;
}
.jk-toast-x:hover[b-bqvwk8mthm] { color: #495057; }

.jk-toast.is-success[b-bqvwk8mthm] { border-left-color: #0ab39c; }
.jk-toast.is-success .jk-toast-ic[b-bqvwk8mthm] { color: #0ab39c; }
.jk-toast.is-info[b-bqvwk8mthm]    { border-left-color: #299cdb; }
.jk-toast.is-info .jk-toast-ic[b-bqvwk8mthm]    { color: #299cdb; }
.jk-toast.is-warning[b-bqvwk8mthm] { border-left-color: #f7b84b; }
.jk-toast.is-warning .jk-toast-ic[b-bqvwk8mthm] { color: #f7b84b; }
.jk-toast.is-error[b-bqvwk8mthm]   { border-left-color: #f06548; }
.jk-toast.is-error .jk-toast-ic[b-bqvwk8mthm]   { color: #f06548; }
