/* =====================================================================
 * Dev Preview pane — code-tab right-side panel for the agent-driven
 * preview. Owns BOTH tabs:
 *   • "Dev"   — iframe at /preview/{sid}/
 *   • "파일"  — viewer for `open_file_preview` results
 *
 * Deliberately independent from `artifacts.css`. The two modules
 * don't share DOM, state, or selectors so the chat-tab ArtifactsUI
 * can keep evolving without dragging the code tab along.
 *
 * Visibility model — ONE modifier on `#dev-preview-pane`:
 *   .open  — pane visible (slides in from the right edge)
 *   none   — collapsed (default)
 *
 * The pane is `position: absolute; right: 0` inside the code tab
 * panel so it can slide over `.code-main` without re-flowing the
 * chat layout. `--dev-preview-w` is the user-adjustable width.
 * ===================================================================== */

.dev-preview-pane {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--dev-preview-w, clamp(420px, 50vw, 820px));
    max-width: 90vw;
    background: var(--bg-primary, #fff);
    border-left: 1px solid var(--border, var(--border-color, #e5e5e7));
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transform: translateX(100%);
    transition: transform 220ms ease;
    pointer-events: none;
    z-index: 50;
    /* Default: pane invisible AND non-interactive so a translate that
       hasn't finished animating can't catch clicks on the underlying
       chat surface. */
    visibility: hidden;
}
.dev-preview-pane.open {
    transform: translateX(0);
    pointer-events: auto;
    visibility: visible;
}

/* Preview 가 열려 있는 동안 채팅 영역(.code-main) 을 좌측으로 민다.
   pane 은 여전히 `position: absolute; right: 0` 로 떠 있지만, 채팅
   콘텐츠가 그 폭만큼 padding 으로 비켜나 글이 가려지지 않는다.
   `--dev-preview-w` 는 resize handle 이 :root 에 설정하므로 폭 조정도
   자동 반영된다. transition duration 은 pane 의 슬라이드(220ms) 와
   동일하게 맞춰 시각적 동기화. */
.code-main {
    transition: padding-right 220ms ease;
}
body.dev-preview-open .code-main {
    padding-right: var(--dev-preview-w, clamp(420px, 50vw, 820px));
}
/* Drop the width transition while a drag is in progress so the panel
   tracks the cursor 1:1 instead of easing into each new width. */
body.dev-preview-resizing .dev-preview-pane {
    transition: transform 220ms ease;          /* keep slide-in but… */
}
/* Mid-drag, the cursor frequently enters the dev / file iframe. A
   nested document captures mouse events away from us, so the parent
   `document` stops receiving `mousemove` (and `mouseup`) and the
   drag appears to "stick" or stop tracking the cursor. Disabling
   pointer-events on the iframes only while dragging keeps the parent
   in control of both events without breaking iframe interaction at
   rest. */
body.dev-preview-resizing .dev-preview-iframe,
body.dev-preview-resizing .dev-preview-file-iframe {
    pointer-events: none;
}

/* Resize handle — sits on the left edge. The hit area is 6px wide so
   the user has a comfortable drag target; the visible highlight only
   appears on hover / active drag. */
.dev-preview-resize-handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 6px;
    margin-left: -3px;
    cursor: ew-resize;
    z-index: 5;
    background: transparent;
    transition: background 120ms ease;
}
.dev-preview-resize-handle:hover,
body.dev-preview-resizing .dev-preview-resize-handle {
    background: var(--accent, var(--primary, #6390ea));
    opacity: 0.65;
}
body.dev-preview-resizing {
    cursor: ew-resize;
    user-select: none;
}

/* Header: tabs on the left, close button on the right. Height paired
   with the artifacts pane header so the two visually align when the
   user has both tabs (different sessions across tabs) at once. */
.dev-preview-header {
    display: flex;
    align-items: center;
    gap: 4px;
    min-height: 44px;
    box-sizing: border-box;
    padding: 4px 10px 4px 14px;
    border-bottom: 1px solid var(--border, var(--border-color, #e5e5e7));
    background: var(--bg-secondary, #f7f7f8);
}

.dev-preview-tabs {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.dev-preview-tab {
    appearance: none;
    background: transparent;
    border: 0;
    color: var(--text-secondary);
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    padding: 8px 12px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 120ms ease, color 120ms ease;
}
.dev-preview-tab:hover {
    background: var(--bg-input, rgba(0, 0, 0, 0.04));
    color: var(--text-primary);
}
.dev-preview-tab.active {
    color: var(--text-primary);
    background: var(--bg-primary, #fff);
    font-weight: 600;
}
.dev-preview-tab i { font-size: 14px; }

/* Tiny dot beside the "파일" label that lights up when an
   open_file_preview event has arrived and the user is currently on
   the Dev tab — a soft nudge that there's something new to look at. */
.dev-preview-tab-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent, var(--primary, #6390ea));
    margin-left: 2px;
}
.dev-preview-tab-dot[hidden] { display: none; }

.dev-preview-header .spacer { flex: 1; }

.dev-preview-close,
.dev-preview-reload {
    appearance: none;
    background: transparent;
    border: 0;
    width: 30px;
    height: 30px;
    border-radius: 6px;
    color: var(--text-secondary);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 120ms ease, color 120ms ease;
}
.dev-preview-close:hover,
.dev-preview-reload:hover {
    background: var(--bg-input, rgba(0, 0, 0, 0.06));
    color: var(--text-primary);
}
.dev-preview-close i,
.dev-preview-reload i { font-size: 18px; }

/* Body holds the two tab panels; only the active one is visible. */
.dev-preview-body {
    flex: 1;
    min-height: 0;
    position: relative;
    background: var(--bg-primary, #fff);
    display: flex;
}

.dev-preview-panel {
    flex: 1;
    min-height: 0;
    display: none;
    flex-direction: column;
    overflow: hidden;
}
.dev-preview-panel.active { display: flex; }

/* Dev tab — full-bleed iframe pointed at /preview/{sid}/. */
.dev-preview-iframe {
    flex: 1;
    width: 100%;
    border: 0;
    background: white;
    min-height: 320px;
}

/* Empty state for the dev tab while we have a scope but no payload
   yet (initial pre-toggle state — shouldn't normally render because
   the pane is closed until the first event, but keeps the panel
   resilient if something opens it early). */
.dev-preview-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 32px 24px;
    text-align: center;
}
.dev-preview-empty-icon {
    width: 48px;
    height: 48px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--bg-secondary, #f0f0f2);
    color: var(--text-tertiary);
    margin-bottom: 4px;
}
.dev-preview-empty-icon i { font-size: 22px; }
.dev-preview-empty-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}
.dev-preview-empty-desc {
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--text-tertiary);
    max-width: 260px;
}

/* File tab — a left-side artifact sidebar (cards) plus a viewer.
   Mirrors the ArtifactsUI pattern but with dev-preview-side-* class
   names so this module's CSS is fully isolated from artifacts.css. */
.dev-preview-file-tab {
    flex: 1;
    display: flex;
    flex-direction: row;
    min-height: 0;
    min-width: 0;
}

.dev-preview-side {
    width: 240px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--bg-secondary, #f7f7f8);
    border-right: 1px solid var(--border, var(--border-color, #e5e5e7));
    overflow: hidden;
}
.dev-preview-side-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border, var(--border-color, #e5e5e7));
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
}
.dev-preview-side-count {
    margin-left: auto;
    background: var(--bg-input, rgba(0, 0, 0, 0.06));
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 600;
    padding: 1px 8px;
    border-radius: 999px;
}
.dev-preview-side-list {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.dev-preview-side-empty {
    color: var(--text-tertiary);
    font-size: 12px;
    text-align: center;
    padding: 24px 12px;
}

.dev-preview-side-card {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border, var(--border-color, #e5e5e7));
    border-radius: 8px;
    background: var(--bg-primary, #fff);
    cursor: pointer;
    transition: background 120ms ease, border-color 120ms ease;
    min-width: 0;
}
.dev-preview-side-card:hover {
    background: var(--bg-input, rgba(0, 0, 0, 0.04));
}
.dev-preview-side-card.active {
    border-color: var(--accent, var(--primary, #6390ea));
    background: rgba(99, 144, 234, 0.08);
}
.dev-preview-side-card-icon {
    position: relative;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    background: var(--bg-secondary, #f0f0f2);
    color: var(--text-secondary);
}
.dev-preview-side-card-icon > i:first-child { font-size: 16px; }
/* User-upload corner badge — positioned in the bottom-right of the
   card icon so an at-a-glance scan of the sidebar makes "agent vs
   me" clear without reading the title. */
.dev-preview-side-card-source {
    position: absolute;
    right: -3px;
    bottom: -3px;
    font-size: 10px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--accent, var(--primary, #6390ea));
    color: #fff;
    box-shadow: 0 0 0 2px var(--bg-primary, #fff);
}
.dev-preview-side-card-text {
    flex: 1;
    min-width: 0;
}
.dev-preview-side-card-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dev-preview-side-card-sub {
    font-size: 11px;
    color: var(--text-tertiary);
    margin-top: 1px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dev-preview-side-card-version {
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--accent-light, rgba(99, 144, 234, 0.1));
    color: var(--accent, var(--primary, #6390ea));
    letter-spacing: 0.3px;
}

.dev-preview-file-viewer {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    overflow: hidden;
    background: var(--bg-primary, #fff);
}

/* On a narrow pane (or mobile), drop the sidebar to a row of cards
   above the viewer instead of squeezing it sideways. The breakpoint
   is below the resize-handle minimum so this only kicks in for
   the mobile fallback. */
@media (max-width: 768px) {
    .dev-preview-file-tab {
        flex-direction: column;
    }
    .dev-preview-side {
        width: 100%;
        max-height: 30%;
        border-right: 0;
        border-bottom: 1px solid var(--border, var(--border-color, #e5e5e7));
    }
}

.dev-preview-file-iframe {
    flex: 1;
    width: 100%;
    border: 0;
    background: white;
    min-height: 320px;
}
.dev-preview-file-image {
    margin: auto;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    background: var(--bg-secondary, #f7f7f8);
    padding: 12px;
}
.dev-preview-file-video {
    flex: 1;
    width: 100%;
    background: black;
}

/* 마크다운 뷰어 — `.md` 파일을 marked 로 HTML 변환 후 표시. iframe 과
   달리 본문 컨테이너가 직접 스크롤을 갖고, 내부 타이포그래피는 채팅탭
   어시스턴트 답변과 시각적으로 일관되게 한다(여백/제목 크기/코드 블록). */
.dev-preview-file-markdown {
    flex: 1;
    overflow: auto;
    padding: 24px 28px;
    background: var(--bg-primary, #fff);
    color: var(--text-primary, #1a1a1a);
    font-size: 14px;
    line-height: 1.7;
    word-break: break-word;
}
.dev-preview-file-markdown h1,
.dev-preview-file-markdown h2,
.dev-preview-file-markdown h3 {
    margin-top: 18px;
    margin-bottom: 8px;
    font-weight: 600;
}
.dev-preview-file-markdown h1 { font-size: 20px; }
.dev-preview-file-markdown h2 { font-size: 17px; }
.dev-preview-file-markdown h3 { font-size: 15px; }
.dev-preview-file-markdown p { margin: 6px 0; }
.dev-preview-file-markdown ul,
.dev-preview-file-markdown ol { padding-left: 22px; margin: 6px 0; }
.dev-preview-file-markdown code {
    background: var(--bg-input, rgba(0, 0, 0, 0.06));
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 13px;
    font-family: "SF Mono", "Fira Code", "Consolas", monospace;
}
.dev-preview-file-markdown pre {
    background: #1e1e2e;
    color: #cdd6f4;
    padding: 14px 18px;
    border-radius: 6px;
    overflow-x: auto;
    margin: 8px 0;
    font-size: 13px;
    line-height: 1.5;
}
.dev-preview-file-markdown pre code {
    background: transparent;
    padding: 0;
    color: inherit;
}
.dev-preview-file-markdown table {
    border-collapse: collapse;
    margin: 10px 0;
    max-width: 100%;
}
.dev-preview-file-markdown th,
.dev-preview-file-markdown td {
    border: 1px solid var(--border, var(--border-color, #e5e5e7));
    padding: 6px 10px;
    text-align: left;
    vertical-align: top;
}
.dev-preview-file-markdown th {
    background: var(--bg-secondary, #f7f7f8);
    font-weight: 600;
}
.dev-preview-file-markdown blockquote {
    border-left: 3px solid var(--accent, var(--primary, #6390ea));
    padding-left: 12px;
    color: var(--text-secondary);
    margin: 8px 0;
}

/* Toggle button — lives in the code session toolbar. Hidden by
   default; revealed once the session has a running dev server (set
   by DevPreviewUI.setScope or openDev). */
.btn-dev-preview-toggle[hidden] { display: none !important; }
.btn-dev-preview-toggle.active {
    background: rgba(99, 144, 234, 0.12);
    color: var(--accent, var(--primary, #6390ea));
}

/* New "Preview" split-button + dropdown menu (toolbar). */
.code-preview-dropdown-wrap { display: inline-flex; }
.code-preview-btn {
    display: inline-flex; align-items: center; gap: 5px;
    height: 28px; padding: 0 10px;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.65);
    color: var(--text-primary);
    font-size: 12px; font-weight: 500;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
}
.code-preview-btn:hover {
    background: rgba(255, 255, 255, 0.92);
    border-color: rgba(0, 0, 0, 0.12);
}
.code-preview-btn[aria-pressed="true"] {
    background: rgba(255, 255, 255, 0.92);
    border-color: var(--accent, #6390ea);
    color: var(--accent, #6390ea);
}
.code-preview-btn i { font-size: 14px; }
.code-preview-menu {
    position: absolute; top: calc(100% + 6px); right: 0;
    min-width: 200px; z-index: 1000;
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.06);
    padding: 6px;
    display: flex; flex-direction: column; gap: 2px;
}
.code-preview-menu[hidden] { display: none; }
.code-preview-menu button {
    display: flex; align-items: center; gap: 8px;
    width: 100%; padding: 8px 12px;
    background: transparent; border: 0; border-radius: 8px;
    font-size: 13px; color: var(--text-primary); cursor: pointer;
    text-align: left;
    transition: background 0.1s ease;
}
.code-preview-menu button:hover { background: rgba(99, 144, 234, 0.08); }
.code-preview-menu button .hint {
    margin-left: auto; font-size: 11px; color: var(--text-tertiary);
}

/* URL bar above the panel body */
.dev-preview-urlbar {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-secondary, transparent);
    font-size: 12px;
}
.dev-preview-urlbar a {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--accent, #6390ea);
    text-decoration: none;
}
.dev-preview-urlbar a:hover { text-decoration: underline; }
.dev-preview-urlbar .btn-icon-sm {
    width: 24px; height: 24px;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent; border: 0; border-radius: 4px; cursor: pointer;
    color: var(--text-secondary);
}
.dev-preview-urlbar .btn-icon-sm:hover { background: rgba(99, 144, 234, 0.12); }

/* Diff tab */
.dev-diff-summary {
    display: flex; gap: 12px; align-items: center;
    padding: 10px 14px; font-size: 13px;
    border-bottom: 1px solid var(--border-color);
}
.dev-diff-summary .dev-diff-add { color: #10b981; font-weight: 600; }
.dev-diff-summary .dev-diff-del { color: #ef4444; font-weight: 600; }
.dev-diff-list { padding: 6px 0; overflow-y: auto; }
.dev-diff-row {
    display: grid;
    grid-template-columns: 28px 1fr auto auto;
    gap: 10px; align-items: center;
    padding: 6px 14px; font-size: 12px;
}
.dev-diff-row:hover { background: rgba(99, 144, 234, 0.06); }
.dev-diff-status {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 18px;
    border-radius: 4px; font-weight: 600; font-size: 10px;
    background: rgba(99, 144, 234, 0.14); color: var(--accent, #6390ea);
}
.dev-diff-status.added,    .dev-diff-status.untracked { background: rgba(16,185,129,0.14); color: #047857; }
.dev-diff-status.deleted   { background: rgba(239,68,68,0.14);  color: #b91c1c; }
.dev-diff-status.modified  { background: rgba(245,158,11,0.14); color: #b45309; }
.dev-diff-path {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--text-primary);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dev-diff-add { color: #10b981; }
.dev-diff-del { color: #ef4444; }
.dev-preview-loading,
.dev-preview-error {
    padding: 16px; font-size: 13px; color: var(--text-secondary);
}
.dev-preview-error { color: #b91c1c; }

/* Mobile fallback — fill the viewport, hide the resize handle. */
@media (max-width: 768px) {
    .dev-preview-pane {
        width: 100%;
        max-width: 100%;
    }
    .dev-preview-resize-handle { display: none; }
    /* 모바일은 Preview 가 풀스크린(100%)이라 padding-right 를 같이 주면
       채팅이 0 폭이 된다. 기존 오버레이 동작(덮어쓰기) 을 유지. */
    body.dev-preview-open .code-main {
        padding-right: 0;
    }
}
