/* 주문 진행 안내. 검증이 도는 동안 화면 전체를 잡고, 지금 무엇을 하고 있는지만 보여 준다. */
#ovDialog{border:0;border-radius:18px;padding:0;width:min(460px,calc(100% - 32px));max-height:88dvh;overflow:auto;color:#192733;background:#fff;font:14px/1.6 system-ui;z-index:2147483600;box-shadow:0 18px 48px #17212b2e}
#ovDialog::backdrop{background:#17212bb3}
#ovDialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);margin:0}
/* showModal() 이 다이얼로그 자체에 초점을 준다. 기다리는 동안에는 누를 것이 없어 테두리만
   남으므로 지운다. 안쪽 버튼의 초점 표시는 그대로 둔다. */
#ovDialog:focus{outline:none}

/* 진행 안내 본체 */
#ovDialog .ov-progress{padding:34px 26px 26px;text-align:center}
#ovDialog h2{margin:0;font-size:19px;font-weight:700;line-height:1.45;word-break:keep-all}
#ovDialog #ovLead{margin:10px 0 0;color:#5b6570;word-break:keep-all}
#ovDialog #ovSteps{margin:18px 0 0;padding:0;list-style:none;text-align:left}
#ovDialog #ovSteps li{margin:0;padding:5px 0 5px 22px;border:0;background:none;color:#59616b;font-size:13px;position:relative}
#ovDialog #ovSteps li::before{content:"";position:absolute;left:4px;top:11px;width:9px;height:5px;border-left:2px solid #3aa66f;border-bottom:2px solid #3aa66f;transform:rotate(-45deg)}
#ovDialog #ovElapsed{margin:16px 0 0;color:#8c949d;font-size:12px}
#ovDialog #ovElapsed:empty{display:none}

/* 세 점이 도는 동안은 처리가 살아 있다는 표시다. 멈추면 함께 멈춘다. */
#ovDialog .ov-dots{display:flex;gap:7px;justify-content:center;margin:0 0 18px}
#ovDialog .ov-dots i{width:10px;height:10px;border-radius:50%;animation:ov-bounce 1.05s infinite ease-in-out}
#ovDialog .ov-dots i:nth-child(1){background:#2fb367}
#ovDialog .ov-dots i:nth-child(2){background:#20b6c9;animation-delay:.14s}
#ovDialog .ov-dots i:nth-child(3){background:#3b72e8;animation-delay:.28s}
@keyframes ov-bounce{0%,72%,100%{transform:translateY(0);opacity:.45}36%{transform:translateY(-6px);opacity:1}}
@media(prefers-reduced-motion:reduce){#ovDialog .ov-dots i{animation:none;opacity:1}}

/* 사람이 눌러 줘야 이어지는 자리(결제창 열기). 실패가 아니므로 붉게 칠하지 않는다. */
#ovDialog.ov-waiting .ov-dots i{animation:none;opacity:1}
#ovDialog.ov-waiting .ov-actions{padding-top:6px}

/* 멈춰 선 상태 — 점을 세우고 사유를 강조한다. */
#ovDialog.ov-halted .ov-dots i{animation:none;background:#c2c8ce}
#ovDialog.ov-halted .ov-dots i:nth-child(2){background:#a14b46}
#ovDialog.ov-halted h2{color:#a14b46}
#ovDialog.ov-halted #ovLead{color:#192733}

/* 결제 승인 뒤에 멈춘 자리 — 주문은 이미 접수됐고 돈도 나갔다. 붉게 칠하면 고객이
   「주문이 안 됐다」로 읽고 다시 결제한다. 점은 멈춘 채로 두되 색만 되돌린다. */
#ovDialog.ov-paid .ov-dots i:nth-child(2){background:#2fb367}
#ovDialog.ov-paid h2{color:#1d7a4c}

#ovDialog .ov-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;padding:0 26px 26px}
#ovDialog .ov-actions:empty{display:none}
/* (2026-10-30 카드 1353 다) 할 일 단추를 보낸 뒤 결과 한 줄 — 단추 줄 아래 한 줄을 차지하고 가운데로(새 크기 값 없음) */
#ovDialog #ovActionStatus{flex-basis:100%;margin:0;text-align:center}
/* (2026-10-30 김 부장 검사) 손님 막힌 창의 진단번호는 접어 둔다 — «문의할 때 쓰는 번호 보기»를 누르면 번호. 편집기 손님 화면은 본문과 같은 글씨 단계 */
#ovDialog .ov-run-fold summary{cursor:pointer;display:inline;color:#6b7480;text-decoration:underline;text-underline-offset:.2em}
#ovDialog .ov-run-fold span{display:block;margin-top:.3em;font-family:ui-monospace,monospace;overflow-wrap:anywhere;color:#6b7480}
body.ed-role-client #ovDialog .ov-run-fold{font-size:var(--ed-type-sm-size);line-height:var(--ed-type-sm-line)}
/* 취소 버튼 — 침습 구간에서는 **숨기지 않고 비활성**한다(판정 ⑥-1).
   숨기면 「버튼이 사라졌다」가 되고, 비활성이면 「지금은 안 된다」가 된다. */
#ovDialog #ovCancel:disabled{opacity:.42;cursor:not-allowed}
#ovDialog button{font:inherit;cursor:pointer;min-height:44px;padding:8px 18px;border:1px solid #cdd4da;border-radius:10px;background:#fff;color:#192733}
#ovDialog #ovNext{border-color:#192733;background:#192733;color:#fff;font-weight:700}

/* ── 아래는 등록된 진단 계정에만 열리는 상세(#ovDiagBody). 고객 화면에는 나오지 않는다. */
#ovDialog .ov-body{padding:0 18px 18px;overflow:auto;max-height:48dvh;text-align:left;border-top:1px solid #eceff1;margin-top:8px;padding-top:16px}
#ovDialog .ov-body ol{padding:0;list-style:none}
#ovDialog .ov-body li{padding:10px 0;overflow-wrap:anywhere}
#ovDialog summary{cursor:pointer;font-weight:700}
#ovDialog pre{white-space:pre-wrap;overflow-wrap:anywhere;color:#192733}
#ovDialog textarea{width:100%;min-height:150px;box-sizing:border-box}

/* Status words remain visible independently of color. Use the site's semantic colors. */
#ovDialog .ov-pass{--ov-ink:var(--bj-success,#356a55);--ov-fill:#edf5f0}
#ovDialog .ov-fail{--ov-ink:var(--bj-danger,#a14b46);--ov-fill:#fff0ef}
#ovDialog .ov-running,#ovDialog .ov-pending{--ov-ink:#795a16;--ov-fill:#fff6db}
#ovDialog .ov-unknown,#ovDialog .ov-not_run,#ovDialog .ov-skipped{--ov-ink:#59616b;--ov-fill:#f0f2f4}
#ovDialog #ovCounts{display:flex;gap:6px;flex-wrap:wrap}
#ovDialog .ov-badge{display:inline-block;padding:3px 9px;border-radius:6px;font-weight:700;color:var(--ov-ink);background:var(--ov-fill)}
#ovDialog .ov-status{padding:12px;border-radius:6px;font-weight:700;color:var(--ov-ink);background:var(--ov-fill)}
#ovDialog .ov-body li{margin:8px 0;padding:10px 12px;border:1px solid #e5e7eb;border-radius:6px;background:var(--ov-fill);color:var(--ov-ink)}

/* 의미 단계(HTTP 요청 하나)를 가로 체크포인트로 낸다. 누르면 그 단계의 검사만 아래에 펼친다. */
#ovDialog .ov-rail{display:flex;margin:14px 0 0;padding:2px 0 4px;list-style:none;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:thin;scroll-behavior:smooth}
#ovDialog .ov-rail::-webkit-scrollbar{height:6px}
#ovDialog .ov-rail::-webkit-scrollbar-thumb{border-radius:3px;background:#cdd4da}
#ovDialog .ov-rail li{flex:1 0 114px;min-width:114px;margin:0;padding:0;border:0;border-radius:0;background:none;color:inherit;position:relative;text-align:center}
/* 이음선은 원의 중심을 지난다. 양 끝 바깥으로는 내보내지 않는다. */
#ovDialog .ov-rail li::before,#ovDialog .ov-rail li::after{content:"";position:absolute;top:11px;height:1px;background:#dfe3e7}
#ovDialog .ov-rail li::before{left:0;right:50%}
#ovDialog .ov-rail li::after{left:50%;right:0}
#ovDialog .ov-rail li:first-child::before,#ovDialog .ov-rail li:last-child::after{display:none}
#ovDialog .ov-rail .ov-node-btn{all:unset;cursor:pointer;display:block;width:100%;padding:0 4px;box-sizing:border-box}
#ovDialog .ov-rail .ov-node-dot{position:relative;z-index:1;display:block;box-sizing:border-box;width:16px;height:16px;margin:3px auto 0;border:1px solid #cdd4da;border-radius:50%;background:#fff}
#ovDialog .ov-rail .ov-node-label{display:block;margin-top:8px;font-size:11px;line-height:1.35;color:#59616b;word-break:keep-all}
#ovDialog .ov-rail .ov-node-sub{display:block;margin-top:2px;font-size:10px;color:#9aa2ab}
#ovDialog .ov-rail .ov-node-btn:focus-visible .ov-node-dot{box-shadow:0 0 0 3px #3b72e833}
/* 통과는 채워서 체크, 실패는 채워서 ×, 진행 중은 테를 굵게. 색만으로 가르지 않는다. */
#ovDialog .ov-rail .ov-pass .ov-node-dot,#ovDialog .ov-rail li.ov-pass .ov-node-dot{border-color:#3aa66f;background:#3aa66f}
#ovDialog .ov-rail li.ov-pass .ov-node-dot::after{content:"";position:absolute;left:4px;top:5px;width:6px;height:3px;border-left:1.5px solid #fff;border-bottom:1.5px solid #fff;transform:rotate(-45deg)}
#ovDialog .ov-rail li.ov-fail .ov-node-dot{border-color:#a14b46;background:#a14b46}
#ovDialog .ov-rail li.ov-fail .ov-node-dot::after{content:"×";position:absolute;inset:0;color:#fff;font-size:11px;line-height:14px;font-weight:700}
#ovDialog .ov-rail li.ov-fail .ov-node-label{color:#a14b46;font-weight:700}
#ovDialog .ov-rail li.ov-running .ov-node-dot,#ovDialog .ov-rail li.ov-pending .ov-node-dot{border:3px solid #795a16}
#ovDialog .ov-rail li.ov-running .ov-node-label,#ovDialog .ov-rail li.ov-pending .ov-node-label{color:#795a16;font-weight:700}
#ovDialog .ov-rail .ov-node-btn[aria-current] .ov-node-dot{box-shadow:0 0 0 3px #192733}
#ovDialog .ov-rail .ov-node-btn[aria-current] .ov-node-label{color:#192733;font-weight:700}
/* 고른 단계의 검사 */
#ovDialog #ovStageDetail{margin-top:16px}
#ovDialog .ov-stage-head{margin:0 0 8px;font-weight:700;font-size:13px}
#ovDialog #ovStageDetail ol{margin:0;padding-left:0}
#ovDialog .ov-repeat{margin:0 0 8px;padding:8px 10px;border-radius:6px;font-weight:700;color:#795a16;background:#fff6db}

/* ── 실행 로그 — 개발자 계정에만 열린다. 콘솔처럼 읽혀야 해서 어둡게·고정폭으로 둔다. */
#ovDialog #ovConsole{margin:0 18px 16px;text-align:left}
#ovDialog .ov-console-head{margin:0 0 6px;color:#8c949d;font-size:11px;font-weight:700}
#ovDialog .ov-console{border-radius:8px;background:#11181f;color:#c9d4de;
 font:11px/1.55 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
 height:300px;box-sizing:border-box;overflow:auto;overscroll-behavior:contain;padding:10px 12px}
#ovDialog .ov-console .ov-log{white-space:pre-wrap;overflow-wrap:anywhere}
#ovDialog .ov-console .ov-log-running{color:#93a7ba}
#ovDialog .ov-console .ov-log-pass{color:#67cf96}
#ovDialog .ov-console .ov-log-fail{color:#ff9d95}
#ovDialog .ov-console .ov-log-client{color:#ffd071}
#ovDialog .ov-console .ov-log-skipped,#ovDialog .ov-console .ov-log-not_run,
#ovDialog .ov-console .ov-log-unknown,#ovDialog .ov-console .ov-log-pending{color:#7d8794}

/* 진단 상세가 열리면 읽을 자리가 필요하다. */
#ovDialog:has(#ovConsole:not([hidden])),
#ovDialog:has(#ovDiagBody:not([hidden])){width:min(760px,calc(100% - 24px))}

@media(max-width:480px){
 #ovDialog{width:calc(100% - 28px)}
 #ovDialog .ov-progress{padding:28px 20px 22px}
 #ovDialog h2{font-size:17px}
 #ovDialog .ov-actions{padding:0 20px 22px}
 #ovDialog #ovElapsed{font-size:11px}
 #ovDialog #ovConsole{margin:0 14px 14px}
 #ovDialog .ov-console{font-size:10px}
 #ovDialog .ov-body{max-height:52dvh}
}

/* 고객 체크포인트 띠 — 시작할 때 전체가 보이고 상태만 바뀐다 */
#ovDialog #ovSteps.ov-plan{display:flex;gap:2px;margin:22px 0 4px;padding:0;list-style:none;flex-wrap:wrap;justify-content:center}
#ovDialog #ovSteps.ov-plan li{display:flex;flex-direction:column;align-items:center;gap:7px;flex:1 1 104px;min-width:88px;max-width:150px;margin:0;padding:4px 2px;border:0;background:none;position:relative}
#ovDialog #ovSteps.ov-plan li::before{content:none}
/* 노드 사이를 잇는 선 — 하나의 흐름이라는 것을 보이게 한다 */
#ovDialog #ovSteps.ov-plan li::after{content:"";position:absolute;top:15px;left:calc(50% + 17px);right:calc(-50% + 17px);height:2px;background:#e3e8ee}
#ovDialog #ovSteps.ov-plan li:last-child::after{content:none}
/* 줄바꿈 경계에서도 이음선을 끊는다 (2026-09-19 실측).
   이음선은 right:calc(-50% + 17px) 로 **다음 칸까지** 뻗는데, 띠가 줄바꿈되면 그 줄
   마지막 칸의 선은 이어질 곳이 없다 — 허공으로 뻗어 나간다. last-child 만으로는 안 잡힌다.
   ⚠ 뷰포트 미디어쿼리로는 못 고친다. 줄바꿈은 **패널 폭**이 정하므로 PC(1440px 뷰포트)에서도
     같은 자리에서 3+3 으로 접힌다(실측). 그래서 JS 가 offsetTop 으로 줄 끝을 찾아
     .ov-p-eol 을 붙이고, 여기서는 그 표식만 본다. */
#ovDialog #ovSteps.ov-plan li.ov-p-eol::after{content:none}
#ovDialog #ovSteps.ov-plan li.ov-p-done::after{background:#35b37e}
#ovDialog .ov-pdot{width:26px;height:26px;border-radius:50%;border:2px solid #dde3ea;background:#fff;display:block;position:relative;box-sizing:border-box;z-index:1}
#ovDialog .ov-plabel{font-size:12.5px;font-weight:600;color:#8c95a1;text-align:center;line-height:1.35;letter-spacing:-.2px}
#ovDialog .ov-psub{font-size:11px;color:#a8b0ba;margin-top:-3px}
#ovDialog .ov-p-done .ov-pdot{border-color:#35b37e;background:#35b37e}
#ovDialog .ov-p-done .ov-pdot::after{content:"";position:absolute;left:8px;top:7px;width:7px;height:11px;border-right:2.5px solid #fff;border-bottom:2.5px solid #fff;transform:rotate(42deg)}
#ovDialog .ov-p-done .ov-plabel{color:#3c4653}
#ovDialog .ov-p-done .ov-psub{color:#35b37e}
#ovDialog .ov-p-current .ov-pdot{border-color:#2f6fed;border-width:3px;box-shadow:0 0 0 4px rgba(47,111,237,.14)}
#ovDialog .ov-p-current .ov-plabel{color:#17325f;font-weight:700}
#ovDialog .ov-p-current .ov-psub{color:#2f6fed;font-weight:600}
#ovDialog .ov-p-fail .ov-pdot{border-color:#c0392f;background:#c0392f;transform:rotate(45deg);
 background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);
 background-size:2.5px 13px,13px 2.5px;background-position:center,center;background-repeat:no-repeat}
#ovDialog .ov-p-fail .ov-plabel{color:#a5322a;font-weight:700}
#ovDialog .ov-p-fail .ov-psub{color:#c0392f;font-weight:600}
@media (max-width:520px){#ovDialog #ovSteps.ov-plan li{flex-basis:78px;min-width:70px}#ovDialog .ov-plabel{font-size:11.5px}}
#ovDialog .ov-p-skip .ov-pdot{border-color:#e3e8ee;background:#f4f6f8}
#ovDialog .ov-p-skip .ov-pdot::after{content:"";position:absolute;left:6px;top:10px;width:10px;height:2px;background:#c3cad2}
#ovDialog .ov-p-skip .ov-plabel,#ovDialog .ov-p-skip .ov-psub{color:#b6bdc6}
