/* ============================================================
 * Social Radar — Component utilities
 * 모든 변수는 tokens.css 의 :root 에서 옴.
 * ============================================================ */

/* ─── Type utils ─────────────────────────────────────────── */
.mono { font-family: var(--font-mono); letter-spacing: 0; }
.num  { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

.ink     { color: var(--ink); }
.ink-2   { color: var(--ink-2); }
.ink-3   { color: var(--ink-3); }
.ink-4   { color: var(--ink-4); }
.muted   { color: var(--muted); }
.muted-2 { color: var(--muted-2); }

.hair   { border-color: var(--line); }

.sec-label {
  font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted-2); font-weight: 600;
}

.hr { height: 1px; background: var(--line); }

/* ─── Surface ────────────────────────────────────────────── */
.surface      { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; }
.surface-flat { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; }

/* ─── Pills ──────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; padding: 2.5px 8px;
  border: 1px solid var(--line); border-radius: 999px;
  background: #fff; color: var(--ink-2);
}
.pill-ghost {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; padding: 2.5px 8px;
  border-radius: 999px;
  background: var(--bg-2); color: var(--muted);
}
.pill-blue {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; padding: 2.5px 9px;
  border-radius: 999px;
  background: var(--accent-soft); color: var(--accent); font-weight: 500;
  border: 1px solid rgba(42,109,244,.18);
}
.pill-soft-ok     { background: var(--ok-soft);     color: #14833b; border: 1px solid rgba(22,163,74,.2); }
.pill-soft-crit   { background: var(--crit-soft);   color: #991b1b; border: 1px solid rgba(220,38,38,.22); }
.pill-soft-warn   { background: var(--warn-soft);   color: #8a4c00; border: 1px solid rgba(217,119,6,.22); }
.pill-soft-violet { background: var(--violet-soft); color: #6d28d9; border: 1px solid rgba(124,58,237,.18); }
.pill-soft-teal   { background: var(--teal-soft);   color: #0b7568; border: 1px solid rgba(13,148,136,.2); }

/* ─── Tags ───────────────────────────────────────────────── */
.tag-dance     { font-size: 9.5px; font-weight: 700; letter-spacing: .1em; padding: 2px 7px; border-radius: 4px; background: var(--bg-2);     color: var(--muted); text-transform: uppercase; }

/* ─── Segmented control ──────────────────────────────────── */
.seg {
  display: inline-flex; padding: 3px;
  background: var(--bg-2); border-radius: 10px;
  font-size: 12px; gap: 2px;
}
.seg > button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 8px;
  color: var(--muted); font-weight: 500;
  cursor: pointer;
}
.seg > button.is-active {
  background: var(--surface); color: var(--accent);
  box-shadow: 0 1px 0 rgba(15,18,22,.04), 0 1px 3px rgba(15,18,22,.06);
}

/* ─── Nav section label (사이드바 그룹 헤더 — "분석" 같은 소제목) ──
 *  와이어프레임 realtime-feed.html L103~107 정합:
 *    font-size: 11px / weight 600 / ink-3 / uppercase / letter-spacing 0.06em
 *    padding: 14px 12px 6px (위쪽 14px 으로 위 nav-row 와의 간격을 시각적 분리)
 *  옛 인라인 클래스 (text-[10px] tracking-wide letter-spacing:.08em / weight 400) 는
 *  와이어프레임 대비 1px 작고 톤이 약했다 — 사용자 보고 (사이드바 비교 스샷). */
.nav-section {
  font-size: 11px; font-weight: 600; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 14px 12px 6px;
}

/* ─── Nav rows ───────────────────────────────────────────────
 *  v4 — 와이어프레임 기준으로 active 톤을 인디고 soft 로 갱신.
 *  옛 검정 톤(`var(--ink)` 배경) 을 더 부드러운 브랜드 soft 로 바꾸어
 *  사이드바에서 시각 무게가 본문 카드와 충돌하지 않게 한다. */
.nav-row {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: 8px;
  color: var(--ink-2); font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.nav-row:hover { background: var(--surface-hover); color: var(--ink); }
.nav-row.active {
  background: var(--brand-soft);
  color: var(--brand);
  font-weight: 600;
}
.nav-row.active [data-lucide] { color: var(--brand); }
.nav-row > [data-lucide],
.nav-row > svg.lucide {
  width: 18px; height: 18px;
  flex-shrink: 0;
  opacity: .8;
}
.nav-row.active > [data-lucide],
.nav-row.active > svg.lucide { opacity: 1; }
.nav-row.is-disabled,
.nav-row[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
}
.nav-row.is-disabled:hover,
.nav-row[aria-disabled="true"]:hover {
  background: transparent;
  color: var(--ink-2);
}
.nav-row .nav-row-badge {
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  background: #f1f5f9;
  color: var(--ink-2);
}
.nav-row.active .nav-row-badge {
  background: rgba(79, 70, 229, .12);
  color: var(--brand);
}

/* ─── Cards (registry) ───────────────────────────────────── */
.reg-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 15px;
  transition: border-color .12s, box-shadow .12s, transform .12s;
  display: flex; flex-direction: column;
  min-height: 178px;
}
.reg-card:hover {
  border-color: #d7d9de;
  box-shadow: 0 1px 0 rgba(15,18,22,.02), 0 6px 22px -6px rgba(15,18,22,.1);
}
.reg-card.featured {
  border-color: rgba(42,109,244,.35);
  box-shadow: 0 0 0 3px rgba(42,109,244,.08);
}
.reg-card.is-disabled {
  opacity: 0.55;
  pointer-events: none;
}

/* ─── Buttons ────────────────────────────────────────────── */
.btn-primary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 9px;
  background: var(--ink); color: #fff; font-size: 12.5px; font-weight: 500;
  box-shadow: 0 1px 0 rgba(0,0,0,.08), 0 1px 3px rgba(15,18,22,.08);
  cursor: pointer;
}
.btn-primary:hover { background: var(--ink-2); }
.btn-primary:disabled,
.btn-primary[disabled] { opacity: 0.5; cursor: not-allowed; }

.btn-outline {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 8px;
  background: var(--surface); color: var(--ink-2); font-size: 12.5px;
  border: 1px solid var(--line);
  cursor: pointer;
}
.btn-outline:hover { border-color: var(--ink-3); }
/* 드롭다운 트리거가 열려있을 때 — feed-dd-btn.is-on 과 동일 톤. */
.btn-outline.active {
  background: var(--bg-2);
  border-color: var(--ink-3);
  color: var(--ink);
}

.btn-ghost {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 8px;
  color: var(--ink-2); font-size: 12.5px;
  cursor: pointer;
}
.btn-ghost:hover { background: var(--bg-2); }

.btn-blue {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 9px;
  background: var(--accent); color: #fff; font-size: 12.5px; font-weight: 500;
  box-shadow: 0 1px 0 rgba(0,0,0,.08), 0 4px 10px -4px rgba(42,109,244,.4);
  cursor: pointer;
}
.btn-blue:hover { background: var(--accent-ink); }

/* ─── Inputs ─────────────────────────────────────────────── */
.input {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  transition: border-color .12s, box-shadow .12s;
}
.input:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(42,109,244,.12);
}
.input input,
.input textarea,
.input select {
  border: 0; outline: 0; background: transparent;
  font-size: 13.5px; flex: 1; color: var(--ink);
  font-family: inherit;
}
.input input::placeholder { color: var(--muted-2); }

.field-label {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-2);
  margin-bottom: 6px;
}
.field-help {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 4px;
}
.field-error {
  font-size: 11.5px;
  color: var(--crit);
  margin-top: 4px;
}

.kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 5px;
  font-family: var(--font-mono); font-size: 10.5px;
  border: 1px solid var(--line); border-radius: 4px;
  color: var(--muted); background: var(--bg-2);
}

/* ─── Toggle switch (Daisy 보강용) ───────────────────────── */
.sr-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 36px; height: 20px;
  background: var(--bg-2);
  border-radius: 999px;
  cursor: pointer;
  transition: background .14s;
}
.sr-toggle::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
  transition: transform .14s;
}
.sr-toggle.is-on { background: var(--accent); }
.sr-toggle.is-on::after { transform: translateX(16px); }

/* ─── Keyword "NEW" badge (24h 이내 등록된 키워드/제외어/이슈) ───
   3 섹션(setup 의 키워드·이슈 탭) 공통 사용. 작은 강조용 dot+pill. */
.kw-badge-new {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  padding: 1px 6px 1px 5px;
  border-radius: 999px;
  background: rgba(42,109,244,.10);
  color: var(--accent);
  border: 1px solid rgba(42,109,244,.22);
  line-height: 1.4;
}
.kw-badge-new::before {
  content: "";
  width: 4px; height: 4px; border-radius: 99px;
  background: var(--accent);
}

/* ─── AI 분석 모니터 — 운영 컨트롤 카드 ──────────────────────
   상태 LED + 토글 버튼(분석 실행 / 자동 큐) + 동시 실행 select.
   톤은 CrawlMonitor 의 "채널별 24h 성공률" 카드와 동일 무게.    */
.ai-sys-led {
  display: inline-grid; place-items: center;
  width: 44px; height: 44px;
  border-radius: 12px;
  border: 1px solid var(--line);
  flex-shrink: 0;
}
.ai-sys-led [data-lucide] { width: 22px; height: 22px; }

.ai-ctrl-btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  white-space: nowrap;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.ai-ctrl-btn:hover { border-color: var(--ink-3); }
.ai-ctrl-btn:disabled { cursor: not-allowed; opacity: .55; }
.ai-ctrl-btn [data-lucide] { width: 14px; height: 14px; }
.ai-ctrl-btn.is-on {
  border-color: rgba(22,163,74,.45);
  background: var(--ok-soft);
  color: #14833b;
}
.ai-ctrl-btn.is-on [data-lucide] { color: #14833b; }
.ai-ctrl-btn.is-off {
  border-color: rgba(217,119,6,.40);
  background: var(--warn-soft);
  color: #92400e;
}
.ai-ctrl-btn.is-off [data-lucide] { color: #92400e; }
.ai-ctrl-btn.is-meta {
  background: var(--bg-2);
  color: var(--muted);
}
.ai-ctrl-btn.is-meta [data-lucide] { color: var(--muted); }
.ai-ctrl-state {
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255,255,255,.55);
  margin-left: 2px;
}
.ai-ctrl-btn.is-off .ai-ctrl-state { background: rgba(255,255,255,.65); }

/* select 를 ai-ctrl-btn label 안에서 자연스럽게 */
.ai-ctrl-select {
  font-size: 12px; font-weight: 600;
  padding: 1px 4px 1px 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink-2);
  margin-left: 2px;
  cursor: pointer;
}
.ai-ctrl-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* feed-dd-row 안에서 trash-2 등에 위험 톤 부여 (운영 도구 dropdown) */
.feed-dd-row.tone-crit { color: var(--crit); }
.feed-dd-row.tone-crit [data-lucide] { color: var(--crit); }

/* ─── Indicators ─────────────────────────────────────────── */
.dot { display:inline-block; width:6px; height:6px; border-radius:9999px; }
.dot-live { background: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,.18); }

/* ─── Avatar ─────────────────────────────────────────────── */
.avatar {
  width: 22px; height: 22px; border-radius: 99px;
  display: inline-grid; place-items: center;
  font-size: 10.5px; font-weight: 600; color: #fff;
}
.avatar-lg { width: 32px; height: 32px; font-size: 12px; }

/* ─── Lucide icons sizing ────────────────────────────────── */
[data-lucide]          { width: 14px; height: 14px; color: var(--muted); stroke-width: 1.75; }

/* ─── Hero banner ────────────────────────────────────────── */
.hero {
  background:
    radial-gradient(900px 300px at 10% 0%, rgba(42,109,244,.08), transparent 60%),
    radial-gradient(700px 300px at 100% 100%, rgba(124,58,237,.08), transparent 60%),
    linear-gradient(180deg, #fff, #fafbfd);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 28px 30px;
  position: relative;
  overflow: hidden;
}
.hero::before {
  content: ""; position: absolute; top: 0; right: 0; width: 320px; height: 100%;
  background-image:
    linear-gradient(rgba(15,18,22,.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(15,18,22,.06) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(240px 240px at 70% 50%, #000, transparent 70%);
  mask-image: radial-gradient(240px 240px at 70% 50%, #000, transparent 70%);
  opacity: .45;
  pointer-events: none;
}

/* ─── Filter chip ────────────────────────────────────────── */
.coll-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 999px;
  font-size: 12.5px; color: var(--ink-2);
  border: 1px solid var(--line); background: var(--surface);
  cursor: pointer;
}
.coll-chip:hover { border-color: var(--ink-3); }
.coll-chip.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }
.coll-chip.is-active [data-lucide] { color: #fff; }

/* ─── Scrollbar ──────────────────────────────────────────── */
.scroll-thin::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll-thin::-webkit-scrollbar-thumb { background: #d8dade; border-radius: 99px; }
.scroll-thin::-webkit-scrollbar-track { background: transparent; }

/* ─── Sparkline placeholder ──────────────────────────────── */
.spark { height: 40px; width: 100%; }

/* ─── Source brand icon ──────────────────────────────────── */
.srcico {
  width: 20px; height: 20px; border-radius: 6px;
  display: inline-grid; place-items: center;
  color: #fff; font-size: 9.5px; font-weight: 700;
}
.src-x                 { background:#0a0a0a; }
.src-naver_news        { background:#16a34a; }
.src-naver_blog        { background:#22c55e; }
.src-naver_cafe        { background:#03c75a; }
.src-naver_cafe_member { background:#03c75a; }
.src-naver_cafe_open   { background:#16a34a; }
.src-dcinside          { background:#1f2024; }
.src-ppomppu           { background:#d97706; }
.src-instagram         { background: linear-gradient(135deg,#ec4899,#06b6d4); }
.src-youtube           { background:#ff0000; }

/* ─── Channel health badges (🟢🟡🔴⚪⚫) ─────────────────── */
.health-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; padding: 2.5px 8px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-2);
  white-space: nowrap;
}
.health-badge::before {
  content: ""; width: 7px; height: 7px; border-radius: 99px; flex-shrink: 0;
}
.health-ok      { background: var(--ok-soft);   color: #14833b; border-color: rgba(22,163,74,.22); }
.health-ok::before      { background: #16a34a; box-shadow: 0 0 0 3px rgba(34,197,94,.18); }
.health-warn    { background: var(--warn-soft); color: #8a4c00; border-color: rgba(217,119,6,.22); }
.health-warn::before    { background: var(--warn); box-shadow: 0 0 0 3px rgba(217,119,6,.18); }
.health-crit    { background: var(--crit-soft); color: #991b1b; border-color: rgba(220,38,38,.22); }
.health-crit::before    { background: var(--crit); box-shadow: 0 0 0 3px rgba(220,38,38,.18); }
.health-soon    { background: var(--bg-2);      color: var(--muted); }
.health-soon::before    { background: var(--muted-3); }
.health-off     { background: var(--surface);   color: var(--muted); }
.health-off::before     { background: var(--muted-3); }

/* ─── Sandbox ────────────────────────────────────────────── */
.sandbox-grid {
  display: grid; grid-template-columns: 320px 1fr; gap: 16px;
  align-items: start;
}
@media (max-width: 980px) { .sandbox-grid { grid-template-columns: 1fr; } }

.tab-bar {
  display: inline-flex; padding: 3px;
  background: var(--bg-2); border-radius: 10px;
  font-size: 12.5px; gap: 2px;
}
.tab-bar > button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 8px;
  color: var(--muted); font-weight: 500;
  cursor: pointer;
}
.tab-bar > button.is-active {
  background: var(--surface); color: var(--ink);
  box-shadow: 0 1px 0 rgba(15,18,22,.04), 0 1px 3px rgba(15,18,22,.06);
}

.code-block {
  font-family: var(--font-mono); font-size: 11.5px;
  background: #0b0b0c; color: #e6e7e8;
  padding: 14px 16px; border-radius: 10px;
  overflow: auto; max-height: 480px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-all;
}

/* 이슈가 매칭된 게시글의 제목 — 칩(chip-bad #991b1b) 과 같은 톤으로
 * 시각적으로 묶어 한 행 안에서 "이 글은 이슈 행" 임을 강조.
 * (와이어프레임 realtime-feed.html 의 칩+제목 정렬 패턴 + 사용자 요청
 *  "제목 색상도 조정" 반영.) */
.feed-row-title-issue { color: #991b1b; }

/* ─── Table ──────────────────────────────────────────────── */
.tbl {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}
.tbl thead th {
  text-align: left;
  font-weight: 500;
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--muted);
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.tbl tbody td {
  padding: 12px;
  border-bottom: 1px solid var(--line-2);
  color: var(--ink-2);
  vertical-align: middle;
}
.tbl tbody tr:hover { background: var(--line-soft); }
.tbl tbody tr:last-child td { border-bottom: 0; }

/* ─── Modal ──────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(15,18,22,.4);
  display: grid; place-items: center; z-index: 50;
  backdrop-filter: blur(4px);
}
.modal-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.25);
  max-width: 560px; width: 92%;
  max-height: 85vh; overflow-y: auto;
}

/* ─── Empty state ────────────────────────────────────────── */
.empty {
  text-align: center;
  padding: 48px 24px;
  color: var(--muted);
}
.empty [data-lucide] { width: 36px; height: 36px; color: var(--muted-2); }

/* ─── Alert / inline notice ──────────────────────────────── */
.alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  font-size: 12.5px;
  color: var(--ink-2);
}
.alert [data-lucide] { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }
.alert-ok    { background: rgba(16,185,129,.06);  border-color: rgba(16,185,129,.35);  color: #047857; }
.alert-ok    [data-lucide] { color: #10b981; }
.alert-warn  { background: rgba(245,158,11,.06);  border-color: rgba(245,158,11,.35);  color: #b45309; }
.alert-warn  [data-lucide] { color: #f59e0b; }
.alert-crit  { background: rgba(239,68,68,.06);   border-color: rgba(239,68,68,.35);   color: #b91c1c; }
.alert-crit  [data-lucide] { color: #ef4444; }
.alert-info  { background: rgba(59,130,246,.06);  border-color: rgba(59,130,246,.30);  color: #1d4ed8; }
.alert-info  [data-lucide] { color: #3b82f6; }

/* ─── Hint / 사용법 카드 ─────────────────────────────────── */
.hint-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px dashed var(--line);
  border-radius: 10px;
}
.hint-card [data-lucide] { width: 16px; height: 16px; color: var(--muted); flex-shrink: 0; margin-top: 2px; }

/* ─── Table row state ────────────────────────────────────── */
.tbl tbody tr.row-ok   { background: rgba(16,185,129,.045); }
.tbl tbody tr.row-crit { background: rgba(239,68,68,.045); }
.tbl tbody tr.row-warn { background: rgba(245,158,11,.045); }
/* error 메시지 인라인 표시용 sub-row — 위 row-crit 와 시각적으로 묶이되 약간 더 진하게 */
.tbl tbody tr.row-crit-detail { background: rgba(239,68,68,.075); }
.tbl tbody tr.row-crit-detail td { border-top: 0; }

/* 행 자체를 클릭 가능하게 — 행 클릭 시 모달 오픈에 사용 */
.tbl tbody tr.clickable { cursor: pointer; }
.tbl tbody tr.clickable:hover td { background: rgba(42,109,244,.04); }

/* ─── Expandable table (어드민 → 프로젝트 v3.4) ───────────── */
/*  - row-main 은 chevron 으로만 펼쳐진다. 펼치면 tr.row-expand 가 바로 아래 그려진다.
    - row-main + row-expand 를 시각적으로 한 카드처럼 묶어 사용자가 "내가 어떤 행을 펼쳤는지" 명확히 인지하게 한다.
    - 펼치기 영향 셀(chevron + 프로젝트명) 은 td 빈 영역까지 cursor:pointer 로 표시한다 (v3.4.2). */
.tbl-expandable tbody tr.row-main.is-open td { background: rgba(42,109,244,.04); }
.tbl-expandable tbody tr.row-main.is-open td:first-child { border-left: 2px solid var(--accent); }
.tbl-expandable tbody tr.row-main td.is-expander { cursor: pointer; }
.tbl-expandable tbody tr.row-main td.is-expander:hover { background: var(--line-soft); }
.tbl-expandable tbody tr.row-expand td { border-top: 0; padding: 0; }
.tbl-expandable tbody tr.row-expand:hover td { background: var(--bg-2); }

.row-chevron {
  display: inline-grid; place-items: center;
  width: 24px; height: 24px;
  border-radius: 6px;
  color: var(--muted);
  background: transparent;
  transition: transform .15s ease, background .15s ease, color .15s ease;
}
.row-chevron:hover { background: var(--bg-2); color: var(--ink-2); }
.row-chevron.is-open { transform: rotate(90deg); color: var(--accent); background: var(--accent-soft); }
.row-chevron [data-lucide] { width: 14px; height: 14px; }

/* ─── 표 가로 스크롤 wrapper (v3.4.2) ───────────────────────
   좁은 뷰포트에서 셀 내용이 잘리지 않도록 surface 안쪽에서 스크롤한다.
   table 에 min-width 를 부여한 컴포넌트(예: Admin Projects)에 함께 사용. */
.tbl-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.tbl-scroll::-webkit-scrollbar { height: 8px; }
.tbl-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 8px; }
.tbl-scroll::-webkit-scrollbar-thumb:hover { background: var(--muted-2); }

/* ─── 채널별 성공률 바 (Crawl Monitor 위젯) ───────────────── */
.ch-rate-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 8px;
}
.ch-rate-row:hover { background: var(--surface-2); }
.ch-rate-bar {
  height: 8px;
  background: var(--surface-2);
  border-radius: 999px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.ch-rate-fill {
  height: 100%;
  border-radius: 999px;
  transition: width .25s ease;
}

/* ─── 잡 상세 모달의 이벤트 타임라인 ───────────────────────── */
/* NOTE: 모달 패널 자체에 max-height:85vh + overflow-y:auto 가 걸려 있어서
   여기서 별도의 max-height/overflow 를 두면 이중 스크롤바가 생긴다.
   타임라인은 자연스럽게 펼쳐지게 두고, 스크롤은 모달 패널이 담당한다. */
.evt-timeline {
  border-left: 2px solid var(--line);
  padding-left: 12px;
  margin-left: 4px;
}
/* 시간 / 코드 / 메시지 — 코드 길이에 맞춰 가변 폭으로 잡고 메시지에 남는 공간을 모두 준다.
   짧은 코드(예: STARTED) 일 때 메시지가 오른쪽으로 밀려 한쪽으로 몰려 보이는 문제 해결. */
.evt-row {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, max-content) minmax(0, 1fr);
  column-gap: 12px;
  align-items: baseline;
  padding: 3px 0;
  font-size: 12px;
  line-height: 1.55;
}
.evt-dot {
  position: absolute;
  left: -17px;
  top: 9px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--muted-2);
  box-shadow: 0 0 0 2px var(--surface);
}
.evt-dot-info { background: #2a6df4; }
.evt-dot-warn { background: #f59e0b; }
.evt-dot-crit { background: #ef4444; }
.evt-time { font-size: 11px; white-space: nowrap; }
.evt-code { color: var(--ink-2); white-space: nowrap; }
.evt-msg  { color: var(--ink); word-break: break-word; min-width: 0; }

/* ─── Login layout ───────────────────────────────────────────
   wireframes/login.html 정합 스타일은 public/theme/login.css 에서 별도 관리.
   resources/views/livewire/auth/login.blade.php 가 @push('head') 로 로드. */

/* ─── Keyword highlight (LiveFeed 모달 등) ────────────────── */
mark.kw-hi {
  background: rgba(255, 196, 0, .35);
  color: inherit;
  padding: 0 2px;
  border-radius: 2px;
  font-weight: 600;
}

/* ─── Alpine x-cloak (있는 동안 표시 숨김) ──────────────── */
[x-cloak] { display: none !important; }

/* ─── LiveFeed/Admin — 통합 검색바 + 빠른필터 드롭다운 ────
 *  설계:
 *   - 검색바 한 줄: 자유 텍스트 input + 빠른필터 dropdown 4개
 *   - 적용 중인 필터는 .feed-recap 한 줄로 항상 노출 (제거 가능) */

.feed-searchbar {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
/* 검색 input 은 넘치게 늘어나지 않도록 폭 캡 — 옆 드롭다운/토글이 같은 무게로 보이도록 */
.feed-search-input {
  flex: 0 1 320px;
  min-width: 220px;
  max-width: 380px;
  padding: 7px 11px;
}
.feed-search-input input { font-size: 13px; }
@media (max-width: 768px) {
  .feed-search-input { flex: 1 1 100%; max-width: none; }
}

/* 빠른필터 드롭다운 (Alpine x-data 토글) */
.feed-dd { position: relative; }
.feed-dd-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 11px;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 9px;
  font-size: 12.5px;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.feed-dd-btn:hover { border-color: var(--ink-3); }
.feed-dd-btn.is-on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.feed-dd-btn.is-on [data-lucide] { color: var(--accent); }
.feed-dd-btn.is-on b { color: var(--accent); }
.feed-dd-btn.is-on.tone-crit { border-color: rgba(220,38,38,.45); background: var(--crit-soft); color: #991b1b; }
.feed-dd-btn.is-on.tone-crit [data-lucide],
.feed-dd-btn.is-on.tone-crit b { color: #991b1b; }
.feed-dd-btn.is-on.tone-ok { border-color: rgba(22,163,74,.45); background: var(--ok-soft); color: #14833b; }
.feed-dd-btn.is-on.tone-ok [data-lucide],
.feed-dd-btn.is-on.tone-ok b { color: #14833b; }
.feed-dd-count {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  background: var(--ink); color: #fff;
  font-size: 10.5px; font-weight: 600;
  border-radius: 999px;
}
.feed-dd-btn.is-on .feed-dd-count { background: var(--accent); }
.feed-dd-btn.is-on.tone-crit .feed-dd-count { background: var(--crit); }
.feed-dd-btn.is-on.tone-ok .feed-dd-count { background: #16a34a; }

.feed-dd-panel {
  position: absolute; right: 0; top: calc(100% + 6px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 1px 0 rgba(15,18,22,.02), 0 18px 36px -16px rgba(15,18,22,.18);
  padding: 6px;
  z-index: 30;
}
.feed-dd-head {
  padding: 4px 4px 6px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
.feed-dd-body { padding: 0; }
.feed-dd-row {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 12.5px;
  color: var(--ink-2);
  cursor: pointer;
  text-align: left;
}
.feed-dd-row:hover { background: var(--bg-2); }
.feed-dd-row.is-on { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.feed-dd-row.is-on [data-lucide] { color: var(--accent); }
.feed-dd-row.is-disabled,
.feed-dd-row[disabled] {
  opacity: .55; cursor: not-allowed;
  color: var(--ink-3);
}
.feed-dd-row.is-disabled:hover,
.feed-dd-row[disabled]:hover { background: transparent; }
.feed-dd-section {
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted-2); font-weight: 600;
  padding: 8px 10px 4px;
}

/* 활성 필터 recap (한 줄 칩) */
.feed-recap {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding-top: 2px;
}
.recap-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px 3px 9px;
  font-size: 11.5px;
  background: var(--bg-2);
  color: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.recap-chip:hover { background: var(--crit-soft); border-color: rgba(220,38,38,.3); color: #991b1b; }
.recap-chip:hover [data-lucide] { color: #991b1b; }
.recap-chip [data-lucide] { color: var(--muted-2); }

@media (max-width: 640px) {
  .feed-dd-panel { right: auto; left: 0; }
}

/* ─── Social Radar pagination (links('pagination.sr')) ─── */
.sr-pager {
  display: inline-flex; align-items: center; gap: 4px;
}
.sr-pager-btn {
  display: inline-grid; place-items: center;
  min-width: 30px; height: 30px;
  padding: 0 9px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  font-size: 12px; font-weight: 500;
  border-radius: 8px;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.sr-pager-btn:hover {
  background: var(--surface-2);
  border-color: var(--ink-3);
  color: var(--ink);
}
.sr-pager-btn.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
  cursor: default;
}
.sr-pager-btn.is-disabled {
  opacity: .35;
  cursor: not-allowed;
  pointer-events: none;
}
.sr-pager-gap {
  padding: 0 4px;
  color: var(--muted-2);
  font-size: 12px;
  user-select: none;
}
.sr-pager-btn svg {
  width: 14px; height: 14px;
  color: currentColor;
  display: block;
}
/* 데스크톱: 인디케이터 숨김 (모든 페이지 번호가 노출되므로 불필요) */
.sr-pager-info {
  display: none;
}
/* 모바일 (≤640px): 페이지 번호 버튼·구분점 숨기고 "n / N" 인디케이터만 노출.
 *  pagination 박스가 17 페이지 같이 많을 때 가로 스크롤 / overflow 깨짐 방지. */
@media (max-width: 640px) {
  .sr-pager-info {
    display: inline-flex; align-items: center;
    padding: 0 10px;
    font-size: 13px;
    color: var(--ink-2);
    white-space: nowrap;
  }
  .sr-pager-info b { color: var(--ink); font-weight: 700; margin-right: 2px; }
  .sr-pager .sr-pager-btn:not([aria-label]),
  .sr-pager .sr-pager-gap {
    display: none;
  }
}

/* ============================================================
 * v3.5 — 성능/모션 향상
 *   - Livewire navigate 상단 진행바
 *   - View Transitions API (브라우저 지원시 자동 fade)
 *   - 표준 스켈레톤 + spinner
 *   - prefers-reduced-motion 가드
 * ============================================================ */

/* ─── Navigate progress bar (#nav-progress) ──────────────── */
#nav-progress {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 2px;
  background: transparent;
  z-index: 100;
  pointer-events: none;
  overflow: hidden;
}
#nav-progress::after {
  content: "";
  display: block;
  height: 100%;
  width: 30%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  transform: translateX(-100%);
  opacity: 0;
  transition: opacity .15s ease-out;
}
#nav-progress.loading::after {
  opacity: 1;
  animation: nav-progress-slide 1.2s linear infinite;
}
#nav-progress.done::after {
  opacity: 0;
  transition: opacity .25s ease-out;
}
@keyframes nav-progress-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(400%); }
}

/* ─── Skeleton loader ────────────────────────────────────── */
.sr-skel {
  background: linear-gradient(90deg, var(--bg-2) 0%, rgba(0,0,0,.06) 50%, var(--bg-2) 100%);
  background-size: 200% 100%;
  animation: sr-skel-shimmer 1.2s ease-in-out infinite;
  border-radius: 6px;
  display: block;
  height: 14px;
}
.sr-skel.h-3 { height: 12px; }
.sr-skel.h-5 { height: 20px; }
.sr-skel.h-8 { height: 32px; }
.sr-skel.w-24 { width: 96px; }
.sr-skel.w-32 { width: 128px; }
.sr-skel.w-1\/2 { width: 50%; }
.sr-skel.w-2\/3 { width: 66.6667%; }
.sr-skel.w-full { width: 100%; }
@keyframes sr-skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ─── Inline spinner (data-lucide loader-2 + .animate-spin 보완) ─── */
@keyframes sr-spin { to { transform: rotate(360deg); } }
.sr-spin {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: sr-spin .7s linear infinite;
  vertical-align: -2px;
}

/* ─── View Transitions (Chromium / Safari TP) ────────────── */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 180ms;
  animation-timing-function: cubic-bezier(.2,.8,.2,1);
}

/* ─── Reduced motion 가드 ────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #nav-progress::after,
  .sr-skel,
  .sr-spin { animation: none !important; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}

/* ============================================================
 * 화살표 마이크로 인터랙션
 *   호버 시 살짝 전진하는 동작을 한 곳에서 관리.
 *   - arrow-right / arrow-up-right : 2px 전진 (CTA 톤)
 *   - chevron-right                : 1px 전진 (가벼운 보조 링크 톤)
 * ============================================================ */
.btn-outline [data-lucide="arrow-right"],
.btn-outline [data-lucide="arrow-up-right"],
.btn-outline [data-lucide="chevron-right"],
.btn-ghost   [data-lucide="arrow-right"],
.btn-ghost   [data-lucide="arrow-up-right"],
.btn-ghost   [data-lucide="chevron-right"] {
  transition: transform .15s ease;
}
.btn-outline:hover [data-lucide="arrow-right"],
.btn-outline:hover [data-lucide="arrow-up-right"],
.btn-ghost:hover   [data-lucide="arrow-right"],
.btn-ghost:hover   [data-lucide="arrow-up-right"] {
  transform: translateX(2px);
}
.btn-outline:hover [data-lucide="chevron-right"],
.btn-ghost:hover   [data-lucide="chevron-right"] {
  transform: translateX(1px);
}
@media (prefers-reduced-motion: reduce) {
  .btn-outline [data-lucide],
  .btn-ghost   [data-lucide] {
    transition: none !important;
    transform: none !important;
  }
}

/* ============================================================
 * 실시간 피드 — 시그널 스트립 / 2행 검색바 / 행 액센트 / 2-pane 모달
 * blade: resources/views/livewire/project/live-feed.blade.php
 * 광고 운영자가 진입 즉시 "오늘 만질 거리"를 식별하고, 게시글
 * 상세에서 본문/댓글/AI 분석을 한 화면에 보도록 한다.
 * ============================================================ */

/* ── 로딩 인디케이터 ────────────────────────────────────
 * Livewire 라운드트립 동안 결과 영역(.feed-loading-target)을 옅게 + 클릭 차단.
 * `wire:loading.delay.shortest.class="is-loading"` 와 짝. 100ms 미만 응답엔
 * 인디케이터가 안 떠서 깜박임 거의 없음.
 * ────────────────────────────────────────────────────── */
.feed-loading-target {
  transition: opacity .12s ease, filter .12s ease;
}
.feed-loading-target.is-loading {
  opacity: .55;
  pointer-events: none;
  filter: saturate(.6);
}

/* 컴팩트 select — 페이징 영역의 "페이지당" 같은 작은 표시 옵션용. */
.select-sm {
  appearance: none;
  -webkit-appearance: none;
  display: inline-block;
  padding: 3px 22px 3px 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background-color: var(--surface);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%237b8190' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
}
.select-sm:hover { border-color: var(--ink-3); }
.select-sm:focus-visible {
  outline: 2px solid var(--accent-soft, rgba(59,130,246,.35));
  outline-offset: 1px;
}

/* ── 리스트 ─────────────────────────────────────────────── */
.feed-row { transition: background-color .12s ease; }
.feed-row:hover { background: rgba(42,109,244,.04); }

/* ── 2-pane 모달 ────────────────────────────────────────── */
/* 모달 오버레이 (백드롭 + 가운데 정렬) — 옛 인라인 style 을 CSS 로 추출.
 *  데스크톱은 상단 40px 여백, 모바일은 풀스크린(아래 ≤640 미디어쿼리). */
.feed-modal-overlay {
  background: rgba(15, 23, 42, .55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  padding: 40px 20px;
  /* 모달 안에서 끝까지 스크롤해도 부모 문서로 전파되지 않게 */
  overscroll-behavior: contain;
}

/* 모달 열린 동안 문서 본문 스크롤 잠금 — 부모 페이지가 같이 스크롤되는 현상 방지.
 *  :has() 는 Chrome 105+/Safari 15.4+/Firefox 121+ 지원 (2026 기준 충분). */
html:has(> body .feed-modal-overlay),
body:has(.feed-modal-overlay) {
  overflow: hidden;
  /* iOS 에서 fixed 모달이 떠 있는 동안에도 body touch-scroll 이 빠져나가지 않게 */
  overscroll-behavior: none;
}

/* feed-modal — 외곽 박스 (와이어프레임 modal-box) */
.feed-modal {
  border-radius: 16px;
  border-color: var(--border-2);
  box-shadow: 0 24px 64px -16px rgba(15, 23, 42, .3);
}

/* 헤더 — 단일 행: src-icon + meta + 원문 + close */
.feed-modal-head {
  display: flex; align-items: center;
  gap: 16px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--border-2);
  flex-shrink: 0;
}

/* 본문 영역 — grid 1fr 380px */
.feed-modal-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  flex: 1 1 auto;
  min-height: 0;
}
@media (max-width: 1024px) {
  .feed-modal-body {
    grid-template-columns: 1fr;
  }
}

/* 좌측 (본문 + 댓글) — 와이어프레임 modal-content */
.feed-modal-left {
  padding: 24px 28px;
  overflow-y: auto;
  border-right: 1px solid var(--border-2);
  min-width: 0;
  min-height: 0;
}
@media (max-width: 1024px) {
  .feed-modal-left {
    border-right: 0;
    border-bottom: 1px solid var(--border-2);
  }
}

/* 좌측 본문 prose — 와이어프레임 text-[14px] leading-[1.8] ink space-y-3.5 */
.feed-modal-prose {
  font-size: 14px;
  line-height: 1.8;
  color: var(--ink);
  word-break: break-word;
  tab-size: 4;
}
.feed-modal-prose p { margin: 0 0 14px; }
.feed-modal-prose p:last-child { margin-bottom: 0; }

/* 댓글 카드 (와이어프레임 .comment 와 동일 스펙) */
.feed-comment {
  padding: 12px 14px;
  background: var(--surface-2);
  border-radius: 8px;
  margin-bottom: 8px;
}
.feed-comment:last-child { margin-bottom: 0; }
.feed-comment.is-reply {
  margin-left: 14px;
  background: var(--surface);
  border: 1px dashed var(--border-2);
}
.feed-comment-meta {
  display: flex; align-items: baseline; gap: 8px;
  margin-bottom: 6px;
  font-size: 12px;
}
.feed-comment-author {
  font-weight: 600;
  color: var(--ink-2);
}
.feed-comment-time {
  font-size: 12px;
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.feed-comment-body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  word-break: break-word;
}
.feed-comment-body p { margin: 0 0 0.4em; }
.feed-comment-body p:last-child { margin-bottom: 0; }

/* 우측 — AI 분석 패널 (와이어프레임 modal-side) */
.feed-modal-right {
  background: var(--surface-2);
  padding: 24px 24px;
  overflow-y: auto;
  min-width: 0;
  min-height: 0;
}

/* 모바일에서만 본문 위에 노출되는 출처/시각 row (헤더가 간소화되므로 보조)
   데스크톱에서는 헤더의 src-icon + meta 가 충분해 숨김. */
.feed-modal .mobile-source-row { display: none; }
@media (max-width: 640px) {
  /* 풀스크린 모달 — 와이어프레임 realtime-feed.html L408~414 정합 */
  .feed-modal-overlay { padding: 0 !important; align-items: stretch !important; }
  .feed-modal-shell { max-width: 100% !important; }
  .feed-modal {
    border-radius: 0 !important;
    box-shadow: none !important;
    /* 100dvh = dynamic viewport height (iOS 주소표시줄 collapse 대응).
     * 미지원 브라우저는 위 100vh fallback. */
    max-height: 100vh !important;
    height: 100vh;
    max-height: 100dvh !important;
    height: 100dvh;
  }

  /* 헤더 — 아이콘/메타 숨기고 "게시글" 라벨로 대체. close + 원문 만 우측에 유지. */
  .feed-modal .mobile-source-row { display: flex !important; }
  .feed-modal-head .modal-header-icon,
  .feed-modal-head .modal-header-meta { display: none !important; }
  .feed-modal-head { padding: 12px 14px; gap: 8px; }
  .feed-modal-head::before {
    content: '게시글';
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
    flex: 1;
  }

  /* 본문 — AI 분석 패널을 위로. grid 1-col + 명시적 grid-row 배치.
   *  ⚠️ 데스크톱의 .feed-modal-left/right { min-height: 0 } 이 모바일까지 새어들면
   *     overflow: visible 일 때 grid cell 이 0 높이로 줄고 콘텐츠는 시각적으로
   *     흘러나와 다음 패널과 겹쳐 보임 — 반드시 min-height: auto !important 로 reset. */
  .feed-modal-body {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto auto !important;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    min-height: 0;
  }
  .feed-modal-left {
    grid-row: 2 !important;
    min-height: auto !important;
    padding: 14px 16px 24px;
    border-right: 0;
    border-bottom: 0;
    overflow: visible !important;
  }
  .feed-modal-right {
    grid-row: 1 !important;
    min-height: auto !important;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-2);
    overflow: visible !important;
  }
  .feed-modal-prose { font-size: 14px; line-height: 1.7; }
  .feed-modal-left h2 { font-size: 18px !important; line-height: 1.4 !important; }

  /* 댓글 영역 헤더 — 좌(라벨/카운트) / 우(필터·정렬 4 버튼) 가 좁은 화면에서
   *  세로 stacked + 버튼 줄 wrap 으로 떨어지게. 정렬 버튼은 컴팩트 폰트/패딩. */
  .feed-modal #feed-comments > .flex.items-center.justify-between {
    flex-direction: column;
    align-items: flex-start !important;
    gap: 10px;
  }
  .feed-modal #feed-comments > .flex.items-center.justify-between > div:last-child {
    flex-wrap: wrap;
  }
  .feed-modal #feed-comments .page-btn {
    font-size: 11px !important;
    padding: 5px 9px !important;
    min-width: auto !important;
    height: auto !important;
  }
}

.feed-ai-btn {
  font-size: 11.5px;
  padding: 6px 10px;
}
.feed-ai-btn [data-lucide] { width: 13px; height: 13px; }

/* sec-label 의 이슈 톤 (관리자 등록 키워드) */
.sec-label.is-issue { color: #991b1b; }

/* 재분석 확인 모달 — 우측 패널 위에 띄우는 가벼운 dialog */
.feed-ai-confirm-backdrop {
  position: fixed; inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, .5);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.feed-ai-confirm-box {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 18px 18px 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
}
.feed-ai-confirm-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 8px;
}
.feed-ai-confirm-head h3 {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
}
.feed-ai-confirm-icon {
  width: 16px; height: 16px;
  color: var(--accent);
}
.feed-ai-confirm-desc {
  font-size: 12px;
  line-height: 1.65;
  color: var(--muted);
  margin: 0 0 14px;
  word-break: keep-all;
  overflow-wrap: anywhere;
}
.feed-ai-confirm-desc .ink { color: var(--ink); font-weight: 600; }
.feed-ai-confirm-actions {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 6px;
}

/* ============================================================
 * v4 — 와이어프레임 별칭 / 신규 클래스 (2026-05)
 *
 * 정책:
 *   - 기존 클래스 (pill / btn-primary / surface-flat / feed-row …) 는 그대로 살아 있다.
 *   - 와이어프레임이 짧게 부르는 이름 (.card / .chip / .btn / .btn-brand …) 도
 *     같은 톤으로 동작하도록 별칭/신규 클래스로 추가만 한다.
 *   - 새 페이지/카드는 짧은 이름을 써도 되고, 옛 클래스를 써도 된다 — 결과 동일.
 *
 * Tailwind safelist (resources/css/app.css 의 @source inline) 에 등록한 항목과 짝.
 * ============================================================ */

/* ─── Chip (= pill 별칭) ────────────────────────────────────
 *  와이어프레임 .chip 은 generic chip, .chip-good/bad/warn/brand 가 톤 별 변형.
 *  기존 .pill-soft-* 와 동일 톤이지만 padding/font-size 를 와이어프레임에 맞췄다. */
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; padding: 3px 9px;
  border-radius: 999px;
  background: #f1f5f9; color: var(--ink-2); font-weight: 500;
}
.chip-sm { font-size: 11px; padding: 2px 7px; }
.chip-good  { background: var(--good-soft);  color: #15803d; }
.chip-bad   { background: var(--bad-soft);   color: #991b1b; }
.chip-warn  { background: var(--warn-soft);  color: #b45309; }
.chip-brand { background: var(--brand-soft); color: var(--brand); }

/* ─── Card (= surface-flat 별칭) ───────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.card-pad { padding: 22px 24px; }
.card-head {
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 14px; margin-bottom: 14px;
  border-bottom: 1px dashed var(--line);
}
.card-head h3 {
  font-size: 13.5px; font-weight: 700; color: var(--ink);
  letter-spacing: -0.005em;
}
.card-head .card-head-meta { margin-left: auto; font-size: 11.5px; color: var(--ink-3); }

/* ─── Hero card (대시보드/데일리 HERO 통일 카드) ──────────── */
.hero-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 28px 32px;
  position: relative;
  overflow: hidden;
}
.hero-card::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(700px 240px at 0% 0%, rgba(79,70,229,.06), transparent 60%),
    radial-gradient(560px 220px at 100% 100%, rgba(34,183,90,.04), transparent 60%);
  pointer-events: none;
}
.hero-card > * { position: relative; }
.hero-card .hero-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--brand);
}
.hero-card h2 {
  font-size: 22px; font-weight: 700; line-height: 1.3; letter-spacing: -0.018em;
  color: var(--ink); margin-top: 6px;
}
.hero-card .hero-lead {
  font-size: 13.5px; color: var(--ink-2); line-height: 1.7;
  margin-top: 8px; max-width: 720px;
}

/* ─── KPI grid (4-up + 반응형) ─────────────────────────────── */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
@media (max-width: 1024px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width:  640px) { .kpi-grid { grid-template-columns: 1fr; } }

/* ─── Risk number cell (게시글 행 / 카드의 위험도 숫자) ─────
 *  feed-risk-score 와 동일 톤 — 와이어프레임에서 .risk-num.risk-low/mid/high 로
 *  부르므로 별칭으로 유지. */
.risk-num {
  display: inline-flex; align-items: baseline;
  font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--ink-2);
}
.risk-num.risk-low  { color: var(--ok); }
.risk-num.risk-mid  { color: var(--warn); }
.risk-num.risk-high { color: var(--crit); }

/* ─── Feed row 좌측 보더 + 출처·제목 톤 — 중위험·고위험만 (저위험은 기본 ink)
 *  3px ::before — feed-row.feed-row-grid 가 position: relative 보유. */
.feed-row.risk-mid::before,
.feed-row.risk-high::before {
  content: ''; position: absolute;
  left: 0; top: 0; bottom: 0; width: 3px;
}
.feed-row.risk-mid::before  { background: var(--warn); }
.feed-row.risk-high::before { background: var(--bad, var(--crit)); }

.feed-row.risk-mid .feed-row-src,
.feed-row.risk-mid .feed-row-title {
  color: var(--warn);
}
.feed-row.risk-high .feed-row-src,
.feed-row.risk-high .feed-row-title {
  color: var(--bad, var(--crit));
}

/* ─── Issue grid cell (대시보드 v4 SECTION 04 — 등록 이슈 점등 그리드) ───
 *  hit-strong : 적중. 빨강 soft + 보더 강조.
 *  miss       : 0건. 그레이 외곽선만. */
.issue-cell {
  padding: 10px 12px; border-radius: 8px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  font-size: 13px;
  transition: border-color .15s, background .15s;
}
.issue-cell.hit-strong {
  background: var(--bad-soft, var(--crit-soft));
  border-color: rgba(220, 72, 72, .2);
}
.issue-cell.miss { background: transparent; color: var(--ink-3); }

/* ─── Print 친화 — 대시보드/리포트 인쇄 버튼 클릭 시 ───
 *  사이드바 / 토픽 바 / 액션 버튼 등 인쇄 시 의미 없는 요소를 자른다. */
@media print {
  .print-hidden,
  aside, header,
  .feed-dd, .feed-dd-panel,
  .sr-toast-host,
  .sr-spin {
    display: none !important;
  }
  .card, .hero-card { box-shadow: none !important; border: 1px solid #ddd !important; }
  body { background: white !important; }
  .issue-cell.hit-strong { background: #fee !important; }
  /* 페이지 break — 섹션 단위 자연스러운 분할 */
  section { page-break-inside: avoid; }
}

/* ─── Filter pill / panel / opt (실시간 피드 드롭다운) ──────
 *  기존 .feed-dd-btn / .feed-dd-panel / .feed-dd-row 와 동일 톤이지만,
 *  새 디자인은 더 짧은 이름을 쓴다. 둘 다 살려둔다. */
/* Filter pill — 와이어프레임 spec: padding 8px 13px / border-radius 10px / font 13px font-medium */
.filter-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 13px; font-weight: 500; color: var(--ink-2);
  cursor: pointer; white-space: nowrap;
  transition: border-color .12s, background .12s, color .12s;
}
.filter-pill:hover { background: var(--surface-hover, var(--bg-2)); }
.filter-pill svg { opacity: .6; }
.filter-pill.active {
  background: #f1f5f9;
  color: var(--ink);
  border-color: var(--border-strong, #d1d5db);
}
.filter-pill.active svg { opacity: .9; }
.filter-pill .filter-pill-count {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  background: var(--ink); color: #fff;
  font-size: 10.5px; font-weight: 600;
  border-radius: 999px;
}
.filter-pill.active .filter-pill-count { background: var(--brand); }

/* Filter dropdown panel — 와이어프레임 spec: top calc + 6px / left:0 / min-w 260 / radius 12 */
.filter-panel {
  position: absolute; top: calc(100% + 6px); left: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 12px 32px -8px rgba(15,23,42,.12);
  min-width: 260px;
  z-index: 40;
  padding: 0;
}
.filter-opt {
  width: 100%;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 14px; border-radius: 0;
  font-size: 13px; color: var(--ink-2);
  cursor: pointer; text-align: left;
  background: transparent; border: 0;
}
.filter-opt:hover { background: var(--surface-hover, var(--bg-2)); }
.filter-opt.active {
  background: var(--brand-soft);
  color: var(--brand);
  font-weight: 500;
}
.filter-opt input[type="checkbox"] {
  width: 14px; height: 14px;
  accent-color: var(--brand);
  cursor: pointer;
  flex-shrink: 0;
}
.filter-opt .src-icon {
  width: 18px; height: 18px;
  font-size: 9px; border-radius: 3px;
}

/* ─── Time tabs (24h / 7d / 30d segmented) ─────────────────
 *  와이어프레임 option-b-suite-minimal.html L439 정합:
 *    <div class="flex items-center gap-1 p-1 rounded-lg time-tabs">
 *  배경 톤만 토큰화. 내부 .tab-pill 은 아래 자체 스펙. */
.time-tabs {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: var(--bg-2);
  border-radius: 10px;
  flex-shrink: 0;
}

/* ─── Tab pill (24h / 7d / 30d 같은 단순 탭) ───────────────── */
.tab-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 11px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 12.5px; font-weight: 500;
  color: var(--ink-3);
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.tab-pill:hover { background: var(--bg-2); color: var(--ink-2); }
.tab-pill.active {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--line);
  box-shadow: 0 1px 0 rgba(15,18,22,.04), 0 1px 3px rgba(15,18,22,.06);
}
.tab-pill[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}
/* `.is-disabled` 는 *시각적으로만* 비활성. 클릭 자체는 막지 않음 —
 *  대시보드의 7일/30일 탭은 클릭 시 "다음 업데이트 예정" 토스트를 띄우므로
 *  pointer-events: auto 를 유지한다. */
.tab-pill.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.tab-pill.is-disabled:hover { background: transparent; color: var(--ink-3); }

/* ─── Btn (와이어프레임 별칭) ──────────────────────────────
 *  기존 .btn-primary / .btn-blue / .btn-outline 와 충돌 안 나도록
 *  *순수* `.btn` 만 새 정의. 와이어프레임은 .btn 단독으로도 outline 취급. */
/* .btn — 와이어프레임 realtime-feed.html L73~80 정렬:
 *   base 는 padding 8px 14px / font 13px / border 0 / bg 투명 / color ink-2.
 *   visual 변종 (.btn-outline / .btn-brand) 이 bg/border 를 채운다.
 *
 * 옛 구현은 .btn 자체에 1px line 보더와 surface bg 를 박아 와이어프레임 대비
 * 모든 버튼이 ~2px 더 두꺼웠고, 보상으로 .btn-brand 가 padding 9px 15px 로 부풀어
 * 결과적으로 버튼이 와이어프레임보다 한 사이즈 크게 렌더되었다 (사용자 보고). */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 500;
  padding: 8px 14px;
  border-radius: 8px;
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
  background: transparent;
  color: var(--ink-2);
  border: 0;
  /* DaisyUI 5 의 .btn 은 layered 룰로 height: 2.5rem (40px), box-shadow inset glossy,
   * text-shadow 0 .5px (white) 를 강제 — unlayered 인 우리 .btn 이 height/shadow 를
   * 명시 안 하면 그대로 누수돼 와이어프레임 spec(text-driven 35.5px) 보다 4~5px 더 높고
   * 살짝 입체감이 도는 채로 렌더된다. height/box-shadow/text-shadow 를 명시 리셋해
   * 와이어프레임의 평평한 버튼으로 일치시킨다. */
  height: auto;
  box-shadow: none;
  text-shadow: none;
}
.btn:disabled,
.btn[disabled] { opacity: .55; cursor: not-allowed; }
/* 와이어프레임 realtime-feed.html L620~626 의 .btn 안 SVG 는 w-4 h-4 (=16px).
 * 옛 14px 은 와이어프레임 대비 한 사이즈 작아 버튼이 살짝 빈약해 보였다 (사용자 보고 — 내보내기/새로고침). */
.btn [data-lucide] { width: 16px; height: 16px; color: inherit; }
.btn-brand {
  background: var(--ink); color: #fff;
}
.btn-brand:hover { background: var(--ink-2); }
.btn-brand [data-lucide] { color: #fff; }

/* `class="btn btn-outline"` 조합용 레이어드 오버라이드.
 * 옛 standalone .btn-outline (L174~) 은 padding 6px 10px / font 12.5px / bg+border 를
 * 한 묶음으로 들고 있는데, 같은 specificity 의 .btn 이 source order 상 더 뒤에 와서
 * 모든 속성을 덮어쓰는 문제가 있다. 여기서는 .btn.btn-outline (specificity 0,0,2,0) 으로
 * bg + border 만 다시 얹어 와이어프레임 spec (.btn 이 padding/font 를 정하고 .btn-outline 이
 * 시각 변종을 더한다) 을 회복. standalone .btn-outline 사용처(어드민 모니터 등)는 그대로 동작. */
.btn.btn-outline {
  background: var(--surface);
  border: 1px solid var(--line);
}
.btn.btn-outline:hover { border-color: var(--ink-3); }
/* .btn-icon — 32x32 정사각 아이콘 버튼.
 * 와이어프레임 realtime-feed.html L82~87 스펙: 평상시 보더/배경 없음, hover 시 surface-hover.
 * (옛 스타일은 surface 배경 + line 보더가 항상 있었으나 와이어프레임과 어긋나
 *  topbar 햄버거/알림이 강한 박스로 보이는 문제가 있었다.) */
.btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  border-radius: 8px;
  background: transparent;
  border: 0;
  color: var(--ink-2);
  cursor: pointer;
  transition: background .12s, color .12s;
}
.btn-icon:hover { background: var(--bg-2, var(--surface-hover, #f3f5f8)); color: var(--ink); }
/* 와이어프레임 realtime-feed.html 의 btn-icon 안 SVG 는 w-5 h-5 (=20px) 그대로.
 * 옛 15px 은 보더 없는 32x32 hit area 안에서 묻혀 보였다 (사용자 보고).  */
.btn-icon [data-lucide] { width: 20px; height: 20px; }

/* ─── nav-super-zone (어드민 사이드바 슈퍼 영역 시각 분리) ──
 *  슈퍼 관리자만 볼 수 있는 운영 메뉴들을 시각적으로 묶어서 일반 메뉴와
 *  분리한다. 라벨 + 좌측 강조 보더 + 옅은 surface 배경. */
.nav-super-zone {
  margin-top: 12px;
  padding: 8px 6px 6px;
  border-radius: 10px;
  background: var(--surface-2);
  border: 1px dashed var(--line);
}
.nav-super-zone-label {
  display: flex; align-items: center; gap: 5px;
  padding: 0 8px 6px;
  font-size: 10px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--brand);
}
.nav-super-zone-label::before {
  content: "";
  width: 4px; height: 4px; border-radius: 99px;
  background: var(--brand);
}
.nav-super-zone .nav-row { padding: 6px 8px; font-size: 12.5px; }

/* ─── Toast (재사용) — Coming soon / 권한 부족 / 클립보드 결과 등 공용 안내 ───
 *  layout 의 #sr-toast-host (Alpine x-data) 가 'toast' window event 를 받아 그린다.
 *  tone ∈ info(default) | ok | warn | crit. */
.sr-toast-host {
  position: fixed; right: 20px; bottom: 20px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 80;
  pointer-events: none;       /* 토스트 자체만 클릭 받도록 */
}
.sr-toast {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  background: var(--ink); color: #fff;
  border-radius: 10px;
  font-size: 12.5px;
  box-shadow: 0 12px 28px -10px rgba(0,0,0,.35);
  max-width: 360px;
  pointer-events: auto;
}
.sr-toast [data-lucide] { color: #fff; flex-shrink: 0; width: 14px; height: 14px; }
.sr-toast-ok   { background: var(--ok); }
.sr-toast-warn { background: var(--warn); color: #fff; }
.sr-toast-crit { background: var(--crit); }

/* ============================================================
 * v4 — APP SHELL (와이어프레임 정렬, 2026-05)
 *
 * 옛 톱-스티키 헤더 + 232px 그리드 사이드바를 폐기하고,
 * 풀높이 좌측 사이드바 (244px) + 페이지별 톱바 패턴으로 통일.
 *
 * - .sr-shell : 최상위 flex (sidebar | main)
 * - .sr-sidebar : 244px, sticky full-height, brand wordmark + 컨텐츠 + 푸터
 * - .sr-main : flex-1, 톱바(브레드크럼+검색+벨+아바타) + 페이지헤더 + 본문
 *
 * 모바일 (≤1024px) 에서 sidebar 는 drawer 로 전환.
 * ============================================================ */
.sr-shell {
  display: flex;
  min-height: 100vh;
  background: var(--bg);
}
.sr-sidebar {
  width: 244px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border, var(--line));
}
.sr-sidebar-inner {
  position: sticky; top: 0;
  height: 100vh;
  display: flex; flex-direction: column;
}
.sr-sidebar-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(11, 18, 32, 0.45);
  backdrop-filter: blur(2px);
  z-index: 40;
}
.sr-sidebar-overlay.open { display: block; }

/* Brand wordmark — 와이어프레임 3-color 규칙
 *   <span class="ink-3">social</span><span class="ink">radar</span><span style="color:var(--brand)">·</span>
 */
.sr-brand {
  padding: 20px 20px 12px;
}
.sr-brand-mark {
  /* 와이어프레임 realtime-feed.html 의 wordmark 와 정확히 동일한 폰트 보장.
   * --font-sans 가 어딘가에서 재정의되거나 부모의 font-feature-settings 가
   * cv02-cv11 같은 Inter 전용 OpenType 변형을 흘려도 이 노드는 영향받지 않게
   * 명시 폰트 스택 + font-feature-settings 명시 리셋. */
  font-family: 'Pretendard Variable', Pretendard, -apple-system, system-ui, sans-serif !important;
  font-feature-settings: normal;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.04em;
  line-height: 1;
}
.sr-brand-mark span {
  /* 자손 <span class="ink-3"> / <span class="ink"> / <span style="color:..."> 도 동일 폰트 강제.
   * DaisyUI / Tailwind preflight 가 a > span 같은 셀렉터로 폰트를 건드리는 회귀 차단. */
  font-family: inherit;
  font-feature-settings: inherit;
}
.sr-brand-mark .ink-3 { color: var(--ink-3); }
.sr-brand-mark .ink   { color: var(--ink); }
.sr-brand-eyebrow {
  font-size: 9px; color: var(--ink-3);
  margin-top: 6px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.16em;
}

/* Workspace card (사이드바 상단 — 8x8 dark square + name + status + chevron) */
.workspace-card {
  width: 100%;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 0; background: transparent;
  text-align: left; cursor: pointer;
  transition: background .12s;
}
.workspace-card:hover { background: var(--surface-hover, #f3f5f8); }
.workspace-card-mark {
  width: 32px; height: 32px;
  flex-shrink: 0;
  border-radius: 7px;
  display: inline-grid; place-items: center;
  background: var(--ink); color: #fff;
  font-size: 11px; font-weight: 700;
}
.workspace-card-body { flex: 1; min-width: 0; }
.workspace-card-name {
  font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.workspace-card-meta {
  font-size: 11px; color: var(--ink-3);
  display: flex; align-items: center; gap: 6px;
  margin-top: 1px;
}
.workspace-card-meta .dot-status {
  width: 7px; height: 7px; border-radius: 99px;
  display: inline-block;
}
.workspace-card-meta .dot-status.is-active   { background: var(--good); }
.workspace-card-meta .dot-status.is-paused   { background: var(--warn); }
.workspace-card-meta .dot-status.is-inactive { background: var(--ink-4, #cbd5e1); }
.workspace-card-meta .dot-status.is-archived { background: var(--ink-3); }

/* Sidebar nav scrollable 영역 + 푸터 (와이어프레임: px-3 py-3) */
.sr-sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
}
.sr-sidebar-foot {
  padding: 12px;
  border-top: 1px solid var(--line);
}

/* ─── Main column ──────────────────────────────────────────── */
.sr-main {
  flex: 1;
  min-width: 0;
  display: flex; flex-direction: column;
}

/* Topbar (per-page) — breadcrumb 좌, search + bell + avatar 우.
 * 와이어프레임 realtime-feed.html L591: px-8 py-3 → 12px vertical, 32px horizontal. */
.sr-topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 32px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  gap: 12px;
}
.sr-breadcrumb {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-3);
  min-width: 0;
}
.sr-breadcrumb-sep { color: var(--ink-4, #cbd5e1); }
.sr-breadcrumb-current { color: var(--ink-2); font-weight: 500; }
.sr-topbar-actions {
  display: flex; align-items: center; gap: 8px;
}
.sr-topbar-divider {
  width: 1px; height: 24px;
  background: var(--line);
  margin: 0 4px;
}

/* Page header (h1 + 액션 버튼)
 * 와이어프레임 realtime-feed.html: px-8 py-5 + border-b + bg-white.
 *   h1: text-[22px] font-bold tracking-tight (Tailwind tracking-tight = -0.025em)
 *   subtitle: text-[13px] ink-2 mt-1 (4px)
 *
 * 좁은 폭에서는 와이어프레임 (L344~355) 처럼 .sr-page-actions 가 다음 줄로 떨어지면서
 * width:100% 가 되고, .btn-secondary-mobile 은 숨김, .btn-label 은 선택적으로 숨겨
 * 아이콘만 남도록 한다. 헤더가 한 줄에 못 들어갈 때 우측 영역이 짜부러지지 않게 하는 핵심.
 */
.sr-page-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 32px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  gap: 12px; flex-wrap: wrap;
}
.sr-page-header > :first-child {
  /* 제목 블록은 남는 공간을 모두 가져가 ellipsis 가 동작하도록 */
  flex: 1 1 auto; min-width: 0;
}
.sr-page-header h1 {
  font-size: 22px; font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.025em;
  /* line-height 는 html 의 1.5 (Tailwind preflight) 를 그대로 상속.
   * 와이어프레임 realtime-feed.html 의 .text-[22px] 는 line-height pair 를 두지 않아
   * h1 line-height = 1.5 가 된다. 옛 명시값 1.2 는 헤더 총 높이를 ~6.6px 짧게 만들어
   * 와이어프레임 대비 어색한 vertical rhythm 을 만들었다. */
}
.sr-page-header .subtitle {
  font-size: 13px; color: var(--ink-2);
  margin-top: 4px;
  font-weight: 400;
}
.sr-page-actions {
  display: flex; align-items: center; gap: 8px;
  flex: 0 0 auto; flex-wrap: wrap;
  justify-content: flex-end;
}

/* Page body wrapper (padding + space-y) */
.sr-page-body {
  padding: 24px 32px;
  display: flex; flex-direction: column; gap: 20px;
}

/* 사이드바 nav 컨테이너 — 와이어프레임 realtime-feed.html 의 nav 패턴.
 * 옛 .surface-flat (border + border-radius 12px) 박스를 제거: 사이드바 자체가
 * 이미 우측 보더 + surface 배경을 가지므로 nav 가 또 카드를 그릴 필요 없다.
 * nav-row 의 hover/active 자체 보더 반경(8px)만 보이게 한다.
 *
 * padding 0 — 와이어프레임은 외곽 <nav class="px-3 py-3"> 단일 컨테이너에 12px gutter 만
 * 두는데, 우리는 layouts/app.blade.php 의 <nav class="sr-sidebar-nav"> (= padding 12px) 안에
 * 다시 <nav class="sr-nav-list"> 가 들어와 8px 을 추가한다. 그 결과 nav-row 와 active 배경이
 * 사이드바 edge 로부터 12+8=20px 인셋되어 와이어프레임(12px)보다 8px 더 안으로 밀린 채 렌더된다
 * (사용자 보고 — 사이드바 비교 스샷). 외곽 컨테이너가 이미 12px 을 책임지므로 여기서는 0 으로 둔다. */
.sr-nav-list {
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
}

/* sr-page-header 는 와이어프레임 realtime-feed.html 처럼 토픅바 직하단에
 * 풀폭 + flush 로 붙어야 한다. sr-page-body 의 padding (24px 32px) 을
 * 음수 마진으로 깨고, 자기 자신의 padding (20px 32px) 으로 컨텐츠를 정렬한다.
 * 하단 24px 마진 = 와이어프레임 본문 wrapper 의 py-6 (24px top padding)
 * 와 같은 시각 간격을 헤더 → KPI 사이에 만든다 (margin collapse 로 space-y-5 의 20px 흡수).
 * Livewire 루트 div(.space-y-5 등) 안에 박혀 있어도 동작하도록 두 단계까지 자손 검사.
 *
 * `:first-child` 가드 — 비활성 배너 / session flash 등 헤더 *위에* 다른 콘텐츠가
 * 들어오는 경우엔 음수 마진을 끄고 정상 flow + flex gap 으로 분리한다.
 * (이 가드 없으면 -24px top 이 배너의 bottom 을 4px 파고들면서 풀-블리드 좌우와
 *  계단식 misalignment 가 발생.) */
.sr-page-body > .sr-page-header:first-child,
.sr-page-body > :first-child > .sr-page-header:first-child {
  margin: -24px -32px 24px;
  width: auto;
}

/* Mobile-only — 햄버거 토글 등 */
.mobile-only { display: none; }

/* ─── Search input (topbar + filter-bar 공용)
 *  와이어프레임 spec: padding 9px 12px 9px 38px / border-radius 10px / font 13px
 *  아이콘은 Lucide <i data-lucide="search"> (topbar) 또는 ::before ⌕ (filter-bar 어디서나).
 *  Lucide 가 박혀 있으면 그것 쓰고, 없으면 pseudo 가 출력. 둘 다 있으면 Lucide 우선. */
.search-wrap { position: relative; }
.search-wrap > [data-lucide="search"],
.search-wrap > svg.lucide-search {
  position: absolute; left: 11px; top: 50%;
  transform: translateY(-50%);
  color: var(--ink-3);
  width: 15px; height: 15px;
  pointer-events: none;
}
.search-wrap:not(:has(> [data-lucide="search"])):not(:has(> svg.lucide-search))::before {
  content: '⌕';
  position: absolute; left: 13px; top: 50%;
  transform: translateY(-50%);
  color: var(--ink-3);
  font-size: 15px;
  pointer-events: none;
}
.search-input {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 12px 9px 38px;
  font-size: 13px;
  color: var(--ink);
  transition: border-color .12s;
}
.search-input::placeholder { color: var(--ink-3); }
.search-input:focus { outline: 0; border-color: var(--ink-3); }

/* ─── KPI 3-up strip (실시간 피드 / 대시보드 헤더) ─────────── */
.kpi-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.kpi-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 18px 22px;
  display: flex; align-items: center; gap: 16px;
}
.kpi-icon {
  width: 40px; height: 40px;
  flex-shrink: 0;
  border-radius: 10px;
  display: inline-grid; place-items: center;
}
.kpi-icon [data-lucide] { width: 18px; height: 18px; }
.kpi-num {
  font-size: 26px; font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.label {
  font-size: 12px; font-weight: 500; color: var(--ink-3);
}

/* ─── Filter bar internals (.card 안에서) ──────────────────── */
.filter-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.filter-wrap { position: relative; }

.filter-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line-2, var(--line));
}
.filter-divider {
  border-top: 1px solid var(--line-2, var(--line));
  margin: 0;
}
/* ─── Source icon (와이어프레임 .src-icon 버전 — 22px, alias of .srcico) ───
 *  옛 .srcico (20px) 와 별개로 와이어프레임은 .src-icon 을 쓴다.
 *  새 코드는 .src-icon 을 쓰고, 옛 코드의 .srcico 도 같은 톤으로 살린다.
 *  컬러 클래스 (.src-naver / .src-x 등) 는 양쪽이 공유. */
.src-icon {
  width: 22px; height: 22px;
  flex-shrink: 0;
  border-radius: 5px;
  display: inline-grid; place-items: center;
  font-weight: 700; font-size: 11px;
  color: #fff;
}
.src-naver { background: #03c75a; }
/* .src-x / .src-dcinside / .src-ppomppu 는 위 .srcico 블록에 이미 정의 — 공유 */

/* ─── Pagination (.feed-row 테이블 푸터) ──────────────────── */
.page-info {
  display: flex; align-items: center; gap: 12px;
  font-size: 12px; color: var(--ink-3);
  flex-wrap: wrap;
}
.page-summary { white-space: nowrap; }
.page-size-label { color: var(--ink-4, #cbd5e1); }
.page-btn {
  min-width: 32px; height: 32px;
  padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  font-size: 13px; font-weight: 500;
  color: var(--ink-2);
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.page-btn:hover { background: var(--surface-hover, var(--bg-2)); }
.page-btn.active { background: var(--ink); color: #fff; }
.page-btn:disabled,
.page-btn[disabled] { opacity: .35; cursor: not-allowed; }

/* feed table head row (5-col 그리드, 헤더 라벨)
 * 와이어프레임 spec: text-[11px] font-semibold uppercase tracking-wider ink-3 / bg surface-2 */
.feed-table-head {
  display: grid;
  grid-template-columns: 180px 1fr 90px 90px 80px;
  gap: 16px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2, var(--bg-2));
  font-size: 11px; font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-3);
}

/* div 기반 정렬 헤더 — Lucide SVG (vertical-align: baseline) 가 라벨 텍스트와
 * 어긋나는 것을 inline-flex 로 잡는다. */
.feed-table-head .th-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.feed-table-head .th-sort.is-right {
  justify-content: flex-end;
}
.feed-table-head .th-sort .th-sort-icon {
  flex-shrink: 0;
  color: var(--muted);
  opacity: .55;
  transition: opacity .12s ease, color .12s ease;
}
.feed-table-head .th-sort:hover .th-sort-icon {
  opacity: .9;
}
.feed-table-head .th-sort.is-sort-active {
  color: var(--ink);
}
.feed-table-head .th-sort.is-sort-active .th-sort-icon {
  opacity: 1;
  color: var(--accent);
}

/* feed-row 전체 — 와이어프레임의 5-col 그리드 (위에 이미 .feed-row 있음, 호환 정의) */
.feed-row.feed-row-grid {
  display: grid;
  grid-template-columns: 180px 1fr 90px 90px 80px;
  gap: 16px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
  align-items: start;
  position: relative;
  cursor: pointer;
  transition: background .12s;
}
.feed-row.feed-row-grid:hover { background: var(--surface-2, var(--bg-2)); }

/* AI 사이드 패널 박스 */
.ai-box {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
}
.ai-label {
  font-size: 11px; font-weight: 700;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 6px;
  padding-left: 8px;
  border-left: 2px solid var(--brand);
}

/* 댓글 카드 */
.comment {
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--surface-2, var(--bg-2));
  margin-bottom: 8px;
}

/* ─── Mobile (≤1024px) — 사이드바 drawer 전환 ─────────────── */
@media (max-width: 1024px) {
  .sr-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    z-index: 50;
    transform: translateX(-100%);
    transition: transform .25s ease;
    box-shadow: 0 8px 32px rgba(11,18,32,0.12);
  }
  .sr-sidebar.open { transform: translateX(0); }
  .mobile-only { display: inline-flex; }

  /* iOS Safari: 100vh 가 주소창/툴바 밖까지 포함해 푸터가 가려질 수 있음 —
     fixed top/bottom 부모 안에서는 100% + min-height:0 로 실제 드로어 높이에 맞춘다. */
  .sr-sidebar-inner {
    height: 100%;
    min-height: 0;
  }
  /* 홈 인디케이터·하단 브라우저 UI와 겹침 방지 (viewport-fit=cover 와 함께) */
  .sr-sidebar-foot {
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }

  .sr-topbar { padding: 12px 16px; }
  .sr-page-header { padding: 16px; }
  .sr-page-body { padding: 16px; }

  /* 본문 padding 이 16px 로 줄어들었으니 헤더의 negative margin 도 16px 로.
   * 안 그러면 header 가 viewport 밖으로 밀려나 제목이 좌측 끝에 클립된다.
   * `:first-child` 가드는 1815~ 의 데스크톱 규칙과 동일 의도. */
  .sr-page-body > .sr-page-header:first-child,
  .sr-page-body > :first-child > .sr-page-header:first-child {
    margin: -16px -16px 16px;
  }

  /* 헤더 우측 액션이 너무 길어 한 줄에 못 들어가면 다음 줄로 떨어뜨리고 우측 정렬 */
  .sr-page-header .sr-page-actions { gap: 6px; }
  .sr-page-header .sr-page-actions .btn { padding: 7px 12px; font-size: 12.5px; }

  .sr-topbar-search { display: none; }

  .kpi-strip { grid-template-columns: repeat(2, 1fr); }
  .kpi-item { padding: 14px 16px; gap: 12px; }
  .kpi-num { font-size: 22px; }

  .filter-panel { left: 0; min-width: 240px; max-width: calc(100vw - 32px); }
}

/* ─── Mobile (≤640px) ─────────────────────────────────────── */
@media (max-width: 640px) {
  .sr-page-header h1 { font-size: 17px; }
  .sr-page-header .subtitle { font-size: 11px; }

  /* 와이어프레임 realtime-feed.html L344~355 정렬:
   *   actions 가 다음 줄로 떨어지며 풀폭, 버튼 컴팩트, secondary 버튼 숨김 */
  .sr-page-header .sr-page-actions {
    width: 100%;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: flex-start;
  }
  .sr-page-header .sr-page-actions .btn {
    padding: 7px 10px;
    font-size: 12px;
    gap: 5px;
  }
  .sr-page-header .sr-page-actions .btn [data-lucide],
  .sr-page-header .sr-page-actions .btn svg { width: 14px; height: 14px; }
  .sr-page-header .sr-page-actions .btn-secondary-mobile { display: none; }

  .kpi-strip { grid-template-columns: 1fr; }

  .filter-bar {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .filter-bar::-webkit-scrollbar { display: none; }
  .filter-bar > * { flex-shrink: 0; }

  .feed-table-head { display: none; }

  .feed-row.feed-row-grid {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px 16px 16px;
  }

}

/* Print 안전 — 사이드바/톱바 자르기 */
@media print {
  .sr-sidebar, .sr-topbar { display: none !important; }
  .sr-page-header { border-bottom: 1px solid #ddd !important; }
}

/* ═════════════════════════════════════════════════════════════
 *  Dashboard wireframe alignment (option-b-suite-minimal.html)
 *  대시보드 인사이트(/p/{slug}) 4섹션 신규 컴포넌트.
 *  기존 .hero-card / .kpi-grid / .issue-cell / .chip-* 를 보조한다.
 * ═════════════════════════════════════════════════════════════ */

/* 섹션 제목 (01·02·03·04 카드 head) */
.heading-sec {
  font-size: 15px; font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.015em;
}
@media (max-width: 640px) {
  .heading-sec { font-size: 14px; }
}

/* 섹션 head — 좌(타이틀) 우(라벨/액션) */
.sec-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}

/* HERO 2-pillar — base 는 Tailwind 유틸(grid grid-cols-2 gap-10) 이 담당,
 * 여기서는 모바일 대응만. */
.hero-2col {} /* base no-op; 와이어프레임 정합 keeper */
.hero-pillar-right {} /* base no-op (Tailwind pl-10 border-l 가 base) */
@media (max-width: 1024px) {
  .hero-2col {
    grid-template-columns: 1fr !important;
    gap: 24px !important;
  }
  .hero-pillar-right {
    padding-left: 0 !important;
    border-left: 0 !important;
    border-top: 1px solid var(--line);
    padding-top: 24px;
  }
}

/* 04 섹션 VOC 3-col */
.voc-grid {} /* base 는 Tailwind grid grid-cols-3 gap-4 */
@media (max-width: 640px) {
  .voc-grid { grid-template-columns: 1fr !important; }
}

/* 02 섹션 — 시간대별 추이 SVG */
.chart-svg { width: 100%; display: block; }
@media (max-width: 640px) {
  .chart-svg { height: 180px !important; }
}

/* 02 섹션 — 주의 신호 위험 카드 */
.risk-card {
  padding: 14px 16px; border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  cursor: pointer;
  transition: border-color .15s;
}
.risk-card:hover { border-color: var(--ink-3, #94a3b8); }

.risk-score {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 15px; flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.risk-score.crit { background: var(--bad-soft, var(--crit-soft)); color: var(--bad, var(--crit)); }
.risk-score.warn { background: var(--warn-soft); color: var(--warn); }

/* 03 섹션 — 이슈 키워드 약한 적중 */
.issue-cell.hit-weak { background: var(--bg-2, #fafbfc); border-color: var(--line); }

/* 03 섹션 — 채널 sentiment 분포 mini-bar (per-channel inline) */
.donut-leg {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; font-size: 13px;
}

/* delta chip — 7d 변화량 (KPI 카드 우상단) */
.delta { font-size: 12px; font-weight: 600; }
.delta.up   { color: var(--bad, var(--crit)); }
.delta.down { color: var(--ok); }
.delta.flat { color: var(--ink-3, #94a3b8); }

/* 진동 도트 — HERO "오늘의 이슈" 라이브 표식 */
.dot-pulse {
  box-shadow: 0 0 0 0 currentColor;
  animation: sr-pulse 2.4s infinite;
}
@keyframes sr-pulse {
  70%  { box-shadow: 0 0 0 6px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* KPI 카드 안의 sparkline 만 28px (전역 .spark = 40px 유지) */
.kpi-grid .spark { height: 28px; }

/* 와이어프레임 hero 패딩 정합 — base override (페이지 헤더 hero 통일) */
.hero-card { padding: 32px 36px; }
@media (max-width: 1024px) { .hero-card { padding: 22px 22px; } }
@media (max-width:  640px) { .hero-card { padding: 18px 16px; border-radius: 10px; } }
.hero-card .hero-title {
  font-size: 24px; font-weight: 700; letter-spacing: -0.02em;
  line-height: 1.25; color: var(--ink);
}
@media (max-width: 640px) {
  .hero-card .hero-title { font-size: 22px !important; }
}

/* 04 섹션 — 핵심 키워드 hashtag chip cloud */
.kw-tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 500;
  background: var(--bg-2, #f8fafc); color: var(--ink-2);
  border: 1px solid var(--line);
}
.kw-tag.tone-pos { background: var(--ok-soft); color: #15803d; border-color: rgba(34,183,90,.2); }
.kw-tag.tone-neg { background: var(--bad-soft, var(--crit-soft)); color: #991b1b; border-color: rgba(220,38,38,.2); }
.kw-tag .kw-count { color: var(--ink-3, #94a3b8); font-size: 11px; }

/* 04 섹션 — VOC 3-col 카드 (좌측 강조는 Blade 에서 border-left 단일로만 지정 — ::before 와 중복 금지) */
.voc-card {
  position: relative;
  padding: 16px 18px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
}

/* 03 섹션 — sentiment 분포 bar (대시보드 채널·이슈·KPI 등 — 행 너비 전체 사용) */
.sb-bar {
  display: flex;
  width: 100%;
  min-width: 0;
  border-radius: 3px;
  overflow: hidden;
  background: var(--line);
}
.sb-bar > span { display: block; height: 100%; }
.sb-bar .sb-pos { background: var(--ok); }
.sb-bar .sb-neu { background: var(--ink-3, #94a3b8); }
.sb-bar .sb-neg { background: var(--bad, var(--crit)); }

/* favor index — KPI 2번째 카드 -100~+100 표시 */
.favor-meter {
  position: relative; height: 8px; border-radius: 4px;
  background: linear-gradient(90deg, var(--bad-soft, var(--crit-soft)) 0%, var(--bg-2) 50%, var(--ok-soft) 100%);
  overflow: visible;
}
.favor-meter .favor-needle {
  position: absolute; top: -4px; width: 3px; height: 16px;
  border-radius: 2px; background: var(--ink);
  transform: translateX(-50%);
}
.favor-meter .favor-axis {
  position: absolute; left: 50%; top: -2px; width: 1px; height: 12px;
  background: var(--ink-3, #94a3b8); opacity: .5;
}
