/* PROJECT JAMES — mobile responsive overrides
 *
 * Strategy: desktop-first inline styles in index.html / admin.html
 * stay untouched; this stylesheet adds @media-gated overrides for
 * narrow viewports (≤ 768px tablet, ≤ 480px phone).
 *
 * Loaded as the LAST stylesheet via <link> at the bottom of <head>
 * so its rules win over the inline base styles. No !important
 * needed — same specificity, later position.
 *
 * Three principles:
 *   1) Touch targets ≥ 44×44px (Apple HIG / Material guidelines).
 *   2) No fixed widths < 100vw — anything horizontal must reflow
 *      or scroll, never clip.
 *   3) Bottom-anchored input area + safe-area-inset-bottom for
 *      iOS notch / home-bar.
 */

/* ─────────────────────────────────────────────────────────
 * Reasoning stream animations (item #1, 2026-05-08; #1-A 2차 개선)
 * 응답 추론 과정 — 활성 stage는 spinner 회전 + 텍스트 shimmer,
 * 완료된 stage는 정적/회색. 진짜 진행 중인 단계가 시각적으로
 * 명확하게 살아있어 보이게.
 *
 * #1-A 변경 (사용자 피드백 2026-05-08):
 *   "뇌신경이 반짝이는 로봇 모양 아이콘 + 첨부된 글자도 그라데이션하게
 *   반짝이게" — 단색 shimmer → 무지개 multi-stop. SVG 브레인-뉴런
 *   아이콘 (.brain-pulse) 추가. 기존 .thinking-label은 그대로 활용.
 *
 * 구조: each `.thinking-line` toggles between:
 *   .thinking-active  — 현재 진행 중 (spinner + shimmer)
 *   .thinking-done    — 완료 (정적, 살짝 흐림)
 * --stage-color CSS 변수에 stage별 색상이 inject됨 (chat.js).
 * ────────────────────────────────────────────────────────*/
@keyframes james-spin {
  to { transform: rotate(360deg); }
}
@keyframes james-pulse-dot {
  0%, 100% { opacity: 0.3; transform: scale(0.85); }
  50%      { opacity: 1.0; transform: scale(1.05); }
}
@keyframes james-shimmer {
  0%   { background-position: -180% 0; }
  100% { background-position:  180% 0; }
}

/* [#1-A] 브레인-뉴런 아이콘 — 로봇 헤드 윤곽 + 내부 노드들이
   서로 다른 phase로 깜빡. 각 뉴런이 ⌀5px, fill에 stage-color
   inject되어 stage 별로 다르게 보임. */
@keyframes james-neuron-blink-1 {
  0%, 100% { opacity: 0.25; }
  20%, 40% { opacity: 1; }
}
@keyframes james-neuron-blink-2 {
  0%, 100% { opacity: 0.25; }
  35%, 55% { opacity: 1; }
}
@keyframes james-neuron-blink-3 {
  0%, 100% { opacity: 0.25; }
  60%, 80% { opacity: 1; }
}
@keyframes james-neuron-pulse {
  0%, 100% { transform: scale(1);    filter: drop-shadow(0 0 1px var(--stage-color, #7c6af7)); }
  50%      { transform: scale(1.06); filter: drop-shadow(0 0 6px var(--stage-color, #7c6af7)); }
}
.brain-pulse {
  width: 22px; height: 22px;
  display: inline-block;
  flex-shrink: 0;
  vertical-align: middle;
  --stage-color: #7c6af7;
}
.brain-pulse svg { width: 100%; height: 100%; overflow: visible; }
.brain-pulse .brain-outline {
  fill: none;
  stroke: var(--stage-color, #7c6af7);
  stroke-width: 1.5;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 2px var(--stage-color, #7c6af7));
}
.brain-pulse .neuron {
  fill: var(--stage-color, #7c6af7);
  transform-origin: center;
  transform-box: fill-box;
}
.brain-pulse .neuron-link {
  stroke: var(--stage-color, #7c6af7);
  stroke-width: 0.6;
  opacity: 0.45;
  fill: none;
}
.brain-pulse.brain-pulse-active .neuron-1 { animation: james-neuron-blink-1 0.9s ease-in-out infinite,
                                                       james-neuron-pulse 0.9s ease-in-out infinite; }
.brain-pulse.brain-pulse-active .neuron-2 { animation: james-neuron-blink-2 0.9s ease-in-out infinite,
                                                       james-neuron-pulse 0.9s ease-in-out infinite; }
.brain-pulse.brain-pulse-active .neuron-3 { animation: james-neuron-blink-3 0.9s ease-in-out infinite,
                                                       james-neuron-pulse 0.9s ease-in-out infinite; }
.brain-pulse.brain-pulse-active .brain-outline {
  animation: james-shimmer 1.2s linear infinite;
}

.thinking-stream {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  font-family: var(--font-mono, ui-monospace, monospace);
  color: var(--muted, #888);
  min-height: 24px;
}
.thinking-placeholder {
  display: flex;
  align-items: center;
  gap: 8px;
  font-style: italic;
  opacity: 0.85;
}
.thinking-spinner-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent, #7c6af7);
  animation: james-pulse-dot 1.0s ease-in-out infinite;
  flex-shrink: 0;
}
.thinking-line {
  display: flex;
  align-items: center;
  gap: 8px;
  transition: opacity .35s ease, color .35s ease;
  color: var(--stage-color, currentColor);
  --stage-color: currentColor;
}
.thinking-icon {
  flex-shrink: 0;
  display: inline-block;
  font-size: 14px;
  line-height: 1;
  width: 18px; text-align: center;
  transform-origin: 50% 50%;
}
/* [#1-A] thinking-label — 무지개 multi-stop gradient + glow.
   기존 stage-color → white → stage-color 단순 패턴 대비, 보색 한
   stop을 더해 "반짝거림"이 명확. text-shadow로 살짝 후광. */
.thinking-label {
  font-weight: 600;
  font-family: inherit;
  background: linear-gradient(
    90deg,
    var(--stage-color, #7c6af7) 0%,
    rgba(255, 255, 255, 0.95) 30%,
    var(--stage-accent, #f06292) 50%,
    rgba(255, 255, 255, 0.95) 70%,
    var(--stage-color, #7c6af7) 100%
  );
  background-size: 220% 100%;
  background-position: 0 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter: drop-shadow(0 0 1px var(--stage-color, #7c6af7));
}
.thinking-detail {
  color: var(--muted, #888);
  font-size: 11px;
  margin-left: 2px;
}
.thinking-elapsed {
  color: var(--muted, #888);
  opacity: 0.7;
}

/* Active state: spinner 회전 + label shimmer */
.thinking-line.thinking-active .thinking-icon {
  animation: james-spin 1.4s linear infinite;
  filter: drop-shadow(0 0 4px var(--stage-color, #7c6af7));
}
.thinking-line.thinking-active .thinking-label {
  animation: james-shimmer 1.2s linear infinite;
}

/* Done state: spinner 정지, 색상 흐림 */
.thinking-line.thinking-done {
  opacity: 0.55;
}
.thinking-line.thinking-done .thinking-icon {
  animation: none;
  filter: none;
}
.thinking-line.thinking-done .thinking-label {
  animation: none;
  background: none;
  -webkit-text-fill-color: var(--stage-color, var(--muted, #888));
  color: var(--stage-color, var(--muted, #888));
}

/* ─────────────────────────────────────────────────────────
 * [§4 #3 phase grouping, 2026-05-12] Reasoning timeline phases
 * — RETRIEVE → EXPAND → VERIFY. Each phase is a small header
 * over a body of one or more thinking-lines. Empty phases are
 * never rendered (chat.js creates them lazily) so an answer that
 * skips graph still reads as a clean two-step timeline.
 * ────────────────────────────────────────────────────────*/
.thinking-phase {
  margin-top: 6px;
}
.thinking-phase + .thinking-phase {
  border-top: 1px dashed var(--border-2, rgba(255, 255, 255, 0.10));
  padding-top: 6px;
  margin-top: 8px;
}
.thinking-phase-header {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  margin-bottom: 4px;
  color: var(--muted, #888);
  /* Phase header inherits the active line's stage color via the
     enclosing .thinking-phase-active rule below, so the header
     visually echoes whichever stage is currently running inside. */
  transition: color .35s ease, opacity .35s ease;
}
.thinking-phase-icon {
  font-size: 11px;
  line-height: 1;
}
.thinking-phase-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Active phase — header pops to accent so the user can tell at a
   glance which timeline phase the reasoner is in right now. */
.thinking-phase-active .thinking-phase-header {
  color: var(--accent-fg, var(--accent, #7c6af7));
}
/* Done phase — header dims to match its lines. */
.thinking-phase-done .thinking-phase-header {
  opacity: 0.6;
}

/* ─────────────────────────────────────────────────────────
 * Admin nav — foldable sections (item #2, 2026-05-08)
 * 데스크탑/모바일 양쪽에서 섹션별 접기/펴기 가능. 각 nav-section을
 * 클릭하면 바로 다음 .nav-group이 슬라이드 닫힘. 모바일은 추가로
 * nav 자체를 햄버거 토글로 펼침/접음.
 * ────────────────────────────────────────────────────────*/
.nav-section.nav-foldable {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: background 0.15s;
}
.nav-section.nav-foldable:hover {
  background: var(--surface-2, #1a1d22);
}
.nav-fold-icon {
  display: inline-block;
  transition: transform 0.2s ease;
  font-size: 10px;
  width: 10px;
  text-align: center;
}
.nav-section.nav-collapsed .nav-fold-icon {
  transform: rotate(-90deg);
}
.nav-group {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  max-height: 600px;             /* enough for any group */
  transition: max-height 0.25s ease, opacity 0.2s ease;
  opacity: 1;
}
.nav-group.nav-group-collapsed {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
}

/* ─────────────────────────────────────────────────────────
 * Tablet + phone (≤ 768px)
 * ────────────────────────────────────────────────────────*/
@media (max-width: 768px) {
  body { font-size: 15px; }

  /* ── 헤더 — 모바일은 여러 요소가 한 줄에 못 들어감 ── */
  header {
    padding: 8px 12px;
    flex-wrap: wrap;
    gap: 6px;
  }
  .header-right {
    gap: 4px;
    flex-wrap: wrap;
    justify-content: flex-end;
  }
  .logo { font-size: 13px; }
  .logo::before { width: 18px; height: 18px; }

  /* PROD/TEST 토글 — 작게 */
  .source-toggle { font-size: 10px; }
  .source-toggle button { padding: 5px 8px; min-height: 30px; }

  /* KO|EN, ADMIN, 로그인, etc. */
  .nav-btn {
    padding: 6px 10px;
    font-size: 12px;
    min-height: 36px;          /* touch target */
  }

  .role-badge {
    padding: 4px 10px;
    font-size: 11px;
  }

  /* ─────────────── chat 페이지 ─────────────── */

  /* 사이드바 — 모바일에선 화면 가득, 닫혔을 때 0.
   * Scoped to ``aside.sidebar`` so it doesn't clobber workspace.html's
   * ``nav.sidebar`` (which is a flow-positioned 200/56px rail with
   * its own inline @media at 700px). */
  aside.sidebar {
    position: fixed;
    z-index: 50;
    inset: 0 auto 0 0;          /* top:0 right:auto bottom:0 left:0 */
    width: 88vw;
    max-width: 360px;
    box-shadow: 4px 0 16px rgba(0, 0, 0, 0.4);
  }
  aside.sidebar.collapsed { width: 0; box-shadow: none; }
  .sidebar-open-btn {
    width: 44px;
    height: 44px;
    font-size: 18px;
  }

  /* 메시지 영역 — 패딩 줄이고 chat 가장자리까지 사용 */
  .messages {
    padding: 16px 12px 12px;
    gap: 14px;
  }
  .msg { max-width: 100%; }
  .bubble {
    padding: 10px 14px;
    font-size: 14.5px;
    border-radius: 12px;
    line-height: 1.55;
  }
  .avatar { width: 28px; height: 28px; font-size: 12px; }

  /* 웰컴 — 좁은 화면에 맞게 */
  .welcome { padding: 24px 16px; }
  .welcome-title { font-size: 22px; }
  .welcome-sub { font-size: 13px; }
  .welcome-chips { gap: 6px; margin-top: 20px; }
  .chip { padding: 8px 12px; font-size: 12px; }

  /* 입력 영역 — 모바일은 항상 바닥 + iOS safe-area */
  .input-area, #input-area, footer.input-area {
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0));
    gap: 6px;
  }
  textarea, input[type="text"], #chat-input {
    font-size: 16px;             /* iOS 자동 줌 방지 (≥ 16px) */
    padding: 10px 12px;
    min-height: 44px;
    border-radius: 10px;
  }
  button, .btn {
    min-height: 36px;
    min-width: 36px;
  }

  /* 답변 옆 buttons (👍 👎 📥) — 가로 스크롤 가능하게 */
  .feedback-btns {
    flex-wrap: wrap;
    overflow-x: auto;
    padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
  }
  .fb-btn {
    flex-shrink: 0;
    padding: 6px 12px !important;
    min-height: 32px;
    font-size: 13px !important;
  }

  /* 그래프 패스 / 메타 정보 — 폰트 살짝 작게 */
  .graph-paths { font-size: 11px; padding: 8px 10px; }
  .meta { font-size: 11px; gap: 6px; }

  /* ─────────────── admin 페이지 ─────────────── */

  /* admin nav — 모바일은 햄버거 토글 + 슬라이드 드로워 (item #2) */
  #admin-nav-toggle {
    display: block !important;
  }
  #admin-nav {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: 80vw;
    max-width: 320px;
    background: var(--surface, #14161a);
    border-right: 1px solid var(--border, #25282f);
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    z-index: 50;
    overflow-y: auto;
    padding: 60px 12px 20px;       /* 토글 버튼 자리 확보 */
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.6);
  }
  #admin-nav.admin-nav-open {
    transform: translateX(0);
  }
  /* admin nav 열렸을 때 본문 클릭 시 닫히도록 backdrop */
  #admin-nav-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 49;
    display: none;
  }
  #admin-nav-backdrop.show {
    display: block;
  }
  /* 본문은 사이드바 위치 무관하게 풀폭 */
  .admin-layout > main, main {
    width: 100%;
  }
  .nav-item {
    padding: 10px 14px;
    min-height: 44px;
    font-size: 14px;
    border-radius: 8px;
  }

  /* 페이지 본문 — 패딩 줄이고 카드들 세로 stack */
  .page, .admin-page, main.admin-content {
    padding: 12px;
  }
  .page-title { font-size: 16px; margin-bottom: 12px; }
  .section-title { font-size: 13px; margin: 12px 0 8px; }

  /* 카드 그리드 → 단일 컬럼 */
  .cards {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 8px !important;
  }
  .card { padding: 10px !important; }
  .card-label { font-size: 10px; }
  .card-value { font-size: 18px !important; }
  .card-sub { font-size: 10px; }

  /* 테이블 — 가로 스크롤 가능하게 */
  .table-wrap, .table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 8px;
  }
  .table-wrap table, .admin-page table {
    min-width: 480px;            /* 너무 좁으면 스크롤 트리거 */
    font-size: 12px;
  }
  .table-wrap th, .table-wrap td,
  .admin-page th, .admin-page td {
    padding: 8px 6px;
  }

  /* hardware 카드, 설정 카드 등 min-width 280/260/220px → 100% */
  [style*="min-width:280px"],
  [style*="min-width:260px"],
  [style*="min-width:220px"],
  [style*="min-width:200px"] {
    min-width: 0 !important;
    width: 100%;
  }

  /* entities/sessions 검색 입력 + 필터 — 한 줄 → 두 줄 */
  #entities-search, #entities-etype-filter {
    width: 100%;
    min-width: 0 !important;
  }
  #entities-counter { width: 100%; text-align: right; }

  /* 페이징 버튼 — 터치 타겟 키움 */
  #entities-prev, #entities-next {
    min-height: 40px;
    padding: 8px 16px !important;
  }

  /* 상세 modal / 세션 turns modal — 풀화면 */
  #entity-detail-modal, #session-turns-modal,
  #login-modal, #admin-login-modal {
    padding: 12px !important;
  }
  #entity-detail-modal > div, #session-turns-modal > div,
  #login-modal > div, #admin-login-modal > div {
    max-width: 100% !important;
    max-height: 92vh !important;
    padding: 14px !important;
    border-radius: 10px;
  }
  #entity-detail-body, #session-turns-body {
    font-size: 12px;
    max-height: 65vh !important;
  }

  /* dashboard 차트 — 너비 100% */
  #dash-chart > div[style*="display:flex"],
  #dash-chart > div[style*="display: flex"] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* ─────────────── workspace 페이지 ───────────────
   * Originally lived inline in workspace.html at the 700px
   * breakpoint; consolidated here so the four pages share a
   * single 768px mobile boundary.
   *
   * Workspace's left rail is ``nav.sidebar`` (NOT ``aside.sidebar``
   * which belongs to the chat page) — selectors are scoped to that
   * element so the chat page's full-screen drawer rules don't
   * collide. The ``.nav-item span:not(.nav-icon)`` collapse is
   * descended from ``nav.sidebar`` for the same reason: admin's
   * sidebar uses ``.nav-item`` with visible labels even on mobile. */
  nav.sidebar {
    width: 56px;
    padding: 12px 4px;
  }
  nav.sidebar .nav-item span:not(.nav-icon) {
    display: none;
  }
  section.content {
    padding: 12px 16px;
  }
  .detail-panel {
    width: 100vw;
  }

  /* ─────────────── graph 페이지 ───────────────
   * Originally inline at 720px; aligned to 768px here. Graph's
   * left side panel is a bare ``aside`` (no class); scoped via
   * ``.main > aside`` so it doesn't clobber chat's ``aside.sidebar``
   * (which has its own full-screen drawer rules above) or workspace's
   * own layout. The neighbor / search-drawer rules use
   * graph-only class names, so no extra scoping is needed.
   *
   * The 480px-specific graph refinements (hide .tsd-type column,
   * hide .np-rel column) live in the ≤ 480px block below. */
  .main > aside {
    display: none;
  }
  .neighbor-panel {
    right: 8px;
    left: 8px;
    top: 56px;
    width: auto;
    max-height: calc(70% - 56px);
    font-size: 12px;
  }
  .neighbor-panel .np-close {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
  }
  .neighbor-panel .np-item {
    padding: 10px 8px;
    font-size: 13px;
  }
  .top-search-drawer {
    width: calc(100% - 16px);
  }
  .top-search-drawer.tsd-open {
    max-height: min(70vh, 540px);
  }
  .top-search-drawer .tsd-list {
    max-height: 60vh;
  }
  .top-search-drawer .tsd-row {
    padding: 12px 10px;
  }
  /* The bottom-left hint overlay is too crowded on phones. */
  .overlay.bl {
    display: none;
  }
}

/* ─────────────────────────────────────────────────────────
 * Phone (≤ 480px) — 더 좁은 폰
 * ────────────────────────────────────────────────────────*/
@media (max-width: 480px) {
  /* 헤더 한 줄에 다 못 넣으면 숨김 우선순위:
   * 우선 PROD/TEST 토글은 ⋮ 메뉴로 보내야 깔끔하지만 v0.2 범위 외 — 일단 작게만. */
  .source-toggle button { padding: 4px 6px; font-size: 9px; }

  /* 카드 단일 컬럼 */
  .cards { grid-template-columns: 1fr !important; }

  /* 웰컴 — 폰 화면 작아서 아주 컴팩트하게 */
  .welcome-title { font-size: 18px; }
  .welcome-sub { font-size: 12px; }

  .bubble { font-size: 14px; padding: 9px 12px; }

  /* 어드민 nav-item 더 작게 */
  .nav-item { padding: 6px 10px; font-size: 12px; min-height: 36px; }

  /* 어드민 페이지 본문 */
  .page-title { font-size: 15px; }
  .section-title { font-size: 12px; }

  /* ─────────────── graph 페이지 — 폰 ───────────────
   * On the narrowest devices, free up horizontal space by hiding
   * the type column in the search drawer and the relation column
   * in the neighbor panel. Class names are graph-only so no
   * additional scoping is needed. */
  .top-search-drawer .tsd-row .tsd-type {
    display: none;
  }
  .neighbor-panel .np-rel {
    display: none;
  }
}

/* ─────────────────────────────────────────────────────────
 * 가로 모드 (landscape) 폰 — 헤더가 너무 두꺼워지면 안됨
 * ────────────────────────────────────────────────────────*/
@media (max-width: 920px) and (max-height: 480px) {
  header { padding: 4px 10px; }
  .messages { padding: 8px 12px; }
  .welcome { padding: 12px; }
  .welcome-title { font-size: 18px; margin-bottom: 4px; }
}

/* ─────────────────────────────────────────────────────────
 * 다크 모드 명시 + 시스템 모드 존중
 * (자메스 기본은 dark — 여기선 모바일 전용 미세 조정만)
 * ────────────────────────────────────────────────────────*/
@media (max-width: 768px) and (prefers-color-scheme: dark) {
  /* 폰 OLED 화면에서 가독성 */
  .bubble { line-height: 1.6; }
}

/* ─────────────────────────────────────────────────────────
 * 접근성 — 모바일 사용자 다수가 큰 글자 선호
 * 시스템 폰트 크기 설정 존중 (rem이 아닌 곳도 대응)
 * ────────────────────────────────────────────────────────*/
@media (max-width: 768px) {
  /* 줄바꿈 안 되어 잘리는 텍스트 방지 */
  td, th, .card-value, .badge-status {
    word-break: break-word;
    overflow-wrap: break-word;
  }
  /* 코드 블록 — 가로 스크롤 */
  pre, code {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
}
