
  /* ===== Design Tokens ===== */
  :root{
    --blue:#0B73FF;
    --blue-dark:#0A5FD4;
    --light-blue:#EAF3FF;
    --border:#E5EAF2;
    --text-dark:#17233C;
    --text-muted:#6B7894;
    --bg:#F7FAFF;
    --white:#FFFFFF;

    --green-bg:#E7F7EE; --green-tx:#12A452;
    --blue-bg:#E7F1FF;  --blue-tx:#0B73FF;
    --gray-bg:#EEF1F6;  --gray-tx:#8A96A9;
    --red-bg:#FDECEC;   --red-tx:#E04646;

    /* 결과 포인트 3색. 범례 점(.lg-dot)과 지도 점(getPointStyle)이 함께 읽는다.
       한쪽만 고치면 범례와 지도가 어긋나므로 반드시 여기서 바꾼다. */
    --pt-strong:#5B21B6;    /* 해당 구간 · 최상위 매칭 위치 */
    --pt-soft:#0E7490;      /* 주요 발병 보고 국가 · 유사 매칭 위치 */
    --pt-selected:#DC2626;  /* 선택된 위치 */

    --radius:10px;
    --radius-sm:8px;
    --shadow-card:0 10px 30px rgba(17,35,60,.10);
    --sidebar-w:352px;
    --spatial-panel-width:392px;
    --header-h:64px;
    /* 전역 헤더 전용 색상 (콘텐츠 --blue 에는 영향 없음) */
    --header-bg:#0A5FD4;
    --header-bg-deep:#0959C4;
    --header-text:#FFFFFF;
    --header-muted:#DCEBFF;
    --header-subtle:#BFD9F5;
    --header-active:#FFFFFF;
    --header-hover:rgba(255,255,255,.12);
    --header-active-bg:rgba(255,255,255,.16);
    --header-border:rgba(255,255,255,.16);
  }

  *{box-sizing:border-box;margin:0;padding:0}
  html,body{height:100%}
  body{
    font-family:"Pretendard","Inter","Noto Sans KR",system-ui,-apple-system,"Segoe UI",sans-serif;
    color:var(--text-dark);
    background:var(--bg);
    -webkit-font-smoothing:antialiased;
    overflow:hidden;
  }
  button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
  input,select{font-family:inherit}
  svg{display:block}

  /* ===== App Shell ===== */
  .app{display:flex;flex-direction:column;height:100vh;min-width:1440px}

  /* ===== Header ===== */
  .header{
    position:relative;z-index:100;
    height:var(--header-h);
    flex:0 0 var(--header-h);
    background:var(--header-bg);
    border-bottom:1px solid var(--header-border);
    box-shadow:0 2px 8px rgba(10,95,212,.18);
    display:flex;align-items:center;
    padding:0 24px;
    gap:24px;
  }
  .brand{display:flex;align-items:center;gap:10px;min-width:240px}
  .brand .logo-ic{
    width:34px;height:34px;border-radius:9px;
    background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.24);
    display:flex;align-items:center;justify-content:center;color:#fff;
    box-shadow:none;
  }
  .brand .name{font-size:19px;font-weight:700;letter-spacing:-.2px;color:var(--header-text)}
  .brand .name b{color:#CBE5FF}

  .nav{display:flex;align-items:center;gap:6px;flex:1;justify-content:center}
  .nav a{
    display:flex;align-items:center;gap:7px;
    padding:8px 14px;border-radius:8px;
    font-size:14px;font-weight:500;color:var(--header-muted);
    position:relative;text-decoration:none;
    transition:color .15s,background .15s;
  }
  .nav a:hover{color:#FFFFFF;background:var(--header-hover)}
  .nav a.active{color:#FFFFFF;font-weight:600;background:var(--header-active-bg)}
  .nav a.active::after{
    content:"";position:absolute;left:12px;right:12px;bottom:-13px;height:2.5px;
    background:var(--header-active);border-radius:2px;
  }
  .nav a:focus-visible,.icon-btn:focus-visible,.profile:focus-visible{outline:2px solid #D6ECFF;outline-offset:2px}
  .nav a svg{width:17px;height:17px}

  .header-right{display:flex;align-items:center;gap:14px;min-width:0}
  .pill{
    display:inline-flex;align-items:center;gap:6px;
    padding:6px 12px;border-radius:999px;
    font-size:12.5px;font-weight:600;
    background:rgba(26,190,112,.20);color:#B1F1CF;border:1px solid rgba(151,239,194,.28);
    white-space:nowrap;
  }
  .pill .dot{width:6px;height:6px;border-radius:50%;background:#6EE0A5}
  .icon-btn{
    width:38px;height:38px;border-radius:9px;
    display:flex;align-items:center;justify-content:center;
    color:var(--header-muted);position:relative;
  }
  .icon-btn:hover{background:var(--header-hover);color:#FFFFFF}
  .icon-btn .badge{
    position:absolute;top:8px;right:9px;width:7px;height:7px;
    border-radius:50%;background:#E04646;border:1.5px solid var(--header-bg);
  }
  /* 로그아웃은 CSRF 때문에 POST 여야 해서 form 으로 감싼다.
     form 이 헤더 정렬을 깨지 않도록 flex 항목으로 만든다. */
  .logout-form{display:flex;align-items:center}
  .profile{display:flex;align-items:center;gap:9px;padding:4px 6px 4px 4px;border-radius:10px;cursor:pointer}
  .profile:hover{background:var(--header-hover)}
  .avatar{
    width:36px;height:36px;border-radius:50%;
    background:linear-gradient(135deg,#cfe1ff,#9ec2ff);
    display:flex;align-items:center;justify-content:center;color:#fff;
    border:1px solid rgba(255,255,255,.42);
  }
  .profile .who{line-height:1.15}
  .profile .who .ko{font-size:13.5px;font-weight:600;color:var(--header-text)}
  .profile .who .en{font-size:11px;color:var(--header-subtle)}
  .profile .chev{color:var(--header-muted)}

  /* ===== Main ===== */
  .main{flex:1;display:flex;min-height:0;position:relative}

  /* ===== Running Panel (지도 위 오버레이) ===== */
  .running-panel{
    position:absolute;
    left:var(--sidebar-w);
    top:0;
    height:100%;
    width:360px;
    z-index:200;
    display:flex;flex-direction:column;
    background:var(--white);
    border-right:1px solid var(--border);
    box-shadow:14px 0 34px rgba(17,35,60,.10);
    opacity:0;
    transform:translateX(-14px);
    pointer-events:none;
    visibility:hidden;
    transition:opacity .26s ease,transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .3s;
  }
  .running-panel.is-open{
    opacity:1;transform:none;pointer-events:auto;visibility:visible;
    transition:opacity .26s ease,transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear 0s;
  }
  @media (prefers-reduced-motion:reduce){.running-panel{transition:none}}

  .rp-head{
    display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
    padding:20px 20px 16px;border-bottom:1px solid var(--border);
  }
  .rp-head h2{font-size:15.5px;font-weight:700;color:var(--text-dark)}
  .rp-head p{font-size:12px;color:var(--text-muted);margin-top:5px}
  .running-panel-close{
    width:32px;height:32px;flex-shrink:0;border-radius:8px;
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  .running-panel-close:hover{background:#F3F6FC;color:var(--text-dark)}

  .rp-body{flex:1;overflow-y:auto;padding:16px 20px 20px}
  .rp-body::-webkit-scrollbar{width:8px}
  .rp-body::-webkit-scrollbar-track{background:#F1F3F8;border-radius:8px}
  .rp-body::-webkit-scrollbar-thumb{background:#C9D2E0;border-radius:8px;border:2px solid #F1F3F8}

  .rp-target{
    padding:11px 13px;border-radius:var(--radius-sm);
    background:var(--light-blue);border:1px solid #D5E4FF;
    margin-bottom:18px;
  }
  .rp-target .rt-name{font-size:13px;font-weight:600;color:var(--text-dark)}
  .rp-target .rt-id{font-size:11px;color:var(--blue);margin-top:3px}

  /* Timeline */
  .timeline{position:relative;display:flex;flex-direction:column;gap:4px}
  .timeline::before{
    content:"";position:absolute;left:13px;top:20px;bottom:20px;
    width:2px;background:var(--border);
  }
  .timeline-step{
    position:relative;z-index:1;
    display:flex;align-items:flex-start;gap:12px;
    padding:11px 10px;border-radius:var(--radius-sm);
    background:transparent;
  }
  .timeline-step.running{background:var(--light-blue)}

  .ts-dot{
    width:28px;height:28px;flex-shrink:0;border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    border:2px solid var(--white);
  }
  .timeline-step.completed .ts-dot{background:var(--green-tx);color:#fff}
  .timeline-step.running .ts-dot{background:var(--blue);color:#fff}
  .timeline-step.pending .ts-dot{background:#E6EAF1;color:#A6B0C1}
  .timeline-step.running .ts-dot svg{animation:tsPulse 1.6s ease-in-out infinite}
  @keyframes tsPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
  @media (prefers-reduced-motion:reduce){.timeline-step.running .ts-dot svg{animation:none}}

  .ts-main{flex:1;min-width:0;padding-top:1px;display:flex;flex-direction:column}
  .ts-title{font-size:13px;font-weight:600;color:var(--text-dark)}
  .timeline-step.pending .ts-title{color:#9AA8BD}
  .ts-desc{font-size:11.5px;color:var(--text-muted);margin-top:3px;line-height:1.5}
  .timeline-step.pending .ts-desc{color:#B3BDCC}

  /* 시간 / 상태 텍스트: 오른쪽 끝 고정 (FR badge 제거로 빈 공간 없음) */
  .ts-time{
    flex-shrink:0;align-self:center;margin-left:auto;
    font-size:11px;font-weight:600;white-space:nowrap;
  }
  .timeline-step.completed .ts-time{color:var(--green-tx)}
  .timeline-step.running .ts-time{color:var(--blue)}
  .timeline-step.pending .ts-time{color:var(--gray-tx);font-weight:500}

  /* Overall progress */
  .rp-foot{padding:16px 20px 20px;border-top:1px solid var(--border);background:#FCFDFF}
  .rp-progress-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:9px}
  .rp-progress-head span{font-size:12px;color:var(--text-muted)}
  .rp-progress-head strong{font-size:14px;font-weight:700;color:var(--blue)}
  .rp-progress-track{height:8px;border-radius:999px;background:#E9EEF6;overflow:hidden}
  .overall-progress-bar{
    height:100%;border-radius:999px;
    background:linear-gradient(90deg,#3E93FF,var(--blue));
    transition:width .4s ease;
  }
  .rp-eta{font-size:11px;color:var(--text-muted);margin-top:9px}

  /* ===== Genomic Results Panel ===== */
  .genomic-results-panel{
    position:absolute;
    left:var(--sidebar-w);
    top:0;height:100%;
    width:720px;
    max-width:calc(100vw - var(--sidebar-w) - 40px);
    z-index:200;
    display:flex;flex-direction:column;
    background:var(--white);
    border-right:1px solid var(--border);
    box-shadow:14px 0 34px rgba(17,35,60,.12);
    opacity:0;transform:translateX(-14px);
    pointer-events:none;visibility:hidden;
    transition:opacity .26s ease,transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .3s;
  }
  .genomic-results-panel.is-open{
    opacity:1;transform:none;pointer-events:auto;visibility:visible;
    transition:opacity .26s ease,transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear 0s;
  }
  @media (prefers-reduced-motion:reduce){.genomic-results-panel{transition:none}}

  .gr-head{
    display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
    padding:18px 20px;border-bottom:1px solid var(--border);flex-shrink:0;
  }
  .gr-head h2{font-size:16px;font-weight:700;color:var(--text-dark)}
  .gr-head p{font-size:12px;color:var(--text-muted);margin-top:5px}
  .gr-head-actions{display:flex;align-items:center;gap:10px;flex-shrink:0}
  .spatial-cta{
    display:flex;flex-direction:column;align-items:flex-start;gap:2px;
    padding:8px 14px;border-radius:9px;
    border:1px solid var(--blue);background:var(--light-blue);
    transition:background .14s;
  }
  .spatial-cta:hover{background:#DCEAFF}
  .spatial-cta .sc-main{font-size:12.5px;font-weight:700;color:var(--blue);white-space:nowrap}
  .spatial-cta .sc-sub{font-size:10.5px;color:var(--text-muted);white-space:nowrap}
  .genomic-results-close{
    width:32px;height:32px;flex-shrink:0;border-radius:8px;
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  .genomic-results-close:hover{background:#F3F6FC;color:var(--text-dark)}

  .gr-body{flex:1;overflow-y:auto;padding:16px 20px 22px}
  .gr-body::-webkit-scrollbar{width:8px}
  .gr-body::-webkit-scrollbar-track{background:#F1F3F8;border-radius:8px}
  .gr-body::-webkit-scrollbar-thumb{background:#C9D2E0;border-radius:8px;border:2px solid #F1F3F8}

  .gr-target{
    padding:10px 13px;border-radius:var(--radius-sm);
    background:var(--light-blue);border:1px solid #D5E4FF;margin-bottom:16px;
  }
  .gr-target .rt-name{font-size:13px;font-weight:600;color:var(--text-dark)}
  .gr-target .rt-id{font-size:11px;color:var(--blue);margin-top:3px}

  /* 요약 지표 카드 */
  .summary-metrics{
    display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;margin-bottom:18px;
  }
  .summary-metric-card{
    border:1px solid var(--border);border-radius:10px;background:#fff;
    padding:12px 12px 11px;min-width:0;
  }
  .smc-top{display:flex;align-items:center;gap:6px;margin-bottom:8px}
  .smc-ic{
    width:24px;height:24px;flex-shrink:0;border-radius:7px;
    background:var(--light-blue);color:var(--blue);
    display:flex;align-items:center;justify-content:center;
  }
  .smc-label{font-size:11px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .smc-value{font-size:17px;font-weight:700;color:var(--text-dark);letter-spacing:-.3px}
  .smc-sub{font-size:10.5px;color:var(--text-muted);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

  /* 결과 검색 */
  .gr-search-row{display:flex;gap:8px;margin-bottom:12px}
  .gr-search{flex:1}
  .gr-search input{height:38px}
  .gr-filter-btn{
    width:38px;flex:0 0 38px;border:1px solid var(--border);border-radius:var(--radius-sm);
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);background:#fff;
  }
  .gr-filter-btn:hover{border-color:var(--blue);color:var(--blue)}

  /* 결과 테이블 — 컬럼이 많아 가로 스크롤 */
  .gr-table-wrap{border:1px solid var(--border);border-radius:10px;overflow-x:auto}
  .gr-table-wrap::-webkit-scrollbar{height:8px}
  .gr-table-wrap::-webkit-scrollbar-track{background:#F1F3F8}
  .gr-table-wrap::-webkit-scrollbar-thumb{background:#C9D2E0;border-radius:8px;border:2px solid #F1F3F8}

  .genomic-results-table{width:100%;min-width:1428px;border-collapse:collapse;font-size:12px;table-layout:fixed}
  .genomic-results-table col.c-no{width:48px}
  .genomic-results-table col.c-query{width:90px}
  .genomic-results-table col.c-rank{width:60px}
  .genomic-results-table col.c-pred{width:100px}
  .genomic-results-table col.c-acc{width:110px}
  .genomic-results-table col.c-bucket{width:100px}
  .genomic-results-table col.c-taxid{width:80px}
  .genomic-results-table col.c-sci{width:120px}
  .genomic-results-table col.c-pi{width:90px}
  .genomic-results-table col.c-qcover{width:120px}
  .genomic-results-table col.c-eval{width:90px}
  .genomic-results-table col.c-desc{width:420px}

  .genomic-results-table th{
    background:#F5F7FB;color:var(--text-muted);
    font-size:11px;font-weight:600;text-align:left;
    padding:10px 10px;border-bottom:1px solid var(--border);white-space:nowrap;
  }
  .genomic-results-table th.num{text-align:right}
  .genomic-results-table td{
    padding:11px 10px;border-bottom:1px solid #F0F3F8;
    color:var(--text-dark);white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis;
  }
  .genomic-results-table tbody tr:last-child td{border-bottom:none}
  .genomic-results-table tbody tr{cursor:pointer;transition:background .14s}
  .genomic-results-table tbody tr:hover{background:#F0F7FF}
  .genomic-results-table tbody tr.selected{background:#FFF1F2;box-shadow:inset 0 0 0 1px #EF4444}
  .genomic-results-table td.num{text-align:right;font-variant-numeric:tabular-nums}
  .td-name{font-weight:600}
  .td-muted{color:var(--text-muted);font-size:11.5px}
  .description-cell{
    max-width:420px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
    color:var(--text-muted);font-size:11.5px;
  }
  .gr-empty{text-align:center;padding:28px;color:var(--text-muted)}

  .gr-pagination{
    display:flex;align-items:center;justify-content:space-between;
    margin:12px 0 20px;
  }
  .pg-ellipsis{color:var(--text-muted);font-size:12px;padding:0 2px}

  /* 상세 + 해석 */
  .gr-detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
  .result-detail-card,.interpretation-card{
    border:1px solid var(--border);border-radius:10px;background:#fff;padding:16px;
  }
  .rdc-head{display:flex;align-items:center;gap:8px;margin-bottom:14px}
  .rdc-title{font-size:15px;font-weight:700;color:var(--text-dark)}
  .rdc-badge{
    padding:3px 9px;border-radius:999px;
    background:#FFF1F2;color:#EF4444;border:1px solid #FECACA;
    font-size:10.5px;font-weight:600;
  }
  .rdc-list{display:flex;flex-direction:column;gap:8px}
  .rdc-row{display:flex;align-items:baseline;justify-content:space-between;gap:12px;font-size:12px}
  .rdc-row dt{color:var(--text-muted);flex-shrink:0}
  .rdc-row dd{color:var(--text-dark);font-weight:600;text-align:right;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .rdc-desc{margin-top:14px;padding-top:12px;border-top:1px solid var(--border)}
  .rdc-desc-label{font-size:11px;color:var(--text-muted);margin-bottom:5px}
  .rdc-desc p{
    font-size:11.5px;color:var(--text-dark);line-height:1.6;
    display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
    overflow:hidden;
  }

  .interpretation-card h3{font-size:13.5px;font-weight:700;color:var(--text-dark);margin-bottom:14px}
  .ic-headline{
    display:flex;align-items:center;gap:8px;
    font-size:13px;font-weight:700;color:var(--green-tx);margin-bottom:10px;
  }
  .ic-headline.warn{color:#B4690E}
  .ic-check,.ic-alert{
    width:22px;height:22px;flex-shrink:0;border-radius:50%;
    background:var(--green-bg);color:var(--green-tx);
    display:flex;align-items:center;justify-content:center;
  }
  .ic-alert{background:#FEF6E7;color:#B4690E}
  .interpretation-card p{font-size:12px;color:var(--text-muted);line-height:1.65;margin-bottom:6px}
  .risk-badge{
    display:inline-flex;align-items:center;
    margin-top:10px;padding:6px 12px;border-radius:999px;
    background:var(--green-bg);color:var(--green-tx);
    font-size:11.5px;font-weight:700;
  }
  .risk-badge.warn{background:#FEF6E7;color:#B4690E;border:1px solid #F6DFB4}

  /* ===== Sidebar ===== */
  .sidebar{
    width:var(--sidebar-w);flex:0 0 var(--sidebar-w);
    background:var(--white);
    border-right:1px solid var(--border);
    overflow-y:auto;overflow-x:hidden;
    padding:16px 14px 22px;
  }
  /* thin custom scrollbar */
  .sidebar::-webkit-scrollbar{width:8px}
  .sidebar::-webkit-scrollbar-track{background:#F1F3F8;border-radius:8px}
  .sidebar::-webkit-scrollbar-thumb{background:#C9D2E0;border-radius:8px;border:2px solid #F1F3F8}
  .sidebar::-webkit-scrollbar-thumb:hover{background:#B4BFD1}
  .sidebar{scrollbar-width:thin;scrollbar-color:#C9D2E0 #F1F3F8}

  /* 아코디언 헤더 버튼 공통 컴포넌트 (새 분석 시작 / 분석 이력 공용) */
  .new-btn{
    width:100%;min-height:48px;
    display:flex;align-items:center;justify-content:space-between;gap:10px;
    background:var(--blue);color:#fff;
    padding:13px 14px;border-radius:var(--radius);
    font-size:14.5px;font-weight:600;line-height:1.4;
    text-align:left;
    box-shadow:0 6px 16px rgba(11,115,255,.28);
  }
  .accordion-left{
    display:flex;align-items:center;gap:9px;
    flex:1;min-width:0;          /* 텍스트가 길어도 오른쪽 영역을 침범하지 않음 */
  }
  .accordion-icon{display:flex;flex-shrink:0}
  .accordion-icon svg{width:18px;height:18px}
  .accordion-title{
    min-width:0;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
  }
  .accordion-right{
    display:flex;align-items:center;gap:9px;
    flex-shrink:0;               /* pill + chevron은 항상 오른쪽 끝에 고정 */
  }
  .new-btn:hover{background:var(--blue-dark)}
  .new-btn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}

  .form{padding:12px 4px 0}

  /* ----- Compact 2열 레이아웃 ----- */
  .compact-grid-2{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:8px;
  }
  .compact-field{min-width:0}
  .compact-field label{
    display:block;
    font-size:12px;color:var(--text-muted);
    margin-bottom:4px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .compact-field .m-control input,
  .compact-field .m-control select{
    height:36px;padding:0 10px;
    font-size:13px;
    text-overflow:ellipsis;   /* 값/placeholder가 길면 말줄임 */
  }
  /* 오른쪽 아이콘이 있는 컨트롤만 여유 패딩 */
  .compact-field .m-control select,
  #collectionDate{padding-right:28px}
  .compact-field .m-control input::placeholder{font-size:12px}
  .compact-field .m-ic{right:9px}
  .full-width{grid-column:1 / -1}

  /* ----- Accordion (공용) ----- */
  .chevron-icon,.history-chevron-icon{
    display:flex;flex-shrink:0;
    transition:transform .3s cubic-bezier(.4,0,.2,1);
  }
  .chevron-icon svg,.history-chevron-icon svg{width:18px;height:18px}
  /* 닫힘 상태: ∧ 아이콘을 180도 돌려 ∨ 로 */
  .new-analysis-toggle[aria-expanded="false"] .chevron-icon,
  .history-toggle[aria-expanded="false"] .history-chevron-icon{transform:rotate(180deg)}

  /* 권한이 없으면 감춘다. DOM 에서 빼지 않는 이유는 hyperai-main.js 가
     이 안의 요소를 여러 곳에서 참조하기 때문이다. 없애면 그쪽이 깨진다.
     (home.jsp 의 canNewAnalysis 참조) */
  .new-analysis-toggle[hidden],
  .new-analysis-accordion[hidden]{display:none}

  .new-analysis-accordion,
  .history-accordion,
  .sample-metadata-accordion{
    overflow:hidden;
    max-height:0;
    opacity:0;
    visibility:hidden;
    transition:max-height .34s cubic-bezier(.4,0,.2,1),
               opacity .24s ease,
               visibility 0s linear .34s;
  }
  .new-analysis-accordion.is-open,
  .history-accordion.is-open,
  .sample-metadata-accordion.is-open{
    opacity:1;
    visibility:visible;
    transition:max-height .34s cubic-bezier(.4,0,.2,1),
               opacity .24s ease .06s,
               visibility 0s linear 0s;
  }
  /* 열림 완료 후 내부 높이 변화에도 잘리지 않도록 JS가 지정 */
  .new-analysis-accordion.is-settled,
  .history-accordion.is-settled,
  .sample-metadata-accordion.is-settled{max-height:none;overflow:visible}

  @media (prefers-reduced-motion:reduce){
    .new-analysis-accordion,.history-accordion,.sample-metadata-accordion,
    .chevron-icon,.history-chevron-icon,.sample-metadata-chevron{transition:none}
  }

  /* 샘플 정보: 다른 섹션 제목과 동일한 라인 스타일 (박스 없음) */
  .sample-metadata-toggle{
    width:100%;
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    border:none;background:transparent;
    padding:0;min-height:24px;box-shadow:none;border-radius:0;
    text-align:left;cursor:pointer;
  }
  .sample-metadata-toggle .section-title{flex:1;min-width:0;transition:color .14s}
  .sample-metadata-toggle:hover .section-title{color:var(--blue)}
  .sample-metadata-toggle:hover .sample-metadata-chevron{color:var(--blue)}
  .sample-metadata-toggle:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:4px}
  .sample-metadata-chevron{
    display:flex;flex-shrink:0;color:var(--text-muted);
    transition:transform .3s cubic-bezier(.4,0,.2,1),color .14s;
  }
  .sample-metadata-chevron svg{width:17px;height:17px}
  /* 닫힘 상태: ∧ 아이콘을 180도 돌려 ∨ 로 */
  .sample-metadata-toggle[aria-expanded="false"] .sample-metadata-chevron{transform:rotate(180deg)}
  .sample-metadata-accordion{padding-top:0}

  .field-group{margin-top:0;margin-bottom:12px}
  /* 섹션 제목 + 필수 dot + 구분선 */
  .section-header{margin-bottom:0}
  .section-title-row{
    display:flex;align-items:center;gap:6px;min-width:0;
  }
  .section-title{
    font-size:14px;font-weight:700;color:var(--text-dark);
    margin:0;line-height:1.3;text-align:left;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  /* 제목 오른쪽의 작은 빨간 dot (텍스트 없음) */
  .required-dot{
    width:6px;height:6px;flex-shrink:0;
    background:#EF4444;border-radius:50%;
  }
  .section-divider{
    width:100%;height:1px;background:var(--border);
    margin-top:6px;margin-bottom:8px;
  }

  .search-wrap{position:relative}
  .search-wrap input{
    width:100%;height:36px;padding:0 38px 0 13px;
    border:1px solid var(--border);border-radius:var(--radius-sm);
    font-size:13px;color:var(--text-dark);background:var(--white);
  }
  .search-wrap input::placeholder{color:#A6B0C1}
  .search-wrap input:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(11,115,255,.12)}
  .search-wrap .s-ic{position:absolute;right:12px;top:50%;transform:translateY(-50%);color:#A6B0C1}

  .pathogen-selected[hidden]{display:none}

  /* dropzone */
  .dropzone{
    width:100%;
    border:1.6px dashed #C6D5EA;border-radius:var(--radius);
    background:#FAFCFF;
    min-height:0;padding:13px 12px;text-align:center;
    display:flex;flex-direction:column;align-items:center;gap:4px;
    cursor:pointer;
    transition:border-color .15s,background .15s;
  }
  .dropzone:hover{border-color:var(--blue);background:#F4F9FF}
  .dropzone:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .dropzone.is-dragover{border-color:var(--blue);background:var(--light-blue);border-style:dashed}
  .dropzone.is-dragover .up-ic{transform:translateY(-2px)}
  /* 파일이 올라간 동안에는 업로드 영역을 감춘다.
     .dropzone 이 display:flex 라 브라우저 기본 [hidden] 규칙을 이긴다.
     이 줄이 없으면 hidden 을 걸어도 그대로 보인다.
     (.file-info·.file-error-message 도 같은 이유로 각자 규칙을 갖고 있다) */
  .dropzone[hidden]{display:none}
  .dropzone .up-ic{color:var(--blue);margin-bottom:2px;line-height:0;transition:transform .15s}
  .dropzone .dz-main{font-size:12.5px;font-weight:600;color:var(--text-dark)}
  .dropzone .dz-sub{font-size:11px;color:var(--text-muted);line-height:1.45}

  /* file error */
  .file-error-message{
    display:flex;align-items:center;gap:6px;
    margin-top:9px;padding:8px 11px;border-radius:7px;
    background:var(--red-bg);border:1px solid #F8D7D7;
    color:var(--red-tx);font-size:11.5px;font-weight:500;line-height:1.45;
  }
  .file-error-message[hidden]{display:none}

  /* selected file */
  .file-info{
    display:flex;align-items:center;gap:10px;
    margin-top:9px;padding:10px 11px;border-radius:var(--radius-sm);
    background:#F4F9FF;border:1px solid #CFE2FF;
  }
  .file-info[hidden]{display:none}
  .file-info .fi-ic{color:var(--blue);flex-shrink:0;display:flex}
  .file-info .fi-text{min-width:0;flex:1;display:flex;flex-direction:column;gap:3px}
  .file-name{
    font-size:12.5px;font-weight:600;color:var(--text-dark);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .fi-meta{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-muted)}
  .fi-dot{color:#C6D0DE}
  .file-type{font-weight:600;color:var(--blue)}
  .file-remove-btn{
    width:26px;height:26px;flex-shrink:0;border-radius:6px;
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  .file-remove-btn:hover{background:#E4EFFF;color:var(--red-tx)}

  /* metadata inputs */
  .m-field{margin-bottom:8px}
  .m-field:last-child{margin-bottom:0}
  .m-label{display:block;font-size:12px;color:var(--text-muted);margin-bottom:4px}
  .m-control{position:relative}
  .m-control select,.m-control input{
    width:100%;padding:10px 13px;
    border:1px solid var(--border);border-radius:var(--radius-sm);
    font-size:13px;color:var(--text-dark);background:var(--white);
    appearance:none;
  }
  /* 실제 입력/선택된 값은 진한 텍스트, placeholder만 연한 회색 */
  .sidebar input,
  .sidebar select{color:var(--text-dark)}
  .sidebar input::placeholder{color:#9AA8BD}
  .sidebar select.placeholder{color:#9AA8BD}
  .sidebar select:not(.placeholder){color:var(--text-dark)}
  .sidebar select option{color:var(--text-dark)}
  .sidebar select option[value=""]{color:#9AA8BD}
  .m-control select:focus,.m-control input:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(11,115,255,.12)}
  .m-control .m-ic{position:absolute;top:50%;right:12px;transform:translateY(-50%);color:#A6B0C1;pointer-events:none}
  .m-control .m-ic-left{right:auto;left:12px}
  .m-control.has-left input{padding-left:36px}

  #farmRegionCard[hidden]{display:none!important}
  .farm-region-area{fill:rgba(217,119,6,.24);stroke:#B45309;stroke-width:1.2;cursor:pointer;pointer-events:visiblePainted}
  .farm-region-area:hover,.farm-region-area.selected,.farm-region-area:focus{fill:rgba(217,119,6,.5);stroke:#78350F;stroke-width:2.5;outline:none}
  .farm-region-row{display:block;width:100%;padding:10px;text-align:left;background:#fff;border:1px solid #E5E7EB;border-radius:6px;margin:6px 0;cursor:pointer}
  .farm-region-row strong,.farm-region-row span{display:block}
  .farm-region-row span{font-size:11px;color:#64748B;margin-top:5px;line-height:1.5}
  .farm-region-row[aria-pressed="true"],.farm-region-row:focus-visible{border-color:#B45309;background:#FFFBEB;outline:2px solid #B45309}

  /* ----- 분석 조건 설정 ----- */
  .cond-label{display:flex;align-items:center;gap:5px}
  .info-ic{display:inline-flex;color:#A6B0C1;cursor:help}

  /* 현재 지원하는 참조 DB 선택 항목 */
  .reference-db-group{
    display:grid;
    grid-template-columns:minmax(0,1fr);
    gap:8px;
    width:100%;
  }
  .reference-db-checkbox{position:relative;display:block;min-width:0;cursor:pointer;user-select:none}
  .reference-db-checkbox input{position:absolute;opacity:0;width:0;height:0}
  .reference-db-chip{
    box-sizing:border-box;
    width:100%;height:36px;min-width:0;
    display:inline-flex;align-items:center;justify-content:center;gap:5px;
    padding:0 8px;border-radius:8px;
    border:1px solid #DDE5F0;background:#FFFFFF;
    color:var(--text-muted);font-size:13px;font-weight:600;
    white-space:nowrap;
    transition:border-color .14s,background .14s,color .14s;
  }
  .reference-db-chip:hover{border-color:#CFE2FF}
  .chip-check{
    display:inline-flex;width:14px;height:14px;flex-shrink:0;
    color:#C6D0DE;transition:color .14s;
  }
  .chip-check svg{width:14px;height:14px}
  /* 선택 상태 */
  .reference-db-checkbox input:checked + .reference-db-chip{
    border-color:var(--blue);background:#F0F7FF;color:var(--blue);
  }
  .reference-db-checkbox input:checked + .reference-db-chip .chip-check{color:var(--blue)}
  .reference-db-checkbox input:focus-visible + .reference-db-chip{box-shadow:0 0 0 3px rgba(11,115,255,.18)}
  /* 비활성 상태: 아직 연동되지 않은 참조 DB.
     label 에 클래스를 따로 두는 이유는 :has(input:disabled) 를 피하기 위해서다.
     커서는 label 이 쥐고 있어 input 만으로는 바꿀 수 없다. */
  .reference-db-checkbox.is-disabled{cursor:not-allowed}
  .reference-db-checkbox input:disabled + .reference-db-chip{
    border-color:#E8EDF4;background:#F5F7FA;color:#AEB8C7;
  }
  /* 못 고르는 항목에 hover 반응이 남아 있으면 눌러도 되는 것처럼 보인다 */
  .reference-db-checkbox input:disabled + .reference-db-chip:hover{border-color:#E8EDF4}
  .reference-db-checkbox input:disabled + .reference-db-chip .chip-check{color:#DCE3EC}

  /* 사이드바의 수집 일자 입력은 브라우저 기본 달력을 사용한다. */

  /* Chrome 은 내부 여백과 최소 너비를 따로 잡아서, 좁은 사이드바에서
     값이 잘리거나 아이콘과 겹친다. */
  .sidebar input[type=date]::-webkit-datetime-edit{padding:0}
  .sidebar input[type=date]::-webkit-inner-spin-button{display:none}
  /* 브라우저 기본 달력 버튼을 투명하게 만들어 우리 아이콘(.m-ic) 위에
     겹쳐 둔다. 보이는 것은 우리 아이콘이고, 실제로 눌리는 것은 이 기본 버튼이다.
     직접 달력을 만들지 않고 브라우저 것을 그대로 쓰기 위한 배치다.
     30px 는 두 아이콘(오른쪽에서 9px·12px 자리)을 모두 덮는 폭이다. */
  .sidebar input[type=date]::-webkit-calendar-picker-indicator{
    position:absolute;right:0;top:0;
    width:30px;height:100%;margin:0;padding:0;
    opacity:0;cursor:pointer;
  }
  .sidebar input[type=date]:disabled::-webkit-calendar-picker-indicator{cursor:not-allowed}
  /* :not(:focus) 가 꼭 필요하다.
     type=date 는 연·월·일 중 일부만 채워진 상태도 invalid(badInput)로 본다.
     이 조건이 없으면 날짜를 한 칸씩 채워 넣는 동안 칸이 붉어졌다 돌아온다.
     아직 입력 중인 사람에게 틀렸다고 말하는 셈이라, 칸을 떠난 뒤에 알린다.
     그 사이에도 실행 버튼은 잠겨 있으므로 잘못된 값이 그냥 넘어가지는 않는다.

     required 를 걸지 않았으므로 빈 값은 invalid 가 아니다. */
  .sidebar input[type=date]:invalid:not(:focus){
    border-color:var(--red-tx);background:var(--red-bg);
  }
  /* run button */
  .run-btn{
    width:100%;height:44px;margin-top:10px;
    display:flex;align-items:center;justify-content:center;gap:8px;
    padding:0 12px;border-radius:var(--radius);
    background:#EDF0F5;color:#A6B0C1;
    font-size:14px;font-weight:600;cursor:not-allowed;
  }
  .run-btn.is-active{
    background:var(--blue);color:#fff;cursor:pointer;
    box-shadow:0 6px 16px rgba(11,115,255,.28);
  }
  .run-btn.is-active:hover{background:var(--blue-dark)}
  .run-hint{text-align:center;font-size:11.5px;color:#A6B0C1;margin-top:6px}
  .run-hint.is-active{color:var(--blue)}

  /* divider before history */
  .sec-divider{height:1px;background:var(--border);margin:22px 0 0}

  /* History */
  .history{margin-top:22px}
  /* 버튼은 .new-btn 컴포넌트를 그대로 공유한다 (크기 오버라이드 없음) */
  .history-count-pill{
    flex-shrink:0;
    padding:3px 9px;border-radius:999px;
    background:rgba(255,255,255,.22);
    color:#fff;font-size:11px;font-weight:600;line-height:1.4;
    white-space:nowrap;
  }
  .history-accordion{padding-top:14px}

  .history-search{margin-bottom:12px}
  .history-search .search-wrap{width:100%}

  .status-filters{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}
  .sf{
    padding:5px 12px;border-radius:999px;font-size:12px;font-weight:500;
    border:1px solid var(--border);color:var(--text-muted);background:#fff;
  }
  .sf.active{background:var(--light-blue);border-color:#CFE2FF;color:var(--blue);font-weight:600}
  .sf:hover:not(.active){background:#F3F6FC}

  .hist-list{display:flex;flex-direction:column;gap:9px}
  .hist-empty{
    padding:28px 10px;text-align:center;
    color:var(--text-muted);font-size:12px;
    border:1px dashed var(--border);border-radius:var(--radius);background:#FAFCFF;
  }
  .history-item{
    position:relative;overflow:hidden;
    border:1px solid var(--border);border-radius:var(--radius);
    background:#fff;padding:11px 12px;
    display:flex;align-items:center;justify-content:space-between;gap:10px;
    cursor:pointer;transition:border-color .15s,background .15s;
  }
  .history-item:hover{border-color:#CFE2FF}
  .history-item.selected{border-color:var(--blue);background:#F4F9FF}
  /* 왼쪽 파란 강조선 */
  .history-item.selected::before{
    content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
    background:var(--blue);border-radius:3px 0 0 3px;
  }
  .history-item.selected .hc-left{padding-left:5px}
  .history-item .hc-left{min-width:0;transition:padding-left .15s}
  .hc-name{font-size:13px;font-weight:600;color:var(--text-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .hc-id{font-size:11px;color:var(--text-muted);margin-top:3px}
  .history-item .hc-right{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex-shrink:0}
  .hc-date{font-size:11px;color:var(--text-muted);white-space:nowrap}
  .badge-status{padding:3px 9px;border-radius:999px;font-size:11px;font-weight:600}
  .b-done{background:var(--green-bg);color:var(--green-tx)}
  .b-run{background:var(--blue-bg);color:var(--blue-tx)}
  .b-fail{background:var(--red-bg);color:var(--red-tx)}

  /* pagination */
  .pagination{display:flex;align-items:center;justify-content:space-between;margin-top:16px}
  .page-info{font-size:12px;color:var(--text-muted)}
  .page-btns{display:flex;align-items:center;gap:4px}
  .pg{
    min-width:28px;height:28px;padding:0 6px;border-radius:7px;
    display:flex;align-items:center;justify-content:center;
    font-size:12.5px;color:var(--text-muted);border:1px solid transparent;
  }
  .pg:hover{background:#F3F6FC}
  .pg.active{background:var(--blue);color:#fff;font-weight:600}
  .pg.arrow{color:var(--text-muted)}

  /* ===== Map (OpenLayers 배경지도 + SVG 오버레이) =====
     배경지도는 .basemap-canvas 가, 분석 결과 표출은 그 위의
     .svg-world-map 이 담당한다. pan/zoom 은 OpenLayers 가 처리하므로
     SVG 는 포인터 이벤트를 통과시키고, 클릭 대상만 되살린다. */
  .map-area{
    position:relative;
    flex:1;min-width:0;
    height:calc(100vh - var(--header-h));
    overflow:hidden;
    background:#EAF4FF;
  }
  .svg-map-viewport{
    position:absolute;inset:0;z-index:1;
    touch-action:none;
  }
  .basemap-canvas{
    position:absolute;inset:0;z-index:0;
    background:#EAF4FF;
  }
  .basemap-canvas .ol-viewport{cursor:grab}
  .basemap-canvas .ol-viewport:active{cursor:grabbing}
  .svg-world-map{
    position:absolute;inset:0;z-index:1;
    width:100%;height:100%;display:block;
    pointer-events:none;
  }
  /* 지도 위에서 클릭·호버가 필요한 요소만 이벤트를 받는다.
     나머지 빈 영역의 클릭은 아래 배경지도로 통과시킨다. */
  .svg-world-map .map-point-group,
  .svg-world-map .map-point-hit,
  .svg-world-map .spatial-fixed-point,
  .svg-world-map [data-feature-type]{pointer-events:auto}
  /* 본 지도의 배경은 배경지도 타일이 담당하므로 목업 SVG 지형은 감춘다.
     대시보드 미니맵(#dashMiniMap)은 이 지형 path 를 복제해 쓰므로
     .svg-world-map 안쪽에만 적용한다. */
  .svg-world-map .world-ocean,
  .svg-world-map .world-land-layer{display:none}
  /* 국가 경계 */
  .world-land{
    fill:#FFFFFF;
    stroke:#CFE0F3;
    stroke-width:.6;
    vector-effect:non-scaling-stroke;
  }
  /* 해안선 */
  .world-coast{
    fill:none;
    stroke:#C2D8EF;
    stroke-width:1;
    stroke-linejoin:round;
    vector-effect:non-scaling-stroke;
  }

  /* 포인트 (색상·반지름은 JS가 줌 배율에 맞춰 지정) */
  .map-point-group{cursor:pointer}
  .map-point-group circle{transition:r .16s ease}
  .map-point-group:focus-visible{outline:none}
  .map-point-group:focus-visible .map-point-core{stroke:#17233C}
  .map-point-group:hover .map-point-core{stroke:#17233C}

  /* 포인트 팝업 — 헤더/패널보다 위 */
  .map-popup{
    position:fixed;z-index:999;
    min-width:200px;max-width:260px;
    padding:12px 14px;border-radius:10px;
    background:#fff;border:1px solid var(--border);
    box-shadow:0 14px 32px rgba(17,35,60,.20);
    font-size:12px;line-height:1.6;color:var(--text-dark);
  }
  .map-popup[hidden]{display:none}
  .mt-close{
    position:absolute;top:7px;right:7px;
    width:22px;height:22px;border-radius:6px;
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  .mt-close:hover{background:#F3F6FC;color:var(--text-dark)}
  .mt-title{font-size:13px;font-weight:700;margin-bottom:2px;padding-right:22px}
  .mt-sub{font-size:11px;color:var(--blue);font-weight:600;margin-bottom:8px}
  .map-popup dl{display:grid;grid-template-columns:auto 1fr;gap:3px 12px;margin:0}
  .map-popup dt{color:var(--text-muted);white-space:nowrap}
  .map-popup dd{margin:0;font-weight:600;text-align:right}
  /* 위험 지역 팝업: 넓은 폭 + label/value 2열 그리드 */
  .risk-popup{width:344px;max-width:380px;padding:16px}
  .risk-popup .mt-title{padding-right:26px}
  .risk-popup-body{display:flex;flex-direction:column;gap:8px;margin-top:2px}
  .risk-popup-row{display:grid;grid-template-columns:104px 1fr;column-gap:12px;align-items:start}
  .risk-popup-label{color:#6B7894;font-size:12px;line-height:1.5}
  .risk-popup-value{
    color:#17233C;font-size:12px;font-weight:600;line-height:1.5;word-break:keep-all;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  }

  /* 지도 위 오버레이 계층 */
  .map-legend{z-index:150}
  .map-legend[hidden]{display:none}
  .map-controls{z-index:150}

  .map-controls{
    position:absolute;bottom:24px;right:20px;
    display:flex;flex-direction:column;
    background:#fff;border:1px solid var(--border);border-radius:10px;
    box-shadow:0 4px 14px rgba(17,35,60,.08);overflow:hidden;
  }
  .map-controls button{
    width:40px;height:40px;display:flex;align-items:center;justify-content:center;
    color:var(--text-muted);border-bottom:1px solid var(--border);
  }
  .map-controls button:last-child{border-bottom:none}
  .map-controls button:hover{background:#F3F6FC;color:var(--blue)}

  .legend{
    position:absolute;left:20px;bottom:20px;
    background:#fff;border:1px solid var(--border);border-radius:12px;
    box-shadow:0 6px 18px rgba(17,35,60,.08);
    padding:14px 16px;display:flex;flex-direction:column;gap:10px;
  }
  .legend .lg-row[hidden]{display:none}
  .legend .lg-row{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--text-dark)}
  .legend .lg-dot{width:11px;height:11px;border-radius:50%}
  .lg-dot.strong{background:var(--pt-strong)}
  .lg-dot.soft{background:var(--pt-soft)}
  .lg-dot.selected{background:var(--pt-selected)}


  @media (prefers-reduced-motion:no-preference){
    .new-btn,.run-btn{transition:background .15s}
  }

  /* ===== Pathogen Modal ===== */
  .pathogen-search-input{cursor:pointer}
  .pathogen-search-trigger{cursor:pointer}
  .pathogen-search-trigger:hover{color:var(--blue)}

  .pathogen-selected{
    display:flex;align-items:center;gap:6px;min-height:29px;
    margin-top:6px;padding:4px 9px;border-radius:7px;
    background:var(--light-blue);border:1px solid #D5E4FF;
    color:var(--blue);font-size:11.5px;font-weight:600;
  }

  .pathogen-modal-overlay{
    position:fixed;inset:0;z-index:1100;
    background:rgba(17,35,60,.48);
    display:flex;align-items:center;justify-content:center;
    padding:24px;
    animation:pmFade .18s ease;
  }
  .pathogen-modal-overlay[hidden]{display:none}
  @keyframes pmFade{from{opacity:0}to{opacity:1}}
  @keyframes pmRise{from{opacity:0;transform:translateY(10px) scale(.985)}to{opacity:1;transform:none}}

  .pathogen-modal{
    width:720px;max-width:calc(100vw - 48px);max-height:calc(100vh - 48px);
    background:#fff;border:1px solid var(--border);border-radius:12px;
    box-shadow:0 24px 60px rgba(17,35,60,.24);
    display:flex;flex-direction:column;overflow:hidden;
    animation:pmRise .22s cubic-bezier(.4,0,.2,1);
  }
  @media (prefers-reduced-motion:reduce){
    .pathogen-modal-overlay,.pathogen-modal{animation:none}
  }

  .pm-head{
    display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
    padding:22px 24px 18px;border-bottom:1px solid var(--border);
  }
  .pm-head h2{font-size:17px;font-weight:700;color:var(--text-dark)}
  .pm-head p{font-size:12.5px;color:var(--text-muted);margin-top:6px}
  .pathogen-modal-close{
    width:34px;height:34px;flex-shrink:0;border-radius:8px;
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  .pathogen-modal-close:hover{background:#F3F6FC;color:var(--text-dark)}

  .pm-body{padding:20px 24px 4px;overflow-y:auto}
  .pm-search{position:relative}
  .pm-search input{
    width:100%;padding:13px 14px 13px 44px;
    border:1px solid var(--border);border-radius:var(--radius);
    font-size:14px;color:var(--text-dark);background:#FAFCFF;
  }
  .pm-search input::placeholder{color:#A6B0C1}
  .pm-search input:focus{outline:none;border-color:var(--blue);background:#fff;box-shadow:0 0 0 3px rgba(11,115,255,.12)}
  .pm-search-ic{position:absolute;left:15px;top:50%;transform:translateY(-50%);color:#A6B0C1;pointer-events:none}
  .pm-hint{font-size:11.5px;color:var(--text-muted);margin:8px 2px 16px}

  .pathogen-list{display:flex;flex-direction:column;gap:8px;padding-bottom:18px}
  .pathogen-item{
    display:flex;align-items:center;justify-content:space-between;gap:14px;
    width:100%;text-align:left;
    padding:13px 15px;border:1px solid var(--border);border-radius:var(--radius);
    background:#fff;cursor:pointer;
    transition:background .14s,border-color .14s;
  }
  .pathogen-item:hover{background:var(--light-blue);border-color:#CFE2FF}
  .pathogen-item.selected{background:#F4F9FF;border-color:var(--blue);box-shadow:0 0 0 1px var(--blue) inset}
  .pathogen-item:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .pi-left{display:flex;flex-direction:column;min-width:0}
  .pi-name{font-size:14px;font-weight:600;color:var(--text-dark)}
  .pi-desc{font-size:12px;color:var(--text-muted);margin-top:4px}
  .pi-acc{font-size:11px;color:#A6B0C1;margin-top:5px;font-family:"Inter",monospace}
  .pi-right{display:flex;align-items:center;gap:10px;flex-shrink:0}
  .pi-badge{
    padding:3px 10px;border-radius:999px;
    background:var(--blue-bg);color:var(--blue-tx);
    font-size:11px;font-weight:600;
  }
  .pi-check{color:var(--blue);opacity:0}
  .pathogen-item.selected .pi-check{opacity:1}

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

  .pm-foot{
    display:flex;justify-content:flex-end;gap:10px;
    padding:16px 24px;border-top:1px solid var(--border);background:#FCFDFF;
  }
  .pathogen-cancel-btn,.pathogen-confirm-btn{
    padding:11px 22px;border-radius:var(--radius-sm);
    font-size:13.5px;font-weight:600;
  }
  .pathogen-cancel-btn{border:1px solid var(--border);background:#fff;color:var(--text-muted)}
  .pathogen-cancel-btn:hover{background:#F3F6FC;color:var(--text-dark)}
  .pathogen-confirm-btn{background:var(--blue);color:#fff}
  .pathogen-confirm-btn:hover:not(:disabled){background:var(--blue-dark)}
  .pathogen-confirm-btn:disabled{background:#EDF0F5;color:#A6B0C1;cursor:not-allowed}

  /* ===== Spatial Analysis Panel ===== */
  .spatial-panel{
    position:absolute;
    left:var(--sidebar-w);
    top:0;height:100%;
    width:var(--spatial-panel-width);
    max-width:calc(100vw - var(--sidebar-w) - 40px);
    z-index:200;
    display:flex;flex-direction:column;
    background:var(--white);
    border-right:1px solid var(--border);
    box-shadow:14px 0 34px rgba(17,35,60,.12);
    opacity:0;transform:translateX(-14px);
    pointer-events:none;visibility:hidden;
    transition:opacity .26s ease,transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .3s;
  }
  .spatial-panel.is-open{
    opacity:1;transform:none;pointer-events:auto;visibility:visible;
    transition:opacity .26s ease,transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear 0s;
  }
  @media (prefers-reduced-motion:reduce){.spatial-panel{transition:none}}

  .sp-head{
    display:flex;align-items:flex-start;gap:10px;
    padding:18px 18px 15px;border-bottom:1px solid var(--border);flex-shrink:0;
  }
  .sp-head-text{flex:1;min-width:0}
  .spatial-back-btn{
    width:28px;height:28px;flex-shrink:0;
    display:flex;align-items:center;justify-content:center;
    border-radius:8px;background:transparent;color:#334155;
    cursor:pointer;transition:background .14s,color .14s;
  }
  .spatial-back-btn:hover{background:var(--light-blue);color:var(--blue)}
  .spatial-back-btn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .sp-head h2{
    display:flex;align-items:center;gap:6px;
    font-size:14px;font-weight:700;color:var(--text-dark);
    white-space:nowrap;
  }
  .sp-info{display:inline-flex;color:#A6B0C1;cursor:help}
  .sp-head p{font-size:11.5px;color:var(--text-muted);margin-top:5px}
  .spatial-panel-close{
    width:30px;height:30px;flex-shrink:0;border-radius:8px;
    display:flex;align-items:center;justify-content:center;color:var(--text-muted);
  }
  .spatial-panel-close:hover{background:#F3F6FC;color:var(--text-dark)}

  .sp-body{flex:1;overflow-y:auto;padding:14px 16px 20px;display:flex;flex-direction:column;gap:10px}
  .sp-body::-webkit-scrollbar{width:8px}
  .sp-body::-webkit-scrollbar-track{background:#F1F3F8;border-radius:8px}
  .sp-body::-webkit-scrollbar-thumb{background:#C9D2E0;border-radius:8px;border:2px solid #F1F3F8}

  .sp-card{border:1px solid var(--border);border-radius:10px;background:#fff;padding:12px 13px}
  .sp-card-head{display:flex;align-items:center;gap:8px;margin-bottom:10px}
  .sp-ic{
    width:26px;height:26px;flex-shrink:0;border-radius:8px;
    display:flex;align-items:center;justify-content:center;
  }
  .sp-ic.red{background:#FEF2F2;color:#EF4444}
  .sp-ic.blue{background:var(--light-blue);color:var(--blue)}
  .sp-ic.orange{background:#FFF4E8;color:#F97316}
  .sp-ic.teal{background:#E6FAF7;color:#14B8A6}
  .sp-ic.purple{background:#F5EDFF;color:#A855F7}
  .sp-title{font-size:12.5px;font-weight:700;color:var(--text-dark);min-width:0}
  .sp-title em{font-style:normal;font-weight:500;color:var(--text-muted);font-size:11px}

  .sp-kv .k{font-size:11px;color:var(--text-muted)}
  .sp-source{font-size:14px;font-weight:700;color:#EF4444;margin:4px 0 10px}
  .sp-conf{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
  .sp-conf .k{font-size:11.5px;color:var(--text-muted)}
  .sp-conf .v.red{font-size:13px;font-weight:700;color:#EF4444}
  .sp-bar{height:6px;border-radius:999px;background:#F1F3F8;overflow:hidden}
  .sp-bar-fill.red{height:100%;border-radius:999px;background:linear-gradient(90deg,#F87171,#EF4444)}

  .sp-list{display:flex;flex-direction:column;gap:6px}
  .sp-list div{display:flex;align-items:center;justify-content:space-between;gap:10px}
  .sp-list dt{font-size:11.5px;color:var(--text-muted);flex-shrink:0}
  .sp-list dd{margin:0;font-size:12px;font-weight:600;color:var(--text-dark);text-align:right}
  .sp-list dd.blue{color:var(--blue)}
  .sp-list dd.orange{color:#F97316}
  .sp-list dd.teal{color:#14B8A6}
  .sp-list dd.purple{color:#A855F7}
  .sp-list dd.link{cursor:pointer}
  .sp-list dd.link:hover{text-decoration:underline}
  .sp-list dd.occ-red{color:#EF4444}
  /* 발생 지점 요약 카드 */
  #occurrenceSummaryCard{transition:border-color .16s,box-shadow .16s}
  #occurrenceSummaryCard.selected{border-color:#EF4444;box-shadow:0 0 0 2px rgba(239,68,68,.14)}
  .occ-layer-status{
    margin-left:auto;flex-shrink:0;font-size:9px;font-weight:600;
    padding:2px 7px;border-radius:999px;background:#FEF2F2;color:#EF4444;white-space:nowrap;
  }
  .occ-layer-status.off{background:#F1F3F8;color:var(--text-muted)}
  .occ-selected{
    margin-top:9px;padding-top:8px;border-top:1px dashed var(--border);
    display:flex;align-items:center;gap:8px;font-size:11px;flex-wrap:wrap;
  }
  .occ-selected .k{color:var(--text-muted)}
  .occ-selected .v{font-weight:700;color:var(--text-dark)}
  .occ-risk{padding:2px 7px;border-radius:999px;font-size:9.5px;font-weight:700}
  .occ-risk.HIGH{background:var(--red-bg);color:var(--red-tx)}
  .occ-risk.MEDIUM{background:#FFF4E8;color:#C2410C}
  .occ-risk.LOW{background:var(--green-bg);color:var(--green-tx)}
  .occurrence-dot{cursor:pointer}
  /* 관측 위치 선택: 점 모양은 그대로 두고 흰색 간격 + 얇은 빨간 외곽 링만 추가 (타깃형으로 바뀌지 않게) */
  .occurrence-dot.selected{stroke:#fff;stroke-width:1;filter:none}
  .risk-region-heat{cursor:pointer}
  .chip-blue{
    display:inline-flex;padding:2px 8px;border-radius:999px;
    background:var(--light-blue);color:var(--blue);
    font-size:10.5px;font-weight:700;
  }
  .sp-warn{
    margin-top:10px;padding:6px 10px;border-radius:999px;
    background:#FEF6E7;color:#B4690E;border:1px solid #F6DFB4;
    font-size:10.5px;font-weight:700;text-align:center;
  }
  .sp-season{
    margin-top:10px;padding:6px 10px;border-radius:999px;
    background:#FFF4E8;color:#C2410C;border:1px solid #FBD9BC;
    font-size:10.5px;font-weight:700;text-align:center;
  }

  /* 상위 위험 지역 테이블 */
  .risk-table{width:100%;border-collapse:collapse;font-size:11px}
  .risk-table th{
    background:#F5F7FB;color:var(--text-muted);font-weight:600;
    text-align:left;padding:7px 8px;border-bottom:1px solid var(--border);white-space:nowrap;
  }
  .risk-table td{padding:8px;border-bottom:1px solid #F0F3F8;color:var(--text-dark);vertical-align:middle}
  .risk-table tbody tr:last-child td{border-bottom:none}
  /* 위험 지역 목록: 전체 7개 표시 + 필요 시 내부 세로 스크롤 */
  .risk-region-list-table-wrap{max-height:260px;overflow-y:auto;margin-top:10px}
  .risk-region-list-table-wrap thead th{position:sticky;top:0;z-index:1}
  .risk-table td:nth-child(2){white-space:normal;word-break:keep-all}
  .rr-reason{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .rr-score{display:inline-flex;align-items:center;gap:5px;font-weight:700;font-size:10.5px;white-space:nowrap}
  .rr-score.lv-HIGH{color:#E04646}
  .rr-score.lv-MEDIUM{color:#C2410C}
  .rr-score.lv-LOW{color:#1E874B}
  .rr-scorebar{width:26px;height:5px;border-radius:999px;background:#EEF1F6;overflow:hidden;flex-shrink:0}
  .rr-scorebar i{display:block;height:100%;border-radius:999px;background:currentColor}
  .risk-region-list-table-wrap th.rr-sort{cursor:pointer;user-select:none;white-space:nowrap}
  .risk-region-list-table-wrap th.rr-sort:hover{color:var(--blue)}
  .rr-arrow{font-size:9px;color:var(--blue)}
  .rr-hint{margin-top:8px;font-size:9.5px;color:#A6B0C1;line-height:1.5}
  .info-pop{position:relative;display:inline-flex;margin-left:4px;vertical-align:middle}
  .info-pop-btn{display:inline-flex;color:#A6B0C1;cursor:pointer;padding:0;background:none;border:none}
  .info-pop-btn:hover{color:var(--blue)}
  .info-pop-body{position:absolute;top:130%;left:0;z-index:40;width:220px;padding:9px 11px;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 8px 22px rgba(17,35,60,.16);font-size:10.5px;line-height:1.55;color:var(--text-dark);display:none}
  .info-pop:hover .info-pop-body,.info-pop.open .info-pop-body{display:block}
  /* 상위 위험 지역 row 선택/hover 연동 */
  .risk-table tbody tr{cursor:pointer;transition:background .12s}
  .risk-table tbody tr:hover td{background:#F7FAFF}
  .risk-table tbody tr.selected td{background:#EFF6FF}
  .risk-table tbody tr.selected td:first-child{box-shadow:inset 3px 0 0 #0B73FF}
  .risk-table td:last-child{color:var(--text-muted);font-size:10.5px}
  .risk-badge{padding:2px 7px;border-radius:999px;font-size:9.5px;font-weight:700;white-space:nowrap}
  .risk-badge.HIGH{background:var(--red-bg);color:var(--red-tx)}
  .risk-badge.MEDIUM{background:#FFF4E8;color:#C2410C}
  .risk-badge.LOW{background:var(--green-bg);color:var(--green-tx)}

  /* ===== 레이어 패널 ===== */
  .layers-panel{
    position:absolute;top:20px;right:20px;z-index:170;
    width:clamp(360px,22vw,410px);max-width:calc(100% - 40px);padding:12px 13px;
    background:#fff;border:1px solid var(--border);border-radius:12px;
    box-shadow:0 8px 22px rgba(17,35,60,.10);
  }
  .layers-panel[hidden]{display:none}
  .lp-title{font-size:12px;font-weight:700;color:var(--text-dark);margin-bottom:10px;display:flex;align-items:center;gap:6px}
  .lp-title-text{flex:1;min-width:0}
  /* 레이어 표출 순서 편집 토글 (순서 변경 / 완료) */
  .lp-orderbtn{flex-shrink:0;padding:3px 8px;border:1px solid #DCE6F7;border-radius:6px;background:#fff;
    color:#41506A;font-size:10px;font-weight:700;line-height:1.3;cursor:pointer;transition:.12s;white-space:nowrap}
  .lp-orderbtn:hover{background:#EEF3FB;border-color:var(--blue);color:var(--blue)}
  .lp-orderbtn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(11,115,255,.18)}
  .lp-orderbtn.is-editing{background:var(--blue);border-color:var(--blue);color:#fff}
  /* flex-wrap 이 없으면 아래 .lp-note 가 레이어 이름과 같은 줄에 끼어 겹친다. */
  .lp-row{display:flex;flex-wrap:wrap;align-items:center;column-gap:6px;row-gap:0;padding:4px 0;user-select:none;position:relative}
  .lp-rowmain{display:flex;align-items:center;gap:7px;flex:1;min-width:0;cursor:pointer}
  /* 드래그 핸들: 기본 상태에서는 숨김, 순서 변경 모드에서만 표시 */
  .lp-handle{display:none;flex-shrink:0;width:15px;height:18px;align-items:center;justify-content:center;
    color:#A6B0C1;cursor:grab;border-radius:4px;touch-action:none}
  .layers-panel.lp-editing .lp-handle{display:flex}
  .lp-handle:hover{color:var(--blue);background:#EEF3FB}
  .lp-handle:active{cursor:grabbing}
  .layers-panel.lp-editing .lp-rowmain{cursor:default}
  .lp-row.lp-dragging{opacity:.45;background:#EEF3FB;border-radius:6px}
  /* 드롭 위치 표시선 (absolute → 드래그 중 레이아웃이 흔들리지 않음) */
  .lp-sec{position:relative}
  .lp-dropline{position:absolute;left:0;right:0;height:0;pointer-events:none;
    border-top:2px solid var(--blue);border-radius:2px;box-shadow:0 0 0 2px rgba(11,115,255,.14)}
  .lp-sec.lp-drop-active{background:rgba(11,115,255,.05);border-radius:7px}
  .lp-row input{position:absolute;opacity:0;width:0;height:0}
  .lp-box{
    width:14px;height:14px;flex-shrink:0;border-radius:4px;
    border:1.5px solid #C6D5EA;background:#fff;
    display:flex;align-items:center;justify-content:center;
    transition:background .14s,border-color .14s;
  }
  .lp-box::after{
    content:"";width:7px;height:4px;
    border-left:2px solid #fff;border-bottom:2px solid #fff;
    transform:rotate(-45deg) translateY(-1px) scale(.6);
    opacity:0;transition:opacity .14s,transform .14s;
  }
  .lp-row input:checked + .lp-box{background:var(--blue);border-color:var(--blue)}
  .lp-row input:checked + .lp-box::after{opacity:1;transform:rotate(-45deg) translateY(-1px) scale(1)}
  .lp-row input:focus-visible + .lp-box{box-shadow:0 0 0 3px rgba(11,115,255,.18)}
  .lp-name{flex:1;min-width:0;font-size:11px;color:var(--text-dark);white-space:normal;overflow:visible;text-overflow:clip;word-break:keep-all;line-height:1.35}
  .lp-ic{display:flex;align-items:center;flex-shrink:0}
  .lp-ic-group{gap:6px}
  .lp-en{display:block;font-style:normal;font-size:9px;font-weight:500;color:var(--text-muted);margin-top:1px}

  .dot{width:7px;height:7px;border-radius:50%;display:inline-block;flex-shrink:0}
  .dot.red{background:#F43F5E}          /* HIGH */
  .dot.orange{background:#F97316}       /* MEDIUM */
  .dot.green{background:#22C55E}        /* LOW */
  .dot.occurrence{background:#EF4444}   /* 국내외 발생·유사 서열 관측 위치 */
  .target-ic{
    width:11px;height:11px;border-radius:50%;
    border:2px solid #FF3B30;background:#FF3B30;
    box-shadow:0 0 0 2px #fff, 0 0 0 4px rgba(255,59,48,.22);
  }
  .blur-ic{
    width:13px;height:13px;border-radius:50%;
    background:radial-gradient(circle, rgba(244,63,94,.55), rgba(244,63,94,0));
  }
  .zone-ic{width:12px;height:12px;border-radius:50%;flex-shrink:0}
  .zone-ic.climate{background:rgba(168,85,247,.20);border:1px solid rgba(168,85,247,.35)}
  .zone-ic.wetland{background:rgba(20,184,166,.18);border:1px solid rgba(20,184,166,.30)}

  /* ===== 공간 분석 범례 ===== */
  .spatial-legend{
    position:absolute;left:24px;bottom:24px;z-index:160;
    display:flex;flex-direction:column;gap:10px;
    width:212px;max-height:calc(100% - 120px);overflow:auto;
    padding:12px 14px;
    background:#fff;border:1px solid var(--border);border-radius:12px;
    box-shadow:0 8px 22px rgba(17,35,60,.10);
  }
  .spatial-legend[hidden]{display:none}
  /* 공간 분석 패널이 열려 있을 때: 패널 오른쪽 경계에서 24px 떨어진 위치 */
  .spatial-legend.spatial-mode{
    left:calc(var(--spatial-panel-width) + 24px);
    max-width:calc(100% - var(--spatial-panel-width) - 48px);
  }
  /* 폭이 부족하면 항목이 2줄로 wrap될 뿐, 패널을 침범하지 않는다 */
  .spatial-legend.spatial-mode .sl-div{align-self:stretch}
  .sl-div{height:1px;width:100%;background:var(--border);margin:2px 0}
  .sl-title{font-size:10.5px;font-weight:700;color:var(--text-dark);margin-bottom:7px}
  .sl-items{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
  .sl-item{display:inline-flex;align-items:center;gap:6px;font-size:10.5px;color:var(--text-muted)}
  .sl-note{margin-top:6px;font-size:9.5px;color:#A6B0C1}

  /* ===== 공간 분석 지도 레이어 =====
     같은 빨강 계열이라도 역할이 다르게 보이도록 크기·형태·투명도까지 구분한다.
     발생·관측 위치 = 작고 단순한 점 / 후보 기준 위치 = 타깃형 마커 / 상대 위험 높음 = 넓은 반투명 영역 */
  /* 국내외 발생·유사 서열 관측 위치: 작은 빨간 채움 점 (번호·십자·동심원 없음) */
  .occurrence-dot{
    fill:#EF4444;stroke:#FFFFFF;stroke-width:1;opacity:.95;
    vector-effect:non-scaling-stroke;
  }
  /* 확산 가능 경로 후보: 관측 위치 간 연결조건을 점선으로 표시한다 */
  .spread-route{
    fill:none;stroke:#2563EB;stroke-width:1.8;
    stroke-dasharray:8 6;stroke-linecap:round;opacity:.75;
    vector-effect:non-scaling-stroke;
  }
  /* 위험 지역 cluster: 진한 배경 + 흰 외곽선 (대형 그림자·radial-gradient 제거) */
  .risk-cluster circle{
    stroke:#FFFFFF;stroke-width:2;
    filter:none;
    vector-effect:non-scaling-stroke;
  }
  .risk-cluster.HIGH circle{fill:#F43F5E}
  .risk-cluster.MEDIUM circle{fill:#F97316}
  .risk-cluster.LOW circle{fill:#22C55E}
  /* 위험 우선지역 후보: 마커별 작은 반투명 halo (화면 고정 크기, blur 없음, 서로 섞이지 않음) */
  .risk-cluster circle.risk-halo{opacity:.15;filter:none;stroke:none;pointer-events:none}
  .risk-cluster.selected circle.risk-halo{opacity:.2}
  /* 위험 지역 cluster 선택 강조 */
  .risk-cluster{cursor:pointer}
  .risk-cluster.selected circle{stroke:#fff;stroke-width:2.6}
  .risk-cluster text{
    fill:#fff;font-size:9.5px;font-weight:800;letter-spacing:-.2px;
    text-anchor:middle;dominant-baseline:central;pointer-events:none;
  }
  /* 최초 관측지역·발원지 후보: 주황 채움 원 + 중앙 흰색 순위 번호 (타깃형 심벌 사용 안 함) */
  .source-marker{cursor:pointer}
  .source-core{fill:#F97316;stroke:#FFFFFF;stroke-width:2;vector-effect:non-scaling-stroke}
  .source-num{
    font-size:8.5px;font-weight:800;fill:#fff;text-anchor:middle;dominant-baseline:central;
    pointer-events:none;paint-order:stroke;stroke:#C2410C;stroke-width:.7;stroke-linejoin:round;
  }
  /* 선택 시: 주황 번호 원을 유지하고 바깥에 빨간 링만 추가 */
  .source-sel-ring{
    fill:none;stroke:#FF1744;stroke-width:2.4;vector-effect:non-scaling-stroke;
    filter:drop-shadow(0 0 1.6px rgba(255,23,68,.65));pointer-events:none;display:none;
  }
  .source-marker.selected .source-sel-ring{display:block}
  .source-label{
    font-size:9.5px;font-weight:700;fill:var(--text-dark);text-anchor:middle;
    paint-order:stroke;stroke:#fff;stroke-width:2.5;stroke-linejoin:round;
  }
  .source-label.sub{font-size:7px;font-weight:500;fill:var(--text-muted)}
  /* 환경 요인: 청록(철새) / 보라(기후) / 하늘색(습지) */
  /* 환경 요인: 전파 경로보다 시각 우선순위를 낮게. 선이 아니라 "면"이 중심 */
  .migration-route{
    fill:none;stroke:#14B8A6;stroke-width:1.2;
    stroke-dasharray:2 6;stroke-linecap:round;
    opacity:.55;vector-effect:non-scaling-stroke;
  }

  body.modal-open{overflow:hidden}

  /* ===== Toast ===== */
  .toast{
    position:fixed;left:50%;bottom:32px;z-index:1200;
    transform:translate(-50%,16px);
    display:flex;align-items:center;gap:9px;
    padding:13px 20px;border-radius:10px;
    background:var(--text-dark);color:#fff;
    font-size:13.5px;font-weight:500;
    box-shadow:0 14px 34px rgba(17,35,60,.28);
    opacity:0;pointer-events:none;
    transition:opacity .22s ease,transform .22s cubic-bezier(.4,0,.2,1);
  }
  .toast.show{opacity:1;transform:translate(-50%,0)}
  .toast .t-ic{color:#5FD08A;display:flex}
  @media (prefers-reduced-motion:reduce){.toast{transition:none}}

  /* ===================== SFR-006 확장 스타일 ===================== */
  /* 분석 대상 요약 헤더 */
  .sp-summary{border:1px solid var(--border);border-radius:10px;background:#F8FAFF;padding:10px 12px;margin-bottom:2px}
  .sp-summary-title{font-size:11px;font-weight:700;color:var(--text-muted);margin-bottom:7px;letter-spacing:.2px}
  .sp-summary-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px 12px}
  .sp-summary-grid .k{font-size:10.5px;color:var(--text-muted)}
  .sp-summary-grid .v{font-size:11.5px;font-weight:600;color:var(--text-dark)}
  .sp-summary-grid .row{display:flex;justify-content:space-between;gap:8px}
  /* 탭 바 */
  /* 데스크톱 패널 기준: 첫째 줄 3개 / 둘째 줄 2개(각 50%) 그리드 배치 */
  .sp-tabs{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:6px;position:sticky;top:0;background:var(--panel-bg,#fff);padding:2px 0 8px;z-index:5}
  .sp-tab:nth-child(-n+3){grid-column:span 2}   /* 1~3번 탭: 각 1/3 (첫째 줄 3개) */
  .sp-tab:nth-child(n+4){grid-column:span 3}    /* 4~5번 탭: 각 1/2 (둘째 줄 2개) */
  .sp-tab{
    min-width:0;white-space:nowrap;text-align:center;
    padding:6px 8px;border-radius:8px;border:1px solid var(--border);background:#fff;
    font-size:11px;font-weight:600;color:var(--text-muted);cursor:pointer;transition:.14s;
  }
  .sp-tab:hover{border-color:#CFE0F3;color:var(--text-dark)}
  .sp-tab.active{background:var(--blue);border-color:var(--blue);color:#fff}
  .sp-tabpanel{display:none;flex-direction:column;gap:10px}
  .sp-tabpanel.active{display:flex}
  /* 클릭 가능한 위치 링크 */
  .loc-link{cursor:pointer;color:var(--blue);text-decoration:underline dotted;text-underline-offset:2px}
  .loc-link:hover{color:#0B57C7}
  .loc-link:focus{outline:none}
  .loc-link:focus-visible,.tl-item:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:3px}
  /* 상태 배지(증가/감소/주의) */
  .env-badge{padding:2px 8px;border-radius:999px;font-size:9.5px;font-weight:700;white-space:nowrap}
  .env-badge.up{background:#FEECEC;color:#D64550}
  .env-badge.down{background:#E7F6EC;color:#1E874B}
  .env-badge.warn{background:#FFF4E8;color:#C2410C}
  .env-badge.flat{background:#EEF1F6;color:#5B6472}
  /* 유래 구분 배지 */
  .origin-badge{display:inline-flex;padding:3px 10px;border-radius:999px;font-size:11px;font-weight:700}
  .origin-badge.inflow{background:#FFF1E8;color:#C2410C}
  .origin-badge.local{background:#E7F6EC;color:#1E874B}
  .origin-badge.unknown{background:#EEF1F6;color:#5B6472}
  /* 역추적 타임라인 */
  .tl{position:relative;margin-top:4px;padding-left:6px}
  .tl-item{position:relative;padding:0 0 12px 20px;cursor:pointer}
  .tl-item::before{content:"";position:absolute;left:4px;top:14px;bottom:-2px;width:2px;background:#E1E8F2}
  .tl-item:last-child::before{display:none}
  .tl-item::after{content:"";position:absolute;left:0;top:3px;width:10px;height:10px;border-radius:50%;background:#fff;border:2px solid var(--blue)}
  .tl-item.active::after,.tl-item:hover::after{background:var(--blue)}
  .tl-item.active{background:#F2F7FF;border-radius:8px}
  .tl-step{font-size:11.5px;font-weight:700;color:var(--text-dark)}
  .tl-meta{font-size:10.5px;color:var(--text-muted);margin-top:2px;line-height:1.5}
  /* 병원체 비교 */
  .cmp-controls{display:flex;flex-direction:column;gap:7px}
  .cmp-controls select{
    width:100%;padding:7px 9px;border:1px solid var(--border);border-radius:8px;font-size:11.5px;color:var(--text-dark);background:#fff;
  }
  .cmp-btns{display:flex;gap:7px}
  .cmp-btn{flex:1;padding:7px;border-radius:8px;font-size:11.5px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:#fff;color:var(--text-dark)}
  .cmp-btn.primary{background:var(--blue);border-color:var(--blue);color:#fff}
  .cmp-cols{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:4px}
  .cmp-col{border:1px solid var(--border);border-radius:8px;padding:9px;cursor:pointer;transition:.14s}
  .cmp-col.exist{background:#F4F8FF}
  .cmp-col.novel{background:#F8F4FF}
  .cmp-col.selected{box-shadow:0 0 0 2px rgba(11,115,255,.35)}
  .cmp-col h4{font-size:11px;margin:0 0 6px;color:var(--text-muted)}
  .cmp-col .cmp-name{font-size:12px;font-weight:700;color:var(--text-dark);margin-bottom:6px}
  .cmp-col dl{display:flex;flex-direction:column;gap:4px;margin:0}
  .cmp-col dl div{display:flex;justify-content:space-between;gap:6px}
  .cmp-col dt{font-size:10px;color:var(--text-muted)}
  .cmp-col dd{margin:0;font-size:10.5px;font-weight:600;color:var(--text-dark);text-align:right}
  .cmp-note{margin-top:8px;padding:9px 11px;border-radius:8px;background:#FFF8EC;border:1px solid #F6E4BD;font-size:11px;line-height:1.6;color:#7A5A17}
  /* 자연어 결과 / 근거 태그 */
  .sum-narrative{padding:11px 13px;border-radius:10px;background:#F5F8FF;border:1px solid #DCE6F7;font-size:11.5px;line-height:1.7;color:var(--text-dark)}
  .tag-wrap{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
  .analysis-tag{padding:3px 9px;border-radius:999px;background:#EEF3FB;color:#41506A;font-size:10.5px;font-weight:600}
  /* ===================== 통합 대시보드 ===================== */
  .dash-view{position:fixed;inset:0;top:56px;z-index:400;background:#F4F7FC;overflow-y:auto;display:none}
  .dash-view.active{display:block}
  .dash-inner{max-width:1320px;margin:0 auto;padding:22px 26px 40px}
  .dash-top{display:flex;align-items:center;flex-wrap:wrap;gap:14px;background:#fff;border:1px solid var(--border);border-radius:12px;padding:16px 18px;box-shadow:0 4px 14px rgba(17,35,60,.06)}
  .dash-top .dt-title{font-size:16px;font-weight:800;color:var(--text-dark)}
  .dash-top .dt-sub{font-size:11.5px;color:var(--text-muted);margin-top:3px}
  .dash-top .dt-kv{display:flex;gap:18px;flex-wrap:wrap}
  .dash-top .dt-kv .k{font-size:10.5px;color:var(--text-muted)}
  .dash-top .dt-kv .v{font-size:12px;font-weight:700;color:var(--text-dark)}
  .dash-top .dt-actions{margin-left:auto;display:flex;gap:8px}
  .dash-btn{padding:9px 14px;border-radius:9px;font-size:12px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:#fff;color:var(--text-dark)}
  .dash-btn.primary{background:var(--blue);border-color:var(--blue);color:#fff}
  .dash-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:16px}
  .dash-kpi{background:#fff;border:1px solid var(--border);border-radius:12px;padding:14px 16px}
  .dash-kpi .kpi-k{font-size:11px;color:var(--text-muted)}
  .dash-kpi .kpi-v{font-size:18px;font-weight:800;color:var(--text-dark);margin-top:4px}
  .dash-kpi .kpi-s{font-size:10.5px;color:var(--text-muted);margin-top:3px}
  .dash-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:16px;align-items:start}
  .dash-card{background:#fff;border:1px solid var(--border);border-radius:12px;padding:16px 18px}
  .dash-card h3{font-size:13px;font-weight:700;margin:0 0 10px;color:var(--text-dark)}
  .dash-card dl{display:flex;flex-direction:column;gap:6px;margin:0}
  .dash-card dl div{display:flex;justify-content:space-between;gap:10px}
  .dash-card dt{font-size:11.5px;color:var(--text-muted)}
  .dash-card dd{margin:0;font-size:11.5px;font-weight:600;color:var(--text-dark);text-align:right}
  .dash-card.span2{grid-column:span 2}
  .dash-map-wrap{position:relative;border:1px solid var(--border);border-radius:10px;overflow:hidden;background:#EAF2FB;height:300px}
  #dashMiniMap{width:100%;height:100%}
  .dash-period{display:flex;align-items:center;flex-wrap:wrap;gap:12px;margin:16px 0;padding:14px;background:#fff;border:1px solid var(--border);border-radius:10px;font-size:13px}
  #dashPeriodStatus{color:var(--text-muted)}
  .dash-map-legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px;font-size:12px;color:var(--text-muted)}
  .dash-map-legend .candidate::before,.dash-map-legend .facility::before{content:"";display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:5px;background:#F97316}
  .dash-map-legend .facility::before{background:#2563EB}
  .dash-narrative{grid-column:span 3}


  /* 현실화된 공간분석 결과 UI */
  .analysis-note{
    padding:9px 11px;border-radius:9px;background:#F7FAFF;border:1px solid #DCE6F7;
    font-size:10.5px;line-height:1.55;color:#52627A;
  }
  .analysis-note.warn{background:#FFF8EC;border-color:#F6E4BD;color:#7A5A17}
  /* 각 탭 최종 안내 박스가 바로 위 데이터 행과 붙지 않도록 공통 상단 여백 */
  .tab-guide-note{margin-top:10px}
  .result-table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:9px}
  .result-table{width:100%;min-width:620px;border-collapse:collapse;font-size:10.5px}
  .result-table th{padding:7px 8px;background:#F5F7FB;color:var(--text-muted);font-weight:700;text-align:left;white-space:nowrap;border-bottom:1px solid var(--border)}
  .result-table td{padding:8px;border-bottom:1px solid #F0F3F8;color:var(--text-dark);vertical-align:top;line-height:1.45}
  .result-table tbody tr:last-child td{border-bottom:none}
  .result-table tbody tr[data-selectable]{cursor:pointer}
  .result-table tbody tr[data-selectable]:hover td{background:#F7FAFF}
  .result-table tbody tr.selected td{background:#EFF6FF}
  .result-table tbody tr.selected td:first-child{box-shadow:inset 3px 0 0 var(--blue)}
  .candidate-rank{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;border-radius:50%;background:#F97316;color:#fff;font-size:9.5px;font-weight:800}
  .detail-box{margin-top:9px;padding:10px 11px;border-radius:9px;background:#F8FAFF;border:1px solid #DCE6F7}
  .detail-box-title{font-size:11px;font-weight:800;color:var(--text-dark);margin-bottom:7px}
  .detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px 10px}
  .detail-grid div{min-width:0}
  .detail-grid .k{display:block;font-size:9.5px;color:var(--text-muted);margin-bottom:2px}
  .detail-grid .v{display:block;font-size:10.5px;font-weight:600;color:var(--text-dark);word-break:keep-all}
  .basis-list{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
  .basis-chip{padding:3px 7px;border-radius:999px;background:#EEF3FB;color:#41506A;font-size:9.5px;font-weight:600}
  .poc-badge{display:inline-flex;align-items:center;padding:3px 9px;border-radius:999px;background:#FFF4E8;color:#C2410C;font-size:10px;font-weight:700}
  .relative-note{font-size:9.5px;color:#A6B0C1;line-height:1.5;margin-top:7px}
  .sfr-marker.selected circle:first-child{stroke-width:3;filter:drop-shadow(0 0 3px rgba(11,115,255,.75))}
  /* 유사 서열 비교: 국가·지역별 건수형 분포 마커 (남색·인디고 채움 원 + 흰색 건수) */
  .sim-dist-marker{cursor:pointer}
  .sim-dist-core{fill:#6366F1;stroke:#fff;stroke-width:1.6;vector-effect:non-scaling-stroke}
  .sim-dist-count{font-size:10.5px;font-weight:800;fill:#fff;text-anchor:middle;dominant-baseline:central;pointer-events:none;paint-order:stroke;stroke:#4338CA;stroke-width:.7;stroke-linejoin:round}
  .sim-dist-marker.sel-secondary .sim-dist-core{stroke:#4338CA;stroke-width:2.6;filter:drop-shadow(0 0 2px rgba(99,102,241,.6))}
  .sim-dist-marker.selected .sim-dist-core{stroke:#fff;stroke-width:1.8}
  /* 유사 서열 수집 위치: 청록색 오픈 원 (채움 없음 → 분포 마커와 명확히 구분) */
  .sim-loc-marker{cursor:pointer}
  .sim-loc-ring{fill:#fff;fill-opacity:.9;stroke:#14B8A6;stroke-width:2.2;vector-effect:non-scaling-stroke}
  .sim-loc-marker:hover .sim-loc-ring{stroke:#0F9488;stroke-width:2.8}
  .sim-loc-marker.selected .sim-loc-ring{stroke:#14B8A6;stroke-width:2.6}
  /* 선택 링·라벨 전용 최상위 오버레이: 레이어 순서와 무관하게 항상 가장 위에 표시 */
  .sim-sel-top{pointer-events:none}
  .sim-sel-ring{fill:none;stroke:#FF1744;stroke-width:2.6;filter:drop-shadow(0 0 1.8px rgba(255,23,68,.7));vector-effect:non-scaling-stroke}
  .sim-sel-label{font-size:9.5px;font-weight:700;fill:var(--text-dark);text-anchor:middle;paint-order:stroke;stroke:#fff;stroke-width:2.8;stroke-linejoin:round}
  /* (구) 선택 링 스타일 — 다른 레이어 호환용 유지 */
  .sfr-sel-ring{fill:none;stroke:#FF1744;stroke-width:2.6;filter:drop-shadow(0 0 1.8px rgba(255,23,68,.7));pointer-events:none;display:none}
  .sfr-marker.selected .sfr-sel-ring{display:block}
  .sfr-mk-label{font-size:9.5px;font-weight:700;fill:var(--text-dark);text-anchor:middle;paint-order:stroke;stroke:#fff;stroke-width:2.8;stroke-linejoin:round;pointer-events:none;display:none}
  .sfr-marker.selected .sfr-mk-label{display:block}
  .sp-tab{font-size:10.5px;padding:6px 7px}


  /* SFR-006 레이어 패널 그룹 */
  .layers-panel{max-height:calc(100% - 40px);overflow-y:auto}
  .lp-group-title{font-size:10px;font-weight:800;color:#8A94A6;letter-spacing:.3px;margin:9px 0 3px;text-transform:none}
  .lp-group-title:first-of-type{margin-top:4px}
  .lp-row .lp-name{font-size:10.5px}
  .lp-row{padding:3px 0}
  .sl-item[data-legend]{width:100%}
  .rdc-empty{padding:16px;font-size:12px;color:var(--text-muted);text-align:center;line-height:1.6}
  :root{--genomic-panel-width:720px}
  /* 범례 위치: 열린 패널 폭 기준(겹침 방지) */
  .spatial-legend.spatial-mode{
    left:calc(var(--sidebar-w) + var(--spatial-panel-width) + 24px);
    max-width:calc(100vw - var(--sidebar-w) - var(--spatial-panel-width) - 300px);
  }
  body.genomic-panel-open .map-legend{ left:calc(var(--sidebar-w) + var(--genomic-panel-width) + 24px); }
  body.dashboard-mode .spatial-legend, body.dashboard-mode .map-legend{ display:none !important; }
  /* 동적 레이어 패널 */
  .lp-sec-title{font-size:10px;font-weight:800;color:#8A94A6;letter-spacing:.3px;margin:10px 0 4px}
  .lp-sec-title:first-child{margin-top:2px}
  .lp-count{display:inline-block;font-size:10.5px;color:var(--blue);font-weight:700;margin:2px 0 2px}
  .lp-controls{display:flex;gap:6px;margin-top:9px}
  .lp-btn{flex:1;padding:6px 4px;border-radius:7px;font-size:10.5px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:#fff;color:var(--text-dark)}
  .lp-btn.primary{background:var(--blue);border-color:var(--blue);color:#fff}
  .lp-chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}
  .lp-chip{font-size:9.5px;font-weight:600;padding:2px 8px;border-radius:999px;background:#EEF3FB;color:#41506A}
  .lp-hint{font-size:9.5px;color:#C2410C;margin-top:6px;display:none}
  .lp-hint.show{display:block}
  .lp-radio{display:flex;align-items:center;gap:8px;padding:3px 0;cursor:pointer;font-size:10.5px;color:var(--text-dark)}
  .lp-radio input{accent-color:var(--blue);width:13px;height:13px}
  .sl-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:2px}
  .sl-head-title{font-size:11px;font-weight:800;color:var(--text-dark)}
  .sl-collapse-btn{border:none;background:none;cursor:pointer;color:var(--text-muted);font-size:10.5px;font-weight:600;padding:2px 4px}
  .spatial-legend.collapsed .sl-body{display:none}
  .sl-legrow{display:flex;align-items:center;gap:7px;font-size:10.5px;color:var(--text-muted);padding:2px 0}
  /* 우하단 지도 도구 컨테이너: 줌 컨트롤(위) + 활성 레이어 범례(아래) */
  .map-bottom-right-tools{position:absolute;right:20px;bottom:20px;z-index:180;display:flex;flex-direction:column;align-items:flex-end;gap:12px;max-height:calc(100% - 40px);pointer-events:none}
  .map-bottom-right-tools .map-controls{position:static;top:auto;right:auto;bottom:auto;pointer-events:auto}
  .map-bottom-right-tools .spatial-legend,.map-bottom-right-tools .map-legend{pointer-events:auto}
  .map-bottom-right-tools .map-legend{position:static;left:auto;right:auto;top:auto;bottom:auto;margin:0;width:200px;max-height:min(46vh,340px);overflow:auto}
  .map-bottom-right-tools .spatial-legend{position:static;left:auto;right:auto;top:auto;bottom:auto;margin:0;width:220px;max-height:min(46vh,340px)}
  /* 레이어 패널 전체 켜기/끄기 보조 버튼 */
  .lp-allbtns{display:flex;gap:6px;margin:6px 0 2px}
  .lp-allbtn{flex:1;padding:5px 4px;border-radius:7px;font-size:10.5px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:#fff;color:var(--text-dark)}
  .lp-allbtn:hover{border-color:#CFE0F3;color:var(--blue)}
  .lp-row.locked{opacity:1;cursor:default}
  .lp-row.locked input{cursor:default}
  .lp-lock{display:inline-flex;align-items:center;gap:3px;font-size:9px;font-weight:600;color:#8A94A6;white-space:nowrap;margin-left:4px}
  .lp-lock svg{opacity:.8}

  /* ===== 포인트 크기·최대 줌 개선: v1.11보다 약 8~10% 큰 화면 고정 심벌 ===== */
  .map-point-hit,.spatial-hit{fill:transparent;stroke:none;pointer-events:all}
  /* 선택 링은 범례의 "선택된 위치" 와 같은 빨강을 쓴다. 링만 다른 빨강이면
     점(#DC2626)과 링(#FF1744)이 두 색으로 보인다. */
  .map-point-selection,.spatial-selection-ring{
    fill:none;stroke:var(--pt-selected);stroke-width:2.6;vector-effect:non-scaling-stroke;
    filter:drop-shadow(0 0 2px rgba(220,38,38,.75));pointer-events:none;
  }
  .map-point-selection{display:none}
  .spatial-selection-ring{display:none}
  /* 관측 위치 선택: 작은 빨간 점 + 흰색 간격 + 얇은 빨간 외곽 링 (인접 형제 순서: dot → gap → ring) */
  .occ-sel-gap{fill:none;stroke:#fff;stroke-width:2.2;vector-effect:non-scaling-stroke;pointer-events:none;display:none}
  .occurrence-dot.selected + .occ-sel-gap{display:block}
  .occurrence-dot.selected + .occ-sel-gap + .spatial-selection-ring{display:block;stroke-width:1.6;filter:none}
  /* 분석 대상 시료 수집 위치: 파란 타깃(외곽 원 + 십자 기준선 + 중앙점), 번호 없음 */
  .sample-ring{fill:none;stroke:#2563EB;stroke-width:1.6;vector-effect:non-scaling-stroke}
  .sample-cross{stroke:#2563EB;stroke-width:1.6;stroke-linecap:round;vector-effect:non-scaling-stroke}
  .sample-core{fill:#2563EB;stroke:#FFFFFF;stroke-width:1.4;vector-effect:non-scaling-stroke}
  /* 지도 포인트 클릭 시 브라우저 기본 검은 사각형 포커스 테두리 제거 (키보드 포커스는 파란 외곽선) */
  .spatial-fixed-point:focus,.occurrence-marker:focus,.source-marker:focus,.sfr-marker:focus{outline:none}
  .spatial-fixed-point:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
  .risk-cluster.selected .risk-selection-ring{display:block}
  .risk-cluster circle.risk-core{
    stroke:#FFFFFF;stroke-width:2;filter:none;vector-effect:non-scaling-stroke;
  }
  .risk-cluster.HIGH circle.risk-core{fill:#F43F5E}
  .risk-cluster.MEDIUM circle.risk-core{fill:#F97316}
  .risk-cluster.LOW circle.risk-core{fill:#22C55E}
  .risk-cluster.selected circle.risk-core{
    stroke:#FFFFFF;stroke-width:2.4;
  }

  /* ===== 환경 발생 가능성 탭: 시기별 분포 변화 / 지역별 상대 발생 가능성 포인트 ===== */
  .env-temporal-marker,.env-regional-marker{cursor:pointer}
  .env-tm-base{fill:none;stroke:#2563EB;stroke-width:2;vector-effect:non-scaling-stroke}      /* 기준 기간만: 남색 오픈 */
  .env-tm-new{fill:#F97316;stroke:#fff;stroke-width:1.4;vector-effect:non-scaling-stroke}      /* 비교 신규: 주황 채움 */
  .env-tm-outer{fill:none;stroke:#2563EB;stroke-width:2;vector-effect:non-scaling-stroke}      /* 두 기간 모두: 남색 외링 */
  .env-tm-inner{fill:none;stroke:#F97316;stroke-width:2;vector-effect:non-scaling-stroke}      /*             주황 내링 */
  .env-regional-core{stroke:#fff;stroke-width:2;vector-effect:non-scaling-stroke}
  .env-regional-marker.HIGH .env-regional-core{fill:#F43F5E}
  .env-regional-marker.MEDIUM .env-regional-core{fill:#F97316}
  .env-regional-marker.LOW .env-regional-core{fill:#22C55E}
  .env-regional-num{fill:#fff;font-size:11.5px;font-weight:800;text-anchor:middle;dominant-baseline:central;pointer-events:none;paint-order:stroke;stroke:rgba(0,0,0,.25);stroke-width:.6}
  .env-sel-ring{fill:none;stroke:#FF1744;stroke-width:2.6;filter:drop-shadow(0 0 1.8px rgba(255,23,68,.7));vector-effect:non-scaling-stroke;display:none;pointer-events:none}
  .env-temporal-marker.selected .env-sel-ring,.env-regional-marker.selected .env-sel-ring{display:block}
  .env-mk-label{font-size:9.5px;font-weight:700;fill:var(--text-dark);text-anchor:middle;paint-order:stroke;stroke:#fff;stroke-width:2.8;stroke-linejoin:round;pointer-events:none;display:none}
  .env-temporal-marker.selected .env-mk-label,.env-regional-marker.selected .env-mk-label{display:block}

  /* ===== 유입 가능성 탭: 후보 번호 포인트 / 시설 아이콘 / 연결경로 ===== */
  .inflow-cand,.inflow-facility{cursor:pointer}
  .inflow-cand-hit,.inflow-fac-hit{fill:transparent;pointer-events:all}
  .inflow-cand-num{
    fill:#fff;font-size:11px;font-weight:800;text-anchor:middle;dominant-baseline:central;
    paint-order:stroke;stroke:#C2410C;stroke-width:2.4;stroke-linejoin:round;pointer-events:none;
  }
  .inflow-label{
    font-size:9.5px;font-weight:700;fill:var(--text-dark);text-anchor:middle;
    paint-order:stroke;stroke:#fff;stroke-width:2.8;stroke-linejoin:round;
    pointer-events:none;display:none;
  }
  .inflow-sel-ring{
    fill:none;stroke:#FF1744;stroke-width:2.6;
    filter:drop-shadow(0 0 1.8px rgba(255,23,68,.7));pointer-events:none;display:none;
  }
  .inflow-cand.sel .inflow-sel-ring,.inflow-facility.sel .inflow-sel-ring{display:block}
  .inflow-cand.sel .inflow-label,.inflow-facility.sel .inflow-label{display:block}
  .inflow-cand.dim,.inflow-facility.dim{opacity:.28}
  .inflow-fac-bg{fill:#fff;stroke:#2563EB;stroke-width:1.6}
  .inflow-fac-icon.fill{fill:#2563EB;pointer-events:none}
  .inflow-fac-icon.stroke{fill:none;stroke:#2563EB;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
  .inflow-route-underlay{fill:none;stroke:#fff;stroke-width:4.2;stroke-linecap:round;vector-effect:non-scaling-stroke;opacity:.9}
  .inflow-route{fill:none;stroke:#F97316;stroke-width:1.9;stroke-dasharray:6 4;stroke-linecap:round;vector-effect:non-scaling-stroke}
  .inflow-arrow{fill:#F97316;stroke:#fff;stroke-width:.8;vector-effect:non-scaling-stroke}
  .inflow-route-hit{fill:none;stroke:transparent;stroke-width:12;vector-effect:non-scaling-stroke;pointer-events:stroke;cursor:pointer}
  .inflow-route.hl{stroke:#FF1744;stroke-width:2.7;stroke-dasharray:none;filter:drop-shadow(0 0 1.6px rgba(255,23,68,.6))}
  .inflow-arrow.hl{fill:#FF1744}
  .inflow-route.dim,.inflow-route-underlay.dim,.inflow-arrow.dim{opacity:.25}
  .loc-link.inflow-active{background:rgba(249,115,22,.16);border-radius:4px;box-shadow:0 0 0 1px rgba(249,115,22,.42)}
  tr.inflow-active-row{background:rgba(249,115,22,.07)}
  /* 후보 아코디언 행 보조 강조: 주 선택(.selected 파란 바)과 명확히 구분되는 주황 톤. 펼침을 유발하지 않는다 */
  .oa-item.inflow-active-row:not(.selected){background:rgba(249,115,22,.09);box-shadow:inset 3px 0 0 rgba(249,115,22,.5)}

  /* ===== 최초 관측·경로 탭: 확산 경로 / 숙주 연결선 / 중첩 관측지점 ===== */
  /* 확산 가능 경로 후보: 파란 곡선 점선 + 화살표 + 흰 언더레이 */
  .origin-spread-underlay{fill:none;stroke:#fff;stroke-width:4.2;stroke-linecap:round;vector-effect:non-scaling-stroke;opacity:.9}
  .origin-spread{fill:none;stroke:#2563EB;stroke-width:1.9;stroke-dasharray:6 4;stroke-linecap:round;vector-effect:non-scaling-stroke}
  .origin-spread-arrow{fill:#2563EB;stroke:#fff;stroke-width:.8;vector-effect:non-scaling-stroke}
  .origin-spread-hit{fill:none;stroke:transparent;stroke-width:12;vector-effect:non-scaling-stroke;pointer-events:stroke;cursor:pointer}
  .origin-spread.hl{stroke:#1D4ED8;stroke-width:2.7;stroke-dasharray:none;filter:drop-shadow(0 0 1.5px rgba(29,78,216,.5))}
  .origin-spread-arrow.hl{fill:#1D4ED8}
  .origin-spread.dim,.origin-spread-underlay.dim,.origin-spread-arrow.dim{opacity:.22}
  /* 주요 숙주 관측 연결정보: 청록 얇은 무방향 선 (화살표 없음) */
  .host-link{fill:none;stroke:#14B8A6;stroke-width:1.3;stroke-dasharray:3 3;stroke-linecap:round;vector-effect:non-scaling-stroke;opacity:.9}
  .host-link-hit{fill:none;stroke:transparent;stroke-width:10;vector-effect:non-scaling-stroke;pointer-events:stroke;cursor:pointer}
  .host-link.hl{stroke:#0E8C82;stroke-width:2.1;stroke-dasharray:none;opacity:1}
  .host-link.dim{opacity:.2}
  /* 숙주 관측점: 청록 포인트 (고정 크기) */
  .host-point{cursor:pointer}
  .host-point-dot{fill:#14B8A6;stroke:#fff;stroke-width:1.4}
  .host-sel-ring{fill:none;stroke:#0E8C82;stroke-width:2.4;filter:drop-shadow(0 0 1.5px rgba(14,140,130,.6));display:none;pointer-events:none}
  .host-point.sel .host-sel-ring{display:block}
  .host-point.dim{opacity:.32}
  .origin-point-label{font-size:9px;font-weight:700;fill:#0E7C74;text-anchor:middle;paint-order:stroke;stroke:#fff;stroke-width:2.4;stroke-linejoin:round;pointer-events:none;display:none}
  .host-point.sel .origin-point-label{display:block}
  /* 숙주·서식지 중첩 관측지점: 보라 반투명 링 (선 아님, 면 데이터 없음 → 임의 폴리곤 미생성) */
  .overlap-ring{fill:rgba(139,92,246,.18);stroke:#8B5CF6;stroke-width:1.4;stroke-dasharray:3 2}
  .overlap-point{cursor:pointer}
  .overlap-point.sel .overlap-ring{stroke-width:2.4;fill:rgba(139,92,246,.28);filter:drop-shadow(0 0 2px rgba(139,92,246,.5))}
  /* 최초 관측·경로 사이드 목록 (아코디언: 기본 한 줄 + 클릭 시 상세 펼침, 가로 스크롤 없음) */
  .origin-list-scroll{max-height:240px;overflow-y:auto;overflow-x:hidden;border:1px solid var(--border);border-radius:9px}
  /* 자료 없음 안내처럼 목록에 바로 넣는 문자열도 같은 크기로 보이도록 기본 크기를 목록에 둔다. */
  .oa-list{display:flex;flex-direction:column;font-size:10.5px;line-height:1.55;color:var(--text-dark)}
  .oa-sub{padding:0 9px 8px;font-size:10.5px;line-height:1.55;color:#52627A;word-break:keep-all}
  .oa-tag{flex-shrink:0;margin-left:auto;padding:1px 6px;border-radius:999px;background:#EEF3FB;color:#52627A;font-size:9.5px;font-weight:600;white-space:nowrap}
  .oa-item{border-bottom:1px solid var(--border);cursor:pointer;transition:background .12s}
  .oa-item:last-child{border-bottom:none}
  .oa-item:hover{background:#F4F8FF}
  .oa-item.selected{background:var(--light-blue);box-shadow:inset 3px 0 0 var(--blue)}
  .oa-head{display:flex;align-items:center;gap:6px;padding:7px 9px;font-size:10.5px;color:var(--text-dark);line-height:1.4}
  .oa-head-txt{flex:1;min-width:0;white-space:normal;word-break:keep-all}
  .oa-head b{font-weight:700}
  .oa-arrow{color:var(--text-muted);padding:0 1px}
  .oa-caret{flex-shrink:0;color:var(--text-muted);transition:transform .15s}
  .oa-item.selected .oa-caret{transform:rotate(180deg)}
  .oa-detail{display:none;padding:2px 10px 9px 12px}
  .oa-item.selected .oa-detail{display:block}
  .oa-row{display:flex;gap:8px;padding:2.5px 0;font-size:10px;line-height:1.45;border-top:1px dashed var(--border)}
  .oa-row:first-child{border-top:none}
  .oa-k{flex:0 0 78px;color:var(--text-muted);font-weight:600}
  .oa-v{flex:1;min-width:0;color:var(--text-dark);white-space:normal;word-break:keep-all}
  .oa-na{color:#A6B0C1}
  .oa-row-cases{align-items:flex-start}
  .oa-cases{display:flex;flex-direction:column;gap:4px}
  .oa-case{display:flex;flex-direction:column;line-height:1.35}
  .oa-case b{font-weight:700;color:var(--text-dark)}
  .oa-case span{color:var(--text-muted);font-size:9px}


/* API records share the compact list styling while retaining native details behavior. */
.oa-list .connected-record {font-size:11px; line-height:1.5; padding:8px; overflow-wrap:anywhere;}
.connected-record summary {cursor:pointer; font-weight:600;}
.connected-record dl {display:grid; grid-template-columns:90px minmax(0,1fr); gap:6px; margin:8px 0;}
.connected-record dt {color:var(--text-muted);}
.connected-record dd {margin:0;}
.connected-record button {margin-top:6px; padding:5px 8px; border:1px solid var(--border); border-radius:5px; cursor:pointer;}
/* Station observation controls within the environmental data card. */
.weather-query-form { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; }
.weather-query-form label { display:flex; flex-direction:column; gap:4px; font-size:12px; }
.weather-query-form input,.weather-query-form select { width:100%; min-width:0; box-sizing:border-box; padding:6px; border:1px solid #cbd5e1; border-radius:4px; }
.weather-query-form button { grid-column:1/-1; padding:8px; cursor:pointer; }

/* ===== 분석 설명 슬라이드 패널 ===========================================
   각 결과 카드의 "분석 설명" 버튼으로 열린다. 원천 데이터 · 분석 절차 ·
   분석식 · 한계를 한 화면에 모은다. 오른쪽에서 밀려 나오며 공간분석 패널
   (z-index 200)보다 위에 있어야 탭을 보면서 읽을 수 있다. */
.ax-btn{
  margin-left:auto;flex-shrink:0;
  padding:4px 9px;border:1px solid var(--border);border-radius:999px;
  background:var(--white);color:var(--text-muted);
  font-size:11px;font-weight:600;letter-spacing:.01em;line-height:1.5;
  cursor:pointer;transition:border-color .14s,color .14s,background .14s;
}
.ax-btn:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-bg)}
.ax-btn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.gr-head-actions .ax-btn{align-self:center;margin-left:0}

.analysis-explain{
  position:fixed;top:0;right:0;bottom:0;
  width:min(480px,100vw);
  display:flex;flex-direction:column;
  background:var(--white);border-left:1px solid var(--border);
  box-shadow:-14px 0 38px rgba(17,35,60,.14);
  z-index:420;
  transform:translateX(100%);
  transition:transform .2s ease;
  visibility:hidden;
}
.analysis-explain.open{transform:translateX(0);visibility:visible}
@media (prefers-reduced-motion:reduce){.analysis-explain{transition:none}}

.ax-head{
  display:flex;align-items:flex-start;gap:12px;
  padding:18px 18px 14px;border-bottom:1px solid var(--border);flex-shrink:0;
}
.ax-head-text{flex:1;min-width:0}
.ax-eyebrow{
  display:block;font-size:10.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--blue);margin-bottom:3px;
}
.ax-head h2{margin:0;font-size:16px;font-weight:700;color:var(--text-dark);line-height:1.35}
.ax-close{
  width:28px;height:28px;flex-shrink:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:none;border-radius:8px;background:transparent;color:#334155;cursor:pointer;
}
.ax-close:hover{background:var(--bg)}

.ax-body{
  flex:1;min-height:0;overflow-y:auto;
  padding:16px 18px 30px;
  display:flex;flex-direction:column;gap:18px;
}
.ax-body:focus{outline:none}
.ax-lead{margin:0;font-size:12.5px;line-height:1.7;color:var(--text-dark)}

.ax-block{display:flex;flex-direction:column;gap:8px}
.ax-block h3{
  margin:0;font-size:11px;font-weight:700;letter-spacing:.055em;
  text-transform:uppercase;color:var(--text-muted);
}
.ax-ul{margin:0;padding-left:17px;display:flex;flex-direction:column;gap:6px}
.ax-ul li{font-size:12px;line-height:1.7;color:var(--text-dark)}

.ax-dl{margin:0;display:flex;flex-direction:column;gap:9px}
.ax-dl > div{
  display:grid;grid-template-columns:104px 1fr;gap:10px;
  padding-bottom:9px;border-bottom:1px dashed var(--border);
}
.ax-dl > div:last-child{border-bottom:none;padding-bottom:0}
.ax-dl dt{margin:0;font-size:11.5px;font-weight:600;color:var(--text-muted);line-height:1.6}
.ax-dl dd{margin:0;font-size:12px;line-height:1.7;color:var(--text-dark);word-break:break-word}
/* 성분식은 기호가 많아 등폭이 읽기 쉽다. */
.ax-dl-formula dd{
  font-family:"Pretendard","Inter","Noto Sans KR",system-ui,sans-serif;
  font-size:11.5px;line-height:1.75;
}

@media (max-width:640px){
  .analysis-explain{width:100vw}
  .ax-dl > div{grid-template-columns:1fr;gap:3px}
}

/* 사용자 설명을 먼저 읽고 필요할 때 상세 계산 기준을 펼친다. */
.ax-details{border-top:1px solid var(--border);padding-top:14px}
.ax-details > summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--text-dark);line-height:1.7}
.ax-details > summary:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
.ax-details-body{display:flex;flex-direction:column;gap:18px;padding-top:16px}
.ax-body .ax-lead,.ax-body .ax-ul li,.ax-body .ax-dl dd{font-size:13px;line-height:1.8}
.ax-body .ax-block h3{font-size:12px;letter-spacing:0;text-transform:none}

/* 자료 없음 사유 블록 — 빈 결과를 오류로 읽지 않도록 사유를 강조한다. */
.ax-block-warn{
  padding:12px 13px;border-radius:9px;
  background:#FFF8EC;border:1px solid #F5D9A8;
}
.ax-block-warn h3{color:#8A5A10}
.ax-block-warn .ax-dl > div{border-bottom-color:#F0E0C2}
.ax-block-warn dt{color:#8A5A10}
.ax-warn-foot{margin:9px 0 0;font-size:11.5px;line-height:1.65;color:#8A5A10}

/* 표의 해석 안내는 값과 분리해 작은 각주로 표시한다. */
.analysis-footnote{margin-top:8px;color:var(--text-muted);font-size:10.5px;line-height:1.5}
.analysis-footnote p{margin:3px 0}

/* 레이어 행 아래 보조 문구 — 생태자연도의 조회 상태·출처·주의 문구를 담는다.
   떠 있던 생태자연도 카드를 없애면서 이 자리로 옮겼다. */
/* 레이어 행 아래 보조 문구. 체크박스·범례 폭(26px)만큼 들여써 이름과 줄을 맞춘다.
   flex-basis 100% 로 한 줄을 통째로 차지하게 해야 이름과 겹치지 않는다. */
.lp-note{
  flex:0 0 100%;
  margin:3px 0 0 26px;
  color:var(--text-muted);
  font-size:10px;line-height:1.55;
  word-break:keep-all;
}
.lp-note:empty{display:none}
/* 출처는 주의 문구 아래에 더 작게 둔다. */
.lp-source{
  flex:0 0 100%;
  margin:2px 0 2px 26px;
  color:#9AA6B8;
  font-size:9.5px;line-height:1.5;
}
.lp-source a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.lp-source a:hover{color:var(--blue)}

/* 탭 맨 아래 주의 문구. 카드마다 적지 않고 탭 하나에 한 줄만 둔다.
   결과 목록과 구분되도록 위에 얇은 선을 두고 여백을 준다. */
.analysis-footnote.tab-footnote{
  margin:14px 2px 4px;
  padding-top:10px;
  border-top:1px solid var(--border);
}
.analysis-footnote.tab-footnote p{margin:0;font-size:11px;line-height:1.6}

/* 유전체 결과 순위의 동점 표시. 순번을 묶지 않고 동점 건수만 덧붙인다 —
   짧은 조각은 완전일치가 수십 건 나와 공동 순위로 묶으면 순번이 무의미해진다. */
.rank-tie{
  display:inline-block;margin-left:4px;padding:1px 5px;
  border-radius:999px;background:var(--gray-bg);color:var(--gray-tx);
  font-size:9.5px;font-weight:700;white-space:nowrap;cursor:help;
}

/* 최초 발견지 → 국내 확산 경로선. 단계별로 이으며 선택 단계를 굵게 표시한다. */
.spread-path-line{
  stroke:#2563EB;stroke-width:1.8;stroke-dasharray:5 3;
  vector-effect:non-scaling-stroke;fill:none;opacity:.85;
}
.spread-path-line.selected{stroke:#DC2626;stroke-width:2.8;stroke-dasharray:none;opacity:1}

/* 미검증은 낮은 위험이 아니다. 중립색으로 별도 표시한다. */
.risk-badge.UNASSESSED { background: #f1f5f9; color: #475569; }

.env-regional-marker.UNASSESSED .env-regional-core { fill: #64748b; }

/* 시군구 경계 면: 원자료 범위를 유지하고 선택 윤곽선만 강조한다. */
/* 부모 SVG의 pointer-events:none을 해제해 구역 클릭을 기존 목록 선택으로 연결한다. */
.risk-region-area{fill-opacity:.22;stroke:#64748b;stroke-width:1.2;cursor:pointer;pointer-events:visiblePainted}
.risk-region-area:hover,.risk-region-area:focus,.risk-region-area.selected{fill-opacity:.4;stroke:#0f172a;stroke-width:3}
/* SVG 확대에 따라 커지는 브라우저 기본 포커스 링 대신 위의 경계 강조를 사용한다. */
.risk-region-area:focus{outline:none}
.risk-area-swatch{display:inline-block;width:12px;height:10px;opacity:.7;border:1px solid #64748b;margin-right:5px}

/* 관측 쌍의 표시 편의: 데이터 제외·관련성 순위가 아니다. */
.observation-pair-filter { display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:10px 0; font-size:12px; }
.observation-pair-filter input { width:100px; padding:5px; border:1px solid #cbd5e1; border-radius:4px; }
.observation-pair-filter button { padding:5px 8px; border:1px solid #cbd5e1; border-radius:4px; background:#fff; cursor:pointer; }
.observation-pair-notice { margin:6px 0; color:#475569; font-size:12px; line-height:1.5; }
.observation-pair-group > summary { padding:10px 4px; cursor:pointer; font-weight:600; }

/* PDF required/optional display policy. Raw API/DB observations are preserved. */
.screen-optional,
#genomicPanel .gr-search-row, #genomicPanel .page-btns,
#occurrenceSummaryCard, #similarCaseCard, #farmRegionCard,
[data-explain="origin-host"], #overlapCard,
[data-explain="risk-summary"], #riskInfoPop,
#spreadHighCount,
#resultDetailCard .rdc-desc { display:none!important; }
/* 결과 패널은 기존 폭을 유지하고 지도와 나란히 표시한다. */
#genomicPanel .genomic-results-table { min-width:0; width:100%; }

[data-explain="spread-risk"] .sp-list > div:has(#spreadHighCount),
#sourceCandBody button { display:none!important; }

/* Requested unreported observations remain visible; only unvalidated grades are hidden. */

/* 월별 기상 비교: 기존 패널 폭 안에서 차트·표를 열람한다. */
.weather-comparison-body{padding:12px 2px 2px;min-width:0}
.weather-region{margin:0 0 7px;font-size:13px;color:var(--text-dark)}
.weather-period,.weather-note,.weather-empty{font-size:11px;line-height:1.6;color:var(--text-muted);margin:6px 0;overflow-wrap:anywhere}
.weather-legend{font-size:11px;margin:8px 0}.weather-baseline{color:#2563eb;margin-right:12px}.weather-comparison{color:#f97316}
.weather-metric{margin:14px 0;border-top:1px solid var(--border);padding-top:10px}
.weather-metric h5{font-size:12px;margin:0 0 5px;color:var(--text-dark)}
.weather-chart{display:block;width:100%;height:auto;max-width:100%;font-size:8px;color:var(--text-muted)}
.weather-chart text{fill:currentColor}.weather-point{cursor:help}
.weather-metric summary,.weather-annual summary{cursor:pointer;font-size:11px;padding:6px 0;color:var(--blue)}
.weather-table-wrap{max-width:100%;overflow-x:auto}
.weather-table-wrap table{border-collapse:collapse;width:100%;font-size:10px;line-height:1.5}
.weather-table-wrap th,.weather-table-wrap td{padding:5px 3px;border-bottom:1px solid var(--border);text-align:right;vertical-align:top}
.weather-table-wrap th:first-child{text-align:left;white-space:nowrap;font-weight:500}
.weather-table-wrap caption{text-align:left;font-size:10px;padding:4px 0}
.weather-table-wrap small{display:block;color:var(--text-muted);font-size:9px}
.weather-annual{border-top:1px solid var(--border);padding-top:5px}.weather-annual dl{font-size:11px;margin:5px 0;line-height:1.6}.weather-annual dt{font-weight:600}.weather-annual dd{margin:0 0 6px}

/* Missing period metrics retain the actual boundary without a zero-count fill. */
.env-temporal-area.observation-missing{fill:none;stroke-dasharray:5 4}
