/* 리전인사이트 목업 — 6개 화면 공통 스타일
   출처: 02.design/새 폴더/mockup.html 의 <style> 전체를 그대로 분리한 것.
   화면별 파일: 1-calendar / 2-input / 3-region / 4-ai-chat / 5-compare / 6-report */
:root{
    --bg:#F4F6F9;
    --bg-panel:#FFFFFF;
    --bg-subtle:#EDF0F4;
    --border:#DFE3E9;
    --text:#14171C;
    --text-muted:#545B66;
    --text-faint:#868D98;
    --accent:#2a78d6;
    --accent-ink:#ffffff;
    --accent-soft:#E4EEFB;
    --accent2:#eb6834;
    --accent2-soft:#FDEBE2;
    --good:#3C8F4C;
    --good-soft:#E1F0E2;
    --warn:#C98A1F;
    --warn-soft:#F7EAD2;
    --critical:#C0483C;
    --critical-soft:#F6DEDA;
    --shadow:rgba(16,24,40,0.07);
    --radius-lg:16px;
    --radius-md:12px;
    --radius-sm:8px;

    /* ── 축제 캘린더(1번 화면) 이식용 토큰 별칭 ─────────────
       region 목업 CSS를 한 줄도 고치지 않고 쓰기 위한 매핑.
       값의 출처는 위 mockup 토큰 하나뿐이다(단일 색 체계 유지). */
    --page:var(--bg);
    --surface-1:var(--bg-panel);
    --surface-2:var(--bg-subtle);
    --text-primary:var(--text);
    --text-secondary:var(--text-muted);
    --muted:var(--text-faint);
    --gridline:var(--border);
    --baseline:var(--border);
    --series-1:var(--accent);
    --series-2:var(--accent2);
    --demph:var(--text-faint);
    --neg:var(--critical);
    --bad:var(--critical);
    --meter-track:var(--accent-soft);
    --focus:var(--accent);
    --r-card:var(--radius-md);
    --r-ctrl:var(--radius-sm);
    --r-mark:4px;
    --lane:212px;
    /* 2026-09-22 색 교체: 목업 시절 청록(#0B5E73)·장미(#B14D69)·회녹 배경(#F1F3EF)은 채도가 낮아
       칙칙했고, 두 색이 색각 이상에서 거의 구별되지 않았다(ΔE 3.8). 기획 문서의 확정 토큰대로
       파랑 #2a78d6 · 주황 #eb6834(다크 #3987e5 · #d95926)로 바꿨다 — 두 모드 모두 색 검증 통과.
       --ref = 액센트의 중간톤. 대응 토큰이 없어 유일하게 직접 지정한다.
       (간트 "예정" 바 + 연간 흐름 전년 점선) */
    --ref:#93BDEE;
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]){
      --bg:#111317;
      --bg-panel:#1A1D22;
      --bg-subtle:#22262C;
      --border:#2F343B;
      --text:#E9ECF0;
      --text-muted:#A3AAB4;
      --text-faint:#737B86;
      --accent:#3987e5;
      --accent-ink:#0B0D10;
      --accent-soft:rgba(57,135,229,0.18);
      --accent2:#d95926;
      --accent2-soft:rgba(217,89,38,0.18);
      --good:#6FBF7C;
      --good-soft:rgba(111,191,124,0.16);
      --warn:#E0AE4E;
      --warn-soft:rgba(224,174,78,0.16);
      --critical:#E08277;
      --critical-soft:rgba(224,130,119,0.16);
      --shadow:rgba(0,0,0,0.45);
    --ref:#2C5E9C;
    }
  }
  :root[data-theme="dark"]{
    --bg:#111317;
    --bg-panel:#1A1D22;
    --bg-subtle:#22262C;
    --border:#2F343B;
    --text:#E9ECF0;
    --text-muted:#A3AAB4;
    --text-faint:#737B86;
    --accent:#3987e5;
    --accent-ink:#0B0D10;
    --accent-soft:rgba(57,135,229,0.18);
    --accent2:#d95926;
    --accent2-soft:rgba(217,89,38,0.18);
    --good:#6FBF7C;
    --good-soft:rgba(111,191,124,0.16);
    --warn:#E0AE4E;
    --warn-soft:rgba(224,174,78,0.16);
    --critical:#E08277;
    --critical-soft:rgba(224,130,119,0.16);
    --shadow:rgba(0,0,0,0.45);
    --ref:#2C5E9C;
  }

  *{box-sizing:border-box;}
  html{-webkit-text-size-adjust:100%;}
  body{
    margin:0;
    background:var(--bg);
    color:var(--text);
    font-family:'Pretendard Variable','Apple SD Gothic Neo','Malgun Gothic',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
    font-size:15px;
    line-height:1.55;
    font-variant-numeric:tabular-nums;
  }
  h1,h2,h3,h4{margin:0;text-wrap:balance;}
  p{margin:0;}
  button{font:inherit;color:inherit;}
  ul{margin:0;padding:0;list-style:none;}
  :focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
  @media (prefers-reduced-motion: reduce){
    *{transition-duration:0.01ms !important;animation-duration:0.01ms !important;}
  }

  /* ---------- shell ---------- */
  .app-shell{display:grid;grid-template-columns:248px 1fr;min-height:100vh;}

  .rail{
    background:var(--bg-panel);
    border-right:1px solid var(--border);
    padding:22px 16px;
    display:flex;
    flex-direction:column;
    gap:22px;
    position:sticky;
    top:0;
    height:100vh;
    overflow-y:auto;
  }
  .brand{padding:0 4px;display:block;text-decoration:none;color:inherit;}
  .brand .mark{font-size:19px;font-weight:800;letter-spacing:-0.01em;}
  .brand .mark span{color:var(--accent);}
  .brand .tag{font-size:12px;color:var(--text-muted);margin-top:2px;}

  .steps{display:flex;flex-direction:column;position:relative;}
  .step{
    display:flex;
    align-items:flex-start;
    gap:12px;
    padding:10px 8px;
    background:transparent;
    border:none;
    border-radius:var(--radius-md);
    text-align:left;
    cursor:pointer;
    position:relative;
  }
  .step{text-decoration:none;color:inherit;font:inherit;}   /* 6개 파일로 쪼개며 button → a */
  .step:hover{background:var(--bg-subtle);}
  .step .num{
    flex:0 0 auto;
    width:26px;height:26px;
    border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    font-size:12px;font-weight:700;
    background:var(--bg-subtle);
    color:var(--text-muted);
    border:1px solid var(--border);
    position:relative;
    z-index:1;
  }
  .step:not(:last-child)::after{
    content:"";
    position:absolute;
    left:21px;
    top:36px;
    width:1px;
    height:calc(100% - 4px);
    background:var(--border);
  }
  .step .label strong{display:block;font-size:13.5px;font-weight:700;}
  .step .label small{display:block;font-size:11.5px;color:var(--text-faint);margin-top:1px;}
  .step.is-active .num{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);}
  .step.is-active{background:var(--accent-soft);}
  .step.is-active .label strong{color:var(--accent);}

  .rail-foot{margin-top:auto;display:flex;flex-direction:column;align-items:flex-start;gap:9px;padding:14px 8px 10px;font-size:11.5px;color:var(--text-faint);border-top:1px solid var(--border);}

  .main{min-width:0;}

  /* ---------- rail 상단 유틸 (구 topbar 를 흡수) ----------
     상단 헤더 바를 없애고 계정·담당지역·테마를 왼쪽 레일로 옮겼다.
     본문이 가로뿐 아니라 세로로도 화면을 끝까지 쓰게 된다. */
  .rail-account{
    display:flex;align-items:center;gap:9px;
    padding:9px 10px;
    border:1px solid var(--border);border-radius:var(--radius-md);
    background:var(--bg-subtle);
  }
  .rail-account .avatar{
    flex:0 0 auto;width:28px;height:28px;border-radius:50%;
    background:var(--accent);color:var(--accent-ink);
    display:flex;align-items:center;justify-content:center;
    font-size:12px;font-weight:800;
  }
  .rail-account .who{font-size:12.5px;font-weight:700;min-width:0;}
  .rail-account .who small{display:block;font-weight:400;color:var(--text-faint);font-size:10.5px;margin-top:1px;}

  .rail-region{display:flex;flex-direction:column;gap:6px;}
  .rail-label{font-size:11px;font-weight:700;letter-spacing:.04em;color:var(--text-faint);padding-left:2px;}
  .rail-region select{
    width:100%;
    appearance:none;
    background:var(--bg-panel);
    border:1px solid var(--border);
    border-radius:var(--radius-sm);
    padding:8px 30px 8px 12px;
    font:inherit;font-weight:600;
    color:var(--text);
    background-image:linear-gradient(45deg,transparent 50%,var(--text-muted) 50%),linear-gradient(135deg,var(--text-muted) 50%,transparent 50%);
    background-position:calc(100% - 16px) 55%,calc(100% - 11px) 55%;
    background-size:5px 5px,5px 5px;
    background-repeat:no-repeat;
    cursor:pointer;
  }
  .updated{font-size:11.5px;color:var(--text-faint);}

  .view{display:none;padding:26px 28px 70px;}   /* max-width 제거 — 우측 공간을 끝까지 쓴다 */
  .view.active{display:block;}
  .view.view-compact{padding-bottom:28px;}   /* 1번 화면 — 하단 버튼을 위로 옮겨 아래 여백이 필요 없다 */
  /* 제목 오른쪽에 부제를 한 줄로 붙인다(2026-09-21). 부제가 길어 칸을 넘으면 줄바꿈 대신 말줄임(…),
     좁은 화면(아래 900px 규칙)에서는 다시 제목 아래로 내린다. */
  .view-head{margin-bottom:20px;display:flex;align-items:baseline;gap:14px;min-width:0;}
  .view-head .view-title{flex:0 0 auto;white-space:nowrap;}
  /* 제목 줄 오른쪽 도구(1번 화면 개최 월·상설 행사) — 필터 하나 때문에 한 줄을 통째로 쓰지 않는다.
     두 컨트롤을 같은 알약 모양(높이 34 · 둥근 끝 · 같은 테두리·그림자)으로 맞췄다(2026-09-22). */
  .view-tools{flex:0 0 auto;display:flex;align-items:center;gap:8px;margin-left:auto;align-self:center;}
  .tool-pill{position:relative;display:inline-flex;align-items:center;gap:10px;height:34px;padding:0 14px;
    border:1px solid var(--border);border-radius:999px;background:var(--bg-panel);
    box-shadow:0 1px 2px var(--shadow);font-size:12.5px;color:var(--text-muted);cursor:pointer;
    transition:border-color .15s ease, box-shadow .15s ease, background-color .15s ease;white-space:nowrap;}
  .tool-pill:hover{border-color:color-mix(in srgb, var(--accent) 45%, var(--border));}
  .tool-pill:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);}
  .tool-pill .k{font-weight:600;}
  /* 개최 월 — 기본 select 모양을 지우고 글자만 남긴다. 화살표는 따로 그린다 */
  .tool-select select{appearance:none;-webkit-appearance:none;border:0;outline:0;background:transparent;
    font:inherit;font-size:13px;font-weight:700;color:var(--text);height:100%;padding:0 18px 0 0;margin-right:-4px;cursor:pointer;}
  .tool-select select option{color:var(--text);background:var(--bg-panel);}
  .tool-select .chev{position:absolute;right:14px;top:50%;width:6px;height:6px;margin-top:-5px;
    border-right:1.5px solid var(--text-muted);border-bottom:1.5px solid var(--text-muted);transform:rotate(45deg);pointer-events:none;}
  /* 상설 행사 포함 — 체크박스를 스위치로. 실제 체크박스는 보이지 않게 남겨 키보드·화면낭독기가 그대로 쓴다 */
  .tool-switch input{position:absolute;opacity:0;width:1px;height:1px;margin:0;}
  .tool-switch .sw{position:relative;width:30px;height:18px;border-radius:999px;background:var(--border);
    transition:background-color .18s ease;flex:0 0 auto;}
  .tool-switch .sw::after{content:'';position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;
    background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .18s ease;}
  .tool-switch input:checked + .sw{background:var(--accent);}
  .tool-switch input:checked + .sw::after{transform:translateX(12px);}
  .tool-switch:has(input:checked){border-color:var(--accent);background:var(--accent-soft);color:var(--text);}
  /* 다음 단계로 — 같은 알약 모양, 액센트로 채워 '행동' 버튼임을 구분 */
  .tool-next{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:700;text-decoration:none;}
  .tool-next:hover{border-color:var(--accent);filter:brightness(1.06);}
  .view-head .view-desc{flex:1 1 auto;min-width:0;margin-top:0;max-width:none;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  @media (max-width:900px){
    .view-head{display:block;}
    .view-tools{margin:10px 0 0;}
    .view-head .view-desc{margin-top:6px;white-space:normal;}
  }
  .view-eyebrow{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);}
  .view-title{font-size:24px;font-weight:800;margin-top:4px;}
  .view-desc{font-size:13.5px;color:var(--text-muted);margin-top:6px;max-width:62ch;}

  /* ---------- primitives ---------- */
  .card{background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius-lg);padding:20px;box-shadow:0 1px 3px var(--shadow);}
  .card-title{font-size:13px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.03em;margin-bottom:14px;display:flex;align-items:center;justify-content:space-between;gap:8px;}
  .stack{display:flex;flex-direction:column;gap:16px;}
  .row{display:flex;gap:16px;flex-wrap:wrap;}
  .grid{display:grid;gap:16px;}
  .grid-4{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));}
  .grid-2{grid-template-columns:repeat(auto-fit,minmax(340px,1fr));}
  .scroll-x{overflow-x:auto;}

  .badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;font-size:11.5px;font-weight:700;white-space:nowrap;}
  .badge-accent{background:var(--accent-soft);color:var(--accent);}
  .badge-accent2{background:var(--accent2-soft);color:var(--accent2);}
  .badge-good{background:var(--good-soft);color:var(--good);}
  .badge-warn{background:var(--warn-soft);color:var(--warn);}
  .badge-critical{background:var(--critical-soft);color:var(--critical);}
  .badge-muted{background:var(--bg-subtle);color:var(--text-muted);}

  .btn{
    text-decoration:none;
    display:inline-flex;align-items:center;gap:8px;
    padding:11px 18px;border-radius:999px;border:1px solid transparent;
    font-weight:700;font-size:13.5px;cursor:pointer;
  }
  .btn-primary{background:var(--accent);color:var(--accent-ink);}
  .btn-primary:hover{filter:brightness(1.08);}
  .btn-ghost{background:transparent;border-color:var(--border);color:var(--text);}
  .btn-ghost:hover{background:var(--bg-subtle);}
  .btn-sm{padding:6px 12px;font-size:12px;}
  .btn[disabled]{opacity:.45;cursor:not-allowed;}

  .next-row{display:flex;justify-content:flex-end;margin-top:24px;}

  .note{
    display:flex;gap:10px;
    background:var(--bg-subtle);
    border:1px dashed var(--border);
    border-radius:var(--radius-md);
    padding:12px 14px;
    font-size:12.5px;
    color:var(--text-muted);
  }
  .note strong{color:var(--text);}
  .note.accent2{background:var(--accent2-soft);border-color:transparent;color:var(--text);}

  /* ---------- KPI ---------- */
  .kpi .label{font-size:11.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--text-muted);font-weight:700;}
  .kpi .value{font-size:27px;font-weight:800;margin-top:8px;}
  .kpi .delta{font-size:12.5px;font-weight:700;margin-top:6px;display:inline-flex;align-items:center;gap:3px;}
  .kpi .delta.up{color:var(--good);}
  .kpi .delta.down{color:var(--critical);}
  .kpi .sub{font-size:12px;color:var(--text-faint);margin-top:2px;}

  /* ---------- charts ---------- */
  .chart-wrap{width:100%;}
  .chart-wrap svg{width:100%;height:auto;display:block;min-width:480px;}
  .legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:12px;font-size:12px;color:var(--text-muted);}
  .legend span{display:inline-flex;align-items:center;gap:6px;}
  .legend i{width:9px;height:9px;border-radius:2px;display:inline-block;}

  .radar-box{display:flex;flex-direction:column;align-items:center;gap:10px;}
  .radar-box svg{width:100%;max-width:260px;}
  .radar-score{font-size:30px;font-weight:800;}
  .radar-score small{font-size:12px;font-weight:600;color:var(--text-muted);}

  .donut-row{display:flex;align-items:center;gap:20px;flex-wrap:wrap;}
  .donut{width:128px;height:128px;border-radius:50%;flex:0 0 auto;position:relative;
    background:conic-gradient(var(--accent) 0 28%,var(--accent2) 28% 45%,var(--good) 45% 60%,var(--warn) 60% 78%,var(--text-faint) 78% 100%);}
  .donut::after{content:"";position:absolute;inset:20px;border-radius:50%;background:var(--bg-panel);}
  .donut-legend{display:flex;flex-direction:column;gap:6px;font-size:13px;}
  .donut-legend li{display:flex;align-items:center;gap:8px;}
  .donut-legend i{width:9px;height:9px;border-radius:2px;flex:0 0 auto;}

  .bars{display:flex;align-items:flex-end;gap:14px;height:150px;padding-top:10px;}
  .bar-col{display:flex;flex-direction:column;align-items:center;gap:6px;flex:1;height:100%;justify-content:flex-end;}
  /* ⚠️ .bar-col 로 감싼다. 전역 `.bar`로 두면 1번 화면 간트 막대(.cal .bar)까지 잡아
     max-width:34px 이 걸린다 — 87일짜리 축제도 3일짜리와 같은 길이로 잘렸다(2026-09-12 수정). */
  .bar-col .bar{width:100%;max-width:34px;border-radius:6px 6px 2px 2px;background:var(--accent);}
  .bar-col .bar.peak{background:var(--accent2);}
  .bar-col .bl{font-size:11px;color:var(--text-faint);}
  /* 2번 '방문객 연령 구성' (2026-09-22) — y축(0·50·100) + 막대 위 수치 + 50 점선(비슷한 규모의 보통 수준).
     카드를 세로 flex로 두고 차트가 남는 높이를 채운다 — 옆 관심 테마 카드와 높이가 맞아 아래가 비지 않는다. */
  .age-card{display:flex;flex-direction:column;}
  .skew-chart{flex:1;min-height:170px;display:grid;grid-template-columns:30px minmax(0,1fr);
    grid-template-rows:minmax(0,1fr) auto auto;column-gap:8px;padding-top:18px;}
  .skew-y{position:relative;font-size:10.5px;color:var(--text-faint);font-variant-numeric:tabular-nums;}
  .skew-y span{position:absolute;right:0;transform:translateY(50%);line-height:1;}
  .skew-y span.mid{color:var(--text-muted);font-weight:700;}
  .skew-plot{position:relative;}
  .skew-plot .gl{position:absolute;left:0;right:0;border-top:1px solid var(--border);}
  .skew-plot .gl.mid{border-top:1.5px dashed var(--text-faint);}
  .skew-cols{position:absolute;inset:0;display:flex;gap:10px;padding:0 4px;}
  .skew-col{position:relative;flex:1;display:flex;align-items:flex-end;justify-content:center;}
  .skew-col .bar{width:100%;max-width:30px;min-height:2px;border-radius:5px 5px 2px 2px;background:var(--accent);opacity:.85;}
  .skew-col .bar.hi{background:var(--accent2);opacity:1;}
  .skew-col .bv{position:absolute;left:0;right:0;text-align:center;font-size:11px;font-weight:700;
    color:var(--text);font-variant-numeric:tabular-nums;transform:translateY(-3px);}
  .skew-x{grid-column:2;display:flex;gap:10px;padding:6px 4px 0;}
  .skew-x span{flex:1;text-align:center;font-size:11px;color:var(--text-faint);}
  .skew-legend{grid-column:2;display:flex;gap:14px;flex-wrap:wrap;margin-top:8px;font-size:11px;color:var(--text-muted);}
  .skew-legend i{display:inline-block;vertical-align:middle;margin-right:5px;}
  .skew-legend .dash{width:16px;border-top:1.5px dashed var(--text-faint);}
  .skew-legend .sw{width:10px;height:10px;border-radius:3px;background:var(--accent2);}

  /* ---------- resource tabs ---------- */
  .tabbar{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px;}
  .tab{padding:7px 14px;border-radius:999px;border:1px solid var(--border);background:var(--bg-panel);font-size:12.5px;font-weight:700;cursor:pointer;color:var(--text-muted);}
  .tab.is-active{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);}
  .res-panel{display:none;}
  .res-panel.is-active{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;}
  .res-card{border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;background:var(--bg-panel);}
  .res-thumb{height:92px;background:linear-gradient(135deg,var(--accent-soft),var(--accent2-soft));display:flex;align-items:center;justify-content:center;font-size:22px;color:var(--accent);}
  .res-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
  .res-body{padding:10px 12px;}
  .res-body .t{font-weight:700;font-size:13.5px;}
  .res-body .m{font-size:11.5px;color:var(--text-faint);margin-top:2px;}

  .infra-badges{display:flex;flex-wrap:wrap;gap:8px;}

  /* ---------- form ---------- */
  fieldset{border:none;padding:0;margin:0;}
  .field{display:flex;flex-direction:column;gap:8px;padding:16px 0;border-bottom:1px solid var(--border);}
  .field[hidden]{display:none;}   /* .field의 display:flex가 hidden 속성을 덮어쓰지 않게 */
  .field:last-child{border-bottom:none;}
  .field-label{font-size:13px;font-weight:700;}
  .field-help{font-size:11.5px;color:var(--text-faint);}
  .choice-row{display:flex;flex-wrap:wrap;gap:8px;}
  .chip-input{position:relative;}
  .chip-input input{position:absolute;opacity:0;inset:0;cursor:pointer;}
  .chip-input label{
    display:inline-flex;align-items:center;gap:6px;
    padding:8px 14px;border-radius:999px;border:1px solid var(--border);
    font-size:12.5px;font-weight:600;cursor:pointer;background:var(--bg-panel);color:var(--text-muted);
  }
  .chip-input input:checked + label{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);}
  .chip-input.muted label{opacity:.55;}
  .chip-input.muted input{cursor:not-allowed;}
  .date-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
  input[type="date"],input[type="text"],textarea,select.plain{
    font:inherit;padding:9px 12px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--bg-panel);color:var(--text);
  }
  textarea{width:100%;resize:vertical;min-height:70px;}

  /* ---------- chat ---------- */
  .chat-shell{display:grid;grid-template-columns:1fr 260px;gap:18px;align-items:start;}
  .chat-panel{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-panel);display:flex;flex-direction:column;height:600px;}
  .chat-log{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:16px;}
  .msg{display:flex;gap:10px;max-width:88%;}
  .msg .who{flex:0 0 auto;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:800;}
  .msg.ai .who{background:var(--accent2-soft);color:var(--accent2);}
  .msg.user{align-self:flex-end;flex-direction:row-reverse;}
  .msg.user .who{background:var(--accent-soft);color:var(--accent);}
  .bubble{background:var(--bg-subtle);border-radius:14px;padding:12px 14px;font-size:13.5px;}
  .msg.user .bubble{background:var(--accent-soft);}
  .cite{margin-top:8px;font-size:11px;color:var(--text-faint);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}
  .idea-cards{display:flex;flex-direction:column;gap:10px;margin-top:12px;}
  .idea-card{border:1px solid var(--border);border-radius:var(--radius-md);padding:12px 14px;background:var(--bg-panel);display:flex;justify-content:space-between;align-items:center;gap:12px;}
  .idea-card.is-selected{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft);}
  .idea-card > div{flex:1;min-width:0;}
  .idea-card > .btn{flex:0 0 68px;width:68px;justify-content:center;text-align:center;align-self:center;padding:6px 8px;line-height:1.3;white-space:normal;word-break:keep-all;border-radius:16px;}
  .idea-card .it{font-weight:700;font-size:13.5px;}
  .idea-card .ib{font-size:11.5px;color:var(--text-faint);margin-top:3px;}
  .chat-input{display:flex;gap:8px;padding:14px;border-top:1px solid var(--border);}
  .chat-input input{flex:1;}
  .ref-panel{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-panel);padding:16px;}
  .ref-panel h4{font-size:12.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted);margin-bottom:10px;}
  .ref-panel li{font-size:12.5px;padding:7px 0;border-bottom:1px solid var(--border);color:var(--text-muted);}
  .ref-panel li:last-child{border-bottom:none;}
  .typing{display:inline-flex;gap:3px;padding:4px 0;}
  .typing i{width:5px;height:5px;border-radius:50%;background:var(--text-faint);animation:blink 1.1s infinite ease-in-out;}
  .typing i:nth-child(2){animation-delay:.15s;}
  .typing i:nth-child(3){animation-delay:.3s;}
  @keyframes blink{0%,80%,100%{opacity:.25;}40%{opacity:1;}}

  /* ---------- compare ---------- */
  .idea-recap{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;padding:14px 18px;border-radius:var(--radius-md);background:var(--accent2-soft);margin-bottom:18px;}
  .segmented{display:inline-flex;border:1px solid var(--border);border-radius:999px;padding:3px;background:var(--bg-panel);}
  .segmented button{padding:6px 14px;border-radius:999px;border:none;background:transparent;font-size:12px;font-weight:700;color:var(--text-muted);cursor:pointer;}
  .segmented button.is-active{background:var(--accent);color:var(--accent-ink);}
  .match-card{border:1px solid var(--border);border-radius:var(--radius-md);padding:16px;background:var(--bg-panel);display:flex;flex-direction:column;gap:8px;}
  .match-card .sim{font-size:22px;font-weight:800;color:var(--accent);}
  .match-card .region{font-weight:700;font-size:14px;}
  .match-detail{margin-top:12px;padding-top:12px;border-top:1px dashed var(--border);display:none;font-size:12.5px;color:var(--text-muted);}
  .match-detail.is-open{display:block;}
  .match-detail .stat{display:flex;justify-content:space-between;padding:4px 0;}
  .match-detail .stat b{color:var(--text);}
  .abs-figure{display:none;color:var(--text-faint);}
  .compare[data-mode="abs"] .pct-figure{display:none;}
  .compare[data-mode="abs"] .abs-figure{display:inline;}
  .steps4{display:flex;flex-direction:column;gap:10px;margin-top:14px;}
  .step4{display:flex;gap:10px;align-items:flex-start;font-size:12.5px;color:var(--text-muted);}
  .step4 .n{flex:0 0 auto;width:20px;height:20px;border-radius:50%;background:var(--bg-subtle);display:flex;align-items:center;justify-content:center;font-size:10.5px;font-weight:800;color:var(--text-muted);}

  /* ---------- report ---------- */
  .report-shell{display:grid;grid-template-columns:230px 1fr;gap:18px;align-items:start;}
  .toc{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-panel);padding:14px;position:sticky;top:78px;}
  .toc li{margin-bottom:2px;}
  .toc a{display:flex;justify-content:space-between;gap:8px;padding:8px 10px;border-radius:var(--radius-sm);font-size:12.5px;color:var(--text-muted);text-decoration:none;}
  .toc a:hover{background:var(--bg-subtle);color:var(--text);}
  .toc .sub{padding-left:18px;font-size:12px;}
  .chapter{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-panel);padding:20px;margin-bottom:16px;}
  .chapter h3{font-size:15px;font-weight:800;display:flex;align-items:center;gap:8px;margin-bottom:10px;}
  .chapter p{font-size:13.5px;color:var(--text-muted);max-width:100ch;line-height:1.7;}
  .chapter .toolbar{display:flex;gap:8px;margin-top:12px;}
  .chapter p + p,.chapter p + ul,.chapter ul + p{margin-top:8px;}
  .chapter ul{margin:0;padding-left:18px;list-style:disc;font-size:13.5px;color:var(--text-muted);max-width:100ch;line-height:1.7;}
  .chapter li{margin-bottom:6px;}
  .chapter li strong{color:var(--text);font-weight:700;}
  .chapter .sub-title{font-size:13.5px;font-weight:700;color:var(--text);margin-top:14px;}
  .chapter .fine{font-size:12px;color:var(--text-faint);}
  .archive-item.is-current{background:var(--bg-subtle);}
  .archive-item{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0;border-bottom:1px solid var(--border);flex-wrap:wrap;}
  .archive-item:last-child{border-bottom:none;}
  .archive-item .t{font-weight:700;font-size:13.5px;}
  .archive-item .m{font-size:11.5px;color:var(--text-faint);}

  @media (max-width:900px){
    .app-shell{grid-template-columns:1fr;}
    .rail{position:sticky;height:auto;flex-direction:row;overflow-x:auto;padding:12px;gap:14px;}
    .brand{display:none;}
    .rail-account{display:none;}
    .rail-region{flex-direction:row;align-items:center;flex:0 0 auto;}
    .rail-label{display:none;}
    .rail-region select{width:auto;}
    .steps{flex-direction:row;}
    .step{flex-direction:column;align-items:center;gap:4px;min-width:74px;text-align:center;}
    .step .label small{display:none;}
    .step:not(:last-child)::after{display:none;}
    .rail-foot{margin-top:0;border-top:none;padding:0;flex:0 0 auto;}
    .rail-foot .updated,.rail-foot span:last-child{display:none;}
    .chat-shell{grid-template-columns:1fr;}
    .report-shell{grid-template-columns:1fr;}
    .toc{position:static;}
    .view{padding:20px 16px 60px;}
  }

  /* ═══════════════════════════════════════════════════════════
     1번 화면 · 축제 캘린더 이식 CSS
     출처: 02.region-analysis-mockup.html <style> 전체를 `.cal ` 로 스코프.
     제외한 것 — :root 토큰(위 별칭으로 대체) / topbar·tabs·brand·ghost·badge
     (mockup rail 사용) / .wrap(=.view 가 전체 폭) / 설계 노트 / footer
     ═══════════════════════════════════════════════════════════ */
.cal *{box-sizing:border-box}
.cal h1,.cal h2,.cal h3,.cal h4,.cal p,.cal ul,.cal ol{margin:0}
.cal ul{list-style:none;padding:0}
.cal button,.cal select{font:inherit;color:inherit}
.cal :focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:4px}
.cal .field{display:flex;flex-direction:column;gap:5px;min-width:0}
.cal .field label{font-size:11.5px;color:var(--muted)}
.cal .field select{height:36px;padding:0 30px 0 11px;border-radius:var(--r-ctrl); border:1px solid var(--border);background:var(--surface-2);appearance:none;cursor:pointer; background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%); background-position:calc(100% - 16px) 15px,calc(100% - 11px) 15px; background-size:5px 5px,5px 5px;background-repeat:no-repeat}
.cal .stamp{font-size:12px;color:var(--muted);padding-bottom:9px}
/* ── 카드 ─────────────────────────────────────────────── */
.cal .card{background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-card); padding:18px 20px 20px;margin-bottom:16px}
.cal .card-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:14px}
.cal .card-hd h2{font-size:15px;font-weight:600;letter-spacing:-.01em}
.cal .card-hd .src{font-size:11.5px;color:var(--muted);margin-top:3px;font-variant-numeric:tabular-nums}
.cal .card-tools{display:flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:flex-end}
.cal .tbtn{padding:5px 10px;border-radius:var(--r-ctrl);border:1px solid var(--border); background:transparent;color:var(--text-secondary);font-size:12px;cursor:pointer;white-space:nowrap}
.cal .tbtn:hover{background:var(--surface-2)}
.cal .tbtn[aria-pressed="true"]{background:var(--surface-2);color:var(--text-primary);font-weight:600}
.cal .legend{display:flex;gap:14px;flex-wrap:wrap}
.cal .legend li{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-secondary)}
.cal .legend .sw{width:16px;height:3px;border-radius:2px;flex:none}
.cal .legend .sw.dash{background:repeating-linear-gradient(90deg,var(--demph) 0 4px,transparent 4px 7px)}
.cal .legend .sw.box{width:11px;height:11px;border-radius:var(--r-mark)}
/* ── 타임라인 공통 (상단 차트 ↔ 간트 x축 정렬) ─────────── */
.cal .tl-row{display:grid;grid-template-columns:var(--lane) 1fr;align-items:stretch}
.cal .tl-lane{position:relative;padding-right:12px}
.cal .tl-plot{position:relative;min-width:0}
.cal .tl-head .tl-plot{height:22px}
.cal .tl-head .m-lbl{position:absolute;top:0;transform:translateX(-50%);font-size:11.5px;color:var(--muted); font-variant-numeric:tabular-nums;white-space:nowrap}
.cal .tl-head .m-lbl.now{color:var(--text-primary);font-weight:700}
/* 격자 오버레이. laned = 왼쪽 라벨 열만큼 밀어서 플롯 영역에만 걸친다 */
.cal .grid-ov{position:absolute;inset:0;pointer-events:none;z-index:0}
.cal .grid-ov.laned{left:var(--lane);z-index:2}
.cal .grid-ov i{position:absolute;top:0;bottom:0;width:1px;background:var(--gridline)}
.cal .now-band{position:absolute;top:0;bottom:0;background:var(--surface-2)}
.cal .today-line{position:absolute;top:0;bottom:0;width:0;border-left:1px dashed var(--baseline)}
.cal .y-tick{position:absolute;right:12px;transform:translateY(-50%);font-size:11px;color:var(--muted); font-variant-numeric:tabular-nums}
.cal svg{display:block;width:100%;height:auto;overflow:visible}
.cal .tl-plot svg{position:relative;z-index:1}
/* 격자·현재월 띠 위에 선이 그려지도록 */
.cal .grid-line{stroke:var(--gridline);stroke-width:1}
.cal .ln-cur{stroke:var(--series-1);fill:none;stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round}
.cal .ln-prev{stroke:var(--demph);fill:none;stroke-width:2;stroke-dasharray:5 4;stroke-linecap:round}
.cal .dot-cur{fill:var(--series-1);stroke:var(--surface-1);stroke-width:2}
.cal .dot-now{fill:var(--surface-1);stroke:var(--series-1);stroke-width:3}
.cal .val{fill:var(--text-primary);font-size:11.5px;font-weight:600;font-variant-numeric:tabular-nums}
/* ── 간트 ─────────────────────────────────────────────── */
.cal .gantt{position:relative}
.cal .fest{border-top:1px solid var(--gridline)}
.cal .fest:first-child{border-top:0}
.cal .fest-row{display:grid;grid-template-columns:var(--lane) 1fr;align-items:center;width:100%; background:transparent;border:0;padding:0;cursor:pointer;text-align:left}
.cal .fest-row:hover{background:var(--surface-2)}
.cal .fest-row[aria-expanded="true"]{background:var(--surface-2)}
.cal .fest-lane{display:flex;align-items:center;gap:7px;padding:8px 12px 8px 0;min-width:0}
.cal .caret{flex:none;width:14px;color:var(--muted);font-size:10px;transition:transform .15s}
.cal .fest-row[aria-expanded="true"] .caret{transform:rotate(90deg);color:var(--series-1)}
.cal .fest-txt{display:flex;flex-direction:column;min-width:0}
.cal .fest-region{font-size:10.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal .fest-name{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal .fest-row[aria-expanded="true"] .fest-name{font-weight:600}
.cal .fest.mine .fest-name{color:var(--series-1);font-weight:600}
.cal .fest-plot{position:relative;height:48px}
.cal .bar{position:absolute;top:16px;height:16px;max-width:none;border-radius:var(--r-mark);background:var(--ref); overflow:hidden;min-width:3px}
.cal .fest.mine .bar{outline:1.5px solid var(--series-1);outline-offset:1.5px}
.cal .bar.done{background:var(--demph)}
.cal .bar.live{background:var(--meter-track)}
.cal .bar.soon{background:var(--ref)}
.cal .bar > i{position:absolute;inset:0 auto 0 0;background:var(--series-1);border-radius:var(--r-mark)}
.cal .fest-row[aria-expanded="true"] .bar{outline:2px solid var(--series-1);outline-offset:2px}
.cal .bar-lbl{position:absolute;top:17px;font-size:11px;color:var(--muted);white-space:nowrap; font-variant-numeric:tabular-nums}
.cal .chip{display:inline-flex;align-items:center;padding:2px 7px;border-radius:999px;font-size:10.5px; font-weight:600;white-space:nowrap;border:1px solid var(--border);background:var(--surface-2);color:var(--text-secondary)}
.cal .chip.live{background:var(--series-1);color:#fff;border-color:transparent}
.cal .chip.soon{color:var(--series-1);border-color:var(--series-1)}
/* ── 아코디언 패널 ────────────────────────────────────── */
.cal .fest-panel{position:relative;z-index:3;background:var(--surface-2);border-radius:var(--r-ctrl); padding:18px 20px;margin:0 0 10px}
.cal .fest-panel[hidden]{display:none}
.cal .panel-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:24px}
.cal .panel-h{font-size:12px;font-weight:600;color:var(--text-secondary);margin-bottom:10px; letter-spacing:.02em}
.cal .kv{border-top:1px solid var(--border)}
.cal .kv div{display:flex;gap:14px;padding:7px 0;font-size:12.5px}
.cal .kv div+div{border-top:1px solid var(--border)}
.cal .kv dt{color:var(--muted);flex:none;width:64px}
.cal .kv dd{margin:0;min-width:0}
/* 축제 상세 포스터 — API가 주는 firstimage. 없는 축제(710건 중 7건)는 아예 안 그린다 */
/* 간트 페이지 이동 — 한 달에 150건 넘는 달이 있어 여러 쪽으로 끊는다(_calendar.js PER_PAGE) */
.cal .pager{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:14px}
.cal .pager .tbtn[disabled]{opacity:.4;cursor:default}
.cal .pager-info{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
/* 영상 묶음이 검색 결과인지 권역 채널인지 밝히는 한 줄 */
.cal .ch-note{margin-top:8px;font-size:11px;color:var(--muted)}
.cal .fest-poster{width:100%;max-height:200px;object-fit:cover;border-radius:var(--r-ctrl);
  border:1px solid var(--border);margin-bottom:12px;display:block}
.cal .kv dd a{color:var(--accent)}
/* 간트 월 필터 — 축제가 연 700건이라 한 달씩 끊어 본다 */
.cal .fest-filter{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}
.cal .fest-filter select{font:inherit;color:var(--text);background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--r-ctrl);padding:5px 8px}
.cal .mini{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:14px}
.cal .mini div{background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-ctrl);padding:10px 12px}
.cal .mini .m-l{font-size:11px;color:var(--muted)}
.cal .mini .m-v{font-size:18px;font-weight:600;letter-spacing:-.02em;margin-top:2px;font-variant-numeric:tabular-nums}
.cal .mini .m-d{font-size:11px;font-weight:600}
.cal .up{color:var(--good)}
.cal .down{color:var(--bad)}
.cal .ai{margin-top:14px;padding:11px 13px;border-radius:var(--r-ctrl);background:var(--surface-1); border:1px solid var(--border);font-size:12.5px;color:var(--text-secondary);line-height:1.6}
.cal .ai b{color:var(--text-primary);font-weight:600}
.cal .ai .tag{display:block;font-size:11px;color:var(--series-1);font-weight:600;margin-bottom:3px}
/* ── 채널 / 썸네일 ────────────────────────────────────── */
.cal .ch-hd{display:flex;align-items:center;gap:9px;margin-bottom:11px}
.cal .avatar{width:34px;height:34px;border-radius:50%;flex:none;display:grid;place-items:center; font-size:12px;font-weight:700;color:#fff;background:var(--series-1);letter-spacing:-.03em}
.cal .ch-meta{min-width:0}
.cal .ch-name{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal .ch-sub{font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.cal .ch-open{margin-left:auto;flex:none}
.cal .strip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.cal .strip.wide-3{grid-template-columns:repeat(3,1fr)}
.cal .vid{min-width:0}
.cal .thumb{position:relative;aspect-ratio:9/16;border-radius:var(--r-ctrl);overflow:hidden; background:linear-gradient(150deg,color-mix(in srgb,var(--tint,#2a78d6) 34%,var(--surface-2)) 0%, color-mix(in srgb,var(--tint,#2a78d6) 10%,var(--surface-2)) 55%,var(--surface-2) 100%); border:1px solid var(--border);display:grid;place-items:center}
.cal .thumb.wide{aspect-ratio:16/9}
.cal .thumb::after{content:"";width:0;height:0;border-style:solid;border-width:9px 0 9px 15px; border-color:transparent transparent transparent color-mix(in srgb,var(--text-primary) 32%,transparent)}
.cal .dur{position:absolute;right:6px;bottom:6px;padding:1px 5px;border-radius:4px;font-size:10.5px; font-weight:600;background:rgba(0,0,0,.68);color:#fff;font-variant-numeric:tabular-nums}
.cal .sflag{position:absolute;left:6px;top:6px;padding:1px 6px;border-radius:4px;font-size:10px; font-weight:700;background:var(--neg);color:#fff;letter-spacing:.02em}
.cal .v-title{font-size:12px;line-height:1.4;margin-top:7px;display:-webkit-box;-webkit-line-clamp:2; -webkit-box-orient:vertical;overflow:hidden}
.cal .v-meta{font-size:11px;color:var(--muted);margin-top:3px;font-variant-numeric:tabular-nums}
.cal .ch-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.cal .ch-card{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-card);padding:14px 16px 16px}
.cal .empty-note{font-size:12.5px;color:var(--muted);padding:10px 0 0}
/* ── 표 보기 ──────────────────────────────────────────── */
.cal .table-wrap{overflow-x:auto;max-height:360px;overflow-y:auto}
.cal table{border-collapse:collapse;width:100%;font-size:12.5px;font-variant-numeric:tabular-nums}
.cal th,.cal td{padding:7px 10px;text-align:right;white-space:nowrap}
.cal th:first-child,.cal td:first-child{text-align:left}
.cal thead th{position:sticky;top:0;background:var(--surface-1);color:var(--text-secondary); font-weight:600;border-bottom:1px solid var(--baseline)}
.cal tbody tr+tr td{border-top:1px solid var(--gridline)}
.cal [hidden]{display:none !important}
@media (max-width:1080px){
  .cal .panel-grid,.cal .ch-grid{grid-template-columns:minmax(0,1fr)}
  .cal .strip{grid-template-columns:repeat(3,1fr)}
}
/* 2026-09-22: 권역 카드가 한 줄에 2개라 6권역이 세 줄(세로로 길게) 쌓였다. 1280px부터 한 줄에 3개로 →
   두 줄. 카드 폭이 좁아지니 쇼츠는 3개만 보이고 4번째는 '더 보기' 창에서 본다. 카드 여백도 줄였다. */
@media (min-width:1280px){
  .cal .ch-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
  .cal .ch-card{padding:12px 14px 14px}
  .cal .ch-card .strip:not(.wide-3){grid-template-columns:repeat(3,1fr);gap:10px}
  .cal .ch-card .strip:not(.wide-3) > .vid:nth-child(n+4){display:none}
}

/* ── 이식 조정 (mockup 쪽 레이아웃에 맞추느라 새로 쓴 것) ── */
.cal .filters{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;
  background:var(--bg-subtle);border:1px solid var(--border);border-radius:var(--radius-md);
  padding:14px 16px;margin-bottom:16px}
.cal .filters .spacer{flex:1}
@media (max-width:1080px){ .cal{--lane:160px} }

  /* ---------- index 허브 전용 ---------- */
  .hub{display:block;text-decoration:none;color:inherit;}
  .hub:hover{border-color:var(--accent);}
  .hub-hd{display:flex;align-items:center;gap:12px;margin-bottom:10px;}
  .hub-num{
    flex:0 0 auto;width:30px;height:30px;border-radius:50%;
    background:var(--accent);color:var(--accent-ink);
    display:flex;align-items:center;justify-content:center;
    font-size:13px;font-weight:800;
  }
  .hub-t{font-size:15px;font-weight:800;}
  .hub-s{font-size:11.5px;color:var(--text-faint);margin-top:1px;}
  .hub-hd .badge{margin-left:auto;}
  .hub-d{font-size:13px;color:var(--text-muted);line-height:1.65;}
  .hub-k{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px;padding:0;list-style:none;}
  .hub-k li{font-size:11.5px;padding:3px 9px;border-radius:999px;background:var(--bg-subtle);color:var(--text-muted);}
  .hub-flow{
    display:flex;align-items:center;flex-wrap:wrap;gap:8px;
    font-size:12.5px;color:var(--text-muted);
  }
  .hub-flow b{color:var(--text);font-weight:700;}
  .hub-flow i{color:var(--text-faint);font-style:normal;}

  /* ---------- index = 로그인 화면 ----------
     03.features.md 1번: 홍보 랜딩이 아니라 로그인이 서비스의 입구다.
     한 줄 소개 하나 + 아이디/비밀번호/로그인. 회원가입·비밀번호 찾기 없음.
     지역 선택도 없다 — 소속 지자체는 계정에 매여 있다. */
  .login-page{
    min-height:100vh;
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:26px;padding:40px 20px;
  }
  .login-brand{text-align:center;}
  .login-brand .mark{font-size:30px;font-weight:800;letter-spacing:-0.02em;}
  .login-brand .mark span{color:var(--accent);}
  .login-brand .tagline{
    font-size:14px;color:var(--text-muted);margin-top:10px;
    max-width:46ch;line-height:1.6;
    word-break:keep-all;   /* 한국어가 단어 중간에서 끊기지 않게 */
  }
  .login-card{
    width:100%;max-width:380px;
    background:var(--bg-panel);border:1px solid var(--border);
    border-radius:var(--radius-lg);padding:28px 26px;
    box-shadow:0 1px 3px var(--shadow);
  }
  .login-field{display:flex;flex-direction:column;gap:7px;margin-bottom:16px;}
  .login-field label{font-size:12.5px;font-weight:700;}
  .login-field input{
    height:42px;padding:0 13px;
    border:1px solid var(--border);border-radius:var(--radius-sm);
    background:var(--bg);color:var(--text);
    font:inherit;font-size:13.5px;
  }
  .login-field input:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent;}
  .login-submit{width:100%;justify-content:center;margin-top:4px;}
  .login-error{
    display:none;margin:0 0 14px;padding:9px 12px;
    border-radius:var(--radius-sm);background:var(--critical-soft);color:var(--critical);
    font-size:12.5px;font-weight:600;
  }
  .login-error.is-shown{display:block;}
  .login-demo{
    margin-top:20px;padding-top:16px;border-top:1px solid var(--border);
    font-size:12px;color:var(--text-faint);line-height:1.7;
  }
  .login-demo b{color:var(--text-muted);}
  .login-demo code{
    background:var(--bg-subtle);color:var(--text-muted);
    padding:1px 6px;border-radius:4px;font-size:11.5px;
  }
  .login-foot{
    display:flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:center;
    font-size:11.5px;color:var(--text-faint);text-align:center;
  }
  .login-foot a{color:var(--text-muted);}

  /* ---------- 1번 화면 · 전국 축제 지도 (2026-08-24) ----------
     경계 데이터 출처: southkorea/southkorea-maps (kostat 2018, MIT).
     원본 GeoJSON을 단순화(약 400m 허용오차)해 SVG path 로 구워 넣었다 —
     외부 파일 0개 원칙을 지키기 위해서다.
     ⚠️ 목업 축척에서 점으로도 안 보이는 원거리 도서(서해5도·울릉/독도)는 생략했고
        제주는 좌하단 인셋으로 뺐다. 실제 구현 시 정식 경계 데이터로 교체한다. */
  .cal-top{display:grid;grid-template-columns:340px minmax(0,1fr);gap:16px;align-items:stretch;}
  .cal-top>.card{margin-bottom:16px;}
  .cal .cal-map{display:flex;flex-direction:column;}
  .cal .cal-year{display:flex;flex-direction:column;justify-content:center;}

  /* 연간 흐름은 간트와 축을 공유하지 않으므로 y축 레인을 좁게 쓴다
     (212px 레인은 축제 이름 칸에 맞춘 값이라 반폭 카드에서는 과했다) */
  .cal .cal-year .tl-row{grid-template-columns:52px minmax(0,1fr);}
  .cal .cal-year .tl-lane{padding-right:8px;}
  /* '표로 보기' — 카드 높이(왼쪽 지도에 맞춰 늘어난 높이)를 표가 채운다. 원래는 360px 상한 +
     세로 가운데 정렬이라 표가 가운데 작게 떠 있었다(2026-09-21). 행은 남는 높이만큼 고르게 늘어난다. */
  .cal .cal-year.is-table{justify-content:flex-start;}
  .cal .cal-year.is-table .table-wrap{flex:1 1 auto;min-height:0;max-height:none;}
  .cal .cal-year.is-table .table-wrap table{height:100%;}
  /* 2번 화면 월별 외지인 추이도 같은 이유 — 레인에는 y축 눈금('1500 만명')만 들어간다 (2026-09-21) */
  .cal.mv-chart .tl-row{grid-template-columns:64px minmax(0,1fr);}
  .cal.mv-chart .tl-lane{padding-right:8px;}

  .krmap-wrap{position:relative;flex:1;display:flex;align-items:center;min-height:0;}
  /* .cal svg 는 값 라벨이 잘리지 않게 overflow:visible 이다 (연간 흐름용).
     지도는 확대하면 카드 밖으로 넘치므로 여기서만 되돌린다. */
  .cal svg.krmap{width:100%;max-height:430px;margin:0 auto;display:block;
    overflow:hidden;touch-action:none;cursor:grab;border-radius:var(--radius-sm);}
  .krmap.is-drag{cursor:grabbing;}
  .kr-land{fill:var(--bg-subtle);stroke:var(--text-faint);stroke-width:1.4;stroke-opacity:.5;
    vector-effect:non-scaling-stroke;}
  .kr-inset{fill:none;stroke:var(--text-faint);stroke-width:1.4;stroke-opacity:.45;
    stroke-dasharray:5 4;vector-effect:non-scaling-stroke;}
  .kr-halo{fill:transparent;}
  .kr-dot{fill:var(--text-muted);stroke:var(--bg-panel);stroke-width:4;r:13;}
  .kr-pin{cursor:pointer;}
  .kr-pin.mine .kr-dot{fill:var(--accent);r:17;}
  .kr-pin:hover .kr-dot,.kr-pin:focus-visible .kr-dot{fill:var(--accent);r:17;}
  .kr-pin.is-on .kr-dot{fill:var(--accent);r:19;}
  .kr-pin.is-on .kr-halo{fill:var(--accent-soft);}
  .kr-pin:focus{outline:none;}
  .kr-pin:focus-visible .kr-halo{fill:var(--accent-soft);}

  /* 확대 버튼은 지도 위 모서리에 얹는다 — 카드 헤더가 좁아 제목을 밀어냈다 */
  .kr-zoom{
    position:absolute;top:0;right:0;z-index:4;
    display:flex;flex-direction:column;gap:4px;
  }
  .kr-zoom .tbtn{
    width:28px;height:28px;padding:0;
    display:flex;align-items:center;justify-content:center;
    background:var(--bg-panel);font-size:14px;line-height:1;
  }

  .kr-tip{
    position:absolute;z-index:5;pointer-events:none;
    transform:translate(-50%,-100%);
    background:var(--text);color:var(--bg-panel);
    padding:7px 10px;border-radius:var(--radius-sm);
    font-size:12px;line-height:1.45;white-space:nowrap;
    box-shadow:0 2px 10px var(--shadow);
  }
  .kr-tip b{display:block;font-size:12.5px;font-weight:700;}
  .kr-tip span{opacity:.75;}

  @media (max-width:1080px){
    .cal-top{grid-template-columns:minmax(0,1fr);}
    .krmap{max-height:360px;}
  }

  /* ---------- 1번 화면 · 공식 채널 실데이터 (GET /api/channels) ----------
     쇼츠 썸네일은 세로 영상 양옆에 검은 띠를 붙인 4:3 이미지로만 받을 수 있어서
     9:16 틀에 가운데 맞춤으로 잘라 영상 부분만 보이게 한다. */
  .cal a.vid{display:block;text-decoration:none;color:inherit;}
  .cal a.vid:hover .thumb{border-color:var(--accent);}
  .cal a.vid:hover .v-title{color:var(--accent);}
  .cal a.vid:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:var(--r-ctrl);}
  .cal .thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;}
  .cal .thumb:has(img)::after{content:none;}
  .cal .thumb .sflag,.cal .thumb .dur{z-index:1;}
  .cal img.avatar{object-fit:cover;background:var(--bg-subtle);}
  .cal a.ch-open{text-decoration:none;}
  .cal .ch-filter{font-weight:600;color:var(--warn);}
  .cal .ch-msg{font-size:12.5px;color:var(--muted);padding:14px 2px;}

  /* ---------- 1번 화면 · 영상 재생 창(모달) ----------
     쇼츠는 세로 9:16, 일반 영상은 가로 16:9. 화면을 넘지 않게 높이·폭을 제한한다. */
  .yt-modal{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:16px;}
  .yt-modal[hidden]{display:none;}
  .yt-backdrop{position:absolute;inset:0;background:rgba(0,0,0,.72);}
  .yt-dialog{position:relative;background:var(--bg-panel);border:1px solid var(--border);
    border-radius:var(--radius-lg);padding:12px;box-shadow:0 12px 40px rgba(0,0,0,.45);max-width:100%;}
  /* width:0 + min-width:100% — 긴 제목이 창 폭을 늘리지 않게 한다(창 폭은 재생 틀이 정한다) */
  .yt-hd{display:flex;align-items:center;gap:8px;margin-bottom:10px;width:0;min-width:100%;}
  .yt-title{flex:1;min-width:0;margin:0;font-size:13px;font-weight:600;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  /* 창은 body 바로 아래에 붙어 .cal .tbtn 스타일이 안 먹는다 → 여기서 따로 준다 */
  .yt-ext,.yt-x{flex:none;display:inline-flex;align-items:center;justify-content:center;height:30px;
    padding:0 10px;border-radius:var(--radius-sm);border:1px solid var(--border);background:transparent;
    color:var(--text-muted);font:inherit;font-size:12px;text-decoration:none;cursor:pointer;white-space:nowrap;}
  .yt-ext:hover,.yt-x:hover{background:var(--bg-subtle);color:var(--text);}
  .yt-ext:focus-visible,.yt-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
  .yt-x{width:30px;padding:0;font-size:14px;}
  .yt-frame{width:min(960px, calc(100vw - 58px));aspect-ratio:16/9;background:#000;
    border-radius:var(--radius-sm);overflow:hidden;}
  .yt-frame.short{width:auto;height:min(78vh, 760px);aspect-ratio:9/16;}
  .yt-frame iframe{display:block;width:100%;height:100%;border:0;}
  body.yt-open{overflow:hidden;}
  /* 권역 '더 보기' (2026-09-22) — 카드 머리 오른쪽 버튼 + 큰 목록 창. 재생 창(z 100)이 이 창(z 90) 위에 뜬다 */
  .cal .ch-more-btn{margin-left:auto;display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 10px;
    border:1px solid var(--border);border-radius:999px;background:var(--bg-panel);color:var(--text-muted);
    font-size:11.5px;font-weight:600;cursor:pointer;transition:border-color .15s, color .15s;}
  .cal .ch-more-btn b{color:var(--accent);font-weight:700;}
  .cal .ch-more-btn:hover{border-color:var(--accent);color:var(--text);}
  .cal .ch-more-btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
  .more-modal{position:fixed;inset:0;z-index:90;display:grid;place-items:center;padding:24px;}
  .more-modal[hidden]{display:none;}
  .more-backdrop{position:absolute;inset:0;background:rgba(10,14,20,.55);}
  .more-dialog{position:relative;width:min(1080px,100%);max-height:calc(100vh - 48px);display:flex;flex-direction:column;
    background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius-lg);
    box-shadow:0 20px 50px rgba(0,0,0,.25);overflow:hidden;}
  .more-hd{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--border);}
  .more-head{min-width:0;}
  .more-title{font-size:16px;font-weight:800;color:var(--text);}
  .more-sub{font-size:12px;color:var(--text-faint);margin-top:2px;}
  .more-tabs{display:flex;gap:6px;margin-left:auto;}
  .more-body{overflow-y:auto;padding:18px 20px 22px;}
  .more-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:16px 12px;}
  .more-grid.wide{grid-template-columns:repeat(auto-fill,minmax(230px,1fr));}
  body.more-open{overflow:hidden;}
  @media (max-width:640px){
    .more-modal{padding:0;}
    .more-dialog{max-height:100vh;height:100vh;border-radius:0;}
    .more-hd{flex-wrap:wrap;}
  }


/* ③ 비슷한 지자체 채널에서 반응을 얻은 콘텐츠 · 축제 댓글 반응 (2026-09-13) ─────────── */
.cal .bench-mine-box{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-card);padding:12px 14px;margin-bottom:14px;font-size:12.5px;color:var(--text-secondary);line-height:1.65}
.cal .bench-mine-box p+p{margin-top:4px}
.cal .bench-mine-box b{color:var(--text-primary)}
.cal .bench-mine-note{margin:0 0 10px}
.cal .bench-table{display:flex;flex-direction:column;gap:2px}
.cal .bench-head,.cal .bench-row{display:grid;grid-template-columns:minmax(120px,1.3fr) minmax(0,2.4fr) 52px 64px 84px;align-items:center;gap:10px}
.cal .bench-head{font-size:11px;color:var(--muted);padding:0 8px 6px}
.cal .bench-head small{font-weight:400}
.cal .bench-head span:nth-child(4),.cal .bench-head span:nth-child(5){text-align:right}
.cal .bench-row{width:100%;text-align:left;border:1px solid transparent;background:transparent;border-radius:var(--r-ctrl);padding:7px 8px;font-size:12.5px;color:var(--text-primary);cursor:pointer;font-variant-numeric:tabular-nums}
.cal .bench-row:hover{background:var(--surface-2)}
.cal .bench-row.on{background:var(--surface-2);border-color:var(--border)}
.cal .bench-label small{font-size:10.5px;color:var(--warn);margin-left:4px;font-weight:400}
.cal .bench-bar{position:relative;height:10px;background:var(--surface-1);border-radius:4px}
.cal .bench-bar i{position:absolute;left:0;top:0;bottom:0;background:var(--series-1);border-radius:4px}
.cal .bench-bar .avg{position:absolute;top:-3px;bottom:-3px;width:2px;margin-left:-1px;background:var(--text-secondary)}
.cal .bench-rate{font-weight:600;text-align:right}
.cal .bench-n,.cal .bench-mine{font-size:11.5px;color:var(--muted);text-align:right}
.cal .bench-ex-h{margin-top:16px}
.cal .v-meta .ratio{color:var(--series-1);font-weight:600}
.cal .fest-react{margin-top:14px}
.cal .react-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.cal .react-col{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-ctrl);padding:10px 12px;min-width:0}
.cal .react-h{font-size:12px;font-weight:600;margin-bottom:6px}
.cal .react-col.bad .react-h{color:var(--warn)}
.cal .react-col.good .react-h{color:var(--series-1)}
.cal .react-item+.react-item{border-top:1px solid var(--border);margin-top:6px;padding-top:6px}
.cal .react-label{font-size:12.5px}
.cal .react-n{float:right;font-size:12px;font-variant-numeric:tabular-nums;color:var(--text-secondary)}
.cal .react-q{font-size:11.5px;color:var(--muted);margin-top:3px;line-height:1.5;overflow-wrap:anywhere}
.cal .react-empty{font-size:11.5px;color:var(--muted)}
@media (max-width:720px){
  .cal .bench-head,.cal .bench-row{grid-template-columns:minmax(0,1fr) 48px 58px}
  .cal .bench-bar,.cal .bench-mine,.cal .bench-head span:nth-child(2),.cal .bench-head span:nth-child(3),.cal .bench-head span:nth-child(5){display:none}
  .cal .react-grid{grid-template-columns:minmax(0,1fr)}
}
.cal .bench-warn{color:var(--warn);font-size:11.5px}

/* 3번 화면 — 타깃 칩 옆 우리 지역 근거 수치 (2026-09-13) */
.chip-input .chip-hint{font-size:10.5px;font-weight:400;opacity:.75;white-space:nowrap}

/* 2번 화면 지자체 채널 분석 — 사례 영상 크기 (2026-09-14)
   1번 화면의 .strip(4칸 고정)을 넓은 2번 카드에 그대로 쓰면 쇼츠 한 장이 화면 절반 높이가 됐다.
   한 장 폭을 140px 안팎으로 묶고, 남는 칸은 비워 둔다. */
.cal .strip.bench-strip{grid-template-columns:repeat(auto-fill,minmax(118px,140px));gap:12px}
.cal .strip.bench-strip .vid:has(.thumb.wide){grid-column:span 2}
.cal .strip.bench-strip .v-title{font-size:11.5px}
.cal .strip.bench-strip .v-meta{font-size:10.5px}

/* ── 카드별 데이터 출처 배지 "i" (2026-09-20) ─────────────────────────
   왜 넣었나: 공모전 FAQ(09-20)가 "단순 데이터 출처 명시는 필수 사항"으로 정리했다.
   금지되는 건 *공사가 만든 서비스처럼 보이게 하는 것*이지 출처 표기가 아니다.
   → 카드마다 무슨 데이터를 썼는지 여기서 밝힌다. 로고 이미지는 쓰지 않고 텍스트만.
   ⚠️ `TourAPI` 단독 표기는 지양 대상이라 쓰지 않는다 — API 이름 + `출처: ⓒ한국관광공사`. */
.info-btn{
  /* 글자를 baseline 에 앉히면 'i' 처럼 내려뻗는 획이 없는 글자는 원 아래쪽에 붙는다.
     → inline-flex 로 박스 기준 가운데 정렬한다(글꼴 metrics 와 무관해진다).
     top:-1px 은 제목 글자와의 눈높이 보정(원이 x-height 기준보다 조금 크다). */
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  box-sizing:border-box;width:17px;height:17px;padding:0;margin-left:6px;
  border:1px solid transparent;border-radius:999px;background:var(--accent-soft);
  color:var(--accent);font:700 11px/1 ui-sans-serif,system-ui,sans-serif;
  font-style:italic;cursor:pointer;
  /* ⚠️ .card-title · .kpi .label 은 text-transform:uppercase 라 그냥 두면
     2번 화면에서만 'i' 가 'I' 로 바뀌어 1번 화면과 모양이 달라진다. 상속을 끊는다. */
  text-transform:none;letter-spacing:0;
  /* 이탤릭 'i' 는 오른쪽으로 기울어 원 안에서 왼쪽으로 치우쳐 보인다 — 한 칸 밀어 준다 */
  text-indent:1px;
  vertical-align:middle;position:relative;top:-1px;
}
/* 출처 종류를 아이콘 색으로 구분한다 — 툴팁을 열기 전에도 무슨 데이터인지 보인다.
   kto = 공사 OpenAPI(청록) · yt = 유튜브(자주) · both = 둘 다(반반) */
.info-btn[data-kind="yt"]{background:var(--accent2-soft);color:var(--accent2)}
.info-btn[data-kind="both"]{background:linear-gradient(90deg,var(--accent-soft) 0 50%,var(--accent2-soft) 50% 100%)}
.info-btn:hover{filter:brightness(.95)}
.info-btn[aria-expanded="true"]{background:var(--accent);color:var(--accent-ink)}
.info-btn[data-kind="yt"][aria-expanded="true"]{background:var(--accent2);color:#fff}
.info-btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* .card-title 은 space-between 이라 그냥 두면 "i" 가 가운데로 밀린다 →
   남는 공간을 배지 앞에 몰아줘 제목 바로 옆에 붙인다. */
.card-title > .info-btn{margin-right:auto}
.kpi .label{display:flex;align-items:center;gap:0}
.kpi .label .info-btn{margin-left:auto;top:0}

.info-pop{
  position:fixed;z-index:70;max-width:340px;min-width:220px;
  padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius-md);
  background:var(--bg-panel);box-shadow:0 10px 28px var(--shadow);
  font-size:12px;line-height:1.55;color:var(--text-muted);
}
.info-pop .info-hd{font-size:11px;font-weight:700;letter-spacing:.03em;
  text-transform:uppercase;color:var(--text-faint);margin-bottom:6px}
.info-pop p{margin:0 0 5px}
.info-pop p:last-child{margin-bottom:0}
.info-pop p.kto::before,.info-pop p.ext::before{
  content:'';display:inline-block;width:6px;height:6px;border-radius:999px;
  margin-right:6px;vertical-align:1px;
}
.info-pop p.kto::before{background:var(--accent)}
.info-pop p.ext::before{background:var(--accent2)}
.info-pop p.sec{margin:10px 0 4px;font-size:11px;font-weight:700;color:var(--text);}
.info-pop p.sec:first-of-type{margin-top:2px;}
.info-pop:has(p.sec){max-width:400px;}
.info-pop p.src{margin-top:8px;padding-top:8px;border-top:1px solid var(--border);
  color:var(--text-faint);font-size:11.5px}

/* 좌측 레일 아래 출처 한 줄 — 툴팁을 열지 않아도 보이는 표기가 하나는 있어야 한다.
   텍스트만 쓴다(로고 이미지 금지, 09-20 FAQ). */
.rail-src{font-size:10.5px;line-height:1.55;color:var(--text-faint);margin:0}

/* 로그인 — 정식 명칭 한 줄(마크는 'K-파일럿'으로 짧게 쓰고, 풀네임은 여기서 보여준다) */
.login-brand .tagline .full-name{
  display:block;margin-bottom:6px;
  font-size:15px;font-weight:700;color:var(--text);letter-spacing:-.01em;
}
