/* 공통 기반: :root 색 토큰, 다크 모드 html[data-theme="dark"], 공통 레이아웃·한글 폰트 */
  /* 한글 UI 폰트 — Inter/IBM Plex Mono는 한글 글리프가 없어서, 지금까지 한글은 전부 OS
     기본 폰트(Windows는 맑은 고딕 등)로 대체 렌더링되고 있었다. Pretendard는 Apple SD
     Gothic Neo/San Francisco 계열과 잘 어울리는 굵기·비례로 만들어진 가변 폰트라, 헤더
     워드마크가 주는 느낌(Inter/IBM Plex Mono)을 크게 벗어나지 않으면서 한글까지 통일된
     글꼴로 보여준다. 서버가 static/ 전체를 "/"로 그대로 서빙하므로 /fonts/...로 받는다. */
  @font-face{
    font-family: 'Pretendard Variable';
    font-weight: 45 920;
    font-style: normal;
    font-display: swap;
    src: url('/fonts/PretendardVariable.woff2') format('woff2-variations');
  }
  /* IBM Plex Mono — --mono가 첫 글꼴로 지정해 두고도 파일이 없어서 Windows에서는 Consolas로 보이고
     있었다(NS-1). latin 400/500/600만 자체 호스팅한다(OFL, static/fonts/IBMPlexMono-LICENSE.txt). */
  @font-face{ font-family:'IBM Plex Mono'; font-weight:400; font-style:normal; font-display:swap; src:url('/fonts/IBMPlexMono-400.woff2') format('woff2'); }
  @font-face{ font-family:'IBM Plex Mono'; font-weight:500; font-style:normal; font-display:swap; src:url('/fonts/IBMPlexMono-500.woff2') format('woff2'); }
  @font-face{ font-family:'IBM Plex Mono'; font-weight:600; font-style:normal; font-display:swap; src:url('/fonts/IBMPlexMono-600.woff2') format('woff2'); }
  :root{
    --bg: #F7F8FA;
    --panel: #FFFFFF;
    --border: #E3E6EB;
    --text: #1B1F24;
    --text-dim: #6B7280;
    --log-text: #475467;
    --queued: #2563EB; --queued-rgb: 37,99,235;
    --running: #B45309; --running-rgb: 180,83,9;
    --done: #15803D; --done-rgb: 21,128,61;
    --failed: #DC2626; --failed-rgb: 220,38,38;
    --interrupted: #7C3AED; --interrupted-rgb: 124,58,237;
    /* 두 스택 모두 한글 대체 폰트로 Pretendard Variable을 추가한다 — 영문/숫자는 원래
       폰트(IBM Plex Mono/Inter) 그대로 쓰이고, 그 폰트에 없는 한글 글리프만 브라우저가
       자동으로 Pretendard로 넘어가 렌더링한다(폰트 스택의 문자 단위 폴백 특성 이용). */
    --mono: 'IBM Plex Mono', 'Pretendard Variable', 'SFMono-Regular', Menlo, Consolas, monospace;
    /* 로고·메뉴·제목이 함께 쓰는 자간 — 로그인 화면 워드마크의 느낌을 앱 전체로 */
    --track-brand: 0.24em; --track-nav: 0.14em; --track-label: 0.16em;
    --sans: 'Pretendard Variable', 'Inter', -apple-system, sans-serif;

    /* 버튼 디자인 시스템 — 색상별(파랑=주요 동작/초록=시작/빨강=위험) 그라데이션과
       hover/disabled 상태를 한곳에서 정의해서, 페이지 전체 버튼이 같은 규칙(그라데이션
       방향, 눌림 효과, 그림자, 라운드)을 공유하게 한다. 새 버튼을 추가할 때도 아래
       .btn-primary/.btn-success/.btn-danger/.btn-ghost 중 맞는 걸 그대로 쓰면 된다. */
    --radius-md: 8px;
    --radius-sm: 6px;
    --gap-xs: 6px;
    --gap-sm: 8px;
    --gap-md: 12px;
    --gap-lg: 20px;

    --grad-primary: linear-gradient(135deg, #3B7DF5, #2054D6);
    --grad-primary-hover: linear-gradient(135deg, #5691F7, #2C63EE);
    --grad-success: linear-gradient(135deg, #1E9350, #0F6B33);
    --grad-success-hover: linear-gradient(135deg, #22A75C, #128038);
    --grad-danger: linear-gradient(135deg, #E5484D, #C81E23);
    --grad-danger-hover: linear-gradient(135deg, #EE6367, #DC2626);
    --grad-running: linear-gradient(135deg, #D97706, #B45309);
    --grad-running-hover: linear-gradient(135deg, #E88A1B, #C2660A);
  }
  /* 밤 모드 — OS 설정을 기본으로 따르되(prefers-color-scheme), 사용자가 헤더의
     토글로 명시적으로 고르면 그 선택(html[data-theme])이 OS 설정보다 우선한다.
     accent 색(queued/running/done/failed/interrupted, 그라데이션)은 두 테마에서
     이미 충분히 선명해 그대로 두고, 배경/글자 계열만 뒤집는다. */
  @media (prefers-color-scheme: dark){
    html:not([data-theme="light"]){
      --bg: #14161B;
      --panel: #1C1F26;
      --border: #2C3038;
      --text: #E7E9ED;
      --text-dim: #97A0AC;
      --log-text: #B8C0CC;
      color-scheme: dark;
    }
  }
  html[data-theme="dark"]{
    --bg: #14161B;
    --panel: #1C1F26;
    --border: #2C3038;
    --text: #E7E9ED;
    --text-dim: #97A0AC;
    --log-text: #B8C0CC;
    color-scheme: dark;
  }
  /* color-scheme을 지정해두면 <input type="date"> 달력 아이콘·팝업 같은 브라우저
     기본 폼 컨트롤이 테마에 맞게 알아서 뒤집힌다 — 밤 모드에서 아이콘이 배경과 겹쳐
     안 보이던 문제를 막는다. data-theme="light"로 명시했을 땐 OS가 밤 모드여도 낮
     모드로 고정해야 하므로 명시적으로 되돌려준다. */
  html[data-theme="light"]{ color-scheme: light; }
  *{ box-sizing: border-box; }
  html{
    /* 문서 어딘가가 뷰포트보다 넓어지면(줄바꿈 안 되는 요소 등) 일부 모바일
       브라우저에서 position:fixed 요소(로그인 화면 등)의 정렬 기준 폭이 실제 화면
       보다 넓게 잡혀 중앙 정렬된 내용이 옆으로 밀려 잘려 보일 수 있다. 항상 화면
       폭에 고정되도록 가로 오버플로를 막아둔다. */
    overflow-x:hidden;
  }
  body{
    margin:0;
    background:var(--bg);
    color:var(--text);
    font-family:var(--sans);
    min-height:100vh;
    /* hidden이 아니라 clip — html이 이미 가로 오버플로를 막고 있고, body에 hidden을 걸면 body가
       스크롤 컨테이너가 되어 그 안의 position:sticky(갤러리 선택 툴바)가 동작하지 않는다. */
    overflow-x:clip;
  }
  header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:18px 28px;
    background:var(--panel);
    border-bottom:1px solid var(--border);
  }
  /* 로그인 화면(.login-mark/.login-wordmark)과 같은 초승달 + 자간 넓은 모노 워드마크 —
     색은 테마 변수라 밤/낮 모드에 자동으로 맞는다. */
  .brand{
    display:flex;
    align-items:center;
    gap:12px;
    color:var(--text);
    text-decoration:none;
    cursor:pointer;
    -webkit-tap-highlight-color:transparent;
  }
  .brand:focus-visible{ outline:2px solid var(--queued); outline-offset:4px; border-radius:6px; }
  .brand-mark{ width:20px; height:20px; flex:none; }
  .brand-wordmark{
    font-family:var(--mono);
    font-size:13px;
    font-weight:600;
    letter-spacing:var(--track-brand);
    text-transform:uppercase;
  }
  .header-right{
    display:flex;
    align-items:center;
    gap:16px;
  }
  /* "지금 상태" 요약 줄 — 작업 이동 모달의 "지금 이 작업이 배정된 파드" 등에 쓴다. */
  .comfy-endpoint-current{
    font-family:var(--mono);
    font-size:11.5px;
    color:var(--text-dim);
    border:1px solid var(--border);
    border-radius:var(--radius-sm);
    padding:8px 10px;
    line-height:1.7;
    word-break:break-all;
  }
  .comfy-endpoint-current b{ color:var(--text); font-weight:600; }

  /* 밤 모드/낮 모드 전환 버튼 — 필(pill) 형태로 헤더 톤을 맞춘다. */
  .theme-toggle-btn{
    display:inline-flex;
    align-items:center;
    gap:6px;
    font-family:var(--mono);
    font-size:11.5px;
    font-weight:600;
    padding:4px 10px;
    border-radius:20px;
    border:1px solid var(--border);
    background:var(--panel);
    color:var(--text-dim);
    cursor:pointer;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
  }
  .theme-toggle-btn:hover{ border-color:var(--queued); color:var(--queued); }

  /* ---- 로그인 화면 (미니멀 센터드형) ---- */
  /* 아직 별도 로그인 시스템은 없다 — 서버가 NIGHTSHIFT_API_KEY를 요구할 수 있으니,
     본 화면 접속 전에 이 게이트를 한 번 거치게 한다. 장식 없이 여백·정렬만으로
     위계를 만들고, 키 입력은 모달을 거치지 않고 이 화면 한가운데서 바로
     받는다(Enter로 제출) — 저장된 값 확인/삭제 같은 세부 조작만 하단의 조용한
     링크로 기존 API 키 모달을 열어 처리한다. 색은 새로 만들지 않고 앱이 이미
     쓰는 테마 변수를 그대로 물려받아 밤/낮 모드 전환에 자동으로 맞는다. */
  .login-screen{
    position:fixed;
    inset:0;
    /* .modal-overlay(z-index:70)보다 낮아야 한다 — 하단 링크로 여는 API 키
       모달이 이 화면 뒤에 가려지면 안 된다. */
    z-index:65;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:24px;
    background:
      radial-gradient(circle at 50% 42%, rgba(var(--queued-rgb),0.05), transparent 60%),
      radial-gradient(var(--border) 1px, transparent 1px) 0 0/28px 28px,
      var(--bg);
  }
  .login-content{
    width:100%;
    max-width:320px;
    display:flex;
    flex-direction:column;
    align-items:center;
    text-align:center;
    gap:20px;
  }
  @media (prefers-reduced-motion: no-preference){
    .login-content{ animation: login-rise .5s cubic-bezier(.16,1,.3,1) both; }
  }
  @keyframes login-rise{
    from{ opacity:0; transform:translateY(6px); }
    to{ opacity:1; transform:translateY(0); }
  }
  .login-mark{ width:20px; height:20px; color:var(--text); }
  .login-heading{ display:flex; flex-direction:column; gap:8px; }
  .login-wordmark{
    font-family:var(--mono);
    font-size:12px;
    font-weight:600;
    letter-spacing:var(--track-brand);
    text-transform:uppercase;
    color:var(--text);
  }
  .login-tagline{
    font-size:13.5px;
    color:var(--text-dim);
    line-height:1.6;
    max-width:30ch;
  }
  .login-access-field{ width:100%; display:flex; flex-direction:column; gap:10px; }
  .login-field-shell{
    width:100%;
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:999px;
    padding:12px 20px;
    transition: border-color .2s ease, box-shadow .2s ease;
  }
  .login-field-shell:focus-within{
    border-color:var(--queued);
    box-shadow:0 0 0 4px rgba(var(--queued-rgb),0.14);
  }
  .login-enter-hint{
    display:flex; align-items:center; justify-content:center; gap:6px;
    font-size:11px;
    color:var(--text-dim);
    opacity:0.6;
    transition:opacity .2s ease;
  }
  .login-submit-btn{
    width:100%;
    padding:11px 20px;
    border:none;
    border-radius:999px;
    background:var(--grad-primary);
    color:#fff;
    font-family:var(--sans);
    font-size:14px;
    font-weight:600;
    cursor:pointer;
    transition: box-shadow .15s ease, transform .05s ease;
  }
  .login-submit-btn:hover{ box-shadow:0 4px 14px rgba(var(--queued-rgb),0.35); }
  .login-submit-btn:active{ transform:translateY(1px); }
  .login-error{
    font-size:12.5px;
    color:var(--failed);
    min-height:1.2em;
  }
  .login-notice, .account-ok{ font-size:12.5px; color:var(--done); min-height:1.2em; line-height:1.5; }
  .login-input{
    width:100%; border:none; outline:none; background:none; text-align:center;
    font-family:var(--mono); font-size:14px; letter-spacing:0.03em; color:var(--text);
  }
  .login-input::placeholder{ color:var(--text-dim); opacity:0.7; }
  .login-tabs{ display:flex; gap:22px; }
  .login-tab{
    background:none; border:none; padding:4px 2px; cursor:pointer; color:var(--text-dim);
    font-family:var(--mono); font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:var(--track-nav);
    border-bottom:2px solid transparent;
  }
  .login-tab.active{ color:var(--text); border-bottom-color:var(--queued); }
  .user-chip{
    display:inline-flex; align-items:center; gap:6px; padding:4px 10px; border-radius:20px;
    border:1px solid var(--border); background:var(--panel); color:var(--text-dim); cursor:pointer;
    font-family:var(--mono); font-size:11.5px; font-weight:600; max-width:180px;
  }
  .user-chip:hover{ border-color:var(--queued); color:var(--queued); }
  .user-chip-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:110px; }
  .role-badge{
    font-size:9.5px; text-transform:uppercase; letter-spacing:0.1em; padding:1px 5px; border-radius:4px;
    background:rgba(var(--queued-rgb),0.12); color:var(--queued);
  }
  .tab-badge{
    display:inline-block; min-width:16px; padding:0 5px; margin-left:6px; border-radius:8px; text-align:center;
    background:var(--failed); color:#fff; font-size:10px; line-height:16px; letter-spacing:0;
  }
  .admin-stats{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:16px; }
  .admin-stat{
    flex:1 1 120px; padding:10px 14px; border:1px solid var(--border); border-radius:var(--radius-md); background:var(--bg);
    font-family:var(--mono); font-size:11.5px; color:var(--text-dim);
  }
  .admin-stat b{ display:block; font-size:20px; color:var(--text); margin-top:2px; }
  .admin-stat.attention b{ color:var(--running); }
  .admin-users{ display:flex; flex-direction:column; gap:10px; }
  .admin-user{
    display:grid; grid-template-columns:minmax(0,1.4fr) auto minmax(0,1.3fr) auto; align-items:center; gap:10px 16px;
    padding:12px 14px; border:1px solid var(--border); border-radius:var(--radius-md); background:var(--panel);
  }
  .admin-user.pending{ border-color:rgba(var(--running-rgb),0.5); background:rgba(var(--running-rgb),0.05); }
  .admin-user.disabled{ opacity:.7; }
  .admin-user-name{ font-weight:600; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .admin-user-sub{ font-size:12px; color:var(--text-dim); overflow-wrap:anywhere; }
  .admin-user-meta{ font-family:var(--mono); font-size:11.5px; color:var(--text-dim); display:flex; flex-direction:column; gap:2px; }
  .admin-user-actions{ display:flex; flex-wrap:wrap; gap:6px; justify-content:flex-end; }
  .status-pill{
    font-family:var(--mono); font-size:11px; font-weight:600; padding:2px 10px; border-radius:20px; white-space:nowrap;
    border:1px solid var(--border); color:var(--text-dim);
  }
  .status-pill.active{ color:var(--done); border-color:rgba(var(--done-rgb),0.4); background:rgba(var(--done-rgb),0.08); }
  .status-pill.pending{ color:var(--running); border-color:rgba(var(--running-rgb),0.45); background:rgba(var(--running-rgb),0.1); }
  .status-pill.disabled{ color:var(--failed); border-color:rgba(var(--failed-rgb),0.4); background:rgba(var(--failed-rgb),0.07); }
  .owner-badge{ display:inline-flex; align-items:center; gap:4px; }
  @media (max-width:820px){
    .admin-user{ grid-template-columns:1fr auto; }
    .admin-user-meta, .admin-user-actions{ grid-column:1 / -1; }
    .admin-user-actions{ justify-content:flex-start; }
  }
  .account-facts{ display:grid; grid-template-columns:auto 1fr; gap:6px 14px; margin:0 0 14px; font-size:13px; }
  .account-facts dt{ color:var(--text-dim); font-family:var(--mono); font-size:11.5px; }
  .account-facts dd{ margin:0; overflow-wrap:anywhere; }
  .account-dev-link{ display:flex; align-items:center; gap:6px; margin-top:14px; padding-top:12px; border-top:1px solid var(--border);
    font-size:13px; color:var(--queued); text-decoration:none; }
  .account-dev-link span{ color:var(--text-dim); }
  .account-dev-link:hover{ text-decoration:underline; text-underline-offset:3px; }
  .account-secret-input{ display:flex; gap:6px; align-items:center; }
  .account-secret-input .option-input{ flex:1; max-width:none; }
  .account-secret-input .icon-btn{ flex-shrink:0; }
  @media (max-width:640px){ .user-chip-name{ max-width:64px; } .user-chip .role-badge{ display:none; } }
  .login-watermark{
    position:absolute;
    left:0; right:0; bottom:max(22px, env(safe-area-inset-bottom,0px));
    text-align:center;
    font-family:var(--mono);
    font-size:10px;
    letter-spacing:0.22em;
    text-transform:uppercase;
    color:var(--text-dim);
    opacity:0.45;
    pointer-events:none;
  }

  .tab-bar{
    background:var(--panel);
    border-bottom:1px solid var(--border);
  }
  .tab-bar-inner{
    max-width:1180px;
    margin:0 auto;
    padding:0 28px;
    display:flex;
    gap:4px;
    /* 탭이 화면 폭보다 많아지면(좁은 모바일) 줄바꿈 대신 가로 스크롤 — 탭 줄은
       세로로 쌓이면 오히려 어색해서, 카드 목록과 달리 스크롤 쪽을 택했다. */
    overflow-x:auto;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
  }
  .tab-bar-inner::-webkit-scrollbar{ display:none; }
  .tab-btn{
    background:none;
    border:none;
    border-bottom:2px solid transparent;
    color:var(--text-dim);
    font-family:var(--mono);
    font-size:12px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:var(--track-nav);
    padding:12px 8px;
    cursor:pointer;
    margin-bottom:-1px;
    white-space:nowrap;
    flex-shrink:0;
  }
  .tab-btn:hover{ color:var(--text); }
  .tab-btn.active{ color:var(--queued); border-bottom-color:var(--queued); }
  /* 상단 내비는 평소 아이콘만 보이고, 마우스를 올리면 오른쪽으로 제목이 펼쳐진다. 호버가 없는
     기기(폰·태블릿)에서는 늘 아이콘만 — 제목은 title로 남는다. */
  #global-tab-bar .tab-btn{ display:inline-flex; align-items:center; padding:12px 10px; }
  #global-tab-bar .tab-btn .ico{ width:17px; height:17px; vertical-align:0; }
  #global-tab-bar .tab-label{ display:inline-block; max-width:0; opacity:0; overflow:hidden; margin-left:0;
                              transition:max-width .28s ease, opacity .2s ease, margin-left .28s ease; }
  @media (hover:hover){
    #global-tab-bar .tab-btn:hover .tab-label,
    #global-tab-bar .tab-btn:focus-visible .tab-label{ max-width:12em; opacity:1; margin-left:7px; }
  }
  @media (prefers-reduced-motion:reduce){ #global-tab-bar .tab-label{ transition:none; } }
  .tab-bar-sep{ width:1px; height:16px; align-self:center; background:var(--border); margin:0 8px; }

  /* 파드 스코프 바 — 전역 탭바 아래에 한 줄 더 붙는다. 바탕색을 본문과 같게 해서
     "여기부터는 이 파드 안"이라는 게 탭바와 눈으로 구분되게 한다. */
  .pod-bar{ background:var(--bg); border-bottom:1px solid var(--border); }
  .pod-bar-inner{
    max-width:1180px; margin:0 auto; padding:9px 28px;
    display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  }
  .pod-bar-back{
    background:none; border:1px solid var(--border); border-radius:6px;
    color:var(--text-dim); font-family:var(--mono); font-size:12px;
    text-transform:uppercase; letter-spacing:var(--track-nav);
    padding:4px 9px; cursor:pointer; flex:none;
  }
  .pod-bar-back:hover{ color:var(--queued); border-color:var(--queued); }
  .pod-bar-select{
    background:var(--panel); border:1px solid var(--border); border-radius:6px;
    color:var(--text); font-family:var(--mono); font-size:13px; font-weight:600;
    padding:4px 8px; cursor:pointer; max-width:260px;
  }
  .pod-bar-kind{ font-size:10.5px; color:var(--text-dim); border:1px solid var(--border); border-radius:4px; padding:1px 5px; }
  .pod-bar-subtabs{ display:flex; gap:4px; margin-left:auto; }
  .pod-subtab-btn{
    background:none; border:1px solid transparent; border-radius:6px;
    color:var(--text-dim); font-family:var(--mono); font-size:12px; font-weight:600;
    text-transform:uppercase; letter-spacing:var(--track-nav);
    padding:5px 10px; cursor:pointer;
  }
  .pod-subtab-btn:hover{ color:var(--text); }
  .pod-subtab-btn.active{ color:var(--queued); border-color:var(--queued); background:rgba(var(--queued-rgb),0.08); }
  .pod-subtab-btn:disabled{ opacity:0.4; cursor:not-allowed; }
  .pod-subtab-btn:disabled:hover{ color:var(--text-dim); }

  /* New Job 패널 안에서 "새 작업"(마법사/업로드)과 "세부 설정"(옵션/CSV/제출)을
     나누는 탭 — .pod-bar-subtabs/.pod-subtab-btn과 같은 페이지 내 탭 패턴. */
  .new-job-tabs{
    display:flex; gap:4px;
    border-bottom:1px solid var(--border);
    padding-bottom:10px;
    margin-bottom:14px;
  }

  /* Lucide SVG 아이콘(body 맨 위 스프라이트) — 글자 크기에 맞춰 커지고 글자색을 따른다. */
  .ico{
    width:1.2em; height:1.2em; flex:none;
    fill:none; stroke:currentColor; stroke-width:2;
    stroke-linecap:round; stroke-linejoin:round;
    vertical-align:-0.22em;
  }
  .ico-spin{ animation: enhance-spin .8s linear infinite; }
  .collapse-btn .ico{ width:14px; height:14px; vertical-align:middle; }
  .pod-bar-back, .pod-subtab-btn, .lightbox-actions button, #pod-bar-settings, #project-bar-settings{
    display:inline-flex; align-items:center; justify-content:center; gap:6px;
  }
  /* ---- 결과물 메타(즐겨찾기·평점·태그·메모): 갤러리 필터/별/라이트박스 정보 패널 ---- */
  .gallery-filter-row{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:12px; }
  .gallery-filter-row .gf-search{ flex:1 1 200px; min-width:150px; max-width:340px; padding:7px 10px; font-size:13px; cursor:text; }
  .gallery-filter-row select{ font-size:12.5px; }
  /* 날짜 범위 입력(DB 탭의 생성 정보/업데이트 내역 등) — 기본 .option-input은 모달 폼에
     맞춘 굵은 패딩/큰 글자라 옆의 종류 탭(.enhance-mode)·필터 지우기 버튼과 높이·글꼴이
     안 맞았다. 같은 줄의 고스트 버튼 계열(.load-btn 등, 4px 10px / 11px mono)에 맞춘다. */
  .gallery-filter-row input[type="date"]{
    font-family:var(--mono);
    font-size:11px;
    font-weight:600;
    padding:4px 8px;
    border-radius:var(--radius-sm);
    max-width:128px;
  }
  .db-filter-dash{ color:var(--text-dim); font-size:11px; font-family:var(--mono); }
  /* "필터 지우기"는 모달 취소 버튼(.modal-btn-secondary)을 그대로 쓰고 있어 크기가
     한 단계 컸다 — .gallery-toolbar에서 이미 쓰던 것과 같은 축소 규칙을 적용한다. */
  .gallery-filter-row .modal-btn-secondary{ padding:4px 10px; font-size:11px; }
  .gf-toggle{ display:inline-flex; align-items:center; gap:6px; }
  .gf-toggle.on{ color:var(--queued); border-color:var(--queued); background:rgba(var(--queued-rgb),0.08); }
  .gf-toggle.on .ico{ fill:currentColor; }
  .gallery-item-fav, .vgallery-item-fav{
    position:absolute; top:34px; right:6px; z-index:2;
    width:22px; height:22px; padding:0; border:none; border-radius:50%;
    background:rgba(0,0,0,0.45); color:#fff; cursor:pointer;
    display:flex; align-items:center; justify-content:center;
    opacity:0; transition:opacity .12s ease, transform .12s ease;
  }
  .gallery-item-fav .ico, .vgallery-item-fav .ico{ width:13px; height:13px; vertical-align:0; }
  .gallery-item:hover .gallery-item-fav, .vgallery-item:hover .vgallery-item-fav,
  .gallery-item-fav.on, .vgallery-item-fav.on, .gallery-item-fav:focus-visible, .vgallery-item-fav:focus-visible{ opacity:1; }
  .gallery-item-fav.on, .vgallery-item-fav.on{ color:#FBBF24; }
  .gallery-item-fav.on .ico, .vgallery-item-fav.on .ico{ fill:currentColor; }
  .gallery-item-fav:hover, .vgallery-item-fav:hover{ transform:scale(1.1); }
  @media (hover:none){ .gallery-item-fav, .vgallery-item-fav{ opacity:0.85; } }
  .gallery-details-col.name .ico.fav{ color:#F59E0B; fill:currentColor; width:12px; height:12px; }
  .gallery-item-nsfw, .vgallery-item-nsfw{
    position:absolute; top:34px; left:6px; z-index:2;
    width:22px; height:22px; border-radius:50%;
    background:rgba(0,0,0,0.45); color:#F87171;
    display:flex; align-items:center; justify-content:center;
    pointer-events:none;
  }
  .gallery-item-nsfw .ico, .vgallery-item-nsfw .ico{ width:13px; height:13px; fill:currentColor; }
  .gallery-details-col.name .ico.nsfw, .vgallery-details-col.name .ico.nsfw{ color:#F87171; fill:currentColor; width:12px; height:12px; }
  .gallery-item-blur-overlay, .vgallery-item-blur-overlay{
    position:absolute; inset:0; z-index:1;
    display:flex; align-items:center; justify-content:center;
    background:rgba(20,20,24,0.82); color:rgba(255,255,255,0.75);
    pointer-events:none;
  }
  .gallery-item-blur-overlay .ico, .vgallery-item-blur-overlay .ico{ width:28px; height:28px; }
  .gallery-item.details .gallery-item-thumb, .vgallery-item.details .vgallery-item-thumb{ position:relative; }
  .gallery-item.details .gallery-item-blur-overlay .ico, .vgallery-item.details .vgallery-item-blur-overlay .ico{ width:18px; height:18px; }

  /* 이미지/영상은 고정 높이(100vh - 얼마)로 줄이지 않고, 정보 줄·버튼·별점 줄이 차지하는 만큼을 뺀 나머지 칸을
     채우게 한다(flex로 줄어듦, 비율은 object-fit). 세로로 긴 이미지나 폰 주소창 때문에 화면이 낮을 때도 별점·
     정보 아코디언 줄이 화면 밖으로 밀려나지 않는다. */
  .lightbox-img-wrap .lightbox-img{ max-height:none; min-height:96px; flex:0 1 auto; object-fit:contain; }
  .asset-meta{ width:100%; max-width:640px; color:#E5E7EB; font-size:12.5px; }
  .am-bar{ display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap; }
  .am-fav, .am-star{ background:none; border:none; padding:2px; cursor:pointer; color:rgba(255,255,255,0.4); display:inline-flex; }
  .am-fav .ico{ width:20px; height:20px; }
  .am-star .ico{ width:17px; height:17px; }
  .am-fav:hover, .am-star:hover{ color:#FCD34D; }
  .am-fav.on, .am-star.on{ color:#FBBF24; }
  .am-fav.on .ico, .am-star.on .ico{ fill:currentColor; }
  .am-nsfw{ background:none; border:none; padding:2px; cursor:pointer; color:rgba(255,255,255,0.4); display:inline-flex; }
  .am-nsfw .ico{ width:20px; height:20px; }
  .am-nsfw:hover{ color:#F87171; }
  .am-nsfw.on{ color:#F87171; }
  .am-nsfw.on .ico{ fill:currentColor; }
  .am-stars{ display:inline-flex; gap:2px; }
  .am-status{ min-width:5.5em; font-family:var(--mono); font-size:11px; color:#9CA3AF; }
  .am-toggle{
    display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:999px;
    background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.18); color:#E5E7EB;
    font-family:var(--mono); font-size:11.5px; cursor:pointer;
  }
  .am-toggle .ico{ transition:transform .15s ease; }
  .am-toggle.open .ico{ transform:rotate(180deg); }
  @media (min-width:900px){
    .lightbox-overlay:not(.lightbox-fullscreen) .am-toggle .ico{ transform:rotate(-90deg); }
    .lightbox-overlay:not(.lightbox-fullscreen) .am-toggle.open .ico{ transform:rotate(90deg); }
  }
  .am-toggle:hover{ background:rgba(255,255,255,0.14); }
  .am-body{
    margin-top:8px; padding:10px 12px; display:flex; flex-direction:column; gap:8px;
    background:rgba(255,255,255,0.06); border:1px solid rgba(255,255,255,0.12); border-radius:8px;
    max-height:36vh; overflow-y:auto; text-align:left;
  }
  .am-body[hidden]{ display:none; }
  /* .option-input(input.option-input / textarea.option-input)보다 특이도가 높아야 이긴다 */
  .am-body input.am-tag-input, .am-body textarea.am-note{
    width:100%; max-width:none; background:rgba(0,0,0,0.35); color:#fff;
    border-color:rgba(255,255,255,0.2); cursor:text; font-size:12.5px; padding:7px 10px;
  }
  .am-body input.am-tag-input::placeholder, .am-body textarea.am-note::placeholder{ color:#9CA3AF; }
  .am-body textarea.am-note{ resize:vertical; min-height:2.6em; }
  .am-tags{ display:flex; flex-wrap:wrap; gap:6px; }
  .am-chip{
    display:inline-flex; align-items:center; gap:3px; padding:2px 4px 2px 9px; border-radius:999px;
    background:rgba(var(--queued-rgb),0.28); color:#DBEAFE; font-family:var(--mono); font-size:11.5px;
  }
  .am-chip button{ background:none; border:none; color:inherit; cursor:pointer; padding:2px; display:inline-flex; opacity:0.8; }
  .am-chip button:hover{ opacity:1; }
  .am-chip .ico{ width:12px; height:12px; }
  .am-empty{ color:#9CA3AF; font-size:12px; }
  .am-facts{ display:grid; grid-template-columns:auto 1fr; gap:3px 12px; margin:0; }
  .am-kv{ display:contents; }
  .am-facts dt{ color:#9CA3AF; }
  .am-facts dd{ margin:0; word-break:break-all; font-family:var(--mono); font-size:11.5px; }
  .am-prompt-head{ display:flex; align-items:center; justify-content:space-between; color:#9CA3AF; margin-top:2px; }
  .am-prompt{
    font-family:var(--mono); font-size:11.5px; line-height:1.55; white-space:pre-wrap; word-break:break-word;
    background:rgba(0,0,0,0.35); padding:8px 10px; border-radius:6px; max-height:130px; overflow:auto; margin-top:4px;
  }
  .am-badge{ margin-left:6px; padding:1px 6px; border-radius:999px; background:rgba(var(--queued-rgb),0.28); color:#DBEAFE; font-size:11px; }
  @media (max-width:640px){
    .am-status{ min-width:0; }
    .gallery-filter-row .gf-search{ flex:1 1 100%; max-width:none; }
  }

  /* 갤러리·영상 탭에 파일을 끌어 올렸을 때 — 놓으면 업로드 창이 열린다 */
  .upload-drop > .panel{ outline:2px dashed var(--running); outline-offset:-4px; }
  .board-viewport.upload-drop{ outline:2px dashed var(--running); outline-offset:-4px; }
  /* 긴 목록 끝의 "더 보기" — 화면 가까이 오면 저절로 눌린다(01-core-jobs.js setupLoadMore) */
  .load-more-btn{
    display:block; width:100%; margin:14px 0 4px; padding:10px; border-radius:8px; cursor:pointer;
    font:inherit; font-size:13px; color:var(--text-dim); background:var(--bg); border:1px dashed var(--border);
  }
  .load-more-btn:hover{ color:var(--text); border-color:rgba(var(--queued-rgb),0.6); }
  .load-more-btn[hidden]{ display:none; }
  /* ---- 프로젝트 (홈 대시보드 / 새 작업 폼의 대상 선택) ---- */
  .home-archived-toggle{
    display:inline-flex; align-items:center; gap:6px;
    font-size:12.5px; color:var(--text-dim); cursor:pointer; margin-left:auto;
  }
  .home-strip-pods{ align-self:center; margin-left:auto; }
  .project-card{
    position:relative; display:flex; flex-direction:column; overflow:hidden;
    background:var(--panel); border:1px solid var(--border); border-radius:10px;
    cursor:pointer; transition:border-color .12s ease, box-shadow .12s ease;
  }
  .project-card:hover, .project-card:focus-visible{
    border-color:var(--queued); box-shadow:0 2px 10px rgba(var(--queued-rgb),0.12); outline:none;
  }
  .project-card.inbox{ border-style:dashed; }
  .project-card.archived{ opacity:0.6; }
  .project-cover{
    position:relative;
    height:150px; background:var(--bg); display:flex; align-items:center; justify-content:center;
    border-bottom:1px solid var(--border);
  }
  /* 대표 이미지 고르기 — 카드 커버 오른쪽 위. 마우스에서는 카드에 올렸을 때, 터치에서는 항상 보인다. */
  .project-cover-btn{
    position:absolute; top:8px; right:8px; z-index:2; width:30px; height:30px; padding:0;
    display:inline-flex; align-items:center; justify-content:center; cursor:pointer;
    border:none; border-radius:50%; background:rgba(0,0,0,0.55); color:#fff; opacity:0;
    transition:opacity .12s ease, transform .12s ease;
  }
  .project-card:hover .project-cover-btn, .project-cover-btn:focus-visible{ opacity:1; }
  .project-cover-btn:hover{ transform:scale(1.1); background:rgba(0,0,0,0.75); }
  .project-cover-btn .ico{ width:16px; height:16px; }
  @media (hover:none){ .project-cover-btn{ opacity:0.85; } }
  .cover-picker-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(96px, 1fr)); gap:8px; max-height:52vh; overflow-y:auto; padding:2px; }
  .cover-picker-item{
    position:relative; aspect-ratio:1; padding:0; border:2px solid transparent; border-radius:8px; overflow:hidden;
    cursor:pointer; background:var(--bg);
  }
  .cover-picker-item img{ width:100%; height:100%; object-fit:cover; display:block; }
  #cover-picker-auto.active{ border-color:var(--queued); color:var(--queued); }
  .cover-picker-item:hover{ border-color:var(--text-dim); }
  .cover-picker-item.current{ border-color:var(--queued); }
  .cover-picker-item.current::after{
    content:''; position:absolute; top:6px; right:6px; width:18px; height:18px; border-radius:50%;
    background:var(--queued) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/12px no-repeat;
  }
  .project-cover-img{ width:100%; height:100%; object-fit:cover; display:block; }
  .project-cover-empty{ color:var(--text-dim); opacity:0.45; }
  .project-cover-empty .ico{ width:36px; height:36px; }
  .project-card-body{ padding:12px 14px; display:flex; flex-direction:column; gap:6px; }
  .project-card-head{ display:flex; align-items:center; gap:8px; }
  .project-card-name{
    flex:1; min-width:0; font-weight:600; font-size:14px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .project-card-edit{ flex:none; padding:4px 7px; }
  .project-card-desc{
    font-size:12px; color:var(--text-dim); line-height:1.5;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  }
  .project-card-stats{
    display:flex; flex-wrap:wrap; gap:2px 12px;
    font-family:var(--mono); font-size:11.5px; color:var(--text-dim);
  }
  .project-card-stats b{ color:var(--text); font-weight:600; }
  .project-badge{ display:inline-flex; align-items:center; gap:4px; }
  .job-target-row{ display:flex; flex-wrap:wrap; gap:16px; margin-bottom:16px; }
  .job-target-field{ display:flex; flex-direction:column; gap:6px; flex:1 1 220px; max-width:360px; }
  .job-target-field .pod-bar-select{ max-width:none; width:100%; }

  /* 폰에서는 파드 바/서브탭/라이트박스 버튼의 글자를 숨기고 아이콘만 남긴다 — 폭이
     좁아 글자가 한 자씩 세로로 쪼개지던 문제. 서브탭은 한 줄을 똑같은 폭으로 나눠 쓴다. */
  @media (max-width:640px){
    .pod-bar-back .btn-label, .pod-subtab-btn .btn-label, .lightbox-actions .btn-label, .gallery-toolbar .btn-label,
    #pod-edit-modal .modal-footer .btn-label, .board-toolbar .btn-label, .new-job-next-right .btn-label{ display:none; }
    .pod-bar-back{ padding:7px 10px; }
    .pod-bar-subtabs{ flex:1 1 100%; margin-left:0; gap:6px; }
    .pod-subtab-btn{ flex:1; padding:9px 0; }
    .pod-subtab-btn .ico{ width:20px; height:20px; }
    .lightbox-actions{ flex-wrap:wrap; justify-content:center; gap:8px; }
    .lightbox-actions button{ width:40px; height:40px; padding:0; }
    .lightbox-actions .ico{ width:20px; height:20px; }
    #pod-edit-modal .modal-footer{ flex-wrap:wrap; }
    #pod-edit-modal .modal-footer button{ padding:8px; }
  }

  main{
    max-width:1180px;
    margin:0 auto;
    padding:32px 28px 80px;
    display:flex;
    flex-direction:column;
    gap:24px;
  }

  /* 프로젝트 보드 — 헤더/내비/프로젝트 바는 그대로 두고 그 아래 공간을 캔버스가
     전부 쓴다(진짜 전체화면이 아니라 위 main의 가운데 정렬·좌우 여백만 벗겨냄).
     세로 크기는 CSS만으로 "화면 나머지 전부"를 고정하기 어려워(body가 flex 셸이
     아니라 그냥 문서 흐름) resizeBoardViewport()가 실측해서 맞춘다. */
  main#tab-prboard{ max-width:none; margin:0; padding:0; display:block; gap:0; }
  .board-content{ display:flex; min-width:0; }
  .board-current-name{ min-width:0; max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; font-weight:600; }
  .board-tree{ flex:0 0 240px; width:240px; background:var(--panel); border-right:1px solid var(--border); position:relative; display:flex; flex-direction:column; }
  .board-tree[hidden]{ display:flex; flex-basis:12px; width:12px; background:var(--panel-2); cursor:pointer; }
  .board-tree[hidden] > *{ display:none; }
  .board-tree-head{ height:44px; padding:0 8px 0 16px; display:flex; align-items:center; justify-content:space-between; font-size:13px; border-bottom:1px solid var(--border); }
  #board-tree-toggle, .board-tree-head .icon-btn{ width:40px; height:40px; min-width:40px; }
  .board-tree-list{ flex:1; min-height:120px; padding:8px; }
  .board-tree-root{ display:flex; align-items:center; gap:8px; min-height:40px; padding:0 8px; font-size:13px; font-weight:600; color:var(--text-dim); }
  .board-tree-item{ display:flex; align-items:center; gap:8px; width:100%; min-height:44px; padding:0 8px 0 24px; border:0; border-radius:6px; background:transparent; color:var(--text); font:inherit; font-size:13px; text-align:left; cursor:pointer; }
  .board-tree-item:hover, .board-tree-item:focus-visible{ background:var(--panel-2); }
  .board-tree-item[aria-selected="true"]{ background:var(--panel-2); color:var(--accent); font-weight:600; }
  .board-tree-item .ico, .board-tree-root .ico{ flex:none; }
  .board-tree-item span{ overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
  .board-tree-empty{ padding:16px; font-size:13px; color:var(--text-dim); line-height:1.6; }
  .board-tree-menu{ position:fixed; z-index:1001; min-width:150px; padding:4px; border:1px solid var(--border); border-radius:8px; background:var(--panel); box-shadow:0 8px 24px rgba(16,24,40,.12); }
  .board-tree-menu button{ display:block; width:100%; min-height:40px; padding:8px 12px; border:0; border-radius:6px; background:transparent; color:var(--text); font:inherit; font-size:13px; text-align:left; cursor:pointer; }
  .board-tree-menu button:hover, .board-tree-menu button:focus-visible{ background:var(--panel-2); }
  .board-tree-menu button.danger{ color:var(--failed); }
  @media(max-width:700px){ .board-content{ position:relative; } .board-tree{ position:absolute; z-index:10; top:0; left:0; bottom:0; width:min(280px,85vw); box-shadow:0 8px 24px rgba(16,24,40,.12); } .board-tree[hidden]{ width:12px; box-shadow:none; } .board-current-name{ max-width:110px; } }
  .board-toolbar{
    display:flex; align-items:center; gap:8px;
    padding:10px 16px;
    border-bottom:1px solid var(--border);
    background:var(--panel);
  }
  .board-zoom-label{
    font-family:var(--mono); font-size:11.5px; color:var(--text-dim);
    min-width:3.5em; text-align:center;
  }
  .board-viewport{
    position:relative;
    flex:1; min-width:0;
    overflow:hidden;
    background-color:var(--bg);
    /* 점 격자 배경 — "무한 캔버스" 느낌. board-world와 같은 변환을 받도록(팬/줌에
       맞춰) applyBoardTransform()이 background-position/-size를 같이 갱신한다. */
    background-image:radial-gradient(circle, var(--border) 1px, transparent 1px);
    background-size:24px 24px;
    cursor:grab;
    touch-action:none;
  }
  .board-viewport.panning{ cursor:grabbing; }
  .board-world{
    position:absolute; top:0; left:0;
    transform-origin:0 0;
    will-change:transform;
  }
  .board-toolbar-sep{ width:1px; height:20px; background:var(--border); margin:0 4px; }
  /* 폰에서는 버튼이 한 줄에 다 안 들어가 두 줄로 접는다 — 캔버스 높이는 resizeBoardViewport가
     툴바 아래부터 실측하므로 줄 수가 바뀌어도 맞는다. */
  .board-toolbar{ flex-wrap:wrap; row-gap:6px; }
  #board-select-mode-btn[aria-pressed="true"]{ background:rgba(var(--queued-rgb),0.14); color:var(--queued); border-color:var(--queued); }

  /* 고른 카드 · 사각형으로 고르는 중의 틀 · 캔버스 아래쪽 선택 막대 */
  .board-node.selected{ outline:2px solid var(--queued); outline-offset:2px; }
  .board-marquee{
    position:absolute; z-index:7; pointer-events:none;
    border:1px solid var(--queued); background:rgba(var(--queued-rgb),0.08);
  }
  /* 전체 보기 — 캔버스 오른쪽 아래에 떠 있는 동그란 버튼(선택 막대는 가운데 아래라 겹치지 않는다) */
  .board-fit-fab{
    position:absolute; z-index:8; right:16px; bottom:16px; width:44px; height:44px; border-radius:50%;
    display:flex; align-items:center; justify-content:center; cursor:pointer; color:var(--text);
    background:var(--panel); border:1px solid var(--border); box-shadow:0 4px 14px rgba(16,24,40,0.16);
  }
  .board-fit-fab .ico{ width:18px; height:18px; }
  /* 보드 우클릭·길게 누르기 메뉴 */
  .board-ctx-menu{
    position:fixed; z-index:1000; min-width:170px; padding:4px; border-radius:8px; display:flex; flex-direction:column;
    background:var(--panel); border:1px solid var(--border); box-shadow:0 4px 14px rgba(16,24,40,0.16);
  }
  .board-ctx-menu button{
    display:flex; align-items:center; gap:8px; padding:8px 10px; border:none; border-radius:6px; background:transparent;
    font:inherit; font-size:13px; color:var(--text); text-align:left; cursor:pointer;
  }
  .board-ctx-menu button:hover:not(:disabled){ background:rgba(var(--queued-rgb),0.12); color:var(--queued); }
  .board-ctx-menu button:disabled{ color:var(--text-dim); cursor:default; }
  .board-ctx-menu .ico{ width:14px; height:14px; }
  .board-fit-fab:hover{ border-color:rgba(var(--queued-rgb),0.6); color:var(--queued); }
  .board-selection-bar{
    position:absolute; z-index:8; left:50%; bottom:16px; transform:translateX(-50%);
    display:flex; align-items:center; gap:6px;
    padding:6px 6px 6px 14px;
    background:var(--panel); border:1px solid var(--border); border-radius:999px;
    box-shadow:0 4px 14px rgba(16,24,40,0.16);
    font-size:13px; white-space:nowrap; cursor:default;
  }
  .board-selection-count{ color:var(--text); font-weight:600; margin-right:4px; }
  .board-selection-btn{
    display:inline-flex; align-items:center; gap:4px;
    padding:6px 12px; border-radius:999px; border:1px solid var(--border);
    background:var(--bg); color:var(--text); font-size:12.5px; cursor:pointer;
  }
  .board-selection-btn .ico{ width:13px; height:13px; }
  .board-selection-btn.danger{ color:var(--failed); }
  .board-selection-btn.danger:hover{ background:rgba(var(--failed-rgb),0.1); }

  /* 카드(노드) — 좌표는 board-world 기준(월드 좌표), 배율과 무관하게 px로 저장/복원된다. */
  .board-node{
    position:absolute;
    border:1px solid var(--border);
    border-radius:10px;
    background:var(--panel);
    box-shadow:0 1px 3px rgba(16,24,40,0.08);
    overflow:hidden;
    cursor:grab;
    touch-action:none;
  }
  /* 캔버스 위에서는 글자 선택을 막는다 — Shift+클릭으로 카드를 여러 장 고를 때 브라우저가
     그 사이 글자를 선택해 두면, 이어서 끌 때 "선택한 글자 끌어다 놓기"가 시작되며 카드 끌기가
     취소(pointercancel)된다. 글쓰기 중인 글칸만 예외. */
  .board-viewport{ -webkit-user-select:none; user-select:none; }
  .board-node-textarea{ -webkit-user-select:text; user-select:text; }
  .board-node.dragging{ cursor:grabbing; box-shadow:0 8px 20px rgba(16,24,40,0.22); z-index:5; }
  /* 카드 크기와 상관없이 이미지·영상 전체가 보이게(NS-5) — 남는 칸은 카드 배경. 예전엔 cover라 잘려 보였다. */
  .board-node-image img, .board-node-video video{
    width:100%; height:100%; object-fit:contain; display:block; pointer-events:none;
  }
  .board-node-empty{ border:1px dashed var(--border); }
  .board-node-fill{
    width:100%; height:100%; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:8px; padding:16px; border:0; background:var(--panel-2); color:var(--text-dim);
    font:inherit; font-size:13px; text-align:center; cursor:pointer;
  }
  .board-node-fill .ico{ width:24px; height:24px; }
  .board-node-fill:focus-visible{ outline:2px solid var(--accent); outline-offset:-4px; }
  .board-node-textarea{
    width:100%; height:100%; border:none; resize:none; box-sizing:border-box;
    padding:10px; font-family:var(--sans); font-size:13px; line-height:1.5;
    color:var(--text); background:none; cursor:text;
  }
  /* 텍스트 카드는 본문이 전부 글 입력칸이다. 글쓰기 중(.editing)이 아닐 때는 글칸이
     포인터를 안 받아서 카드 어디를 잡아도 끌리고, 톡 누르면 글쓰기로 들어간다
     (JS의 endBoardNodeDrag 참고). 위쪽 띠(손잡이)를 톡 누르면 글쓰기 없이 고르기만 한다.
     글쓰기 중에는 글칸이 평소처럼 글자 선택·스크롤을 받고, 그동안 카드를 옮기려면 띠를 잡는다. */
  .board-node-text{ display:flex; flex-direction:column; }
  .board-node-text .board-node-textarea{ flex:1; min-height:0; height:auto; }
  .board-node-text:not(.editing) .board-node-textarea{ pointer-events:none; cursor:inherit; }
  .board-node-text.editing{ cursor:default; }
  .board-node-text.editing .board-node-textarea{ touch-action:pan-y; }
  .board-node-grip{
    flex:none; height:22px;
    border-bottom:1px solid var(--border);
    background-color:var(--bg);
    background-image:radial-gradient(circle, var(--text-dim) 1px, transparent 1.2px);
    background-size:6px 6px; background-position:center; background-repeat:repeat-x;
    opacity:.9;
  }
  .board-node-textarea:focus{ outline:2px solid rgba(var(--queued-rgb),0.35); outline-offset:-2px; }
  .board-node-del{
    position:absolute; top:4px; right:4px;
    width:22px; height:22px; padding:0;
    display:flex; align-items:center; justify-content:center;
    background:rgba(17,24,39,0.55); color:#fff; border:none; border-radius:6px;
    cursor:pointer; opacity:0; transition:opacity .12s ease, background .12s ease;
  }
  .board-node:hover .board-node-del, .board-node-del:focus-visible{ opacity:1; }
  .board-node-del .ico{ width:13px; height:13px; }
  .board-node-del:hover{ background:rgba(var(--failed-rgb),0.85); }

  /* 연결 점 — 끌어서 다른 카드에 놓으면 선이 이어진다. 카드가 overflow:hidden이라
     바깥으로 삐져나오게 못 하고 오른쪽 가장자리 안쪽에 둔다. 마우스가 없는
     기기(터치)는 호버가 없으니 항상 보이게 한다. */
  .board-node-handle{
    position:absolute; right:4px; top:50%;
    width:16px; height:16px; margin-top:-8px;
    border-radius:50%;
    background:var(--panel); border:2px solid var(--queued);
    box-sizing:border-box;
    cursor:crosshair; touch-action:none;
    opacity:0; transition:opacity .12s ease, transform .12s ease;
  }
  .board-node:hover .board-node-handle{ opacity:1; }
  .board-node-handle:hover{ transform:scale(1.25); }
  @media (hover:none){ .board-node-handle{ opacity:1; } }
  /* 손가락으로 누르는 기기는 연결 점·손잡이를 더 크게 — 작은 점은 손끝에 가려 잘 안 잡힌다. */
  @media (pointer:coarse){
    .board-node-handle{ width:26px; height:26px; margin-top:-13px; right:2px; }
    .board-node-grip{ height:30px; }
  }
  .board-node.connect-target{ outline:2px solid var(--queued); outline-offset:2px; }
  .board-viewport.connecting, .board-viewport.connecting .board-node{ cursor:crosshair; }

  /* 연결선 층 — board-world와 같은 팬/줌 변환을 받는다. 크기 1px에 overflow:visible로
     두고 선은 월드 좌표 그대로 그린다(음수 좌표도 잘리지 않게). 카드보다 먼저 그려
     카드 아래에 깔린다. 선마다 눈에 보이는 가는 선 + 클릭하기 쉬운 투명한 굵은 선 한 쌍. */
  .board-edges{
    position:absolute; left:0; top:0; width:1px; height:1px;
    overflow:visible; pointer-events:none;
  }
  .board-edges-top{ z-index:5; }
  .board-edge-line{ fill:none; stroke:var(--text-dim); stroke-width:2; pointer-events:none; }
  .board-edge-arrow{ fill:none; stroke:transparent; stroke-width:2; pointer-events:none; }
  .board-edge-arrow.selected{ stroke-width:3; }
  .board-edge-hit{ fill:none; stroke:transparent; stroke-width:16; pointer-events:stroke; cursor:pointer; }
  .board-edge-hit:hover + .board-edge-line{ stroke:var(--text); }
  .board-edge-line.selected{ stroke:var(--queued); stroke-width:3; }
  .board-edge-temp{ fill:none; stroke:var(--queued); stroke-width:2; stroke-dasharray:6 5; pointer-events:none; }
  #board-arrow path{ fill:var(--text-dim); }
  #board-arrow-sel path{ fill:var(--queued); }
  /* 고른 선 가운데 뜨는 "끊기" 버튼 — 터치 기기에는 Delete 키가 없어서 필요하다. */
  .board-edge-del{
    position:absolute; z-index:6;
    width:24px; height:24px; margin:-12px 0 0 -12px; padding:0;
    display:flex; align-items:center; justify-content:center;
    background:var(--panel); color:var(--failed);
    border:1px solid var(--border); border-radius:50%;
    box-shadow:0 1px 4px rgba(16,24,40,0.18);
    cursor:pointer;
  }
  .board-edge-del .ico{ width:13px; height:13px; }
  .board-edge-del:hover{ background:rgba(var(--failed-rgb),0.12); }

  /* NSFW 카드 — 갤러리와 같은 설정(nsfwMode)을 따른다. 블러/안 보기일 때는 썸네일·영상을
     아예 받지 않고 가림막만 그린다(갤러리 블러와 같은 모양). 안 보기라도 카드 자체는 남긴다 —
     카드를 빼면 거기 붙은 선이 허공으로 이어지고, 그 자리에 다른 카드를 겹쳐 놓게 된다. */
  .board-nsfw-cover{
    position:absolute; inset:0;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px;
    background:rgba(20,20,24,0.88); color:rgba(255,255,255,0.75);
    font-size:12px; pointer-events:none;
  }
  .board-nsfw-cover .ico{ width:28px; height:28px; }
  .board-picker-item{ position:relative; }

  /* 묶음 틀(frame) — 카드들 뒤에 깔리는 제목 달린 틀. 틀 안쪽은 포인터를 안 받아서 빈 곳을
     끌면 캔버스처럼 화면이 움직이고(큰 틀 안에서도 팬·사각형 고르기가 된다), 위쪽 제목 띠를
     잡아야 틀이 움직인다. 오른쪽 아래 모서리를 끌면 크기가 바뀐다. */
  .board-node.board-frame{
    background:rgba(var(--queued-rgb),0.04);
    border:1.5px solid rgba(var(--queued-rgb),0.35);
    border-radius:12px; box-shadow:none;
    overflow:visible; pointer-events:none; cursor:default;
  }
  .board-node.board-frame.dragging{ z-index:auto; box-shadow:none; }
  .board-frame-bar{
    position:absolute; left:0; right:0; top:0; height:34px; box-sizing:border-box;
    padding:0 36px 0 10px; display:flex; align-items:center;
    background:rgba(var(--queued-rgb),0.08); border-radius:10px 10px 0 0;
    pointer-events:auto; cursor:grab;
  }
  .board-node-textarea.board-frame-title{
    flex:1; min-width:0; width:auto; height:auto; padding:3px 6px; border-radius:5px;
    font-size:13px; font-weight:600; color:var(--queued); line-height:1.3;
  }
  .board-frame:not(.editing) .board-frame-title{ pointer-events:none; cursor:inherit; }
  .board-frame.editing .board-frame-title{ background:var(--panel); }
  .board-frame .board-node-del{ pointer-events:auto; }
  /* 묶음 접기 — 접기 버튼, 개수, 접힌 틀은 제목 띠만 남은 칩(안의 카드·선은 숨긴다) */
  .board-frame-fold{
    flex:none; width:24px; height:24px; margin-right:2px; padding:0; border:none; border-radius:5px; cursor:pointer;
    display:flex; align-items:center; justify-content:center; background:transparent; color:var(--queued);
  }
  .board-frame-fold:hover{ background:rgba(var(--queued-rgb),0.14); }
  .board-frame-fold .ico{ width:15px; height:15px; }
  .board-frame-count{ flex:none; margin-left:6px; font-size:12px; color:var(--text-dim); }
  .board-node.board-frame.collapsed{ width:auto !important; height:auto !important; min-width:180px; background:var(--panel); }
  .board-frame.collapsed .board-frame-bar{ position:static; border-radius:10px; }
  .board-frame.collapsed .board-frame-resize{ display:none; }
  .board-hidden{ display:none !important; }
  /* 이미지·영상·텍스트 카드의 크기 손잡이 — 카드가 overflow:hidden이라 안쪽 모서리에 둔다.
     마우스는 카드에 올렸을 때만, 터치는 늘 보인다(연결 점과 같은 규칙). */
  .board-node-resize{
    position:absolute; right:3px; bottom:3px; width:14px; height:14px; box-sizing:border-box; z-index:2;
    border-radius:3px; background:var(--panel); border:1.5px solid rgba(var(--queued-rgb),0.7);
    cursor:nwse-resize; touch-action:none; opacity:0; transition:opacity .12s ease;
  }
  .board-node:hover .board-node-resize, .board-node.selected .board-node-resize{ opacity:1; }
  @media (hover:none){ .board-node-resize{ opacity:1; } }
  @media (pointer:coarse){ .board-node-resize{ width:22px; height:22px; } }
  .board-frame-resize{
    position:absolute; right:-7px; bottom:-7px; width:16px; height:16px; box-sizing:border-box;
    border-radius:4px; background:var(--panel); border:1.5px solid rgba(var(--queued-rgb),0.6);
    pointer-events:auto; cursor:nwse-resize; touch-action:none;
  }
  @media (pointer:coarse){
    .board-frame-bar{ height:40px; }
    .board-frame-resize{ width:26px; height:26px; right:-12px; bottom:-12px; }
  }

  /* 생성 카드(gen) — 머리(프리셋 이름·템플릿), 입구 줄(왼쪽 가장자리의 점에 이미지 카드 선을
     잇는다), 꺼낸 옵션 칸. 높이는 서버 _board_gen_height와 맞춘다(머리 52, 입구 30, 글칸 96, 그 밖 60). */
  .board-node-gen{ display:flex; flex-direction:column; overflow:visible; border-color:rgba(var(--running-rgb),0.45); }
  .board-gen-head{
    flex:none; height:40px; box-sizing:border-box; padding:0 34px 0 12px;
    display:flex; align-items:center; gap:7px;
    background:rgba(var(--running-rgb),0.08); border-bottom:1px solid var(--border); border-radius:10px 10px 0 0;
  }
  .board-gen-head .ico{ width:15px; height:15px; color:var(--running); flex:none; }
  .board-gen-name{ font-size:13px; font-weight:600; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .board-gen-tpl{ font-size:11px; color:var(--text-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; margin-left:auto; }
  .board-gen-slots{ flex:none; padding:6px 0 2px; position:relative; }
  /* 이미지 아닌 카드를 끌어 올렸을 때 — 입구 줄을 덮어 안내한다(자리를 차지하지 않아 입구 점 위치는 그대로) */
  .board-node.connect-no-slot .board-gen-slots::after{
    content:'이미지 카드만 입구에 이어져요 — 여기 놓으면 보통 선이 돼요';
    position:absolute; inset:0; display:flex; align-items:center; justify-content:center; padding:0 12px;
    text-align:center; font-size:12px; color:var(--text); background:linear-gradient(rgba(var(--failed-rgb),0.16), rgba(var(--failed-rgb),0.16)), var(--panel); border-radius:6px;
  }
  .board-gen-slot{ position:relative; height:30px; display:flex; align-items:center; gap:6px; padding:0 12px 0 16px; font-size:12px; }
  .board-gen-slot-label{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text); }
  .board-gen-slot-label em{ font-style:normal; color:var(--text-dim); }
  .board-gen-slot-state{ font-size:11px; color:var(--text-dim); white-space:nowrap; }
  .board-gen-port{
    position:absolute; left:calc(-1px - var(--board-port-size, 10px) / 2); top:50%; margin-top:calc(var(--board-port-size, 10px) / -2); width:var(--board-port-size, 10px); height:var(--board-port-size, 10px); box-sizing:border-box;
    border-radius:50%; background:var(--panel); border:2px solid var(--running); cursor:pointer;
  }
  .board-gen-port::before{ content:""; position:absolute; inset:-7px; border-radius:50%; }   /* 누르기 쉽게 넓힌 자리 */
  .board-gen-port:hover{ transform:scale(1.35); }
  .board-gen-fields{ flex:1; min-height:0; overflow:hidden; padding:4px 12px 10px; display:flex; flex-direction:column; gap:6px; }
  /* 글칸 모서리 연결점 — 점의 가운데가 글상자 좌상단 모서리에 온다(ComfyUI식). 글칸 묶음(.board-gen-fields)이
     overflow:hidden이라 카드 가장자리로 내보내면 반쯤 잘린다 — 안쪽 여백(12px) 안에 두어야 한다. */
  .board-gen-control{ position:relative; flex:1 0 auto; display:flex; flex-direction:column; }
  .board-gen-control > textarea.board-gen-input{ flex:1 0 auto; }
  .board-gen-control > .board-gen-port{ left:calc(var(--board-port-size, 10px) / -2); top:calc(var(--board-port-size, 10px) / -2); margin-top:0; z-index:1; cursor:default; }
  .board-gen-port.filled, .board-gen-slot.filled .board-gen-port{ background:var(--running); }
  .board-gen-port.connect-slot{ transform:scale(1.35); background:rgba(var(--running-rgb),0.4); }
  .board-gen-input:disabled{ cursor:not-allowed; opacity:0.7; }
  .board-gen-slot.text .board-gen-port{ cursor:default; }
  .board-gen-slot.connect-slot{ background:rgba(var(--running-rgb),0.14); }
  .board-gen-slot-state img{ width:22px; height:22px; object-fit:cover; border-radius:4px; vertical-align:middle; margin-right:3px; }
  .board-gen-foot{
    flex:none; height:46px; box-sizing:border-box; padding:0 10px 0 12px;
    display:flex; align-items:center; gap:6px; border-top:1px solid var(--border);
  }
  .board-gen-status{ flex:1; min-width:0; display:flex; align-items:center; gap:6px; overflow:hidden; white-space:nowrap; font-size:11px; color:var(--text-dim); }
  .board-gen-status .badge{ flex:none; }
  .board-gen-status > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; }   /* 카드를 좁히면 말줄임 */
  .board-gen-btn{
    flex:none; display:inline-flex; align-items:center; gap:4px; padding:5px 10px; border-radius:6px;
    border:1px solid var(--border); background:var(--panel); color:var(--text); font-size:12px; cursor:pointer;
  }
  .board-gen-btn .ico{ width:12px; height:12px; }
  .board-gen-btn.primary{ background:var(--running); border-color:var(--running); color:#fff; }
  .board-gen-btn:disabled{ opacity:.45; cursor:not-allowed; }
  .board-gen-btn.primary.busy{ opacity:.7; background:var(--text-dim); border-color:var(--text-dim); }
  /* 오른쪽 연결 점은 카드 바깥 가장자리에 — 안쪽에 두면 입력칸을 가린다(카드가 overflow:visible). */
  .board-node-gen .board-node-handle{ right:-8px; }
  @media (pointer:coarse){ .board-node-gen .board-node-handle{ right:-13px; } }
  /* 생성 카드의 크기 손잡이는 안쪽 모서리면 "실행" 버튼과 겹쳐서 틀처럼 모서리 바깥에 걸친다(카드가 overflow:visible) */
  .board-node-gen .board-node-resize{ right:-7px; bottom:-7px; }
  @media (pointer:coarse){ .board-node-gen .board-node-resize{ right:-11px; bottom:-11px; } }
  .board-gen-field{ display:flex; flex-direction:column; gap:3px; }
  .board-gen-field-label{ font-size:11px; color:var(--text-dim); display:flex; align-items:center; gap:4px; }
  .board-gen-copy{
    margin-left:auto; width:22px; height:22px; padding:0; border:none; border-radius:5px; cursor:pointer;
    display:inline-flex; align-items:center; justify-content:center; background:transparent; color:var(--text-dim);
  }
  .board-gen-copy:hover{ background:rgba(var(--queued-rgb),0.12); color:var(--queued); }
  .board-gen-copy .ico{ width:13px; height:13px; }
  .board-gen-input{
    width:100%; box-sizing:border-box; font:inherit; font-size:12.5px; color:var(--text);
    background:var(--bg); border:1px solid var(--border); border-radius:6px; padding:6px 8px;
    -webkit-user-select:text; user-select:text; cursor:text;
  }
  textarea.board-gen-input{ resize:none; height:66px; line-height:1.4; }
  /* 카드를 키우면 남는 높이를 글칸(프롬프트)이 나눠 채운다 — 66px은 최소, 글칸이 여럿이면 똑같이 나눈다 */
  .board-gen-field.grow{ flex:1 0 auto; }
  .board-gen-field.grow textarea.board-gen-input{ flex:1 0 auto; }
  select.board-gen-input{ cursor:pointer; }
  .board-gen-input:focus{ outline:2px solid rgba(var(--running-rgb),0.35); outline-offset:-1px; }

  /* 작업(Job) 카드 — 안쪽은 전부 표시용이라 포인터를 안 받는다(카드 어디를 잡아도 끌리고,
     톡 누르면 상세 창). 상태 배지는 작업 목록의 .badge를 그대로 쓴다. */
  .board-job-body{
    position:absolute; inset:0; padding:10px 12px;
    display:flex; flex-direction:column; gap:7px;
    pointer-events:none; overflow:hidden;
  }
  .board-job-body .board-node-fill{ pointer-events:auto; }
  .board-job-head{ display:flex; align-items:center; gap:8px; min-width:0; }
  .board-job-label{ font-size:12.5px; font-weight:600; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .board-job-prompt{
    font-size:12px; line-height:1.45; color:var(--text-dim);
    display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
  }
  .board-job-dim{ font-style:italic; opacity:.7; }
  .board-job-progress{ display:flex; align-items:center; gap:8px; font-family:var(--mono); font-size:11px; color:var(--text-dim); }
  .board-job-bar{ flex:1; height:5px; border-radius:3px; background:var(--border); overflow:hidden; }
  .board-job-bar > div{ height:100%; background:var(--running); }
  .board-job-thumbs{ display:grid; grid-template-columns:repeat(4, 1fr); gap:4px; margin-top:auto; }
  .board-job-thumb{
    aspect-ratio:1; border-radius:5px; overflow:hidden; background:var(--bg);
    display:flex; align-items:center; justify-content:center; color:var(--text-dim);
  }
  .board-job-thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
  .board-job-thumb.nsfw{ background:rgba(20,20,24,0.88); color:rgba(255,255,255,0.75); }
  .board-job-thumb .ico{ width:16px; height:16px; }
  .board-job-note{ margin:auto; display:flex; flex-direction:column; align-items:center; gap:6px; font-size:12px; color:var(--text-dim); }
  .board-job-note .ico{ width:20px; height:20px; }
  /* 작업 고르기 창 — 격자 대신 한 줄씩 */
  .board-asset-picker-grid.jobs{ grid-template-columns:1fr; gap:6px; }
  .board-picker-job{
    display:flex; align-items:center; gap:10px; width:100%; padding:9px 12px; text-align:left;
    border:1px solid var(--border); border-radius:8px; background:var(--panel); color:var(--text); cursor:pointer;
  }
  .board-picker-job:hover{ border-color:var(--queued); }
  .board-picker-job-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; font-size:12.5px; }
  .board-picker-job-text span{ color:var(--text-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; }
  .board-picker-job-when{ font-family:var(--mono); font-size:11px; color:var(--text-dim); white-space:nowrap; }

  /* 보드에 놓을 이미지/영상을 고르는 모달 — 프로젝트 결과물을 이름으로 거른다. */
  #board-asset-picker-search:not([hidden]){
    display:block;
    box-sizing:border-box;
    width:100%;
    margin-bottom:12px;
    padding:8px 12px;
    border:1px solid var(--border);
    border-radius:6px;
    background:var(--panel);
    color:var(--text);
    font:inherit;
  }
  #board-asset-picker-search:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
  .board-asset-picker-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(110px, 1fr));
    gap:8px;
    max-height:60vh;
    overflow-y:auto;
  }
  .board-picker-item{
    aspect-ratio:1; padding:0;
    border:1px solid var(--border); border-radius:8px;
    overflow:hidden; cursor:pointer; background:var(--bg);
  }
  .board-picker-item img, .board-picker-item video{ width:100%; height:100%; object-fit:cover; display:block; }
  .board-picker-item:hover{ border-color:var(--queued); }

  .panel{
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:12px;
    padding:24px;
    box-shadow: 0 1px 2px rgba(16,24,40,0.04), 0 1px 3px rgba(16,24,40,0.03);
  }

  /* New job 패널 안에서 "무엇을 만들지 고르는 부분"(마법사/워크플로우 업로드)과
     "그 선택에 따라 달라지는 세부 옵션"을 시각적으로 나누는 카드 — .panel을 중첩해서
     쓰면 무거워 보여 테두리만 있는 가벼운 변형을 쓴다. */
  .subpanel{
    border:1px solid var(--border);
    border-radius:10px;
    padding:16px;
  }
  .subpanel + .subpanel{ margin-top:16px; }

  .upload-form{
    display:flex;
    flex-direction:column;
    gap:16px;
  }
  .field{
    display:flex;
    flex-direction:column;
    gap:6px;
  }
  .manual-template-toggle{ font-size:12.5px; margin-top:18px; }
  .manual-template-toggle summary{
    cursor:pointer; color:var(--text-dim); font-family:var(--mono); font-size:11.5px;
    list-style:none; display:flex; align-items:center; gap:6px;
  }
  .manual-template-toggle summary::-webkit-details-marker{ display:none; }
  .manual-template-toggle summary::before{ content:'▸'; font-size:10px; }
  .manual-template-toggle[open] summary::before{ content:'▾'; }
  .manual-template-toggle summary:hover{ color:var(--text); }
  .manual-template-toggle .field{ margin-top:10px; }
  .field-label{
    font-family:var(--mono);
    font-size:11px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:0.05em;
    color:var(--text-dim);
  }
  .field-label .opt{ text-transform:none; letter-spacing:0; font-weight:400; color:var(--text-dim); }
  /* 필드 라벨 오른쪽에 보조 버튼(예: "최근 워크플로우")을 붙일 때 쓴다. */
  .field-label-row{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:var(--gap-md);
  }
  .field-label-row .field-label{ flex-shrink:0; }
  /* "최근 사용한 워크플로우"/"최근 사용한 CSV" 모달 목록 — 둘이 클래스를 공유한다.
     파일명은 길면 말줄임, 시각/선택 버튼은 고정 폭으로 오른쪽에 붙는다. */
  .recent-workflows-list{
    display:flex;
    flex-direction:column;
    gap:6px;
    max-height:360px;
    overflow-y:auto;
  }
  .recent-workflow-item{
    display:flex;
    align-items:center;
    gap:var(--gap-md);
    padding:8px 10px;
    border:1px solid var(--border);
    border-radius:var(--radius-sm);
  }
  .recent-workflow-name{
    flex:1 1 auto;
    min-width:0;
    font-family:var(--mono);
    font-size:12.5px;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
    cursor:pointer;
  }
  .recent-workflow-name:hover{ color:var(--queued); text-decoration:underline; }
  .recent-workflow-time{
    font-family:var(--mono);
    font-size:11px;
    color:var(--text-dim);
    white-space:nowrap;
    flex-shrink:0;
  }
  /* 문구 없이 아이콘 하나만 담는 작은 버튼(휴지통 등) — .del-btn과 같은 색
     규칙(hover 시 빨강)을 쓰되 정사각형 아이콘 크기로 맞춘다. */
  .icon-btn{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:26px;
    height:26px;
    padding:0;
    flex-shrink:0;
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:var(--radius-sm);
    color:var(--text-dim);
    cursor:pointer;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
  }
  .icon-btn:hover{ border-color:var(--failed); color:var(--failed); background:rgba(var(--failed-rgb),0.06); }
  .icon-btn svg{ width:14px; height:14px; }
  /* 삭제처럼 되돌릴 수 없는 동작이 아닌 icon-btn(예: 다운로드)은 빨강 대신 파랑 계열로 hover */
  .icon-btn-neutral:hover{ border-color:var(--queued); color:var(--queued); background:rgba(var(--queued-rgb),0.06); }
  /* "선택"(.load-btn)과 휴지통(.icon-btn) 버튼의 너비를 맞춰서 나란히 놓았을 때
     들쭉날쭉해 보이지 않게 한다. */
  .recent-workflow-item .load-btn,
  .recent-workflow-item .icon-btn{
    width:56px;
    justify-content:center;
  }
  .options-fields{
    display:flex;
    flex-direction:column;
    gap:16px;
  }
  select#template-select,
  input.option-input,
  select.option-input,
  textarea.option-input{
    background:var(--panel);
    color:var(--text);
    border:1px solid var(--border);
    border-radius:8px;
    padding:10px 12px;
    font-family:var(--sans);
    font-size:14px;
    cursor:pointer;
  }
  input.option-input{ cursor:text; max-width:220px; }
  select.option-input{ max-width:280px; }
  textarea.option-input{
    cursor:text;
    width:100%;
    max-width:520px;
    min-height:80px;
    resize:vertical;
    line-height:1.5;
  }
  select#template-select:focus,
  input.option-input:focus,
  select.option-input:focus,
  textarea.option-input:focus{ outline:2px solid rgba(var(--queued-rgb),0.35); border-color:var(--queued); }

  /* New Job 모달의 "세부 설정" 탭은 모달 자체가 넓어서(modal-panel-wide), 짧은
     고정폭(220~520px)으로 잘라두면 오른쪽에 애매하게 빈 공간이 남는다 — 가로로
     나란히 둘 값(.field-pair, 예: 시드 개수·시드 방식)만 반씩 나누고, 나머지는
     칸을 끝까지 채운다. */
  #options-fields input.option-input,
  #options-fields select.option-input,
  #options-fields textarea.option-input,
  #lora-trigger-field input.option-input,
  #quality-prompt-field input.option-input{
    max-width:none;
    width:100%;
  }
  .field-pair{ display:flex; gap:16px; flex-wrap:wrap; }
  .field-pair > .field{ flex:1 1 200px; }

  /* "입력 이미지" 옵션 — 드롭다운 + 업로드/갤러리 버튼을 한 줄에 (buildInputImageControl) */
  .input-image-control{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:8px;
  }
  .input-image-control select.option-input{ flex:1 1 200px; }

  /* 참조 이미지/비디오/오디오 슬롯의 카드 갤러리(buildAssetGalleryControl) — 드롭다운
     대신 썸네일이 보이는 작은 카드를 나란히 늘어놓는다. */
  .ref-gallery{ display:flex; flex-wrap:wrap; gap:6px; }
  .ref-gallery-single{ display:inline-block; }
  .ref-card{
    width:92px; height:92px;
    border:2px solid var(--border);
    border-radius:var(--radius-sm);
    cursor:pointer;
    overflow:hidden;
    position:relative;
    display:flex; align-items:center; justify-content:center;
    background:var(--surface-2, rgba(255,255,255,0.03));
    flex-shrink:0;
  }
  .ref-card:hover{ border-color:var(--queued); }
  .ref-card.selected{ border-color:var(--queued); box-shadow:0 0 0 2px rgba(var(--queued-rgb),0.25); }
  .ref-card img, .ref-card video{ width:100%; height:100%; object-fit:cover; pointer-events:none; }
  .ref-card-none{ font-size:11px; color:var(--text-dim); text-align:center; padding:2px; line-height:1.2; }
  .ref-card-audio{ flex-direction:column; gap:4px; padding:4px; }
  .ref-card-audio .ico{ width:28px; height:28px; color:var(--text-dim); }
  .ref-card-audio-label{ font-size:9.5px; color:var(--text-dim); max-width:82px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ref-card-badge{ position:absolute; bottom:2px; right:2px; background:rgba(0,0,0,0.55); border-radius:999px; padding:2px; display:flex; }
  .ref-card-badge .ico{ width:10px; height:10px; color:#fff; }
  .ref-card-upload{ border-style:dashed; color:var(--text-dim); }
  .ref-card-upload:hover{ color:var(--text); }
  .ref-card-add{ border-style:dashed; color:var(--text-dim); }
  .ref-card-add:hover{ color:var(--text); border-color:var(--queued); }
  .ref-card-add .ico{ width:28px; height:28px; }
  .ref-card-remove{
    position:absolute; top:-6px; right:-6px;
    width:18px; height:18px; border-radius:999px;
    background:var(--failed); color:#fff; border:none;
    font-size:13px; line-height:1; cursor:pointer;
    display:flex; align-items:center; justify-content:center;
  }

  /* 메인 프롬프트의 "직접 입력"(항상 보임) 아래로 랜덤생성 버튼(자주 씀 — 항상 보임)과
     "Prompt Enhance"(AI로 다시 써주는 것 — 실제로는 잘 안 쓴다는 피드백으로 접어둠,
     .prompt-enhance-details)를 세로로 쌓는다. 실제로 큐에 보내는 값은 hidden
     input(.option-input)에 모이므로, 여기 두 텍스트 에어리어(.enhance-textarea)는
     일부러 .option-input 셀렉터 밖에 둬서 제출 시 중복으로 잡히지 않게 한다. */
  .prompt-enhance{ display:flex; flex-direction:column; gap:10px; }
  .prompt-enhance-col{ display:flex; flex-direction:column; gap:6px; min-width:0; }
  .prompt-enhance-quick{ display:flex; gap:8px; flex-wrap:wrap; }
  .prompt-enhance-details summary{
    cursor:pointer; font-family:var(--mono); font-size:11px; color:var(--text-dim);
    list-style:none; display:flex; align-items:center; gap:6px;
  }
  .prompt-enhance-details summary::-webkit-details-marker{ display:none; }
  .prompt-enhance-details summary::before{ content:'▸'; font-size:10px; }
  .prompt-enhance-details[open] summary::before{ content:'▾'; }
  .prompt-enhance-details summary:hover{ color:var(--text); }
  .prompt-enhance-details[open] summary{ margin-bottom:10px; }
  .prompt-enhance-details > .prompt-enhance-col{ margin-top:10px; }
  .prompt-enhance-subtitle-row{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:8px;
  }
  /* 복사/Danbooru로 보내기 버튼을 하나로 묶어서 라벨 오른쪽에 붙인다 — 부모가
     justify-content:space-between이라, 버튼을 낱개로 넣으면 서로 멀리 떨어져
     보이는 문제(자식이 3개 이상일 때 균등 배분됨)를 이 래퍼로 자식을 2개(라벨/
     버튼 묶음)로 줄여서 피한다. */
  .prompt-enhance-actions{ display:flex; align-items:center; gap:6px; flex-shrink:0; }
  .prompt-enhance-subtitle{
    font-family:var(--mono);
    font-size:10.5px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:0.04em;
    color:var(--text-dim);
  }
  /* 텍스트를 클립보드로 복사하는 작은 버튼 — 프롬프트 입력/결과 칸 소제목 옆에 쓴다. */
  .copy-btn{
    background:none;
    border:1px solid var(--border);
    border-radius:6px;
    padding:2px 8px;
    font-family:var(--mono);
    font-size:10px;
    font-weight:600;
    color:var(--text-dim);
    cursor:pointer;
    white-space:nowrap;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
  }
  .copy-btn:hover{ border-color:var(--queued); color:var(--queued); background:rgba(var(--queued-rgb),0.06); }
  .copy-btn.copied{ border-color:var(--done); color:var(--done); background:rgba(var(--done-rgb),0.08); }
  .copy-btn.copy-error{ border-color:var(--failed); color:var(--failed); background:rgba(var(--failed-rgb),0.06); }
  textarea.enhance-textarea{
    background:var(--panel);
    color:var(--text);
    border:1px solid var(--border);
    border-radius:8px;
    padding:10px 12px;
    font-family:var(--sans);
    font-size:14px;
    width:100%;
    min-height:110px;
    resize:vertical;
    line-height:1.5;
    cursor:text;
    transition: border-color .15s ease, outline-color .15s ease;
  }
  textarea.enhance-textarea:focus{ outline:2px solid rgba(var(--queued-rgb),0.35); border-color:var(--queued); }
  textarea.enhance-result{ background:rgba(var(--queued-rgb),0.03); }
  /* 접었다 펼 수 있는 <details> 안이라 더 이상 두 텍스트 에어리어 사이 좁은 세로
     칸이 아니다 — 자연어/Danbooru 토글 + Enhance 버튼 + 상태 문구를 가로로 늘어놓는다. */
  .prompt-enhance-middle{
    display:flex;
    flex-direction:row;
    align-items:center;
    flex-wrap:wrap;
    gap:10px;
  }
  /* 자연어/Danbooru 모드 토글 — 탭처럼 둘 중 하나만 활성 상태를 띤다. */
  .enhance-mode{
    display:inline-flex;
    background:var(--bg);
    border:1px solid var(--border);
    border-radius:999px;
    padding:2px;
    gap:2px;
  }
  .enhance-mode-btn{
    background:none;
    border:none;
    border-radius:999px;
    padding:5px 12px;
    font-family:var(--mono);
    font-size:10.5px;
    font-weight:600;
    color:var(--text-dim);
    cursor:pointer;
    white-space:nowrap;
    transition: background .15s ease, color .15s ease, box-shadow .15s ease;
  }
  .enhance-mode-btn:hover:not(.active){ color:var(--text); }
  .enhance-mode-btn.active{
    background:var(--grad-primary);
    color:#fff;
    box-shadow:0 1px 2px rgba(var(--queued-rgb),0.3);
  }
  .enhance-btn{
    position:relative;
    background:var(--grad-primary);
    color:#fff;
    border:none;
    border-radius:var(--radius-md);
    padding:8px 14px;
    font-family:var(--mono);
    font-size:11.5px;
    font-weight:600;
    letter-spacing:0.01em;
    white-space:nowrap;
    cursor:pointer;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:7px;
    box-shadow:0 1px 2px rgba(var(--queued-rgb),0.25);
    transition: background .18s ease, box-shadow .18s ease, transform .1s ease;
  }
  .enhance-btn:hover:not(:disabled){ background:var(--grad-primary-hover); box-shadow:0 4px 10px rgba(var(--queued-rgb),0.3); }
  .enhance-btn:active:not(:disabled){ transform:translateY(1px); }
  .enhance-btn:disabled{ background:var(--border); color:var(--text-dim); box-shadow:none; cursor:not-allowed; }
  /* 프롬프트 개선은 LLM 호출 한 번짜리라 ComfyUI 진행률(%) 정보를 받아올 마땅한
     지표가 없다 — 그런 자원 소모(웹소켓 유지 등) 없이도 "지금 뭔가 하고 있다"는
     신호를 주는 게 목적이라 회전 스피너 하나로 충분하다. */
  .enhance-spinner{
    width:11px; height:11px;
    border:2px solid rgba(255,255,255,0.4);
    border-top-color:#fff;
    border-radius:50%;
    animation: enhance-spin .7s linear infinite;
    flex-shrink:0;
  }
  @keyframes enhance-spin{ to{ transform:rotate(360deg); } }
  /* .enhance-spinner는 어두운 배경(.enhance-btn) 전용으로 흰색 고정이라, .load-btn
     같은 밝은 배경 버튼에 쓰면 안 보인다 — currentColor를 써서 버튼 글자색을
     그대로 따라가는 범용 스피너. 회전+다운로드처럼 여러 장을 처리하느라 시간이
     걸리는 버튼에 "지금 처리 중"임을 보여주는 용도로 쓴다. */
  .btn-spinner{
    display:inline-block;
    width:11px; height:11px;
    border:2px solid currentColor;
    border-top-color:transparent;
    border-radius:50%;
    opacity:0.7;
    animation: enhance-spin .7s linear infinite;
    flex-shrink:0;
    vertical-align:-2px;
  }
  .enhance-status{
    font-family:var(--mono);
    font-size:10.5px;
    color:var(--text-dim);
    text-align:center;
    max-width:150px;
    min-height:1.2em;
  }
  .enhance-status.error{ color:var(--failed); }
  .enhance-status.success{ color:var(--done); }
  .danbooru-per-seed-row{
    display:flex;
    align-items:center;
    gap:6px;
    font-family:var(--mono);
    font-size:10.5px;
    color:var(--text-dim);
    cursor:pointer;
    margin-top:6px;
  }
  .danbooru-per-seed-row input[type="checkbox"]{
    accent-color:var(--queued);
    cursor:pointer;
  }
  /* width/height "이미지 크기" 필드 — 모드 토글(.enhance-mode 재사용) 아래로
     "직접 입력"/"화면비·해상도" 두 패널 중 하나만 보인다. */
  .resolution-control{ display:flex; flex-direction:column; gap:12px; }
  .resolution-manual,
  .resolution-preset{
    display:flex;
    flex-wrap:wrap;
    align-items:flex-end;
    gap:var(--gap-md);
  }
  .resolution-manual[hidden],
  .resolution-preset[hidden]{ display:none; }
  .resolution-preview{
    font-family:var(--mono);
    font-size:12.5px;
    color:var(--text-dim);
    align-self:center;
    white-space:nowrap;
  }

  .slot{
    border:1px dashed var(--border);
    background:var(--bg);
    border-radius:8px;
    padding:16px 14px;
    text-align:center;
    color:var(--text-dim);
    font-size:13px;
    cursor:pointer;
    transition: border-color .15s, background .15s, color .15s;
  }
  .slot.drag{
    border-color:var(--queued);
    background:rgba(var(--queued-rgb),0.06);
    color:var(--text);
  }
  .slot.filled{
    border-style:solid;
    border-color:var(--done);
    background:rgba(var(--done-rgb),0.05);
    color:var(--text);
    font-family:var(--mono);
    font-size:12.5px;
  }
  .slot-input{ display:none; }

  /* 색이 있는 "동작" 버튼(주요/시작/위험) 공통 베이스 — 그라데이션, 그림자, hover 시
     살짝 떠오르는 느낌, disabled 시 그라데이션이 꺼지고 평평해지는 상태를 통일한다. */
  .submit-btn,
  .danger-btn,
  .start-queue-btn{
    align-self:flex-start;
    color:#fff;
    border:none;
    border-radius:var(--radius-md);
    padding:10px 22px;
    font-family:var(--mono);
    font-size:13px;
    font-weight:600;
    letter-spacing:0.01em;
    cursor:pointer;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:var(--gap-xs);
    transition: background .18s ease, box-shadow .18s ease, transform .1s ease;
  }
  .submit-btn:active,
  .danger-btn:active,
  .start-queue-btn:active{ transform:translateY(1px); }
  .submit-btn:disabled,
  .danger-btn:disabled,
  .start-queue-btn:disabled{
    background:var(--border) !important;
    color:var(--text-dim);
    box-shadow:none;
    cursor:not-allowed;
    transform:none;
  }

  .submit-btn{
    background:var(--grad-primary);
    box-shadow:0 1px 2px rgba(var(--queued-rgb),0.25), 0 1px 1px rgba(16,24,40,0.06);
  }
  .submit-btn:hover:not(:disabled){ background:var(--grad-primary-hover); box-shadow:0 4px 10px rgba(var(--queued-rgb),0.3); }

  .danger-btn{
    background:var(--grad-danger);
    box-shadow:0 1px 2px rgba(var(--failed-rgb),0.25), 0 1px 1px rgba(16,24,40,0.06);
  }
  .danger-btn:hover:not(:disabled){ background:var(--grad-danger-hover); box-shadow:0 4px 10px rgba(var(--failed-rgb),0.3); }

  .upload-error{
    color:var(--failed);
    font-size:12.5px;
    font-family:var(--mono);
    min-height:1em;
  }
  .email-hint{ font-size:12.5px; color:var(--text-dim); margin:-4px 0 12px; }
  .email-hint.error{ color:var(--failed); }
  /* 항상 떠 있으면 거슬리는 긴 안내문을 "?" 아이콘 뒤에 숨겨 두는 도움말 —
     데스크탑은 호버로, 터치 기기는 탭(버튼 클릭으로 open 클래스 토글)으로 연다. */
  .help-tip{ position:relative; display:inline-flex; vertical-align:middle; margin-left:2px; }
  .help-tip-btn{
    display:inline-flex; align-items:center; justify-content:center;
    width:18px; height:18px; padding:0; flex-shrink:0;
    border:1px solid var(--border); border-radius:50%; background:var(--panel);
    color:var(--text-dim); cursor:pointer;
  }
  .help-tip-btn:hover, .help-tip-btn:focus-visible{ color:var(--queued); border-color:var(--queued); }
  .help-tip-btn .ico{ width:12px; height:12px; }
  .help-tip-pop{
    position:absolute; top:calc(100% + 8px); left:0; z-index:20;
    width:280px; max-width:min(280px, 70vw); padding:10px 12px;
    background:var(--panel); border:1px solid var(--border); border-radius:var(--radius-md);
    box-shadow:0 6px 20px rgba(0,0,0,0.16);
    font-size:12.5px; line-height:1.5; color:var(--text-dim); font-weight:400;
    text-transform:none; letter-spacing:normal;
    opacity:0; visibility:hidden; transform:translateY(-4px); pointer-events:none;
    transition:opacity .12s ease, transform .12s ease, visibility .12s;
  }
  .help-tip:hover .help-tip-pop,
  .help-tip.open .help-tip-pop{ opacity:1; visibility:visible; transform:translateY(0); pointer-events:auto; }
  @media (max-width:760px){ .help-tip-pop{ left:auto; right:0; } }
  /* RunPod에서 가져온 이름을 nightshift 이름 입력칸에 한 번에 채워주는 제안 줄
     — 자동으로 덮어쓰지는 않는다(사용자가 일부러 지은 이름을 조용히 바꾸면
     안 되므로), 눌러야만 채워지는 링크 버튼으로만 둔다. */
  .pod-name-suggest{ font-size:12px; color:var(--text-dim); }
  .pod-name-suggest button{
    background:none; border:none; padding:0; margin-left:4px;
    color:var(--queued); font-size:12px; cursor:pointer; text-decoration:underline;
  }
  .runpod-info-grid{ display:grid; grid-template-columns:auto 1fr; gap:5px 12px; font-size:12.5px; }
  .runpod-info-grid .ri-k{ color:var(--text-dim); }
  .runpod-info-grid .ri-v{ color:var(--text); font-family:var(--mono); }
  input.email-input{ max-width:320px; }
  .email-result{ color:var(--done); font-size:12.5px; font-family:var(--mono); min-height:1em; }
  .output-actions{ display:flex; gap:var(--gap-lg); flex-wrap:wrap; }
  /* 좁은 화면에서는 버튼 3개가 서로 다른 텍스트 길이 때문에 들쭉날쭉하게 왼쪽
     정렬되던 걸, 세로로 쌓고 폭을 전부 맞춰서 길이/정렬을 통일한다. */
  @media (max-width:640px){
    .output-actions{ flex-direction:column; align-items:stretch; }
    .output-actions > div{ width:100%; }
    .output-actions .submit-btn,
    .output-actions .danger-btn{ width:100%; }
  }

  .section-label{
    font-family:var(--mono);
    font-size:12px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:var(--track-label);
    color:var(--text-dim);
    margin-bottom:16px;
  }

  .panel-header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    margin-bottom:16px;
  }
  .panel-header .section-label{ margin-bottom:0; transition:color .15s ease; }
  /* 접기/펼치기 버튼을 제목 오른쪽 끝이 아니라 제목 왼쪽에 불릿처럼 붙여서,
     "이 줄 전체가 접기 트리거"라는 게 한눈에 보이게 한다. 버튼 하나에만
     클릭 리스너를 달지 않고 이 그룹 전체(.panel-header-title)에 다는 이유도
     같은 맥락 — 텍스트를 눌러도 접히고 펼쳐져야 자연스럽다. */
  .panel-header-title{
    display:flex;
    align-items:center;
    gap:8px;
    cursor:pointer;
    min-width:0;
  }
  .panel-header-title:hover .collapse-btn{ color:var(--queued); }
  .panel-header-title:hover .section-label{ color:var(--text); }
  .panel-header-actions{ display:flex; align-items:center; gap:var(--gap-md); flex-shrink:0; }
  /* 갤러리/영상/Danbooru 탭 제목 줄 — actions가 flex-shrink:0이라 좁은 화면에서
     줄어들 곳이 제목(section-label)뿐이라 글자가 한 자씩 세로로 쪼개지고
     actions는 화면 밖으로 넘어갔다. 좁은 화면에서는 아래 줄로 넘기고, actions
     자신도 필요하면 여러 줄로 접히게 한다. */
  @media (max-width:640px){
    .panel-header{ flex-wrap:wrap; }
    /* flex-shrink:0을 그대로 두면 넓어진 채로 화면 밖까지 넘어가버려서, 줄 하나를
       통째로 차지하게(width:100%) 만들어야 그 안에서 다시 flex-wrap이 걸린다. */
    .panel-header-actions{ flex-wrap:wrap; flex-shrink:1; width:100%; }
  }
  .collapse-btn{
    background:none;
    border:none;
    color:var(--text-dim);
    width:14px;
    height:14px;
    flex-shrink:0;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    font-size:11px;
    line-height:1;
    cursor:pointer;
    padding:0;
    transition: transform .15s ease, color .15s ease;
  }
  .panel.collapsed .panel-header{ margin-bottom:0; }
  .panel.collapsed .panel-body{ display:none; }
  .panel.collapsed .collapse-btn{ transform:rotate(-90deg); }
  .start-queue-btn{
    background:var(--grad-success);
    padding:8px 18px;
    font-size:12.5px;
    box-shadow:0 1px 2px rgba(var(--done-rgb),0.25), 0 1px 1px rgba(16,24,40,0.06);
  }
  .start-queue-btn:hover:not(:disabled){ background:var(--grad-success-hover); box-shadow:0 4px 10px rgba(var(--done-rgb),0.3); }
  /* 자동 실행 모드가 켜져 있는 동안(⏸ 정지로 바뀐 상태) — 시작(초록)과 뚜렷이
     구분되는 색(주황, running 배지와 같은 계열)으로 "지금 계속 돌고 있다"는
     상태를 알린다. */
  .start-queue-btn.running{
    background:var(--grad-running);
    box-shadow:0 1px 2px rgba(var(--running-rgb),0.25), 0 1px 1px rgba(16,24,40,0.06);
  }
  .start-queue-btn.running:hover:not(:disabled){ background:var(--grad-running-hover); box-shadow:0 4px 10px rgba(var(--running-rgb),0.3); }

  .table-scroll{ overflow-x:auto; container-type:inline-size; }
  table{
    width:100%;
    border-collapse:collapse;
    font-size:13px;
  }
  thead th{
    text-align:left;
    font-family:var(--mono);
    font-weight:600;
    font-size:11px;
    text-transform:uppercase;
    letter-spacing:0.05em;
    color:var(--text-dim);
    padding:0 12px 10px;
    border-bottom:1px solid var(--border);
    white-space:nowrap;
  }
  tbody tr{
    cursor:pointer;
    border-bottom:1px solid var(--border);
  }
  tbody tr:last-child{ border-bottom:none; }
  tbody tr:hover{ background:var(--bg); }
  tbody td{
    padding:10px 8px;
    vertical-align:middle;
  }
  .fname{
    font-family:var(--mono);
    font-size:12.5px;
    color:var(--text);
    max-width:190px;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
  }
  .fname.dim{ color:var(--text-dim); }
  .badge{
    display:inline-flex;
    align-items:center;
    gap:6px;
    font-family:var(--mono);
    font-size:11px;
    font-weight:600;
    padding:3px 9px;
    border-radius:20px;
    border:1px solid currentColor;
    white-space:nowrap;
  }
  .badge.pending{ color:var(--queued); background:rgba(var(--queued-rgb),0.10); }
  .badge.queued{ color:var(--queued); background:rgba(var(--queued-rgb),0.10); }
  .badge.running{ color:var(--running); background:rgba(var(--running-rgb),0.10); }
  .badge.done{ color:var(--done); background:rgba(var(--done-rgb),0.10); }
  .badge.failed{ color:var(--failed); background:rgba(var(--failed-rgb),0.10); }
  .badge.mature{ color:var(--failed); background:rgba(var(--failed-rgb),0.10); }
  .badge.interrupted{ color:var(--interrupted); background:rgba(var(--interrupted-rgb),0.10); }
  /* ComfyUI(GPU)에 연결될 때까지 큐에서 붙잡혀 있는 작업 — 실패가 아니라 대기다.
     "대기중"(queued)과 눈에 띄게 구분돼야 사용자가 "왜 안 도나"를 바로 안다. */
/* 추천 프롬프트는 기존 테마와 입력 스타일을 쓴다. */
#quality-prompt-field { min-width: 0; width: 100%; }
#quality-prompt-input { box-sizing: border-box; width: 100%; max-width: 100%; resize: vertical; padding: 12px; background: var(--panel); color: var(--text); border: 1px solid var(--border); border-radius: 6px; font: inherit; }
#quality-prompt-input:focus-visible { outline: 2px solid var(--queued); outline-offset: 2px; }
.quality-prompt-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 8px; }
.quality-prompt-actions button { min-height: 40px; }
/* 추가 전(미적용) 추천값은 점선·배경으로 구분하고 글자 대비는 그대로 둔다 */
.quality-prompt-pending #quality-prompt-input { background: var(--bg); border-style: dashed; }
.pose-image-control{display:flex;flex-direction:column;gap:8px;min-width:0;}
.pose-image-holder{width:min(160px,100%);height:160px;border:1px dashed var(--border);border-radius:8px;display:flex;align-items:center;justify-content:center;color:var(--text-dim);font-size:13px;overflow:hidden;background:var(--panel-2);text-align:center;}
.pose-image-holder img{width:100%;height:100%;object-fit:contain;}
.pose-image-actions{display:flex;flex-wrap:wrap;gap:8px;}
.pose-image-actions button{min-height:40px;display:inline-flex;align-items:center;gap:4px;}
.pose-image-control [hidden]{display:none!important;}
#pose-image-picker-modal .pose-image-picker{width:min(640px,calc(100vw - 32px));max-height:calc(100dvh - 32px);display:flex;flex-direction:column;overflow:hidden;}
#pose-image-picker-modal{z-index:1100;}
.pose-image-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:12px;padding:16px;min-height:0;overflow-y:auto;overscroll-behavior:contain;}
.pose-image-choice{min-width:0;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px;cursor:pointer;font-size:13px;}
.pose-image-choice img{width:100%;height:128px;object-fit:contain;}
.pose-image-choice span{display:block;word-break:keep-all;overflow-wrap:anywhere;}
.pose-image-choice:focus-visible{outline:2px solid var(--accent,var(--queued));outline-offset:2px;}
.pose-image-picker .modal-close{min-width:40px;min-height:40px;}
.pose-image-picker .error{padding:0 16px 16px;}
.pose-image-picker .modal-header,.pose-image-filters,.pose-image-tabs,.pose-image-navigation,.pose-image-selection,.pose-image-picker .error{flex-shrink:0;}
.pose-image-filters{display:flex;flex-wrap:wrap;gap:8px;padding:12px 16px;border-bottom:1px solid var(--border);}
.pose-image-filters label{display:flex;flex-direction:column;gap:4px;font-size:13px;flex:1;min-width:0;}
.pose-image-filters .pose-image-search{flex-basis:100%;}
.pose-image-filters select,.pose-image-filters input{width:100%;min-width:0;min-height:40px;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:8px;font-size:13px;}
.pose-image-tabs{display:flex;gap:8px;padding:8px 16px;border-bottom:1px solid var(--border);}
.pose-image-tabs button{min-height:40px;padding:8px 16px;background:transparent;color:var(--text-dim);border:0;border-bottom:2px solid transparent;cursor:pointer;font-size:14px;}
.pose-image-tabs button[aria-selected=true]{color:var(--accent,var(--queued));border-bottom-color:var(--accent,var(--queued));}
.pose-image-navigation{display:flex;align-items:center;gap:8px;padding:8px 16px;font-size:13px;color:var(--text-dim);min-width:0;}
#pose-image-context{overflow-wrap:anywhere;min-width:0;}
.pose-image-selection{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--border);font-size:13px;}
.pose-image-selection img{width:64px;height:64px;object-fit:contain;background:var(--panel-2);border-radius:6px;}
.pose-image-selection span{flex:1;min-width:0;overflow-wrap:anywhere;}
.pose-image-selection button,.pose-image-navigation button{min-height:40px;flex-shrink:0;}
.pose-image-choice[aria-pressed=true]{border-color:var(--accent,var(--queued));outline:2px solid var(--accent,var(--queued));outline-offset:-2px;}
.pose-image-choice{position:relative;}
.pose-image-choice .pose-image-check{display:none;position:absolute;right:8px;top:8px;color:var(--accent,var(--queued));background:var(--panel);border-radius:6px;}
.pose-image-choice[aria-pressed=true] .pose-image-check{display:block;}
.pose-image-picker [hidden]{display:none!important;}
.pose-image-picker-grid .empty{grid-column:1/-1;}
.pose-image-actions button,.pose-image-picker .load-btn{font-family:var(--sans);font-size:13px;font-weight:500;}
.pose-image-picker .submit-btn{margin-top:0;}

.board-gen-new-btn { margin-bottom: 12px; }
/* 퀵바의 열림·닫힘 상태와 명령 완성을 보드 캔버스에 표시한다. */
.board-command{
  position:absolute; z-index:9; left:50%; bottom:16px; transform:translateX(-50%);
  width:min(760px, calc(100% - 32px)); box-sizing:border-box;
  display:flex; flex-direction:column; gap:8px; padding:12px;
  color:var(--text); background:var(--panel); border:1px solid var(--border);
  border-radius:12px; box-shadow:0 8px 24px rgba(16,24,40,.12); opacity:.72;
  cursor:text; transition:opacity .12s ease;
}
.board-command[hidden],.board-command-fab[hidden]{ display:none; }
.board-command-head{ display:block; }
.board-command-close{
  position:absolute; right:4px; top:4px;
  width:40px; height:40px; display:flex; align-items:center; justify-content:center;
  border:0; border-radius:6px; background:transparent; color:var(--text-dim); cursor:pointer;
}
.board-command-close:hover{ background:var(--panel-2); color:var(--text); }
.board-command-close .ico{ width:15px; height:15px; }
.board-command-fab{
  position:absolute; z-index:9; right:72px; bottom:16px; min-width:44px; height:44px;
  display:flex; align-items:center; justify-content:center; gap:4px; padding:0 8px;
  border:1px solid var(--border); border-radius:999px; background:var(--panel); color:var(--text);
  box-shadow:0 8px 24px rgba(16,24,40,.12); font-size:14px; cursor:pointer;
}
.board-command-fab .ico{ width:15px; height:15px; }
.board-command-fab:hover{ border-color:var(--accent); }
.board-command:hover,.board-command:focus-within{ opacity:1; }
.board-command:focus-within{ border-color:var(--accent); }
.board-command-label{ font:600 11px var(--mono); letter-spacing:.12em; color:var(--text-dim); }
.board-command textarea{
  width:100%; min-height:24px; max-height:138px; box-sizing:border-box; resize:none; overflow-y:auto;
  border:0; outline:0; padding:0; background:transparent; color:var(--text);
  font-family:inherit; font-size:14px; font-weight:400; line-height:1.6;
  user-select:text; -webkit-user-select:text;
}
.board-command textarea::placeholder{ color:var(--text-dim); }
.board-command-paste-choice{ display:flex; flex-wrap:wrap; gap:8px; }
.board-command-paste-choice[hidden]{ display:none; }
.board-command-paste-choice button{
  min-height:40px; padding:8px 12px; border:1px solid var(--border); border-radius:6px;
  background:var(--panel-2); color:var(--text); font:inherit; font-size:12px; cursor:pointer;
}
.board-command-paste-choice button:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.board-command-error{ font-size:12px; color:var(--failed); }
.board-command-error:empty{ display:none; }
.board-command-menu{
  position:absolute; bottom:calc(100% + 8px); left:0; width:100%; box-sizing:border-box;
  max-height:240px; overflow:auto; padding:4px; background:var(--panel);
  border:1px solid var(--border); border-radius:8px; box-shadow:0 8px 24px rgba(16,24,40,.12);
}
.board-command-menu[hidden]{ display:none; }
.board-command-menu button{
  width:100%; min-height:40px; display:flex; align-items:center; justify-content:space-between;
  gap:12px; padding:8px 12px; border:0; border-radius:6px;
  background:transparent; color:var(--text); font-family:inherit; font-size:13px;
  font-weight:500; text-align:left; cursor:pointer;
}
.board-command-menu button[aria-selected="true"],.board-command-menu button:hover{ background:var(--bg); }
.board-command-menu span{ color:var(--text-dim); }
.board-viewport:has(.board-command:not([hidden])) .board-selection-bar{ bottom:96px; }
/* 퀵바가 열려 있고 화면이 좁으면 퀵바가 오른쪽 아래 맞춤 버튼을 덮으므로 버튼을 퀵바 위로 올린다 */
@media(max-width:900px){
  .board-viewport:has(.board-command:not([hidden])) .board-fit-fab{ bottom:96px; }
}
@media(max-width:700px){
  .board-command{ bottom:8px; width:calc(100% - 16px); }
  .board-viewport:has(.board-command:not([hidden])) .board-fit-fab{ bottom:88px; }
  .board-viewport:has(.board-command:not([hidden])) .board-selection-bar{ bottom:88px; }
}
  /* ---- 대시보드 (파드 카드 캔버스) ---------------------------------------- */
  .dash-totals{
    display:flex; flex-wrap:wrap; gap:18px;
    padding:14px 18px; margin-bottom:12px;
    background:var(--panel); border:1px solid var(--border); border-radius:10px;
  }
  .dash-total{ display:flex; flex-direction:column; gap:2px; }
  .dash-total-label{ font-size:11px; color:var(--text-dim); }
  .dash-total-value{ font-family:var(--mono); font-size:19px; color:var(--text); }
  .dash-total-value.dim{ color:var(--text-dim); }
  .dash-actions{ display:flex; gap:8px; align-items:center; margin-bottom:12px; }

  /* 카드마다 원하는 폭을 정할 수 있게 열 개수 기반 그리드를 쓴다(카드가 span으로 차지). */
  .card-canvas{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(320px, 1fr));
    gap:12px;
  }
  /* 폰 화면에서는 grid의 auto-fill 열 계산을 아예 안 쓴다 — 카드가 비동기로
     나중에 채워지는데(fetchDashboard), 실제 기기 일부에서 grid-template-columns가
     그 시점의 열 개수를 다시 안 맞추고 예전 값을 들고 있는 문제가 있었다. flex
     column은 그런 재계산 여지 자체가 없어 카드가 항상 한 장씩 세로로 쌓인다. */
  @media (max-width:640px){
    .card-canvas{ display:flex; flex-direction:column; }
  }
  .dash-card{
    display:flex; flex-direction:column; gap:10px;
    padding:14px 16px;
    background:var(--panel); border:1px solid var(--border); border-radius:10px;
  }
  .dash-card[data-span="2"]{ grid-column:span 2; }
  /* 카드 전체가 클릭 영역이다 — 눌러도 되는 곳이라는 걸 커서와 미묘한 hover로
     알려준다. 안쪽 버튼(⚙/▶ 시작/⏸ 정지)은 자기 cursor:pointer가 그대로 이기므로
     구분엔 문제없다. */
  .dash-card-clickable{ cursor:pointer; transition:border-color .12s ease, background .12s ease; }
  .dash-card-clickable:hover{ border-color:var(--queued); background:rgba(var(--queued-rgb),0.04); }
  /* 길게 눌러 삭제 — 누르는 동안 카드가 붉게 물들며 살짝 눌린다. 터치에서는 길게 눌러도 글자 선택·확대 메뉴가 뜨지 않게 한다. */
  .dash-card[data-card-type="pod"]{ -webkit-touch-callout:none; }
  @media (hover:none){ .dash-card[data-card-type="pod"]{ -webkit-user-select:none; user-select:none; } }
  .dash-card.pod-pressing{
    border-color:var(--failed); background:rgba(var(--failed-rgb),0.07); transform:scale(0.985);
    transition:transform .38s ease, border-color .2s ease, background .2s ease;
  }
  .dash-longpress-hint{ display:none; font-size:11.5px; color:var(--text-dim); margin:-6px 0 12px; }
  @media (hover:none){ .dash-longpress-hint{ display:block; } }
  /* 상태별 시각 구분 — 점 색깔 하나로는 카드가 많아지면 눈에 잘 안 들어온다.
     왼쪽 띠 색 + 옅은 배경 톤을 더해서, 굳이 점을 찾아보지 않아도 "지금 뭐가
     돌고 있고 뭐가 안 붙는지"가 카드를 훑기만 해도 보이게 한다. hover 시
     border-color를 덮어쓰는 규칙보다 아래 있어야 하고(우선순위), 왼쪽 테두리는
     hover와 무관하게 그 파드의 상태를 계속 보여줘야 하므로 border-left만 별도로
     둔다. */
  .dash-card[data-pod-state]{ border-left-width:3px; border-left-style:solid; }
  .dash-card[data-pod-state="online"]{ border-left-color:var(--done); }
  .dash-card[data-pod-state="offline"]{
    border-left-color:var(--failed);
    background:rgba(var(--failed-rgb),0.045);
  }
  .dash-card[data-pod-state="busy"]{
    border-left-color:var(--running);
    background:rgba(var(--running-rgb),0.05);
  }
  .dash-card[data-pod-state="disabled"]{ border-left-color:var(--border); }
  .dash-card-top{ display:flex; gap:10px; align-items:flex-start; }
  .dash-card-top-info{ flex:1; min-width:0; display:flex; flex-direction:column; gap:6px; }
  /* 카드마다 하나씩 있는 "일꾼 로봇" — 몸통 색은 파드별로 고정(hashToIndex),
     표정/애니메이션은 상태를 따라간다. transform-box를 fill-box로 줘야 SVG
     자체의 bounding box 기준으로 회전/이동해서, 뷰포트 원점 기준으로 어색하게
     튀지 않는다. */
  .dash-robot{ flex:none; width:36px; height:36px; }
  .dash-robot-svg{ display:block; transform-box:fill-box; transform-origin:50% 50%; }
  .dash-robot-online{ animation:robot-bob 2.6s ease-in-out infinite; }
  .dash-robot-busy{ animation:robot-shake 0.5s ease-in-out infinite; }
  .dash-robot-offline{ opacity:0.55; }
  .dash-robot-disabled{ filter:grayscale(1); opacity:0.5; }
  .dash-robot-busy .dash-robot-light{ animation:pulse-run 0.6s infinite; }
  @keyframes robot-bob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-2px); } }
  @keyframes robot-shake{ 0%,100%{ transform:rotate(0deg); } 25%{ transform:rotate(-3deg); } 75%{ transform:rotate(3deg); } }
  /* 카드 머리줄 — 이름이 길면 줄임표(...)로 줄이고, 종류·소유자 배지는 자리가 모자라면 다음 줄로 넘어간다. 설정(⚙) 버튼은
     오른쪽 위에 붙박이로 두어(자리를 padding-right로 비워 둔다) 줄이 바뀌어도 카드 밖으로 밀려나지 않는다. */
  .dash-card-head{ position:relative; display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; padding-right:44px; min-height:34px; }
  .dash-card-name{ flex:1 1 0; min-width:min(16ch, 100%); font-family:var(--mono); font-size:14px; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .dash-card-kind{ flex:0 1 auto; min-width:0; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:10.5px; color:var(--text-dim); border:1px solid var(--border); border-radius:4px; padding:1px 5px; }
  .dash-card-head-right{ position:absolute; top:0; right:0; display:flex; gap:6px; align-items:center; }
  /* 카드의 설정 버튼 — 테두리·바탕 없이 톱니바퀴만. 아이콘은 키우고, 누를 자리(34px)는 손가락에 맞게 둔다. */
  .dash-gear-btn{ display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; padding:0;
                  border:none; background:none; border-radius:50%; color:var(--text-dim); cursor:pointer;
                  transition:color .15s ease, transform .3s ease; }
  .dash-gear-btn .ico{ width:22px; height:22px; vertical-align:0; }
  .dash-gear-btn:hover{ color:var(--queued); transform:rotate(45deg); }
  .dash-gear-btn:focus-visible{ outline:2px solid var(--queued); outline-offset:1px; }
  .dash-dot{ width:8px; height:8px; border-radius:50%; flex:none; background:var(--text-dim); }
  .dash-dot.online{ background:var(--done); }
  .dash-dot.offline{ background:var(--failed); }
  .dash-dot.busy{ background:var(--running); animation:pulse-run 1.2s infinite; }
  .dash-dot.disabled{ background:var(--text-dim); opacity:0.5; }
  .dash-card-url{ font-family:var(--mono); font-size:11px; color:var(--text-dim); word-break:break-all; }
  .dash-card-runpod{ display:flex; flex-wrap:wrap; gap:4px 10px; font-size:10.5px; color:var(--text-dim); }
  .dash-card-runpod b{ color:var(--text); font-weight:500; }
  /* 파드 바로가기(ComfyUI·JupyterLab·파일 브라우저) — 새 탭으로 연다. 카드 클릭(파드 열기)은
     <a>를 누른 경우 무시하므로 링크만 눌러도 카드 이동이 일어나지 않는다. */
  .pod-links{ display:flex; flex-wrap:wrap; gap:6px; }
  .pod-link{ display:inline-flex; align-items:center; gap:4px; font-size:11px; color:var(--queued); text-decoration:none;
             border:1px solid var(--border); border-radius:5px; padding:2px 7px; background:var(--bg); }
  .pod-link:hover{ border-color:var(--queued); }
  .pod-link .ico{ width:12px; height:12px; }
  .pod-bar-links{ display:flex; flex-wrap:wrap; gap:6px; }
  .dash-card-job{ font-size:12px; color:var(--text); }
  .dash-card-job .dim{ color:var(--text-dim); }
  /* 부팅 상태(NS-18) — 켠 지 몇 분째 ComfyUI 응답 없음 / 부팅 실패와 "다시 만들기" */
  .dash-boot{ color:var(--text-dim); }
  .dash-boot.failed{ color:var(--failed); }
  .dash-card-job [data-pod-reboot]{ margin-left:8px; }
  .dash-card-stats{ display:flex; flex-wrap:wrap; gap:14px; }
  .dash-stat{ display:flex; flex-direction:column; }
  .dash-stat-label{ font-size:10.5px; color:var(--text-dim); }
  .dash-stat-value{ font-family:var(--mono); font-size:14px; color:var(--text); }
  .dash-thumbs{ display:flex; gap:6px; }
  /* 최근 작업 카드 — 작업 목록이 파드 안으로 들어가면서 "전체 작업을 한 화면에서"가
     사라지는데, 그 자리를 대신한다. 행을 누르면 그 작업이 있는 파드로 들어간다. */
  .dash-jobs{ display:flex; flex-direction:column; gap:1px; }
  .dash-job-row{
    display:flex; align-items:center; gap:8px;
    padding:4px 6px; border-radius:6px; cursor:pointer; font-size:12px; color:var(--text);
  }
  .dash-job-row:hover{ background:rgba(var(--queued-rgb),0.06); }
  .dash-job-name{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .dash-job-pod{ flex:none; font-size:10.5px; color:var(--text-dim); }
  .dash-thumb{ width:54px; height:54px; object-fit:cover; border-radius:6px; border:1px solid var(--border); }
  .dash-card-actions{ display:flex; flex-wrap:wrap; gap:6px; margin-top:auto; padding-top:4px; }
  .dash-card.disabled{ opacity:0.62; }
  /* 카드의 상태 표시(누르면 설정 창) — 켜짐은 초록, 멈춤/꺼짐은 회색, 바뀌는 중은 파랑 */
  .pod-chip{
    display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:999px; cursor:pointer;
    font:inherit; font-size:11.5px; color:var(--text-dim); background:var(--bg); border:1px solid var(--border);
  }
  .pod-chip::before{ content:''; width:7px; height:7px; border-radius:50%; background:#9aa0a6; }
  .pod-chip.on{ color:var(--text); }
  .pod-chip.on::before{ background:var(--done); }
  .pod-chip.busy::before{ background:var(--running); }
  .pod-chip:hover{ border-color:rgba(var(--queued-rgb),0.6); }

  /* 워커 설정 창 — 주소와 동시 실행 수를 한 줄에. 모바일은 두 줄로, 둘 다 같은(전체) 너비 */
  .pod-edit-addr-row{ display:grid; grid-template-columns:1fr 150px; gap:12px; align-items:end; }
  .pod-edit-addr-row .field{ min-width:0; }
  .pod-edit-addr-row .option-input{ max-width:100%; width:100%; box-sizing:border-box; }
  @media (max-width:640px){ .pod-edit-addr-row{ grid-template-columns:1fr; gap:10px; } }
  /* 숫자 전용 −/+ 고르개 — 가운데 숫자는 직접 치지 않는다 */
  .num-stepper{
    display:flex; align-items:stretch; height:38px; box-sizing:border-box;
    border:1px solid var(--border); border-radius:8px; background:var(--bg); overflow:hidden;
  }
  .num-stepper input{
    flex:1; min-width:0; width:100%; border:none; background:transparent; text-align:center;
    font:inherit; font-size:15px; font-weight:600; color:var(--text); pointer-events:none; -moz-appearance:textfield;
  }
  .num-stepper input::-webkit-outer-spin-button, .num-stepper input::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
  .num-stepper-btn{
    flex:none; width:40px; border:none; background:transparent; color:var(--text); font-size:18px; line-height:1; cursor:pointer;
  }
  .num-stepper-btn:first-child{ border-right:1px solid var(--border); }
  .num-stepper-btn:last-child{ border-left:1px solid var(--border); }
  .num-stepper-btn:hover:not(:disabled){ background:rgba(var(--queued-rgb),0.08); }
  .num-stepper-btn:disabled{ color:var(--text-dim); opacity:0.45; cursor:not-allowed; }

  /* 워커 설정 창의 스위치 줄들 */
  .pod-controls{ display:flex; flex-direction:column; gap:8px; }
  .pod-control-row{
    display:flex; align-items:center; gap:12px; padding:9px 12px;
    border:1px solid var(--border); border-radius:8px; background:var(--bg);
  }
  .pod-control-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; font-size:13px; color:var(--text); }
  .pod-control-text span{ font-size:11.5px; color:var(--text-dim); }
  .pod-control-text span:empty{ display:none; }
  .pod-control-minutes{ flex:none; display:inline-flex; align-items:center; gap:4px; font-size:12.5px; color:var(--text-dim); }
  .pod-control-minutes input{ width:56px; padding:4px 6px; font:inherit; color:var(--text); background:var(--bg); border:1px solid var(--border); border-radius:6px; text-align:right; }
  .pod-control-ico{ flex:none; width:18px; height:18px; color:var(--text-dim); }
  /* RunPod 줄은 아래에 RunPod 정보(이름·GPU·비용·일시)를 이어 붙인다 — 아이콘 너비만큼 들여서 제목과 줄을 맞춘다 */
  .pod-control-runpod{ flex-wrap:wrap; }
  .pod-control-runpod .runpod-info-grid{ flex:1 0 100%; box-sizing:border-box; padding:8px 0 0 30px; border-top:1px dashed var(--border); }
  .pod-switch{
    flex:none; position:relative; width:42px; height:24px; border-radius:12px; padding:0; cursor:pointer;
    background:#b8bdc4; border:none; transition:background .15s ease;
  }
  .pod-switch::after{
    content:''; position:absolute; top:3px; left:3px; width:18px; height:18px; border-radius:50%;
    background:#fff; box-shadow:0 1px 2px rgba(0,0,0,0.25); transition:transform .15s ease;
  }
  .pod-switch[aria-checked="true"]{ background:var(--done); }
  /* 워커 설정 서브탭(NS-9) — 설정 창을 모달이 아니라 화면에 그린다. 닫기(X)·취소는 쓸 일이 없어 숨긴다. */
  .pod-settings-host{ max-width:760px; margin:0 auto; }
  .modal-overlay.inline{ position:static; display:block !important; inset:auto; background:none; padding:0; z-index:auto;
    backdrop-filter:none; animation:none; }
  .modal-overlay.inline .modal-panel{ max-width:none; width:auto; max-height:none; box-shadow:none; animation:none; transform:none; }
  .modal-overlay.inline #pod-edit-close, .modal-overlay.inline #pod-edit-cancel{ display:none; }
  .dash-local-toggle{ margin-left:auto; display:inline-flex; align-items:center; gap:8px; font-size:12.5px; color:var(--text-dim); cursor:pointer; }
  .dash-local-toggle[hidden]{ display:none; }
  .pod-switch[aria-checked="true"]::after{ transform:translateX(18px); }
  .pod-switch:disabled{ opacity:0.45; cursor:not-allowed; }
  .pod-switch:focus-visible{ outline:2px solid rgba(var(--queued-rgb),0.6); outline-offset:2px; }


  /* 워커 안의 "모델" 탭(08b-worker-models.js) */
  .wm-section{ margin-bottom:22px; }
  .wm-section-head{ display:flex; align-items:center; gap:10px; margin-bottom:8px; flex-wrap:wrap; }
  .wm-section-head h3{ margin:0; font-size:13.5px; font-weight:600; color:var(--text); flex:1; min-width:0; }
  .wm-count{ font-size:11.5px; font-weight:400; color:var(--text-dim); }
  .wm-search{ max-width:220px; }
  .wm-row{
    display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:7px 10px; font-size:12.5px;
    border-bottom:1px solid var(--border);
  }
  .wm-name{ flex:1 1 240px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text); font-family:var(--mono); font-size:12px; }
  .wm-kind{ flex:none; font-size:11px; color:var(--text-dim); }
  .wm-jobs{ flex:1 1 100%; font-size:11px; color:var(--text-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .wm-tag{ flex:none; font-size:11px; padding:1px 7px; border-radius:999px; border:1px solid var(--border); color:var(--text-dim); }
  .wm-tag.ok{ color:var(--done); border-color:rgba(var(--done-rgb),0.45); }
  .wm-tag.warn{ color:#EA580C; border-color:rgba(234,88,12,0.45); }   /* 작업 카드의 "조치 필요"와 같은 주황 */
  .wm-dl-state{ flex:none; font-size:11.5px; color:var(--text-dim); }
  .wm-dl-state.error{ color:var(--failed); }
  .wm-dl-bar{ flex:1 1 100%; }
  .wm-group{ border:1px solid var(--border); border-radius:8px; margin-bottom:8px; background:var(--bg); }
  .wm-group > summary{ cursor:pointer; padding:9px 12px; font-size:13px; color:var(--text); }
  .wm-group[open] > summary{ border-bottom:1px solid var(--border); }
  .wm-group .wm-row:last-child{ border-bottom:none; }

  /* 워커 탭 아래 내 RunPod 대시보드 — 잔액·불러온 일시 두 칸, 그 아래 구동 중인 Pod·네트워크 볼륨 목록 */
  .rp-dash{ margin-top:28px; }
  .rp-dash-meta{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:12px; }
  @media (max-width:640px){ .rp-dash-meta{ grid-template-columns:1fr; } }
  .rp-dash-stat{ display:flex; flex-direction:column; gap:4px; min-width:0; padding:12px; border:1px solid var(--border); border-radius:8px; background:var(--bg); }
  .rp-dash-stat b{ font-size:16px; color:var(--text); overflow-wrap:anywhere; }
  .rp-dash-label{ font-size:11.5px; color:var(--text-dim); }
  .rp-dash-sub{ display:flex; align-items:center; gap:6px; margin:16px 0 8px; font-size:13px; font-weight:600; color:var(--text); }
  .rp-dash-sub .wm-count{ margin-left:2px; }
  .rp-dash .load-btn:disabled{ opacity:.6; cursor:wait; }

  /* 워커 추가 = RunPod 파드 만들기 — 추가 창(create-mode)에서만 등급 카드, 주소 입력 칸들은 "고급"을 펼쳤을 때만 */
  #pod-edit-modal:not(.create-mode) .create-only{ display:none; }
  #pod-edit-modal.create-mode:not(.manual-open) .manual-only{ display:none !important; }
  .pod-create-tiers{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:10px 0; }
  @media (max-width:640px){ .pod-create-tiers{ grid-template-columns:1fr; } }
  .pod-create-tier{
    display:flex; flex-direction:column; align-items:flex-start; gap:4px; padding:14px; border-radius:10px; cursor:pointer; text-align:left;
    font:inherit; color:var(--text); background:var(--bg); border:1.5px solid var(--border);
  }
  .pod-create-tier .ico{ width:22px; height:22px; color:var(--queued); }
  .pod-create-tier b{ font-size:14px; }
  .pod-create-tier span{ font-size:12px; color:var(--text-dim); }
  .pod-create-tier:hover:not(:disabled){ border-color:rgba(var(--queued-rgb),0.7); }
  .pod-create-tier:disabled{ opacity:.5; cursor:wait; }
  .pod-manual-toggle{
    display:inline-flex; align-items:center; gap:4px; margin-top:6px; padding:4px 0; border:none; background:none; cursor:pointer;
    font:inherit; font-size:12.5px; color:var(--text-dim);
  }
  .pod-manual-toggle .ico{ width:14px; height:14px; transition:transform .15s ease; }
  #pod-edit-modal.manual-open .pod-manual-toggle .ico{ transform:rotate(180deg); }
  /* ---- JOBS 탭 — Job Queue 카드 보드. 대기/실행/완료/실패 4섹션으로 나눠서 보여준다
     (render()가 채움). 섹션은 갤러리 작업별/날짜별 보기(.gallery-group)와 같은
     "소제목 + 전용 grid" 패턴을 따른다. 카드가 비동기(폴링)로 채워지므로 .card-canvas와
     같은 이유로 모바일에서는 grid 대신 flex-column으로 전환한다.
     카드는 정사각형 — 최소 정보(종류 아이콘+배치 방식, 베이스 모델, 진행률, 시작/정지/
     삭제 아이콘 버튼)만 보이고 나머지(소유자/파드/프로젝트/워크플로우 파일명/시간·옵션
     상세/로그)는 전부 상세 모달(job-detail-*)에서만 보여준다. ---- */
  /* 4단계(대기/실행/완료/실패)를 칸반처럼 좌→우로 나란히 둔다 — 칸이 좁아지면
     .job-board-grid의 auto-fill이 자연히 칸 하나짜리 세로 목록으로 줄어든다. */
  #tab-jobs .panel-header{ flex-wrap:wrap; gap:8px; }
  #clear-done-jobs{
    display:inline-flex; align-items:center; justify-content:center; gap:8px;
    color:var(--failed); background:transparent; border:1px solid var(--border);
    border-radius:6px; padding:8px 12px; font:inherit; font-size:13px; font-weight:500;
    min-height:40px; margin-left:auto; cursor:pointer;
  }
  #clear-done-jobs:hover:not(:disabled){ background:var(--panel-2); border-color:var(--failed); }
  #clear-done-jobs:disabled{ color:var(--text-dim); cursor:not-allowed; }
  #clear-done-jobs:focus-visible{ outline:2px solid var(--accent); outline-offset:4px; }
  .job-cleanup-result{ font-size:13px; color:var(--text-dim); overflow-wrap:anywhere; }
  .job-cleanup-result:not(:empty){ margin-bottom:12px; }
  .job-board{ display:flex; flex-direction:row; align-items:flex-start; gap:16px; overflow-x:auto; }
  .job-section{ flex:1 1 0; min-width:220px; display:flex; flex-direction:column; }
  .job-section-header{
    display:flex; align-items:center; gap:8px;
    font-family:var(--mono); font-size:11.5px; font-weight:600; color:var(--text-dim);
    padding:6px 2px; margin-bottom:8px; border-bottom:1px solid var(--border);
  }
  .job-section-count{ color:var(--text); }
  .job-section-empty{
    font-size:12px; color:var(--text-dim); text-align:center;
    padding:18px 4px; border:1px dashed var(--border); border-radius:10px;
  }
  .job-board-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(140px, 1fr));
    gap:10px;
  }
  @media (max-width:900px){
    .job-board{ flex-direction:column; overflow-x:visible; }
    .job-section{ min-width:0; }
  }
  @media (max-width:640px){
    .job-board-grid{ grid-template-columns:repeat(auto-fill, minmax(120px, 1fr)); }
  }
  .job-card{
    position:relative;
    aspect-ratio:2;
    display:flex; flex-direction:column; justify-content:space-between; gap:4px;
    padding:8px;
    background:var(--panel); border:1px solid var(--border); border-radius:10px;
    border-left-width:3px; border-left-style:solid;
    cursor:pointer;
    transition:border-color .12s ease, background .12s ease;
    -webkit-touch-callout:none;
  }
  /* 대기 칸 맨 끝 "+" 카드 — 잡 카드와 같은 크기·모서리를 쓰되 점선 테두리로
     "아직 잡이 아니다"를 드러낸다. 눌러서 openNewJobModal(). */
  .job-card-add{
    aspect-ratio:2;
    display:flex; align-items:center; justify-content:center;
    background:none; border:1.5px dashed var(--border); border-radius:10px;
    color:var(--text-dim); cursor:pointer;
    transition:border-color .12s ease, color .12s ease, background .12s ease;
  }
  .job-card-add:hover{ border-color:var(--queued); color:var(--queued); background:rgba(var(--queued-rgb),0.04); }
  .job-card-add .ico{ width:20px; height:20px; }
  @media (hover:none){ .job-card{ -webkit-user-select:none; user-select:none; } }
  .job-card:hover{ border-color:var(--queued); background:rgba(var(--queued-rgb),0.04); }
  .job-card[data-status="pending"], .job-card[data-status="queued"]{ border-left-color:var(--queued); }
  .job-card[data-status="running"]{ border-left-color:var(--running); }
  .job-card[data-status="done"]{ border-left-color:var(--done); }
  .job-card[data-status="failed"]{ border-left-color:var(--failed); }
  .job-card[data-status="interrupted"]{ border-left-color:var(--interrupted); }
  /* 일시정지(pending) — 대기열에 있지만 빈 파드가 있어도 시작하지 않는다. 회색 카드로 가라앉히고
     ▶ 버튼만 또렷하게 둔다. 실행 대기(queued)는 보통 카드에 ⏸. */
  .job-card[data-status="pending"]{ background:var(--bg); border-left-color:var(--text-dim); border-style:dashed; border-left-style:solid; }
  .job-card[data-status="pending"] > :not(.job-card-actions){ opacity:.5; filter:grayscale(1); }
  .job-card[data-status="pending"] .start-btn{ color:var(--done); }
  .job-card .pause-btn{ color:var(--queued); }
  .job-card-actions .start-btn .ico, .job-card-actions .pause-btn .ico{ width:16px; height:16px; }
  /* 카드 안에서만 쓰는 위치 지정 — 배지 자체 모양(.pod-badge/.preflight-badge)은
     기존 걸 그대로 재사용해서 모델탭 등과 스타일이 갈라지지 않게 한다. */
  .job-card .preflight-badge{ position:absolute; top:8px; right:8px; }
  .job-card-title{
    display:flex; align-items:center; gap:6px;
    font-family:var(--mono); font-size:12px; color:var(--text);
    padding-right:22px; overflow:hidden;
  }
  .job-card-title .ico{ width:14px; height:14px; flex:none; color:var(--text-dim); }
  .job-card-title span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  /* 실행 대기(queued)인데 파드를 못 찾은 이유 — 스케줄러가 적어 둔 waiting_reason. 한 줄로 줄이고 전체는 툴팁·상세 창에. */
  .model-pods-badge{ display:inline-flex; align-items:center; gap:3px; margin-left:8px; font-size:10.5px; font-family:var(--sans); vertical-align:middle; }
  .model-pods-badge .ico{ width:12px; height:12px; }
  .model-pods-badge.ok{ color:var(--done); }
  .model-pods-badge.warn{ color:#EA580C; }
  .job-card[data-blocked]{ border-left-color:#EA580C; background:rgba(234,88,12,0.05); }
  .job-card[data-blocked] .job-card-wait{ color:#EA580C; }
  .job-card .fetch-models-btn{ color:#EA580C; }
  .job-card-wait.fetching{ color:var(--queued); }
  .job-card-wait{ display:flex; align-items:center; gap:4px; margin-top:2px; font-size:10.5px; color:var(--running); min-width:0; }
  .job-card-wait .ico{ width:12px; height:12px; flex:none; }
  .job-card-wait span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  /* 모델 안내는 워커 모델 탭으로 가는 링크(NS-3) — 글자색은 상태색 그대로, 올리면 밑줄 */
  a.job-card-models-link{ text-decoration:none; cursor:pointer; }
  a.job-card-models-link:hover span{ text-decoration:underline; text-underline-offset:2px; }
  .job-card-base{ font-size:11px; color:var(--text-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .job-card-actions{ display:flex; gap:2px; justify-content:flex-end; }
  /* 경과 시간은 버튼 줄 왼쪽 끝 — 버튼들은 그대로 오른쪽에 붙는다. */
  .job-card-elapsed{ margin-right:auto; align-self:center; display:inline-flex; align-items:center; gap:3px;
                     font-family:var(--mono); font-size:11px; color:var(--text-dim); font-variant-numeric:tabular-nums; }
  .job-card-elapsed .ico{ width:12px; height:12px; }
  .job-card-elapsed.running{ color:var(--running); }
  /* 카드 안에서는 아이콘 자체가 버튼 — .del-btn/.start-btn/.stop-btn을 감싸던 사각
     테두리·배경을 없애고, hover 시 색만(기존 색 규칙 그대로) 살짝 배경으로 드러낸다. */
  .job-card-actions button{
    flex:none; display:flex; align-items:center; justify-content:center;
    width:22px; height:22px; padding:0;
    background:none; border:none; border-radius:var(--radius-sm);
  }
  /* Jobs 게시판: 넓은 화면은 열을 맞추고 좁은 화면은 각 행 안에 필드명을 둔다. */
  #tab-jobs .panel-header{ align-items:center; }
  #job-add-btn{ min-height:40px; margin-left:auto; }
  #clear-done-jobs{ margin-left:0; }
  .job-list-toolbar{ display:flex; align-items:center; gap:8px; margin-bottom:12px; flex-wrap:wrap; }
  .job-list-toolbar label{ font-size:12px; font-weight:500; color:var(--text-dim); }
  .job-list-toolbar input, .job-list-toolbar select{
    min-height:40px; border:1px solid var(--border); border-radius:6px; background:var(--panel);
    color:var(--text); font:inherit; font-size:13px; padding:8px 12px;
  }
  .job-list-toolbar input{ flex:1 1 220px; min-width:0; }
  .job-list-toolbar input[type="date"]{ flex:none; width:auto; }
  .job-list-toolbar [hidden]{ display:none; }
  .job-list-toolbar .job-show-done{ display:inline-flex; align-items:center; gap:6px; min-height:40px; cursor:pointer; }
  .job-list-toolbar .job-show-done input{ flex:none; width:auto; min-height:0; padding:0; accent-color:var(--accent); }
  .job-list-toolbar select{ max-width:100%; min-width:0; }
  .job-list-toolbar select:disabled{ opacity:.5; }
  .job-list-toolbar :focus-visible, .job-card:focus-visible, .job-card-actions button:focus-visible{
    outline:2px solid var(--accent); outline-offset:2px;
  }
  .job-board{ display:block; width:100%; overflow-x:visible; border:1px solid var(--border); border-radius:8px; }
  .job-list-head, .job-card{
    display:grid; grid-template-columns:minmax(220px,2fr) minmax(150px,1.7fr) minmax(105px,1.2fr) minmax(100px,1fr) minmax(120px,1.2fr) minmax(145px,1.4fr);
    align-items:center; gap:12px; width:100%; min-width:0;
  }
  .job-list-head{
    padding:10px 16px; background:var(--panel-2); color:var(--text-dim);
    font-family:var(--mono); font-size:11px; font-weight:600;
  }
  .job-card{
    aspect-ratio:auto; border:0; border-top:1px solid var(--border); border-radius:0;
    border-left:3px solid transparent; padding:12px 13px; min-height:66px;
    background:var(--panel); user-select:text; -webkit-user-select:text;
  }
  .job-card[data-status="pending"]{ background:var(--panel); border-style:solid; }
  .job-card[data-status="pending"] > :not(.job-card-actions){ opacity:1; filter:none; }
  .job-card .preflight-badge{ position:static; }
  .job-cell{ min-width:0; overflow-wrap:anywhere; }
  .job-main{ display:flex; align-items:center; gap:10px; }
  .job-main-text{ min-width:0; flex:1; }
  .job-thumb{ flex:none; width:48px; height:48px; }
  .job-thumb img{ display:block; width:100%; height:100%; object-fit:cover; border-radius:var(--radius-sm); }
  .job-thumb-tile{
    display:flex; align-items:center; justify-content:center; width:100%; height:100%;
    border-radius:var(--radius-sm); background:var(--bg); color:var(--text-dim);
  }
  .job-card-title{ padding-right:0; font-size:13px; font-weight:500; }
  .job-card-title span:last-child{ min-width:0; }
  .job-card-id{ flex:none; font-size:12px; color:var(--text-dim); font-variant-numeric:tabular-nums; }
  .job-card-base{ font-size:12px; margin:3px 0 0 20px; }
  .job-state{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 8px; }
  .job-card-wait{ flex-basis:100%; margin-top:0; font-size:12px; }
  .job-card-wait span{ white-space:normal; overflow-wrap:anywhere; }
  .job-scope{ display:flex; flex-direction:column; gap:2px; font-size:12px; }
  .job-scope span:last-child{ color:var(--text-dim); }
  .job-progress .progress-wrap{ margin-top:0; }
  .job-finished{ color:var(--text-dim); font-family:var(--mono); font-size:12px; font-variant-numeric:tabular-nums; }
  .job-card-actions{ flex-wrap:wrap; justify-content:flex-start; gap:4px; }
  .job-card-elapsed{ width:100%; margin-right:0; }
  .job-card-actions button{ width:40px; height:40px; border:1px solid var(--border); cursor:pointer; }
  .job-card-actions button:disabled{ cursor:not-allowed; opacity:.5; }
  .job-list-empty{ padding:24px 16px; text-align:center; font-size:13px; color:var(--text-dim); border-top:1px solid var(--border); }
  @media(max-width:900px){
    .job-list-head{ display:none; }
    .job-card{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px 16px; }
    .job-main, .job-state, .job-card-actions{ grid-column:1 / -1; }
    .job-cell:not(.job-main)::before{ content:attr(data-label); display:block; font-size:11px; color:var(--text-dim); margin-bottom:4px; }
    .job-card-actions{ align-items:center; }
    .job-card-elapsed{ width:auto; margin-right:auto; }
  }
  @media(max-width:640px){
    .job-card{ grid-template-columns:1fr 1fr; padding:14px; }
    .job-progress, .job-finished{ grid-column:auto; }
    .job-list-toolbar{ display:grid; grid-template-columns:auto minmax(0,1fr); }
    .job-list-toolbar > label[for="job-search"],
    .job-list-toolbar input[type="search"],
    .job-list-toolbar .job-show-done{ grid-column:1 / -1; }
    .job-list-toolbar select, .job-list-toolbar input[type="date"]{ width:100%; }
    #job-add-btn{ margin-left:0; }
  }
  .job-detail-actions{ display:flex; flex-wrap:wrap; gap:8px; }
  .job-detail-grid{ display:flex; flex-direction:column; gap:10px; }
  .job-detail-preflight{ font-size:12px; color:var(--text-dim); line-height:1.6; white-space:pre-line; }
  .job-detail-prompt{ font-size:13px; color:var(--text); line-height:1.5; white-space:pre-wrap; word-break:break-word; }
  .job-detail-prompt-heading{ display:flex; align-items:center; gap:8px; }
  .job-detail-copy{ display:inline-flex; align-items:center; justify-content:center; width:40px; height:40px; border:0; border-radius:6px; background:transparent; color:var(--text-dim); cursor:pointer; }
  .job-detail-copy:hover{ background:var(--panel-2); color:var(--accent); }
  .job-detail-copy:disabled{ opacity:.4; cursor:default; }
  .job-detail-copy-status{ color:var(--text-dim); font-size:12px; }
  .job-detail-options-details{ min-width:0; }
  .job-detail-options-details summary{ cursor:pointer; }
  .job-detail-options-details[open] summary{ margin-bottom:8px; }
  .job-detail-options{ display:grid; gap:4px; min-width:0; }
  .job-detail-option{ display:grid; grid-template-columns:minmax(100px, 160px) minmax(0, 1fr); gap:8px; min-width:0; padding:8px 12px; border-radius:6px; background:var(--panel-2); font-size:13px; line-height:1.5; }
  .job-detail-option-key{ color:var(--text-dim); overflow-wrap:anywhere; }
  .job-detail-option-value{ color:var(--text); min-width:0; overflow-wrap:anywhere; white-space:pre-wrap; }
  .job-detail-empty{ color:var(--text-dim); font-size:13px; }
  .job-detail-event{ display:flex; flex-wrap:wrap; gap:4px 8px; min-width:0; }
  .job-detail-event-time{ flex:none; font-family:var(--mono); font-variant-numeric:tabular-nums; }
  .job-detail-event-text{ min-width:0; overflow-wrap:anywhere; white-space:pre-wrap; }
  @media(max-width:640px){
    .job-detail-option{ grid-template-columns:minmax(0, 1fr); gap:2px; }
  }
  /* 상세 모달의 생성물 섹션 — 작게 썸네일+파일명, 누르면 그 갤러리 항목으로 이동
     (openGalleryForJobOutput). */
  .job-detail-outputs{ display:flex; flex-wrap:wrap; gap:8px; }
  .job-detail-output{
    display:flex; flex-direction:column; gap:3px; align-items:center;
    width:64px; background:none; border:none; padding:0; cursor:pointer;
  }
  .job-detail-output-thumb{
    width:64px; height:64px; border-radius:6px; border:1px solid var(--border);
    object-fit:cover; background:#000;
  }
  .job-detail-output-name{
    width:100%; font-size:9.5px; color:var(--text-dim); text-align:center;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  /* 로그는 기본 접힘 — <details>는 요소를 다시 안 만들고 display만 바꾸므로, 안의
     <pre id="job-detail-log">가 절대 재생성되지 않아야 한다는 규칙(위 HTML 주석)과
     충돌하지 않는다. */
  .job-detail-log-details summary{ cursor:pointer; font-size:11px; color:var(--text-dim); font-family:var(--mono); }

  /* Claude 글쓰기 파드의 "📝 결과" 탭 — 이미지가 아니라 글이라 갤러리(썸네일 격자)
     대신 이 목록을 쓴다. 행을 누르면 그 자리에서 펼쳐지고(별도 라이트박스 없음),
     펼친 순간에만 서버에서 전문을 받아온다(resultTextCache로 재요청 방지). */
  .results-list{ display:flex; flex-direction:column; gap:6px; }
  .result-row{
    border:1px solid var(--border); border-radius:8px; padding:8px 12px;
    cursor:pointer; background:var(--panel);
  }
  .result-row:hover{ border-color:var(--queued); }
  .result-row.open{ cursor:default; }
  .result-row-head{ display:flex; align-items:center; gap:10px; }
  .result-prompt{
    flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
    font-size:13px; color:var(--text);
  }
  .result-time{ flex:none; font-size:11px; color:var(--text-dim); font-family:var(--mono); }
  .result-full{
    margin-top:8px; padding-top:8px; border-top:1px solid var(--border);
    font-size:13px; line-height:1.6; color:var(--text); white-space:pre-wrap;
    cursor:text;
  }

  /* 작업이 어느 파드(워커)에서 도는지 — 파드가 둘 이상일 때만 나타난다. */
  .pod-badge{
    display:inline-flex; align-items:center;
    padding:1px 6px; margin-right:4px;
    border:1px solid var(--border); border-radius:4px;
    font-family:var(--mono); font-size:10.5px; color:var(--text-dim);
    white-space:nowrap;
  }
  .badge.waiting{ color:var(--interrupted); background:rgba(var(--interrupted-rgb),0.12); }
  .video-edit-panel{ max-width:560px; width:calc(100vw - 24px); }
  .ve-list{ display:flex; flex-direction:column; gap:6px; max-height:46vh; overflow:auto; }
  .ve-row{ display:flex; align-items:center; gap:8px; padding:6px 8px; border:1px solid var(--border); border-radius:var(--radius-sm); }
  .ve-idx{ flex:0 0 18px; font-family:var(--mono); font-size:11px; color:var(--text-dim); text-align:center; }
  .ve-thumb{ flex:0 0 52px; width:52px; height:36px; object-fit:cover; border-radius:4px; background:#000; }
  .ve-name{ flex:1 1 auto; min-width:0; font-family:var(--mono); font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ve-video{ width:100%; max-height:42vh; background:#000; border-radius:var(--radius-sm); }
  .ve-trim-row{ display:flex; align-items:flex-end; gap:8px; flex-wrap:wrap; margin-top:8px; }
  .ve-trim-row .field-label{ display:flex; flex-direction:column; gap:4px; flex:1 1 120px; }
  .job-wait-reason{ font-size:11px; color:var(--text-dim); margin-top:4px; max-width:420px; white-space:normal; line-height:1.4; }
  .badge.waiting .bdot{ animation: pulse-run 1.6s infinite; }
  .badge .bdot{ width:5px; height:5px; border-radius:50%; background:currentColor; }
  .badge.running .bdot{ animation: pulse-run 1.2s infinite; }
  @keyframes pulse-run{ 0%,100%{opacity:1;} 50%{opacity:.35;} }

  .progress-wrap{ display:flex; align-items:center; gap:6px; margin-top:5px; }
  .progress-track{ width:64px; height:4px; border-radius:2px; background:var(--border); overflow:hidden; flex-shrink:0; }
  .progress-fill{ height:100%; border-radius:2px; transition:width .3s ease; }
  .progress-fill.pending{ background:var(--queued); }
  .progress-fill.queued{ background:var(--queued); }
  .progress-fill.running{ background:var(--running); }
  .progress-fill.done{ background:var(--done); }
  .progress-fill.failed{ background:var(--failed); }
  .progress-fill.interrupted{ background:var(--interrupted); }
  .progress-text{ font-family:var(--mono); font-size:10.5px; color:var(--text-dim); white-space:nowrap; }

  .time-cell{ color:var(--text-dim); font-family:var(--mono); font-size:12px; white-space:nowrap; }
  .time-cell.dim{ color:var(--border); }

  @container (max-width:760px){
    .time-s{ display:none; }
  }

  .empty{
    text-align:center;
    padding:40px 0;
    color:var(--text-dim);
    font-size:13px;
  }

  .log-toolbar{ display:flex; justify-content:flex-end; padding:8px 16px 0; }
  pre.log{
    margin:0;
    padding:16px;
    font-family:var(--mono);
    font-size:11.5px;
    line-height:1.5;
    color:var(--log-text);
    white-space:pre-wrap;
    word-break:break-all;
    max-height:320px;
    overflow-y:auto;
  }
  /* "고스트" 버튼 계열 — 흰 배경 + 테두리로 있는 듯 없는 듯 있다가, hover 시에만
     자기 역할에 맞는 색(삭제=빨강, 수정/불러오기=파랑, 취소=중립)을 드러낸다.
     작업 카드(.job-card-actions)나 상세 모달(.job-detail-actions)처럼 여러 개가
     한 줄에 붙어도 크기·간격이 흔들리지 않도록 같은 padding/font-size/radius를
     공유한다. */
  .del-btn,
  .edit-btn,
  .load-btn,
  .start-btn,
  .pause-btn,
  .stop-btn{
    background:var(--panel);
    border:1px solid var(--border);
    color:var(--text-dim);
    border-radius:var(--radius-sm);
    font-family:var(--mono);
    font-weight:600;
    font-size:11px;
    padding:4px 10px;
    cursor:pointer;
    white-space:nowrap;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
  }
  .del-btn:hover{ border-color:var(--failed); color:var(--failed); background:rgba(var(--failed-rgb),0.06); }
  .del-btn:disabled{ opacity:0.45; cursor:not-allowed; }
  .del-btn:disabled:hover{ border-color:var(--border); color:var(--text-dim); background:var(--panel); }
  .edit-btn:hover,
  .load-btn:hover{ border-color:var(--queued); color:var(--queued); background:rgba(var(--queued-rgb),0.06); }
  /* 대기/정지/실패 작업을 (다시) 큐에 올리는 "시작" 버튼 — done(초록) 계열로,
     삭제(빨강)/수정·불러오기(파랑)와 구분되게 한다. */
  .start-btn:hover{ border-color:var(--done); color:var(--done); background:rgba(var(--done-rgb),0.06); }
  /* 진행 중인 작업 하나만 멈추는 "정지" 버튼 — running(주황/노랑) 계열로 구분. */
  .pause-btn:hover{ border-color:var(--text-dim); color:var(--text); }
  .stop-btn:hover{ border-color:var(--running); color:var(--running); background:rgba(var(--running-rgb),0.06); }
  .load-notice{ font-size:12.5px; font-family:var(--mono); min-height:1em; white-space:pre-line; color:var(--text-dim); }
  /* 업로드한 워크플로우가 지금 연결된 ComfyUI에서 돌아갈 수 있는지 검사한 결과 —
     통과(초록)/문제 있음(주황)/확인 못 함(회색) 세 가지 톤을 쓴다. */
  .workflow-check{
    margin-top:8px;
    padding:8px 10px;
    border:1px solid var(--border);
    border-left-width:3px;
    border-radius:var(--radius-sm);
    font-family:var(--mono);
    font-size:11.5px;
    line-height:1.6;
    color:var(--text-dim);
    white-space:pre-line;
  }
  .workflow-check.ok{ border-left-color:var(--done); color:var(--done); }
  .workflow-check.warn{ border-left-color:var(--failed); color:var(--failed); }
  .workflow-check.unknown{ border-left-color:var(--border); }
  .comfy-model-empty{ font-family:var(--mono); font-size:11.5px; color:var(--text-dim); }
  .model-list-loading{
    display:flex; align-items:center; gap:8px;
    padding:20px 4px;
    font-family:var(--mono); font-size:11.5px; color:var(--text-dim);
  }
  .model-list-loading .btn-spinner{ width:14px; height:14px; }

  /* "LoRA" 탭 — 설치된 LoRA마다 트리거 워드를 입력하는 줄. 목록 칸이 좁으면
     이름도 입력칸도 제대로 안 보이는 문제가 있어서, 탭 하나를 통째로 써서
     넉넉하게 보여준다. */
  .lora-tab-list{
    display:flex;
    flex-direction:column;
    gap:8px;
  }
  /* LoRA 행의 호환 family 체크박스들 — 트리거 입력칸 오른쪽에 칩 형태로 늘어놓는다. */

  .model-badge{
    font-family:var(--mono); font-size:11px; color:var(--text-dim); border:1px solid var(--border);
    border-radius:999px; padding:1px 8px; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .preflight-badge{ color:var(--failed); border-color:var(--failed); }
  .inv-off{ opacity:.55; font-size:11px; }
  .inv-cell.yes{ color:var(--done); }
  .inv-cell.no{ color:var(--failed); }
  .inv-cell.off{ color:var(--text-dim); }
  .model-usage{ display:flex; flex-direction:column; gap:8px; margin-top:8px; }
  .model-usage-stats{ font-family:var(--mono); font-size:12px; color:var(--text-dim); }
  .model-samples{ display:flex; flex-wrap:wrap; gap:6px; }
  .model-sample{ width:72px; height:72px; object-fit:cover; border-radius:6px; border:1px solid var(--border); background:var(--bg); }
  .model-usage-actions{ display:flex; flex-wrap:wrap; gap:6px; }
  .gf-model-chip{ font-family:var(--mono); font-size:11px; border:1px solid var(--queued); border-radius:999px; padding:3px 10px;
    max-width:260px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .dl-row{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-bottom:8px; }
  .dl-row .option-input{ flex:1 1 260px; max-width:none; }
  .dl-meta{ font-family:var(--mono); font-size:11.5px; color:var(--text-dim); word-break:break-word; }
  /* 복사(.model-link)/열기(.model-link-open) 둘 다 .icon-btn.icon-btn-neutral로 그려진다 —
     여기서는 라벨과의 간격만 맞춘다. */
  .model-link, .model-link-open{ margin-left:6px; }
  .model-pod-row{ display:flex; align-items:center; gap:10px; padding:4px 0; font-size:12.5px; }
  .model-pod-row{ flex-wrap:wrap; }
  .model-pod-row .inv-cell, .model-pod-row .inv-off{ white-space:nowrap; }
  .model-pod-name{ min-width:120px; font-family:var(--mono); }
  .model-editor{ display:grid; gap:10px 16px; padding:8px 12px 14px 62px; border-top:1px solid var(--border); }

  /* 얼굴 프롬프트 칸은 붙은 워크플로우에 FaceDetailer가 있을 때만 보인다(06-wizard.js setFaceDetailerFieldsVisible). */
  #options-fields:not(.has-face-detailer) .field:has([data-name="face_prompt"], [data-name="face_negative_prompt"]){ display:none; }
  /* 공통 .field의 display:flex가 두 수치 패널의 hidden을 덮지 않게 한다. */
  .fd-panel[hidden]{ display:none; }
  /* 포즈 이미지 칸은 붙은 워크플로우에 DWPreprocessor가 있을 때만 보인다(06-wizard.js setOpenPoseFieldsVisible). */
  #options-fields:not(.has-openpose) .field:has([data-name="pose_image"]){ display:none; }
  .fd-tabs{ display:flex; gap:6px; }
  .fd-tabs .active{ border-color:var(--text); color:var(--text); }
  .fd-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(140px, 1fr)); gap:8px 12px; margin:8px 0; }
  .fd-grid label{ display:grid; gap:4px; min-width:0; overflow-wrap:anywhere; font-family:var(--mono); font-size:11.5px; color:var(--text-dim); }
  .fd-grid .option-input{ width:100%; min-width:0; max-width:none; }
  /* ---- 전역 "모델" 탭 — 갤러리 "자세히 보기"와 같은 표 ---- */
  #tab-lora{ gap:12px; }
  .gallery-toolbar-row{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px; }
  .model-kind-tabs.enhance-mode{ flex-wrap:wrap; border-radius:18px; max-width:100%; }
  .model-kind-count{ margin-left:5px; opacity:.6; font-weight:400; }
  .model-table{ display:flex; flex-direction:column; gap:2px; }
  .model-cols{
    display:grid;
    grid-template-columns: 44px minmax(150px,2.4fr) minmax(90px,1.1fr) minmax(110px,1.4fr) 52px 64px 40px 22px;
    align-items:center;
    gap:10px;
  }
  .model-cols.lora{
    grid-template-columns: 44px minmax(150px,2.2fr) minmax(90px,1fr) minmax(110px,1.3fr) minmax(110px,1.3fr) 52px 64px 40px 22px;
  }
  .model-header{
    padding:6px 8px;
    font-family:var(--mono); font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.04em;
    color:var(--text-dim);
    border-bottom:1px solid var(--border);
    margin-bottom:2px;
  }
  .model-row{ border-radius:6px; border:1px solid transparent; }
  .model-row.open{ background:rgba(var(--queued-rgb),0.05); border-color:rgba(var(--queued-rgb),0.25); }
  .model-row-head{ padding:4px 8px; cursor:pointer; border-radius:6px; }
  .model-row-head:hover{ background:rgba(var(--queued-rgb),0.05); }
  .model-thumb{
    width:44px; height:44px; border-radius:5px; overflow:hidden; background:var(--bg); border:1px solid var(--border);
    display:flex; align-items:center; justify-content:center; color:var(--text-dim);
  }
  .model-thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
  .model-thumb .ico{ width:18px; height:18px; opacity:.6; }
  .model-cell-tags{ display:flex; gap:4px; overflow:hidden; }
  .model-cell-tags .model-badge{ flex:0 0 auto; }
  .gallery-details-col.model-missing{ color:var(--failed); }
  #tab-lora > #model-add-form:empty, #tab-lora > .upload-error:empty{ display:none; }
  .model-chevron{ justify-self:end; transition:transform .15s; color:var(--text-dim); }
  .model-row.open .model-chevron{ transform:rotate(180deg); }
  .model-editor{ grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); }
  .model-size{ white-space:nowrap; font-variant-numeric:tabular-nums; }
  .model-size-src{ font-size:11px; color:var(--text-dim); opacity:.75; margin-left:2px; }
  .model-editor > .model-size-mobile{ display:none; }
  .model-editor > .model-usage, .model-editor > .model-field.wide, .model-editor > .model-full{ grid-column:1 / -1; }
  @media (max-width:760px){
    .model-cols, .model-cols.lora{ grid-template-columns: 44px minmax(100px,2fr) 22px; }
    .model-cols > :not(.model-thumb):not(.lora-tab-name):not(.model-chevron){ display:none; }
    .model-header{ display:none; }
    .model-editor{ grid-template-columns:1fr; padding-left:12px; }
    .model-editor > .model-size-mobile{ display:flex; }
  }
  .model-field{ display:flex; flex-direction:column; gap:4px; font-size:12px; color:var(--text-dim); margin-top:6px; }
  .model-field .option-input{ max-width:none; }
  /* 소속 베이스 모델 복수 선택(체크박스 묶음) */
  .model-base-picks{ display:flex; flex-wrap:wrap; gap:6px 14px; padding:4px 0; }
  .model-base-pick{ display:inline-flex; align-items:center; gap:6px; font-size:12.5px; color:var(--text); cursor:pointer; }
  .model-editor-actions{ display:flex; gap:8px; }

  /* ---- DB 탭 — RunPod 세션 로그. model-table 계열과 같은 그리드 표 느낌이지만
     펼치기(row-head/editor) 없이 한 줄짜리 읽기 전용 표라 훨씬 단순하다. ---- */
  /* 기간 바(단위 세그먼트 · ‹ 기간 › · 오늘)와 그 아래 요약 카드(NS-20). 카드는 .admin-stat 재사용,
     좁은 화면에서도 세 장이 한 줄에 남게 숫자만 줄인다. */
  .db-period-bar{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px; margin-bottom:12px; }
  .db-period-bar [hidden]{ display:none !important; }
  .db-period-nav{ display:flex; align-items:center; gap:4px; }
  .db-period-label, .db-period-pick{
    min-width:150px; padding:6px 8px; border:1px solid transparent; border-radius:var(--radius-sm);
    background:none; color:var(--text); font:inherit; font-size:14px; font-weight:600; text-align:center;
    font-variant-numeric:tabular-nums; cursor:pointer;
  }
  .db-period-label:hover{ background:var(--panel-2); }
  .db-period-pick{ border-color:var(--border); background:var(--panel); cursor:text; }
  .db-session-stats .admin-stat{ flex:1 1 0; min-width:0; }
  .db-session-stats b{ font-variant-numeric:tabular-nums; white-space:nowrap; }
  .db-session-stats-note{ flex-basis:100%; font-size:12px; color:var(--text-dim); }
  @media (max-width:760px){
    .db-session-stats{ flex-wrap:wrap; gap:8px; }
    .db-session-stats .admin-stat{ padding:8px 10px; }
    .db-session-stats b{ font-size:16px; }
    .db-period-label, .db-period-pick{ min-width:0; }
  }
  .db-table{ display:flex; flex-direction:column; gap:2px; }
  .db-cols{
    display:grid;
    grid-template-columns: 44px minmax(120px,1.6fr) minmax(90px,1fr) 60px minmax(120px,1.3fr) minmax(120px,1.3fr) 90px 80px;
    align-items:center;
    gap:10px;
    padding:6px 8px;
  }
  .db-header{
    font-family:var(--mono); font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.04em;
    color:var(--text-dim);
    border-bottom:1px solid var(--border);
    margin-bottom:2px;
  }
  .db-row:nth-child(odd){ background:rgba(255,255,255,0.02); }
  .db-row.db-row-open{ background:rgba(var(--queued-rgb),0.06); }
  .db-cell-num{ font-family:var(--mono); color:var(--text-dim); }
  .db-cell-dim{ color:var(--text-dim); }
  .db-cell-open{ color:var(--queued); font-weight:600; }
  .db-sessions .db-cell-name{ min-width:0; font-size:13px; line-height:1.4; }
  .db-sessions .db-cell-pod, .db-sessions .db-cell-worker{
    display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .db-sessions .db-cell-worker{ font-size:12px; font-weight:400; color:var(--text-dim); }
  /* RunPod 사용 내역은 좁은 화면에서 열을 숨기지 않고, 한 세션을 두 칸짜리 작은 카드로 접는다 —
     파드 이름을 맨 위 한 줄에, 나머지는 항목 이름(data-label)을 앞에 붙여 두 칸씩. 시작·종료·시간·비용이
     전부 보여야 쓸모 있는 표라서다. */
  @media (max-width:760px){
    .db-sessions .db-header{ display:none; }
    .db-sessions .db-cols{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:3px 12px; padding:8px 10px; }
    .db-sessions .db-cols > *{ display:block !important; min-width:0; overflow-wrap:anywhere; }
    .db-sessions .db-cell-num{ display:none !important; }
    .db-sessions .db-cell-name{ grid-column:1 / -1; font-weight:600; }
    .db-sessions [data-label]::before{ content:attr(data-label); margin-right:6px; font-size:10px; font-family:var(--mono);
                                       color:var(--text-dim); text-transform:uppercase; letter-spacing:0.04em; }
    .db-sessions .db-row{ border-bottom:1px solid var(--border); }
  }
  @media (max-width:760px){
    .db-cols{ grid-template-columns: 32px minmax(90px,1.6fr) minmax(70px,1fr) 46px; }
    .db-cols > :nth-child(n+5){ display:none; }
  }
  /* ---- DB 탭 — 업데이트 내역(git 커밋 로그). 커밋마다 본문 길이가 제각각이라
     표 대신 세로로 쌓는 목록이 낫다. ---- */
  .changelog-list{ display:flex; flex-direction:column; }
  .changelog-entry{ padding:10px 8px; border-bottom:1px solid var(--border); }
  .changelog-entry:last-child{ border-bottom:none; }
  .changelog-entry:nth-child(odd){ background:rgba(255,255,255,0.02); }
  .changelog-head{
    display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px;
    font-family:var(--mono); font-size:11px; color:var(--text-dim);
    margin-bottom:4px;
  }
  .changelog-version{
    color:var(--text); background:var(--bg); border:1px solid var(--border);
    border-radius:4px; padding:1px 6px;
  }
  .changelog-tag{
    color:var(--queued); background:rgba(var(--queued-rgb),0.08);
    border-radius:4px; padding:1px 6px; font-weight:600;
  }
  .changelog-title{ font-size:13.5px; font-weight:600; color:var(--text); }
  .changelog-body{
    font-size:12.5px; color:var(--text-dim); line-height:1.5;
    white-space:pre-wrap; margin-top:3px;
  }
  /* ---- DB 탭 — 생성 정보(프롬프트 등). 위 업데이트 내역과 같은 세로 목록 틀을
     쓰되(.changelog-version/.changelog-tag 칩 재사용), 본문은 프롬프트라 어두운
     라이트박스용 .am-prompt 대신 이 패널의 밝은 배경에 맞는 스타일을 따로 둔다. ---- */
  .genlog-list{ display:flex; flex-direction:column; }
  .genlog-entry{ padding:10px 8px; border-bottom:1px solid var(--border); }
  .genlog-entry:last-child{ border-bottom:none; }
  .genlog-entry:nth-child(odd){ background:rgba(255,255,255,0.02); }
  .genlog-head{
    display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px;
    font-family:var(--mono); font-size:11px; color:var(--text-dim);
    margin-bottom:4px;
  }
  .genlog-kind{ display:inline-flex; align-items:center; }
  .genlog-kind .ico{ width:13px; height:13px; }
  .genlog-kind-image{ color:var(--queued); }
  .genlog-kind-video{ color:var(--interrupted); }
  .genlog-prompt{
    font-size:12.5px; color:var(--text); line-height:1.5;
    white-space:pre-wrap; word-break:break-word;
  }
  .genlog-neg{ margin-top:4px; }
  .genlog-neg summary{ cursor:pointer; font-size:11.5px; color:var(--text-dim); }
  .genlog-neg .genlog-prompt{ margin-top:4px; color:var(--text-dim); }
  .genlog-loras{ font-size:11.5px; color:var(--text-dim); margin-top:4px; }
 /* 아직 family로 등록 안 된{
    display:flex; flex-wrap:wrap; align-items:center; gap:8px;
    padding:8px 12px; margin-bottom:10px;
    border:1px dashed var(--border); border-radius:var(--radius-sm);
    font-size:12.5px; color:var(--text-dim);
  }

  /* "새 작업 추가" 마법사 바 — 4단계 버튼 + 적용/초기화. */
  .wizard-bar{
    margin-bottom:12px;
    display:flex;
    flex-direction:column;
    gap:12px;
  }
  .wizard-bar-title{
    font-family:var(--mono);
    font-size:12.5px;
    font-weight:600;
    color:var(--text);
  }
  .wizard-bar-title .opt{ display:block; font-weight:400; text-transform:none; letter-spacing:0; color:var(--text-dim); margin-top:4px; }
  .wizard-steps{
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
    gap:10px;
  }
  .wizard-step-btn{
    background:transparent;
    border:1px solid var(--border);
    border-radius:var(--radius-sm);
    padding:8px 10px;
    font-family:var(--mono);
    font-size:11.5px;
    color:var(--text-dim);
    text-align:left;
    cursor:pointer;
    line-height:1.6;
    transition: border-color .15s ease;
  }
  .wizard-step-btn:hover:not(:disabled){ border-color:var(--queued); }
  .wizard-step-btn:disabled{ opacity:0.5; cursor:not-allowed; }
  .wizard-step-btn.done{ border-color:var(--queued); }
  .wizard-step-num{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:16px; height:16px;
    border-radius:50%;
    background:var(--border);
    color:var(--text);
    font-size:10px;
    margin-right:4px;
  }
  .wizard-step-btn.done .wizard-step-num{ background:var(--queued); color:#fff; }
  .wizard-step-value{ display:block; font-size:12.5px; color:var(--text); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .new-job-next-row{ display:flex; justify-content:space-between; align-items:center; margin-top:16px; }
  .new-job-next-right{ display:flex; align-items:center; gap:8px; }
  /* 폰에서는 긴 글자 대신 짧은 글자 — 아이콘만 두면 무슨 버튼인지 알 수 없다(터치에는 툴팁도 없음). */
  .new-job-next-right .btn-label-short{ display:none; }
  @media (max-width:640px){ .new-job-next-right .btn-label-short{ display:inline; } }
  /* 보드 프리셋 저장 창 */
  .board-preset-body{ display:flex; flex-direction:column; gap:8px; }
  .board-preset-exposed{ display:flex; flex-direction:column; gap:4px; max-height:32vh; overflow-y:auto; }
  .board-preset-exposed label{ display:flex; align-items:center; gap:8px; font-size:13px; cursor:pointer; }
  .board-preset-exposed .board-preset-opt-name{ font-family:var(--mono); font-size:11px; color:var(--text-dim); }
  .board-preset-hint{ font-size:12px; color:var(--text-dim); line-height:1.5; }
  .board-preset-actions{ display:flex; justify-content:flex-end; gap:8px; }
  .board-preset-list-label{ margin-top:10px; padding-top:10px; border-top:1px solid var(--border); }
  .board-preset-list{ display:flex; flex-direction:column; gap:4px; }
  .board-preset-row{ display:flex; align-items:center; gap:8px; font-size:13px; padding:6px 8px; border:1px solid var(--border); border-radius:8px; }
  .board-preset-row .board-preset-row-name{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600; }
  .board-preset-row .board-preset-row-tpl{ color:var(--text-dim); font-size:12px; white-space:nowrap; }
  /* .modal-btn-secondary(테두리 있음, padding 8px)와 .submit-btn(테두리 없음,
     padding 10px)은 원래 세로 크기가 미묘하게 달라(테두리 1px+패딩 2px 차이가
     서로 다 안 상쇄됨) — 나란히 놓이는 이 줄에서만 높이를 맞춘다. */
  .new-job-next-row .modal-btn-secondary{ padding:9px 16px; }

  /* 마법사 모달 안의 선택 목록 — "설치된 모델" 모달과 비슷한 어휘를 쓰되 클릭 가능한 줄. */
  .wizard-pick-section-title{
    font-family:var(--mono);
    font-size:11px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:0.05em;
    color:var(--text-dim);
    margin:14px 0 6px;
  }
  .wizard-pick-section-title:first-child{ margin-top:0; }
  .wizard-pick-list{ display:flex; flex-direction:column; gap:6px; max-height:240px; overflow-y:auto; }
  .wizard-pick-row{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    padding:10px 12px;
    border:1px solid var(--border);
    border-radius:var(--radius-sm);
    cursor:pointer;
    font-family:var(--mono);
    font-size:12.5px;
    color:var(--text);
  }
  .wizard-pick-row:hover:not(.disabled){ border-color:var(--queued); }
  .wizard-pick-row.selected{ border-color:var(--queued); background:rgba(var(--queued-rgb),0.08); }
  .wizard-pick-row.disabled{ opacity:0.5; cursor:not-allowed; }
  .wizard-pick-row-label{ display:flex; flex-direction:column; gap:2px; }
  .wizard-pick-row-hint{ font-size:11px; color:var(--text-dim); font-weight:400; }
  .wizard-pick-row-badge{
    font-size:10.5px;
    color:var(--failed);
    border:1px solid var(--failed);
    border-radius:999px;
    padding:1px 8px;
    flex-shrink:0;
  }
  .wizard-pick-row-strength{ width:70px; flex-shrink:0; }
  #wizard-lora-modal .wizard-pick-row{ flex-wrap:nowrap; font-size:13px; }
  #wizard-lora-modal .wizard-pick-row-label{ flex:1; min-width:0; }
  #wizard-lora-modal .wizard-lora-name{ display:flex; align-items:flex-start; gap:8px; }
  #wizard-lora-modal .wizard-lora-name > span:last-child{ min-width:0; overflow-wrap:anywhere; }
  #wizard-lora-modal .wizard-lora-check{ flex:0 0 1.2em; width:1.2em; color:var(--accent); }
  #wizard-lora-modal .model-pods-badge{ margin-left:calc(1.2em + 8px); overflow-wrap:anywhere; }
  /* MiniMax-H3처럼 부가 입력이 여러 개(참조 개수, 첫/마지막 프레임, 너비/높이 등)일 때
     쓴다 — flex-basis:100%로 같은 줄에 있는 라벨을 밀어내고 항상 다음 줄로 내려간다
     (row 자체가 flex-wrap이라 가능). 그 안의 각 입력칸도 자체적으로 줄바꿈되므로
     PC든 모바일이든 좁아지면 자연스럽게 여러 줄로 쌓인다. */
  .wizard-pick-row-block{
    flex:1 0 100%;
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:10px;
    margin-top:6px;
    padding-top:10px;
    border-top:1px dashed var(--border);
  }
  .wizard-pick-row-block label{ display:inline-flex; align-items:center; gap:4px; font-size:13px; }
  .wizard-pick-row-block input[type="number"]{ max-width:80px; }
  .wizard-pick-row-block select{ max-width:250px; }

  .gallery-count{ font-family:var(--mono); font-size:12px; color:var(--text-dim); }
  .gallery-toolbar{
    display:flex;
    align-items:center;
    gap:var(--gap-md);
    padding:10px 12px;
    margin-bottom:12px;
    /* 스크롤해도 화면 위에 붙어 따라온다 — 아래쪽 이미지를 고르다가 맨 위로 되돌아가지 않게.
       내용이 비쳐 보이지 않게 패널 색 위에 옅은 색을 덧칠한다. */
    position:sticky;
    top:8px;
    z-index:20;
    background:linear-gradient(rgba(var(--queued-rgb),0.06), rgba(var(--queued-rgb),0.06)), var(--panel);
    border:1px solid rgba(var(--queued-rgb),0.25);
    border-radius:var(--radius-md);
    box-shadow:0 4px 14px rgba(16,24,40,0.10);
  }
  /* 이미지/영상 갤러리에서 여러 개를 선택했을 때 뜨는 줄 — 버튼이 줄어들지도
     줄바꿈되지도 않아 "N개 선택됨" 글자만 세로로 쪼개지고 버튼들은 화면 밖으로
     넘어가던 문제. panel-header-actions와 같은 이유라 같은 방식으로 고친다. */
  @media (max-width:640px){
    .gallery-toolbar{ flex-wrap:wrap; }
    .gallery-toolbar-count{ margin-right:0; flex-basis:100%; }
  }
  /* "해제"(.modal-btn-secondary)는 다른 툴바 버튼(.load-btn)보다 커서 줄이 들쭉날쭉했다 — 크기를 맞춘다. */
  .gallery-toolbar .modal-btn-secondary{ padding:4px 10px; font-size:11px; }
  /* 갤러리 보기 방식 토글도 메뉴 이름이라 탭과 같은 영문 대문자 + 넓은 자간 */
  #gallery-view-toggle .enhance-mode-btn, #gallery-display-toggle .enhance-mode-btn,
  #video-gallery-view-toggle .enhance-mode-btn, #video-gallery-display-toggle .enhance-mode-btn{
    text-transform:uppercase; letter-spacing:var(--track-nav); font-size:11px;
  }
  /* 폰에서는 4칸짜리 토글이 패널 폭을 넘으므로 아이콘을 빼고 자간을 줄인다. */
  @media (max-width:640px){
    #gallery-view-toggle .enhance-mode-btn, #gallery-display-toggle .enhance-mode-btn,
    #video-gallery-view-toggle .enhance-mode-btn, #video-gallery-display-toggle .enhance-mode-btn{ letter-spacing:0.06em; }
    #gallery-view-toggle .ico, #gallery-display-toggle .ico, #video-gallery-view-toggle .ico, #video-gallery-display-toggle .ico{ display:none; }
  }
  /* 이미지/영상 갤러리는 홈의 프로젝트 카드처럼 바깥 카드(패널) 없이 페이지 위에 바로 놓는다. */
  #tab-gallery > .panel, #tab-video-gallery > .panel{
    background:none; border:none; box-shadow:none; border-radius:0; padding:0;
  }
  .gallery-toolbar-count{
    font-family:var(--mono);
    font-size:12.5px;
    font-weight:600;
    color:var(--text);
    margin-right:auto;
  }
  .gallery-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(120px, 1fr));
    gap:8px;
  }
  /* 작업별/날짜별 보기 — 그룹(작업 또는 날짜)마다 소제목과 그 그룹의 이미지 격자를
     세로로 나열한다. #gallery-grid 자체가 grid라서(전체 보기용), grid-column을
     꽉 채우지 않으면 그룹들이 한 줄에 나란히 놓여버린다 — 항상 한 행 전체를
     차지하게 만든다. */
  .gallery-group{ grid-column:1 / -1; margin-bottom:20px; }
  .gallery-group:last-child{ margin-bottom:0; }
  .gallery-group-header{
    font-family:var(--mono);
    font-size:11.5px;
    font-weight:600;
    color:var(--text-dim);
    padding:6px 2px;
    margin-bottom:8px;
    border-bottom:1px solid var(--border);
  }
  /* 그룹 소제목의 체크박스 — 그 그룹의 이미지 전체를 한 번에 선택/해제한다. */
  .gallery-group-select-label{
    display:inline-flex;
    align-items:center;
    gap:8px;
    cursor:pointer;
  }
  .gallery-group-select-label input{
    width:14px; height:14px;
    cursor:pointer;
    accent-color:var(--accent, var(--queued));
  }
  .gallery-group-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(120px, 1fr));
    gap:8px;
  }
  /* 열 개수 슬라이더 — 15-gallery.js가 html[data-gal-cols]와 --gal-cols를 지정한다(없으면 위 auto-fill). 폰은 3열 규칙 그대로. */
  .gallery-cols{ display:inline-flex; align-items:center; gap:6px; font-family:var(--mono); font-size:11.5px; color:var(--text-dim); }
  .gallery-cols-range{ width:96px; accent-color:var(--accent, var(--queued)); }
  .gallery-cols-val{ min-width:3ch; }
  .enhance-mode:has(.enhance-mode-btn[data-display="details"].active) ~ .gallery-cols{ display:none; }
  @media (max-width:640px){ .gallery-cols{ display:none; } }
  @media (min-width:641px){
    html[data-gal-cols] #gallery-grid:not(.details-mode), html[data-gal-cols] #gallery-grid .gallery-group-grid:not(.details-mode),
    html[data-gal-cols] #video-gallery-grid:not(.details-mode), html[data-gal-cols] #video-gallery-grid .vgallery-group-grid:not(.details-mode){
      grid-template-columns:repeat(var(--gal-cols), minmax(0, 1fr));
    }
  }
  .gallery-item{
    position:relative;
    aspect-ratio:1;
    border-radius:8px;
    overflow:hidden;
    border:1px solid var(--border);
    cursor:pointer;
    background:var(--bg);
  }
  .gallery-item img{
    width:100%;
    height:100%;
    object-fit:cover;
    display:block;
    transition:transform .15s ease;
  }
  .gallery-item:hover img{ transform:scale(1.05); }
  .gallery-item-name{
    position:absolute;
    left:0; right:0; bottom:0;
    padding:4px 6px;
    font-family:var(--mono);
    font-size:10px;
    color:#fff;
    background:linear-gradient(to top, rgba(0,0,0,0.6), rgba(0,0,0,0));
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
    pointer-events:none;
  }
  .gallery-item-select{
    position:absolute;
    top:6px; left:6px;
    z-index:2;
    width:20px; height:20px;
    border-radius:5px;
    background:rgba(0,0,0,0.45);
    display:flex;
    align-items:center;
    justify-content:center;
    cursor:pointer;
  }
  .gallery-item-select input{
    width:14px; height:14px;
    cursor:pointer;
    accent-color:var(--queued);
  }
  .gallery-item.selected{ outline:2px solid var(--accent, var(--queued)); outline-offset:-2px; }
  /* 길게 눌러 삭제 — 파드 카드와 같은 동작. 터치에서는 길게 눌러도 저장 메뉴가 뜨지 않게 한다. */
  .gallery-item{ -webkit-touch-callout:none; }
  @media (hover:none){ .gallery-item{ -webkit-user-select:none; user-select:none; } }
  .gallery-item.item-pressing{
    outline:2px solid var(--accent, var(--queued)); outline-offset:-2px;
    transition:outline-color .15s ease;
  }
  .gallery-item.details.item-pressing{ transform:none; border-color:var(--accent, var(--queued)); }
  @media (prefers-reduced-motion:reduce){ .gallery-item.item-pressing{ transition:none; } }

  /* "📋 자세히" 보기 — 탐색기 자세히 보기처럼 썸네일은 작게, 파일명/작업/해상도/
     용량/수정 시각을 열로 나란히 보여준다. 헤더 행과 각 데이터 행이 같은
     grid-template-columns(.gallery-details-columns)를 써서 열이 맞춰진다.
     격자 모드의 .gallery-grid/.gallery-group-grid(display:grid, 카드 auto-fill)를
     세로 목록으로, .gallery-item(정사각형 카드)을 한 줄짜리 행으로 바꿔치기한다 —
     선택 체크박스/삭제 버튼/전체 클릭 대상 등 나머지 로직(wireGalleryItems 등)은
     .gallery-item 클래스를 그대로 쓰므로 손댈 필요가 없다. */
  .gallery-grid.details-mode,
  .gallery-group-grid.details-mode{
    display:flex;
    flex-direction:column;
    gap:2px;
  }
  .gallery-details-columns{
    display:grid;
    grid-template-columns: 22px 44px minmax(140px,2.2fr) minmax(110px,1.4fr) 84px 64px 108px 22px;
    align-items:center;
    gap:10px;
  }
  .gallery-details-header{
    padding:6px 8px;
    font-family:var(--mono);
    font-size:10px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:0.04em;
    color:var(--text-dim);
    border-bottom:1px solid var(--border);
    margin-bottom:2px;
  }
  .gallery-item.details{
    position:static;
    aspect-ratio:auto;
    border-radius:6px;
    padding:4px 8px;
    background:transparent;
    border:1px solid transparent;
  }
  .gallery-item.details:hover{ background:rgba(var(--queued-rgb),0.05); }
  .gallery-item.details.selected{ outline:none; background:color-mix(in srgb, var(--accent, var(--queued)) 10%, transparent); border-color:var(--accent, var(--queued)); }
  .gallery-item.details .gallery-item-select{
    position:static;
    width:18px; height:18px;
    background:none;
  }
  .gallery-item.details .gallery-item-thumb{
    width:44px; height:44px;
    border-radius:5px;
    overflow:hidden;
    background:var(--bg);
    flex-shrink:0;
  }
  .gallery-item.details img{
    width:100%; height:100%;
    object-fit:cover;
    display:block;
  }
  .gallery-item.details:hover img{ transform:none; }
  .gallery-details-col{
    font-family:var(--mono);
    font-size:11.5px;
    color:var(--text);
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
  }
  .gallery-details-col.dim,
  .gallery-details-col.size,
  .gallery-details-col.mtime{ color:var(--text-dim); }
  @media (max-width:760px){
    .gallery-details-columns{ grid-template-columns: 22px 40px minmax(100px,2fr) 22px; }
    .gallery-details-col.job, .gallery-details-col.dim, .gallery-details-col.size, .gallery-details-col.mtime{ display:none; }
  }

  /* ---- 영상 갤러리 ----
     이미지 갤러리(.gallery-*)와 시각적으로 똑같지만 클래스명을 vgallery-*로 따로 둔다.
     둘 다 같은 페이지의 숨겨진 DOM으로 동시에 존재하는데(탭 전환은 display:none일 뿐
     제거가 아님), 이미지 갤러리의 "전체선택"/"선택 해제"/그룹 체크박스 동기화 로직이
     document.querySelectorAll('.gallery-item') 처럼 컨테이너로 좁히지 않고 문서
     전체에서 클래스로 찾는다 — 같은 클래스명을 쓰면 영상 갤러리 카드까지 (숨겨진
     채로) 함께 선택 표시가 돼버린다. "자세히 보기"(.vgallery-item.details)는 이미지
     갤러리의 것과 같은 모양이고, 길이/해상도는 ffprobe 없이 브라우저가 <video>의
     메타데이터에서 읽는다(아래 JS). */
  .vgallery-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(120px, 1fr));
    gap:8px;
  }
  .vgallery-group{ grid-column:1 / -1; margin-bottom:20px; }
  .vgallery-group:last-child{ margin-bottom:0; }
  .vgallery-group-header{
    font-family:var(--mono);
    font-size:11.5px;
    font-weight:600;
    color:var(--text-dim);
    padding:6px 2px;
    margin-bottom:8px;
    border-bottom:1px solid var(--border);
  }
  .vgallery-group-select-label{
    display:inline-flex;
    align-items:center;
    gap:8px;
    cursor:pointer;
  }
  .vgallery-group-select-label input{
    width:14px; height:14px;
    cursor:pointer;
    accent-color:var(--queued);
  }
  .vgallery-group-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(120px, 1fr));
    gap:8px;
  }
  /* 갤러리 격자는 폰에서(네 격자 정의보다 뒤에 있어야 이긴다) 3열로 촘촘하게(details 보기는 자체 규칙이 더 구체적이라 그대로다). */
  @media (max-width:640px){
    .gallery-grid, .gallery-group-grid, .vgallery-grid, .vgallery-group-grid{
      grid-template-columns:repeat(3, 1fr); gap:6px;
    }
  }
  .vgallery-item{
    position:relative;
    aspect-ratio:1;
    border-radius:8px;
    overflow:hidden;
    border:1px solid var(--border);
    cursor:pointer;
    background:var(--bg);
  }
  .vgallery-item-media{ width:100%; height:100%; }
  .vgallery-item-media img{
    width:100%;
    height:100%;
    object-fit:cover;
    display:block;
  }
  /* "자세히" 보기 — 이미지 갤러리의 .gallery-item.details와 같은 모양(위 설명 참고). */
  .vgallery-grid.details-mode,
  .vgallery-group-grid.details-mode{ display:flex; flex-direction:column; gap:2px; }
  .vgallery-details-columns{
    display:grid;
    grid-template-columns: 22px 44px minmax(140px,2.2fr) minmax(110px,1.4fr) 60px 84px 64px 108px 22px;
    align-items:center;
    gap:10px;
  }
  .vgallery-details-header{
    padding:6px 8px;
    font-family:var(--mono);
    font-size:10px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:0.04em;
    color:var(--text-dim);
    border-bottom:1px solid var(--border);
    margin-bottom:2px;
  }
  .vgallery-item.details{ position:static; aspect-ratio:auto; border-radius:6px; padding:4px 8px; background:transparent; border:1px solid transparent; }
  .vgallery-item.details:hover{ background:rgba(var(--queued-rgb),0.05); }
  .vgallery-item.details.selected{ outline:none; background:rgba(var(--queued-rgb),0.1); border-color:rgba(var(--queued-rgb),0.3); }
  .vgallery-item.details .vgallery-item-select{ position:static; width:18px; height:18px; background:none; }
  .vgallery-item.details .vgallery-item-thumb{ width:44px; height:44px; border-radius:5px; overflow:hidden; background:var(--bg); flex-shrink:0; }
  .vgallery-item.details .vgallery-item-thumb img{ width:100%; height:100%; object-fit:cover; display:block; pointer-events:none; }
  .vgallery-details-col{
    font-family:var(--mono); font-size:11.5px; color:var(--text);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .vgallery-details-col.dur, .vgallery-details-col.dim, .vgallery-details-col.size, .vgallery-details-col.mtime{ color:var(--text-dim); }
  .vgallery-details-col.name .ico.fav{ color:#F59E0B; fill:currentColor; width:12px; height:12px; }
  @media (max-width:760px){
    .vgallery-details-columns{ grid-template-columns: 22px 40px minmax(100px,2fr) 22px; }
    .vgallery-details-col.job, .vgallery-details-col.dur, .vgallery-details-col.dim,
    .vgallery-details-col.size, .vgallery-details-col.mtime{ display:none; }
  }
  .vgallery-item-name{
    position:absolute;
    left:0; right:0; bottom:0;
    padding:4px 6px;
    font-family:var(--mono);
    font-size:10px;
    color:#fff;
    background:linear-gradient(to top, rgba(0,0,0,0.6), rgba(0,0,0,0));
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
    pointer-events:none;
  }
  .vgallery-item-select{
    position:absolute;
    top:6px; left:6px;
    z-index:2;
    width:20px; height:20px;
    border-radius:5px;
    background:rgba(0,0,0,0.45);
    display:flex;
    align-items:center;
    justify-content:center;
    cursor:pointer;
  }
  .vgallery-item-select input{
    width:14px; height:14px;
    cursor:pointer;
    accent-color:var(--queued);
  }
  .vgallery-item.selected{ outline:2px solid var(--queued); outline-offset:-2px; }
  .vgallery-item{ -webkit-touch-callout:none; }
  @media (hover:none){ .vgallery-item{ -webkit-user-select:none; user-select:none; } }
  .vgallery-item.item-pressing{
    outline:2px solid var(--failed); outline-offset:-2px;
    transform:scale(0.98);
    transition:transform .38s ease, outline-color .2s ease;
  }
  .vgallery-item.details.item-pressing{ transform:none; background:rgba(var(--failed-rgb),0.06); }
  .vgallery-item-play{
    position:absolute;
    inset:0;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:28px;
    color:rgba(255,255,255,0.85);
    text-shadow:0 1px 4px rgba(0,0,0,0.5);
    pointer-events:none;
  }
  .vgallery-item-play .ico{ fill:currentColor; filter:drop-shadow(0 1px 4px rgba(0,0,0,0.5)); }

  /* ---- Danbooru 프롬프트 조립 탭 ---- */
  /* New Job 세부 설정에서 openDanbooruModal()로 띄웠을 때만 붙는 클래스 — main의
     기존 폭 제한/세로 스택(657행)은 그대로 두고 위치·크기·카드 모양만 덧씌운다.
     #danbooru-modal-backdrop(.modal-overlay 재사용)이 뒤에서 어둡게 깔린다. */
  main.as-modal-panel{
    position:fixed;
    top:24px; bottom:24px; left:0; right:0;
    margin:0 auto;
    width:calc(100% - 48px);
    max-width:1100px;
    max-height:calc(100vh - 48px);
    z-index:70;
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:12px;
    box-shadow:0 8px 24px rgba(16,24,40,0.18);
    overflow-y:auto;
  }
  .danbooru-modal-close{ display:none; }
  main.as-modal-panel .danbooru-modal-close{ display:inline-flex; align-items:center; justify-content:center; }
  .danbooru-prompt-box{
    background:rgba(var(--queued-rgb),0.04);
    border:1px solid rgba(var(--queued-rgb),0.25);
    border-radius:var(--radius-md);
    padding:12px;
    margin-bottom:14px;
  }
  .danbooru-prompt-row{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:8px;
    flex-wrap:wrap;
    margin-bottom:6px;
  }
  .danbooru-prompt-row-actions{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .danbooru-prompt-label{
    font-family:var(--mono);
    font-size:10.5px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:0.04em;
    color:var(--text-dim);
  }
  .danbooru-prompt-text{
    font-family:var(--mono);
    font-size:13px;
    line-height:1.6;
    color:var(--text);
    white-space:pre-wrap;
    word-break:break-word;
    min-height:1.6em;
  }
  /* Enhance 실험 결과 — 조립된 프롬프트 상자 안의 하위 칸 */
  .danbooru-enhance-box{
    margin-top:10px;
    padding-top:10px;
    border-top:1px dashed rgba(var(--queued-rgb),0.25);
  }
  .danbooru-conflicts{ display:flex; flex-direction:column; gap:6px; }
  .danbooru-conflict{
    display:flex;
    flex-wrap:wrap;
    gap:4px 10px;
    align-items:baseline;
    background:rgba(var(--failed-rgb),0.06);
    border:1px solid rgba(var(--failed-rgb),0.25);
    border-radius:8px;
    padding:8px 10px;
    font-family:var(--mono);
    font-size:11.5px;
  }
  .danbooru-conflict-msg{ color:var(--failed); font-weight:600; }
  .danbooru-conflict-tags{ color:var(--text-dim); }

  .danbooru-cat{ padding:14px 0; border-bottom:1px solid var(--border); }
  .danbooru-cat:last-child{ border-bottom:none; }
  .danbooru-cat-header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:8px;
    flex-wrap:wrap;
    margin-bottom:10px;
  }
  .danbooru-cat-label{ font-family:var(--mono); font-size:12.5px; font-weight:600; color:var(--text); }
  .danbooru-cat-actions{ display:flex; gap:6px; flex-shrink:0; }
  .danbooru-icon-btn{
    background:none;
    border:1px solid var(--border);
    border-radius:6px;
    width:28px; height:28px;
    display:flex;
    align-items:center;
    justify-content:center;
    cursor:pointer;
    font-size:13px;
    color:var(--text-dim);
    transition: border-color .15s ease, color .15s ease, background .15s ease;
  }
  .danbooru-icon-btn:hover{ border-color:var(--queued); color:var(--queued); }
  .danbooru-icon-btn.active{ background:rgba(var(--queued-rgb),0.12); border-color:var(--queued); color:var(--queued); }

  .danbooru-chips{ display:flex; flex-wrap:wrap; gap:6px; }
  .dtag{
    display:inline-flex;
    align-items:center;
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:999px;
    padding:5px 12px;
    font-family:var(--mono);
    font-size:11.5px;
    color:var(--text);
    cursor:pointer;
    white-space:nowrap;
    transition: background .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
  }
  .dtag:hover{ border-color:var(--queued); color:var(--queued); }
  .dtag.selected{ background:var(--grad-primary); color:#fff; border-color:transparent; }
  .dtag.selected.conflict{ background:var(--failed); box-shadow:0 0 0 2px rgba(var(--failed-rgb),0.3); }
  .danbooru-empty-pool{ font-family:var(--mono); font-size:11.5px; color:var(--text-dim); }

  .danbooru-text-input{ width:100%; max-width:none; min-height:64px; }

  .danbooru-pool-editor{
    margin-top:10px;
    padding:10px;
    background:var(--bg);
    border:1px dashed var(--border);
    border-radius:8px;
  }
  .danbooru-pool-chips{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:8px; }
  .dtag-pool-item{
    display:inline-flex;
    align-items:center;
    gap:4px;
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:999px;
    padding:3px 4px 3px 10px;
    font-family:var(--mono);
    font-size:11px;
    color:var(--text-dim);
  }
  .dtag-pool-remove{
    background:none;
    border:none;
    color:var(--text-dim);
    cursor:pointer;
    width:16px; height:16px;
    border-radius:50%;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:12px;
    line-height:1;
  }
  .dtag-pool-remove:hover{ background:rgba(var(--failed-rgb),0.15); color:var(--failed); }
  .danbooru-pool-add-row{ display:flex; gap:8px; }
  .danbooru-pool-add-row input{ flex:1; max-width:none; }
  .danbooru-pool-hint{ font-family:var(--mono); font-size:10.5px; color:var(--text-dim); margin-bottom:8px; }

  .danbooru-history-item{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    padding:8px 10px;
    border:1px solid var(--border);
    border-radius:8px;
    margin-bottom:6px;
  }
  .danbooru-history-name{ font-family:var(--mono); font-size:12.5px; color:var(--text); word-break:break-word; }
  .danbooru-history-time{ font-family:var(--mono); font-size:10.5px; color:var(--text-dim); margin-top:2px; }
  .danbooru-history-actions{ display:flex; gap:6px; flex-shrink:0; }
  .danbooru-history-save-row{ display:flex; gap:8px; align-items:center; }
  .danbooru-history-name-input{ max-width:220px; }
  @media (max-width:640px){
    .danbooru-history-save-row{ flex-wrap:wrap; }
    .danbooru-history-name-input{ max-width:none; width:100%; }
  }

  .lightbox-overlay{
    position:fixed;
    inset:0;
    background:rgba(10,12,16,0.92);
    display:flex;
    align-items:center;
    justify-content:center;
    z-index:60;
    padding:40px;
  }
  .lightbox-img-wrap{
    position:relative;
    max-width:100%;
    max-height:100%;
    min-height:0;
    display:flex;
    flex-direction:column;
    align-items:center;
    gap:12px;
  }
  .lightbox-img{
    max-width:100%;
    max-height:calc(100vh - 140px);
    border-radius:8px;
    box-shadow:0 10px 40px rgba(0,0,0,0.5);
    /* 스와이프 중엔 손가락을 그대로 따라가야(dragging) 해서 트랜지션을 끄고,
       손을 떼면(놓친 스와이프든 넘어가는 스와이프든) 다시 트랜지션을 켜서
       원위치로 스르륵 돌아온다. */
    transition: transform .22s cubic-bezier(.22,.61,.36,1), filter .15s ease, opacity .15s ease;
  }
  .lightbox-img.dragging{ transition:none; }
  .lightbox-img.lightbox-loading{ filter:blur(6px); opacity:.55; }
  .lightbox-spinner{
    position:absolute;
    top:50%; left:50%;
    /* 가운데 정렬은 margin으로 한다 — transform을 쓰면 enhance-spin 키프레임의 transform이 덮어써서 대각선으로 흔들린다. */
    margin:-15px 0 0 -15px;
    width:30px; height:30px;
    border:3px solid rgba(255,255,255,0.3);
    border-top-color:#fff;
    border-radius:50%;
    animation: enhance-spin .7s linear infinite;
    pointer-events:none;
    z-index:2;
  }
  .lightbox-info{
    font-family:var(--mono);
    font-size:12px;
    color:#D1D5DB;
    text-align:center;
    max-width:100%;
    overflow-wrap:anywhere;
  }
  .lightbox-actions{ display:flex; gap:var(--gap-md); }
  .lightbox-error{ color:#FCA5A5; font-family:var(--mono); font-size:12px; min-height:1em; }
  /* 넓은 화면: 펼친 정보창(am-body)만 이미지/영상 오른쪽 칸에 둔다. 파일 정보·버튼·별점·NSFW는 아래 그대로(좁은 화면·전체 화면은 기존) */
  @media (min-width:900px){
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])){
      display:grid; grid-template-columns:minmax(0,1fr) 320px; grid-auto-rows:min-content;
      align-content:center; align-items:start; column-gap:20px; row-gap:12px; width:100%;
    }
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])) > :not(.lightbox-spinner){ grid-column:1; justify-self:center; }
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])) > .lightbox-img{ grid-row:1; max-height:calc(100vh - 200px); }
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])) > .asset-meta{ display:contents; }
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])) .am-bar{ grid-column:1; justify-self:center; }
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])) .am-body{
      grid-column:2; grid-row:1 / span 6; margin-top:0; max-height:calc(100vh - 80px); justify-self:stretch;
    }
    /* 오른쪽 칸은 세로 여유가 크니 프롬프트 창을 내용만큼 늘린다(패널이 넘치면 패널이 스크롤) */
    .lightbox-overlay:not(.lightbox-fullscreen) .lightbox-img-wrap:has(.am-body:not([hidden])) .am-prompt{ max-height:none; overflow:visible; }
  }
  .lightbox-close{
    position:absolute;
    top:20px; right:24px;
    background:none;
    border:none;
    color:#fff;
    font-size:28px;
    line-height:1;
    cursor:pointer;
    opacity:.8;
    transition: opacity .15s ease, transform .15s ease;
  }
  .lightbox-close:hover{ opacity:1; transform:scale(1.08); }
  .lightbox-fs-btn{
    position:absolute;
    top:22px; right:66px;
    background:none; border:none; color:#fff; cursor:pointer;
    padding:2px; line-height:0; opacity:.8; z-index:3;
    transition: opacity .15s ease, transform .15s ease;
  }
  .lightbox-fs-btn:hover{ opacity:1; transform:scale(1.08); }
  /* 보기 회전 버튼 — 전체 화면에서만 보인다(원본 파일은 건드리지 않는다). */
  .lightbox-rot-btn{
    display:none; position:absolute; top:22px;
    background:none; border:none; color:#fff; cursor:pointer;
    padding:2px; line-height:0; opacity:.8; z-index:3;
    transition: opacity .15s ease, transform .15s ease;
  }
  .lightbox-rot-btn:hover{ opacity:1; transform:scale(1.08); }
  .lightbox-rot-cw{ right:104px; }
  .lightbox-rot-ccw{ right:142px; }
  .lightbox-overlay.lightbox-fullscreen .lightbox-rot-btn{ display:block; }
  /* 전체 화면에서는 이미지가 화면을 덮으므로 닫기·이동 버튼이 그 위에 떠야 하고, 밝은 이미지 위에서도 보이게 그림자를 준다. */
  .lightbox-overlay.lightbox-fullscreen .lightbox-close, .lightbox-overlay.lightbox-fullscreen .lightbox-nav,
  .lightbox-overlay.lightbox-fullscreen .lightbox-fs-btn,
  .lightbox-overlay.lightbox-fullscreen .lightbox-rot-btn{ z-index:3; filter:drop-shadow(0 1px 3px rgba(0,0,0,0.8)); }
  .lightbox-fs-btn .ico, .lightbox-rot-btn .ico{ width:24px; height:24px; }
  /* 전체 화면 — 여백·정보·버튼 줄을 걷어내고 이미지/영상이 화면을 꽉 채운다(닫기 ×와 전체 화면 해제 버튼만 남는다).
     브라우저 전체 화면에서도 같은 배치를 사용하고, 미지원 환경은 창 안을 채운다. */
  .lightbox-overlay.lightbox-fullscreen{ padding:0; background:#000; }
  .lightbox-overlay.lightbox-fullscreen .lightbox-img-wrap{ width:100%; height:100%; max-width:none; max-height:none; gap:0; touch-action:none; overflow:hidden; }
  .lightbox-overlay.lightbox-fullscreen .lightbox-img-wrap .lightbox-img{
    width:100%; height:100%; max-width:none; max-height:none; object-fit:contain; border-radius:0; box-shadow:none;
  }
  /* 보기 회전(NS-24) — CSS 개별 속성 rotate라 스와이프의 style.transform과 겹치지 않고, GPU 합성만 한다.
     90°/270°는 가로·세로를 바꾼 상자를 가운데 두고 돌려서 화면에 맞춘다. */
  .lightbox-overlay.lightbox-fullscreen[data-rot="90"] .lightbox-img-wrap .lightbox-img{ rotate:90deg; }
  .lightbox-overlay.lightbox-fullscreen[data-rot="180"] .lightbox-img-wrap .lightbox-img{ rotate:180deg; }
  .lightbox-overlay.lightbox-fullscreen[data-rot="270"] .lightbox-img-wrap .lightbox-img{ rotate:270deg; }
  .lightbox-overlay.lightbox-fullscreen[data-rot="90"] .lightbox-img-wrap,
  .lightbox-overlay.lightbox-fullscreen[data-rot="270"] .lightbox-img-wrap{ justify-content:center; }
  .lightbox-overlay.lightbox-fullscreen[data-rot="90"] .lightbox-img-wrap .lightbox-img,
  .lightbox-overlay.lightbox-fullscreen[data-rot="270"] .lightbox-img-wrap .lightbox-img{
    flex:none; width:100vh; width:100dvh; height:100vw; height:100dvw;
  }
  .lightbox-overlay.lightbox-fullscreen .lightbox-actions,
  .lightbox-overlay.lightbox-fullscreen .asset-meta,
  .lightbox-overlay.lightbox-fullscreen .lightbox-info,
  .lightbox-overlay.lightbox-fullscreen .lightbox-error{ display:none; }
  @media (hover:none){ .lightbox-overlay.lightbox-fullscreen .lightbox-nav{ display:none; } }
  .lightbox-nav{
    position:absolute;
    z-index:3;
    top:50%;
    transform:translateY(-50%);
    background:rgba(255,255,255,0.08);
    border:1px solid rgba(255,255,255,0.2);
    color:#fff;
    font-size:26px;
    width:44px; height:44px;
    border-radius:50%;
    cursor:pointer;
    display:flex;
    align-items:center;
    justify-content:center;
    transition: background .15s ease, border-color .15s ease, transform .15s ease;
  }
  .lightbox-nav:hover:not(:disabled){ background:rgba(255,255,255,0.18); border-color:rgba(255,255,255,0.35); transform:translateY(-50%) scale(1.06); }
  .lightbox-nav:disabled{ opacity:.25; cursor:not-allowed; }
  .lightbox-prev{ left:20px; }
  .lightbox-next{ right:20px; }
  @media (min-width:900px){
    .lightbox-overlay:not(.lightbox-fullscreen):has(.am-body:not([hidden])) .lightbox-next{
      right:calc(40px + 320px + 20px + 8px);
    }
  }
  /* 폰: 위쪽은 닫기·전체 화면 버튼 자리만 남기고 좌우·아래 여백을 줄여 이미지와 조작 줄에 화면을 더 준다. */
  @media (max-width:640px){ .lightbox-overlay{ padding:44px 12px 12px; } }

  #flash-notice{
    position:fixed; left:50%; bottom:28px; transform:translate(-50%, 12px);
    max-width:calc(100vw - 32px); padding:10px 16px; border-radius:10px;
    background:#111827; color:#fff; font-size:13px; line-height:1.4;
    box-shadow:0 6px 20px rgba(0,0,0,0.3); z-index:200;
    opacity:0; pointer-events:none; transition:opacity .2s, transform .2s;
  }
  #flash-notice.show{ opacity:1; transform:translate(-50%, 0); }
  .modal-overlay{
    position:fixed;
    inset:0;
    background:rgba(17,24,39,0.45);
    display:flex;
    align-items:center;
    justify-content:center;
    padding:24px;
    /* .lightbox-overlay(z-index:60)보다 위여야 한다 — "참조 세트로 보내기"를
       라이트박스 안에서 열 수 있어서, 이 모달이 라이트박스에 가려지면 안 된다. */
    z-index:70;
  }
  .modal-panel{
    background:var(--panel);
    border:1px solid var(--border);
    border-radius:12px;
    box-shadow: 0 8px 24px rgba(16,24,40,0.18);
    width:100%;
    max-width:720px;
    max-height:85vh;
    display:flex;
    flex-direction:column;
    overflow:hidden;
  }
  /* CSV 편집 모달처럼 표(열이 많을 수 있음)를 담는 모달용 — 기본 720px보다 넓힌다. */
  .modal-panel.modal-panel-wide{ max-width:min(1100px, 100%); }

  /* ---- CSV 편집 모달 (표 편집기) ---- */
  .csv-editor-toolbar{
    display:flex;
    align-items:center;
    gap:10px;
    flex-wrap:wrap;
  }
  .csv-editor-hint{ font-size:11.5px; color:var(--text-dim); }
  /* 행 번호 칸 — 헤더가 1행, 첫 데이터 행이 2행(수식 참조 번호와 같다) */
  .csv-editor-table .csv-row-number{ text-align:right; color:var(--text-dim); }
  .csv-editor-table tbody .csv-row-number{ position:static; background:var(--panel); }
  .csv-editor-table td.csv-formula input{ font-family:var(--mono); }
  .csv-editor-table td.csv-formula{ box-shadow:inset 3px 0 rgba(var(--queued-rgb),0.6); }
  .csv-editor-table-wrap{
    overflow-x:auto;
    max-height:50vh;
    overflow-y:auto;
    border:1px solid var(--border);
    border-radius:8px;
  }
  .csv-editor-table{
    border-collapse:collapse;
    width:100%;
  }
  .csv-editor-table th,
  .csv-editor-table td{
    border-bottom:1px solid var(--border);
    border-right:1px solid var(--border);
  }
  .csv-editor-table th:last-child,
  .csv-editor-table td:last-child{ border-right:none; }
  .csv-editor-table th{
    position:sticky;
    top:0;
    z-index:1;
    background:rgba(var(--queued-rgb),0.07);
    font-family:var(--mono);
    font-size:11px;
    font-weight:600;
    color:var(--text);
    padding:8px 10px;
    text-align:left;
    white-space:nowrap;
  }
  .csv-col-required{ color:var(--failed); margin-left:3px; }
  .csv-editor-table td{ padding:0; }
  .csv-editor-table td input{
    display:block;
    width:100%;
    min-width:150px;
    box-sizing:border-box;
    border:none;
    background:transparent;
    padding:7px 10px;
    font-family:var(--sans);
    font-size:12.5px;
    color:var(--text);
  }
  .csv-editor-table td input:focus{
    outline:2px solid rgba(var(--queued-rgb),0.35);
    outline-offset:-2px;
    background:rgba(var(--queued-rgb),0.04);
  }
  .csv-editor-table td.csv-cell-selected{
    background:rgba(var(--queued-rgb),0.12);
    box-shadow:inset 0 0 0 1px rgba(var(--queued-rgb),0.35);
  }
  .csv-editor-row-actions{
    display:flex;
    align-items:center;
    justify-content:center;
    padding:0 6px !important;
  }
  .csv-editor-del-btn{
    border:none;
    background:none;
    color:var(--text-dim);
    cursor:pointer;
    font-size:16px;
    line-height:1;
    padding:6px;
  }
  .csv-editor-del-btn:hover{ color:var(--failed); }
  .modal-header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:16px 20px;
    border-bottom:1px solid var(--border);
  }
  .modal-title{
    font-family:var(--mono);
    font-size:12px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:var(--track-label);
    color:var(--text);
  }
  .modal-close{
    background:none;
    border:none;
    cursor:pointer;
    color:var(--text-dim);
    font-size:20px;
    line-height:1;
    padding:4px;
  }
  .modal-close:hover{ color:var(--text); }
  .modal-body{
    padding:16px 20px;
    display:flex;
    flex-direction:column;
    gap:10px;
    overflow:auto;
  }
  .workflow-textarea{
    width:100%;
    min-height:380px;
    resize:vertical;
    font-family:var(--mono);
    font-size:12.5px;
    line-height:1.5;
    color:var(--text);
    background:var(--bg);
    border:1px solid var(--border);
    border-radius:8px;
    padding:12px;
    tab-size:2;
  }
  .workflow-textarea:focus{ outline:2px solid rgba(var(--queued-rgb),0.35); border-color:var(--queued); }
  .workflow-textarea.invalid{ border-color:var(--failed); }
  .workflow-error{
    color:var(--failed);
    font-family:var(--mono);
    font-size:12px;
    min-height:1.2em;
  }
  .modal-footer{
    display:flex;
    justify-content:flex-end;
    gap:var(--gap-md);
    padding:14px 20px;
    border-top:1px solid var(--border);
  }
  .modal-btn-secondary{
    background:var(--panel);
    border:1px solid var(--border);
    color:var(--text-dim);
    border-radius:var(--radius-sm);
    padding:8px 16px;
    font-family:var(--mono);
    font-weight:600;
    font-size:12.5px;
    cursor:pointer;
    transition: border-color .15s ease, color .15s ease;
  }
  .modal-btn-secondary:hover{ border-color:var(--text-dim); color:var(--text); }
/* Settings 탭 — Base Model 서브탭 목록 */
.settings-bm-list{ display:flex; flex-direction:column; gap:6px; margin:12px 0; }
.settings-bm-row{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.settings-bm-row .option-input{ flex:1 1 160px; min-width:0; }
.settings-bm-move{ display:flex; gap:4px; }
.settings-bm-move button{ min-width:32px; font-variant-numeric:tabular-nums; }
.settings-bm-row .base-model-delete{ color:var(--failed); }

/* Notification 서브탭 폼 */
.settings-form{ display:flex; flex-direction:column; gap:12px; margin:12px 0; max-width:560px; }
.settings-field{ display:flex; flex-direction:column; gap:4px; }
.settings-form label{ cursor:pointer; }

/* 서비스 토큰과 생성 프리셋 관리 */
.settings-record-list{ display:flex; flex-direction:column; gap:8px; margin:12px 0 24px; }
.settings-record{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:12px; padding:12px 16px; border:1px solid var(--border); border-radius:8px; background:var(--panel); overflow-wrap:anywhere; }
.settings-record > div:first-child{ min-width:0; flex:1; }
.settings-record strong{ font-size:14px; font-weight:600; }
.settings-record button{ min-height:40px; }
.settings-issued{ max-width:560px; padding:16px; margin:16px 0 24px; border:1px solid var(--accent); border-radius:8px; background:var(--panel-2); }
.settings-issued .settings-bm-row{ margin-top:8px; }
.settings-preset-form{ max-width:720px; }
.settings-preset-grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
.settings-json-input{ width:100%; min-height:120px; font-family:monospace; overflow-wrap:anywhere; }
.settings-user-choices{ display:flex; flex-wrap:wrap; gap:8px 16px; }
.settings-user-choices label{ display:inline-flex; align-items:center; gap:4px; min-height:40px; }
.settings-danger{ color:var(--failed); }
@media (max-width:640px){ .settings-preset-grid{ grid-template-columns:1fr; } .settings-record button{ flex:1; } }
@media (max-width:640px){
  #settings-subtabs{ flex-wrap:wrap; }
  #settings-subtabs .pod-subtab-btn{ flex:1 1 40%; min-height:40px; white-space:nowrap; }
}

/* Moodboard 크기 선택과 연결선 미리보기 */
.settings-moodboard-group{ display:flex; flex-wrap:wrap; gap:12px; margin:0; padding:12px; border:1px solid var(--border); border-radius:8px; }
.settings-moodboard-group legend{ padding:0 4px; }
.settings-moodboard-group label{ display:inline-flex; align-items:center; gap:4px; min-height:40px; }
.settings-moodboard-preview{ display:flex; align-items:center; justify-content:center; min-height:120px; padding:12px; background:var(--panel-2); border:1px solid var(--border); border-radius:8px; }
.settings-moodboard-preview svg{ display:block; width:min(100%, 320px); height:auto; }

/* RunPod GPU 패밀리 설정 */
.settings-gpu-family{ margin:16px 0; padding:16px; border:1px solid var(--border); border-radius:8px; background:var(--panel); }
.settings-gpu-clouds{ display:flex; flex-direction:column; gap:4px; margin:12px 0; }
.settings-gpu-cloud{ display:flex; align-items:center; gap:8px; min-height:44px; }
.settings-gpu-cloud-name{ flex:1; }
.settings-gpu-cloud .settings-bm-move button{ min-width:40px; min-height:40px; }
.settings-gpu-list{ display:flex; flex-direction:column; gap:4px; }
.settings-gpu-row{ display:flex; align-items:center; gap:12px; min-width:0; padding:8px; border-bottom:1px solid var(--border); }
.settings-gpu-name{ flex:1; min-width:0; overflow-wrap:anywhere; font-size:13px; }
.settings-gpu-name .dl-meta{ display:block; }
.settings-gpu-row .settings-bm-move button{ min-width:40px; min-height:40px; }
.settings-gpu-actions{ display:flex; align-items:center; flex-wrap:wrap; gap:12px; margin:16px 0; }
.settings-gpu-warning{ margin:12px 0; color:var(--failed); overflow-wrap:anywhere; }
.pod-create-tier span{ overflow-wrap:anywhere; }
@media (max-width:640px){ .settings-gpu-family{ padding:12px; } .settings-gpu-row{ gap:8px; } }

/* 베이스 모델 세부 설정 모달 */
#base-model-modal .section-label{ margin-top:16px; }
.settings-parts{ display:flex; flex-direction:column; gap:6px; margin:8px 0; }
.settings-part{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.settings-part-label{ min-width:96px; font-weight:600; }
.settings-part-missing{ color:var(--failed); }
.settings-member-group{ margin:12px 0; display:flex; flex-direction:column; gap:6px; }
.settings-member-file{ flex:1 1 160px; min-width:0; overflow-wrap:anywhere; }
.settings-member-add{ margin-top:12px; }
.settings-member-add select{ flex:0 1 180px; }
  /* ---- Library 탭(Pose) — 17c-library.js ---- */
  .library-grid{
    display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:var(--gap-sm);
  }
  #library-subtabs{ align-items:center; flex-wrap:wrap; }
  #library-custom-tabs{ display:contents; }
  #library-category-create{ margin-left:auto; }
  #library-category-actions{ display:flex; gap:var(--gap-sm); margin-bottom:var(--gap-sm); }
  #library-category-actions[hidden], #library-select-all-btn[hidden], #library-sequence-btn[hidden]{ display:none; }
  #library-category-modal .modal-panel{ max-width:480px; }
  #lfg-kind{ display:flex; flex-wrap:wrap; max-width:100%; }
  .library-card{
    background:var(--panel); border:1px solid var(--border); border-radius:var(--radius-md);
    overflow:hidden; display:flex; flex-direction:column;
  }
  /* 카드 전체가 버튼(NS-40, 안에 순차 생성 체크 버튼을 넣으려고 div role=button) — 누르면 아티클 갤러리 */
  .library-card[role="button"]{ cursor:pointer; width:100%; }
  .library-card[role="button"]:hover{ border-color:var(--accent, var(--queued)); }
  #library-article-grid .gallery-item{ position:relative; }
  /* 순차 생성 체크(NS-42) — 썸네일 오른쪽 위. 체크하면 강조색 */
  .library-check-btn{
    position:absolute; right:var(--gap-xs); top:var(--gap-xs); z-index:1;
    display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; padding:0;
    border:none; border-radius:var(--radius-sm); background:rgba(0,0,0,0.6); color:rgba(255,255,255,0.55); cursor:pointer;
  }
  .library-check-btn[aria-pressed="true"]{ background:var(--accent, var(--queued)); color:#fff; }
  .library-check-btn:focus-visible{ outline:2px solid var(--accent, var(--queued)); outline-offset:2px; }
  .library-details .library-check-btn{ width:24px; height:24px; right:2px; top:2px; }
  /* Position 아티클 격자의 "이 장 삭제"(NS-43) — 썸네일 오른쪽 위 */
  .library-image-delete-btn{
    position:absolute; right:var(--gap-xs); top:var(--gap-xs); z-index:1;
    display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; padding:0;
    border:none; border-radius:var(--radius-sm); background:rgba(0,0,0,0.6); color:#fff; cursor:pointer;
  }
  .library-image-delete-btn:hover, .library-image-delete-btn:focus-visible{ background:var(--danger, var(--failed)); }
  /* 대표 이미지(NS-61) — 아티클 격자의 체크는 오른쪽 아래(위는 삭제 버튼), 대표 배지는 왼쪽 아래 */
  #library-article-grid .library-cover-check{ top:auto; bottom:var(--gap-xs); }
  .library-cover-badge{
    position:absolute; left:var(--gap-xs); bottom:var(--gap-xs); z-index:1;
    display:inline-flex; align-items:center; gap:4px; padding:2px 8px; border-radius:var(--radius-sm);
    background:var(--accent, var(--queued)); color:#fff; font-size:12px; pointer-events:none;
  }
  .library-cover-badge .ico{ width:12px; height:12px; }
  /* 순차 생성 폼 — 총 장수 안내와 포즈 태그 스위치 */
  .pose-sequence-hint{ font-size:14px; color:var(--text); margin:var(--gap-xs) 0; }
  .pose-tag-toggle{ display:inline-flex; align-items:center; gap:8px; margin-top:var(--gap-xs); font-size:12.5px; color:var(--text-dim); cursor:pointer; }
  /* 생성 방식 고르기(NS-51) — 두 버튼을 같은 크기로 나란히(좁으면 위아래) */
  .library-transfer-choices{ display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:var(--gap-sm); }
  .library-transfer-btn{
    display:flex; flex-direction:column; align-items:flex-start; gap:var(--gap-xs); min-height:44px; padding:var(--gap-sm);
    background:var(--panel); color:var(--text); border:1px solid var(--border); border-radius:var(--radius-md);
    font:inherit; text-align:left; cursor:pointer;
  }
  .library-transfer-btn span{ font-size:12.5px; color:var(--text-dim); }
  .library-transfer-btn:hover, .library-transfer-btn:focus-visible{ border-color:var(--accent, var(--queued)); }  .library-info > span{ display:block; }
  .library-thumb{ display:block; aspect-ratio:1; background:var(--bg); position:relative; }
  .library-thumb-count{
    position:absolute; right:var(--gap-xs); bottom:var(--gap-xs); padding:2px 6px; border-radius:var(--radius-sm);
    background:rgba(0,0,0,0.6); color:#fff; font-family:var(--mono); font-size:12px;
    display:inline-flex; align-items:center; gap:4px;
  }
  .library-thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
  .library-info{ padding:var(--gap-sm); display:flex; flex-direction:column; gap:4px; min-width:0; }
  .library-name{ font-weight:600; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .library-desc{
    color:var(--text-dim); font-size:12px;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  }
  .library-desc:empty{ display:none; }
  .library-prompt{ font-family:var(--mono); font-size:12px; color:var(--log-text); word-break:break-word; }

  /* Details — 한 줄에 작은 썸네일 · 명칭 · 설명 · danbooru prompt */
  .library-details{ display:flex; flex-direction:column; gap:var(--gap-xs); }
  .library-details .library-card{ flex-direction:row; align-items:center; }
  .library-details .library-thumb{ width:64px; flex-shrink:0; }
  .library-details .library-desc{ -webkit-line-clamp:3; }

  /* 아티클 갤러리 — 격자는 갤러리의 .gallery-grid/.gallery-item 그대로 */
  #library-article{ display:flex; flex-direction:column; gap:var(--gap-sm); }
  #library-article[hidden], #library-list[hidden]{ display:none; }
  .library-article-head{ display:flex; align-items:center; gap:var(--gap-sm); min-width:0; }
  .library-article-head .library-name{ flex:1; min-width:0; }
  #library-article .library-desc{ -webkit-line-clamp:unset; }
  .library-prompt:empty{ display:none; }
  #library-article-grid .gallery-item{ cursor:pointer; }

  /* 미리보기 — 여러 장을 작은 썸네일 줄로 */
  .pose-add-preview{ display:flex; flex-wrap:wrap; gap:var(--gap-xs); margin-top:var(--gap-sm); }
  .pose-add-preview img{
    width:72px; height:72px; object-fit:cover;
    border:1px solid var(--border); border-radius:var(--radius-sm);
  }
  .pose-add-preview[hidden], .pose-add-meta[hidden], #pose-add-image-field[hidden]{ display:none; }
  #pose-add-gallery{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--gap-sm); }
  #pose-add-gallery[hidden]{ display:none; }
  #pose-add-file[hidden], #pose-add-url[hidden]{ display:none; }
  /* 갤러리에서 Library로 넣기(NS-45) — 같은 미리보기 줄을 쓰고 숨김만 맞춘다 */
  #library-from-gallery-modal .field[hidden], #lfg-done[hidden], #lfg-save[hidden]{ display:none; }
  #lfg-done{ display:flex; align-items:center; gap:var(--gap-sm); flex-wrap:wrap; }

  /* 모바일 — 추가 버튼은 아이콘만(기존 640px 기준) */
  @media (max-width:640px){
    #library-add-btn .btn-label, #library-article-add-btn .btn-label,
    #library-article-edit-btn .btn-label, #library-article-delete-btn .btn-label{ display:none; }
  }

/* 참조 아티클이 많아도 행 약 3개 높이에서 스크롤하고, 모달 본문(flex 세로)에서 베이스 모델 목록을 눌러 줄이지 않는다(NS-61). */
.library-selection-preview { border:1px solid var(--border); border-radius:8px; padding:12px; margin:12px 0; background:var(--panel-2); max-height:240px; overflow-y:auto; flex-shrink:0; }
#wizard-family-modal-body > .wizard-pick-list { flex-shrink:0; }
.library-selection-row { display:flex; gap:12px; align-items:flex-start; font-size:13px; line-height:1.6; }
.library-selection-row + .library-selection-row { margin-top:12px; }
.library-selection-row img { width:64px; height:64px; object-fit:contain; border-radius:6px; flex-shrink:0; }
.library-selection-row > div { min-width:0; overflow-wrap:anywhere; }
.library-selection-row strong { font-weight:600; }
  /* 백틱 빠른 실행창(NS-52) — DESIGN.md 8절 "빠른 입력창" 값을 그대로 쓴다(dev .composer·.cmp-*와 같은 모양).
     nightshift에는 --panel-2·--accent 토큰이 아직 없어 이 부품 안에서만 DESIGN.md 3절 값으로 둔다. */
  .composer{ --cmp-panel-2:#F2F4F7; --cmp-accent:#2563EB; --cmp-strong:#C4CAD3;
    position:fixed; left:50%; bottom:16px; transform:translateX(-50%); z-index:150; width:min(760px, calc(100vw - 28px));
    display:flex; flex-direction:column; gap:8px; padding:12px 12px 8px; background:var(--panel); color:var(--text);
    border:1px solid var(--border); border-radius:12px; box-shadow:0 8px 24px rgba(16,24,40,.12);
    animation:cmp-in .22s cubic-bezier(.2,.8,.2,1); }
  @media (prefers-color-scheme: dark){
    html:not([data-theme="light"]) .composer{ --cmp-panel-2:#22262E; --cmp-accent:#6D9BFF; --cmp-strong:#4A505B; box-shadow:none; }
  }
  html[data-theme="dark"] .composer{ --cmp-panel-2:#22262E; --cmp-accent:#6D9BFF; --cmp-strong:#4A505B; box-shadow:none; }
  .composer[hidden]{ display:none; }
  .composer:focus-within{ border-color:var(--cmp-strong); }
  .composer textarea{ width:100%; box-sizing:border-box; border:none; box-shadow:none; outline:none; background:transparent; color:inherit;
    resize:none; padding:4px; min-height:24px; max-height:40vh; overflow-y:auto; font:inherit; font-size:14px; line-height:1.6; }
  .cmp-bar{ display:flex; align-items:center; gap:8px; min-width:0; }
  .cmp-pill{ min-width:0; max-width:180px; height:32px; padding:0 12px; font:inherit; font-size:13px; color:var(--text);
    background:var(--cmp-panel-2); border:1px solid var(--border); border-radius:999px; cursor:pointer;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; transition:border-color .12s ease; }
  .cmp-pill:hover{ border-color:var(--cmp-strong); }
  .cmp-pill:focus-visible, .cmp-icon:focus-visible, .cmp-send:focus-visible, .cmp-menu button:focus-visible{
    outline:none; box-shadow:0 0 0 3px rgba(37,99,235,.15); }
  .cmp-icon, .cmp-send{ flex-shrink:0; width:32px; height:32px; padding:0; display:inline-flex; align-items:center; justify-content:center;
    border-radius:999px; cursor:pointer; }
  .cmp-icon{ background:transparent; color:var(--text-dim); border:1px solid var(--border); }
  .cmp-icon:hover{ color:var(--text); border-color:var(--cmp-strong); }
  .cmp-send{ margin-left:auto; color:#fff; background:var(--grad-primary); border:none; }
  .cmp-send:hover:not(:disabled){ background:var(--grad-primary-hover); }
  .cmp-send:disabled{ opacity:.4; cursor:default; }
  .cmp-files{ display:flex; flex-wrap:wrap; gap:4px; }
  .cmp-files:empty, .cmp-error:empty{ display:none; }
  .cmp-chip{ display:inline-flex; align-items:center; gap:4px; max-width:100%; padding:2px 4px 2px 10px; font-size:12px; color:var(--text-dim);
    background:var(--cmp-panel-2); border:1px solid var(--border); border-radius:999px; overflow-wrap:anywhere; }
  .cmp-chip.bad{ color:var(--failed); border-color:var(--failed); }
  .cmp-chip.unused{ opacity:.45; }
  .cmp-chip button{ width:22px; height:22px; padding:0; display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
    border:none; background:transparent; color:inherit; border-radius:999px; cursor:pointer; }
  .cmp-chip button .ico{ width:14px; height:14px; }
  .cmp-error{ margin:0; font-size:12px; color:var(--failed); }

  /* 위로 펼쳐지는 메뉴 — 모서리 8, 떠 있는 그림자, 항목 높이 34, 현재 값에 체크 */
  .cmp-menu-wrap{ position:relative; min-width:0; display:flex; }
  .cmp-menu{ position:absolute; left:0; bottom:calc(100% + 8px); min-width:240px; max-width:min(360px, calc(100vw - 40px));
    max-height:50vh; overflow-y:auto; padding:4px; background:var(--panel); border:1px solid var(--border); border-radius:8px;
    box-shadow:0 8px 24px rgba(16,24,40,.12); z-index:1; }
  .cmp-menu[hidden]{ display:none; }
  .cmp-menu button{ display:flex; align-items:center; gap:8px; width:100%; min-height:34px; padding:0 8px; font:inherit; font-size:13px;
    color:var(--text); background:transparent; border:none; border-radius:6px; text-align:left; cursor:pointer; }
  .cmp-menu button:hover:not(:disabled){ background:var(--cmp-panel-2); }
  .cmp-menu button:disabled{ opacity:.45; cursor:default; }
  .cmp-menu .cmp-check{ width:14px; height:14px; flex-shrink:0; color:var(--cmp-accent); visibility:hidden; }
  .cmp-menu button[aria-checked="true"] .cmp-check{ visibility:visible; }
  .cmp-menu .cmp-name{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .cmp-menu .cmp-kind{ flex-shrink:0; font-family:var(--mono); font-size:11px; color:var(--text-dim); }
  .cmp-menu .cmp-empty{ padding:8px; font-size:12px; color:var(--text-dim); }
  .cmp-menu .cmp-sep{ margin:4px 0; border:none; border-top:1px solid var(--border); }

  /* 라이브러리 고르기(NS-52-3) — 창(z-index 150) 위에서 고른다. NS-51 생성 방식 모달도 같이 올린다 */
  #cmp-library-modal, body:has(.composer:not([hidden])) #library-transfer-modal{ z-index:160; }
  .cmp-library-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(96px, 1fr)); gap:8px; max-height:60vh; overflow-y:auto; }
  .cmp-library-grid .gallery-item{ padding:0; border:1px solid var(--border); border-radius:8px; overflow:hidden; background:transparent; cursor:pointer; aspect-ratio:1; }
  .cmp-library-grid .gallery-item img{ width:100%; height:100%; object-fit:cover; display:block; }

  body:has(.composer:not([hidden])) main{ padding-bottom:200px; }
  body:has(.composer:not([hidden])) #flash-notice{ bottom:auto; top:72px; }
  @keyframes cmp-in{ from{ opacity:0; transform:translate(-50%, 4px); } }
  @media (prefers-reduced-motion: reduce){ .composer{ animation:none; } }
  @media (max-width: 800px){
    .cmp-pill{ max-width:120px; }
    .cmp-icon, .cmp-send{ width:40px; height:40px; }
    .cmp-pill{ height:40px; }
  }
/* 프롬프트 옵션 안내 창과 세 입력 위치의 도움말 버튼을 표시한다. */
.prompt-options-help-button{
  display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; padding:0; border:0; border-radius:6px;
  background:transparent; color:var(--text-dim); cursor:pointer;
}
.prompt-options-help-button:hover{ color:var(--accent); background:var(--panel-2); }
.prompt-options-help-button .ico{ width:16px; height:16px; }
.prompt-options-help-button:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.prompt-option-chips{ display:flex; flex-wrap:wrap; gap:4px; min-width:0; margin-top:4px; }
.prompt-option-chips[hidden]{ display:none; }
.prompt-option-chip{ max-width:100%; overflow-wrap:anywhere; padding:4px 8px; border:1px solid var(--border); border-radius:999px; background:var(--panel-2); color:var(--text-dim); font-size:12px; line-height:1.4; }
.prompt-option-chip.error{ color:var(--failed); border-color:var(--failed); }
.board-gen-field-label .prompt-options-help-button{ margin-left:4px; flex:none; }
.csv-editor-table th .prompt-options-help-button{ vertical-align:middle; }
.prompt-options-help-panel{ max-width:min(900px, 100%); }
#prompt-options-help-body{ font-size:14px; line-height:1.6; }
#prompt-options-help-body p{ margin:0; }
#prompt-options-help-body h3{ margin:16px 0 0; font-size:16px; }
#prompt-options-help-body ul{ margin:0; padding-left:24px; }
.prompt-help-table-wrap{ overflow:auto; }
.prompt-help-table{ width:100%; border-collapse:collapse; font-size:13px; }
.prompt-help-table th,.prompt-help-table td{ padding:8px; border-bottom:1px solid var(--border); text-align:left; vertical-align:top; }
.prompt-help-table thead{ background:var(--panel-2); }
.prompt-help-table small{ display:block; color:var(--text-dim); }
.prompt-help-example{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; padding:12px; border:1px solid var(--border); border-radius:8px; }
.prompt-help-examples{ display:grid; gap:8px; }
.prompt-help-example code{ flex:1; min-width:0; overflow-wrap:anywhere; }
.prompt-help-example span{ width:100%; color:var(--text-dim); font-size:13px; }
.prompt-help-copy{ border:1px solid var(--border); border-radius:6px; padding:8px 12px; background:var(--panel-2); color:var(--text); cursor:pointer; }
@media(max-width:600px){
  #prompt-options-help-modal{ padding:8px; }
  .prompt-options-help-panel{ max-height:calc(100dvh - 16px); }
  .prompt-help-table thead{ display:none; }
  .prompt-help-table,.prompt-help-table tbody,.prompt-help-table tr,.prompt-help-table th,.prompt-help-table td{ display:block; }
  .prompt-help-table tr{ border:1px solid var(--border); border-radius:8px; margin-bottom:8px; padding:8px; }
  .prompt-help-table th,.prompt-help-table td{ border:0; padding:4px; }
}
