/* style.css — Dashboard layout/components CSS.
 * Theme color tokens (4 themes + font sizes) live in /static/theme.css (AUTO-GENERATED from
 * jiminbot-hub/lib/design-tokens.json). DO NOT redefine --bg-base / --text-primary / etc. here.
 *
 * Only dashboard-specific layout tokens (radii, button sizes, mono stack, --text-dim) remain.
 */
:root {
  /* Radius */
  --r-sm:  4px;
  --r-md:  6px;
  --r-lg:  8px;
  /* Spacing */
  --section-pad: 10px 14px;
  /* Button base */
  --btn-h: 28px;
  --btn-px: 10px;
  --btn-font: 11px;
  /* Monospace stack */
  --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Code", "Fira Code", monospace;
  /* Dashboard-specific extras not in shared design-tokens */
  --text-dim:      var(--text-muted, #64748b);
  /* Accent purple — not in shared tokens */
  --accent-purple: #818cf8;
  /* Wednesday cell highlight in activity heatmap */
  --hm-wed-border: #f1f5f9;
}

/* ── Component classes — inline style 대체 ───────────────────────────── */

/* KPI stat cards */
.kpi-card {
  background: var(--bg-primary);
  border: 1px solid var(--bg-secondary);
  border-radius: var(--r-md);
  padding: 10px;
  text-align: center;
}
.kpi-card .kpi-value {
  font-size: 20px;
  font-weight: 700;
}
.kpi-card .kpi-value-sm {
  font-size: 14px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kpi-card .kpi-value-md {
  font-size: 18px;
  font-weight: 700;
}
.kpi-value-green  { color: var(--accent-green); }
.kpi-value-blue   { color: var(--accent-blue); }
.kpi-value-purple { color: var(--accent-purple); }
.kpi-value-orange { color: var(--accent-amber); }
.kpi-value-teal   { color: #34d399; }
.kpi-card .kpi-label {
  font-size: 10px;
  color: var(--text-dim);
  margin-top: 2px;
}

/* Console mini — inline pre replacement */
.console-mini {
  background: var(--bg-primary);
  border: 1px solid var(--bg-secondary);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  font-size: 10px;
  color: var(--text-secondary);
  max-height: 80px;
  overflow: hidden;
  margin: 0;
  white-space: pre-wrap;
  word-break: break-all;
}

/* Dashboard health collapsible */
.health-summary-el {
  cursor: pointer;
  padding: 8px 14px;
  background: var(--bg-primary);
  border: 1px solid var(--bg-secondary);
  border-radius: var(--r-lg);
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  user-select: none;
}
.health-body-el {
  padding: 10px 14px;
  background: var(--bg-primary);
  border: 1px solid var(--bg-secondary);
  border-top: none;
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.health-pill {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--bg-secondary);
  color: var(--text-secondary);
}

/* Next-step button variant */
.btn-next-step {
  background: color-mix(in srgb, var(--accent-blue) 18%, transparent);
  border-color: var(--accent-blue);
  color: var(--accent-blue);
}

/* Next-choice banner */
.nc-banner {
  display: none;
  background: var(--bg-primary);
  border-bottom: 2px solid var(--accent-blue);
  padding: 10px 14px;
}
.nc-banner-link {
  background: var(--accent-blue);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  padding: 6px 14px;
  border-radius: 8px;
  text-decoration: none;
  flex-shrink: 0;
}

/* iframe embed frame */
.iframe-frame {
  width: 100%;
  height: 520px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-primary);
}

/* Todo status badge */
.todo-status-badge {
  font-size: 10px;
  padding: 2px 8px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent-purple) 12%, transparent);
  color: var(--accent-purple);
  font-weight: 600;
}

/* Todo progress mini bar */
.todo-pct-label { font-size: 11px; color: var(--text-dim); }
.todo-pct-track {
  height: 4px;
  width: 80px;
  background: var(--bg-secondary);
  border-radius: 2px;
  margin-top: 3px;
}

/* Completion stats alltime row */
.stats-alltime { font-size: 10px; color: var(--text-muted); margin-top: 4px; }

/* Promote bulk button */
.btn-promote {
  font-size: 9px;
  padding: 0.3em 6px;
  background: color-mix(in srgb, var(--accent-blue) 18%, transparent);
  border: 1px solid var(--accent-blue);
  color: var(--accent-blue);
  cursor: pointer;
  border-radius: var(--r-sm);
  white-space: nowrap;
  opacity: 0.4;
}
.btn-promote:not([disabled]) { opacity: 1; }

/* Quick Actions custom button */
.btn-custom {
  background: var(--bg-primary);
  border-color: var(--border);
  color: var(--text-dim);
}

/* Quota update toggle */
.quota-update-toggle-styled {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 2px 8px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--accent-blue) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-blue) 30%, transparent);
  margin-left: 6px;
}

/* Quota manual form header note */
.quota-form-note { font-size: 12px; color: var(--text-secondary); font-weight: 600; margin-bottom: 8px; }

/* Codex head */
.codex-head-val { font-size: 12px; color: var(--accent-purple); }

/* WS status panel */
.ws-status-note { font-size: 11px; }

/* Chat panel hint */
.chat-hint { font-size: 12px; display: flex; align-items: center; gap: 8px; }
.chat-hint-icon { font-size: 14px; }
.chat-hint-accent { color: var(--accent-purple); }

/* todo-due-input panel-input variant */
.input-time-sm {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  font-size: 11px;
  padding: 2px 6px;
  width: 90px;
}

  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  html, body { max-width: 100vw; overflow-x: hidden; }
  body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans KR", sans-serif;
         background: var(--bg-base); color: var(--text-primary); font-size: 14px;
         padding: 12px;
         padding-top: max(12px, env(safe-area-inset-top));
         padding-right: max(12px, env(safe-area-inset-right));
         padding-bottom: max(12px, env(safe-area-inset-bottom));
         padding-left: max(12px, env(safe-area-inset-left));
         line-height: 1.5; }
  .header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;
            gap: 8px; margin-bottom: 12px; }
  .header-left { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .header h1 { font-size: 17px; font-weight: 600; color: var(--text-primary); }
  .header-right { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
  .status-chip { font-size: 12px; padding: 3px 10px; border-radius: 12px; font-weight: 600; }
  .state-active   { background: #065f46; color: #a7f3d0; }
  .state-cooling  { background: #854d0e; color: #fef08a; }
  .state-idle     { background: #334155; color: #cbd5e1; }
  .state-dormant  { background: #1e293b; color: #64748b; }
  #clock { color: var(--text-secondary); font-size: 12px; }
  #conn-badge { font-size: 11px; padding: 2px 8px; border-radius: 4px;
                background: var(--accent-red); color: white; display: none; }

  /* Dashboard top bar: keep settings identical to main and prevent right-side compression. */
  .app-top-nav__left { flex: 0 1 260px; }
  .app-top-nav__center { flex: 0 1 220px; }
  .app-top-nav__right {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-start;
    gap: 8px;
  }
  .app-top-nav__right > .btn,
  .app-top-nav__right > .status-chip,
  .app-top-nav__right > #conn-badge,
  .app-top-nav__right > #clock {
    height: 34px;
    min-height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    white-space: nowrap;
  }
  .app-top-nav__right > .btn {
    padding: 0 12px;
  }
  .app-top-nav__right > #clock {
    min-width: 82px;
  }
  .app-top-nav__settings {
    width: 44px !important;
    min-width: 44px;
    max-width: 44px;
    height: 44px !important;
    min-height: 44px;
    max-height: 44px;
    padding: 0;
    border-radius: 50%;
    flex: 0 0 44px;
    margin-left: auto;
  }

  /* ── Settings panel — matches main.jiminbot20.uk behavior ─────────────── */
  #theme-settings-panel {
    position: fixed;
    top: 0;
    right: 0;
    width: 300px;
    max-width: 100vw;
    height: 100vh;
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    padding: 24px 20px;
    z-index: 300;
    overflow-y: auto;
    box-shadow: var(--shadow);
    transform: translateX(0);
    transition: transform 0.28s ease, background 0.2s;
  }
  #theme-settings-panel.hidden { transform: translateX(100%); pointer-events: none; }
  #theme-settings-panel h3 {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 20px;
    color: var(--text-primary);
  }
  #theme-settings-panel fieldset {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 16px;
  }
  #theme-settings-panel legend {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0 4px;
  }
  #theme-settings-panel label {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    cursor: pointer;
    font-size: 0.875em;
    color: var(--text-primary);
    border-bottom: 1px solid var(--bg-secondary);
  }
  #theme-settings-panel label:last-child { border-bottom: none; }
  #theme-settings-panel label:hover { color: var(--accent-blue); }
  #theme-settings-panel input[type="radio"] {
    accent-color: var(--accent-blue);
    width: 16px;
    height: 16px;
    flex-shrink: 0;
  }
  #theme-settings-close {
    width: 100%;
    padding: 10px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-size: 0.875em;
    cursor: pointer;
    transition: background 0.15s;
  }
  #theme-settings-close:hover { background: var(--border); }
  #theme-settings-close:focus-visible,
  #theme-settings-btn:focus-visible {
    outline: 2px solid var(--accent-blue);
    outline-offset: 2px;
  }
  @media (max-width: 600px) {
    #theme-settings-panel { width: 100vw; border-left: none; }
  }

  .section { background: var(--bg-surface); border-radius: var(--r-lg); padding: var(--section-pad);
             margin-bottom: 10px; border: 1px solid transparent; }
  .section-title { font-size: 11px; font-weight: 700; color: var(--text-secondary); text-transform: uppercase;
                   letter-spacing: 0.05em; margin-bottom: 8px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }

  /* ── Section variant: bare <section> panels (no class="section") get same look ── */
  section.panel {
    background: var(--bg-surface); border-radius: var(--r-lg); padding: var(--section-pad);
    margin-bottom: 10px; border: 1px solid transparent;
  }
  section.panel h2.panel-title {
    font-size: 11px; font-weight: 700; color: var(--text-secondary); text-transform: uppercase;
    letter-spacing: 0.05em; margin-bottom: 8px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    font-family: inherit;
  }

  /* ── Universal padding reset — all interactive elements ───────────────── */
  /* Vertical padding = 0.5em (half of element font-size). min-height removed. */
  button, input[type="button"], input[type="submit"], input[type="reset"],
  input[type="text"], input[type="search"], input[type="number"], input[type="time"],
  select, .btn, .console-btn, .atu-tab, .loss-btn, .todo-btn,
  .todo-add-btn, .todo-prio-select, .quota-form-submit, .tab-btn, .panel-select {
    padding-top: 0.5em;
    padding-bottom: 0.5em;
    line-height: 1;
    min-height: 0;
  }

  /* ── Button base — all small dashboard buttons ───────────────────────── */
  .btn {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 0.5em var(--btn-px);
    font-size: var(--btn-font); font-family: inherit; font-weight: 500;
    border-radius: var(--r-sm); border: 1px solid var(--border-ui);
    background: var(--bg-surface); color: var(--text-secondary);
    cursor: pointer; white-space: nowrap; text-decoration: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    line-height: 1;
  }
  .btn:hover { background: var(--border); color: var(--text-primary); }
  .btn.btn-primary { background: var(--accent-blue); border-color: var(--accent-blue); color: #fff; }
  .btn.btn-primary:hover { background: var(--accent-blue); }
  .btn.btn-accent  { background: var(--accent-blue); border-color: var(--accent-blue); color: #fff; }
  .btn.btn-accent:hover { background: var(--accent-blue); }
  .btn.btn-active  { background: var(--bg-card); border-color: var(--accent-green); color: var(--accent-green); }
  .btn.btn-indigo  { background: var(--accent-purple); border-color: var(--accent-purple); color: #fff; }
  .btn.btn-indigo:hover { background: var(--accent-purple); }

  /* ── Code / pre box — unified dark surface ───────────────────────────── */
  .code-box {
    background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--r-sm);
    padding: 8px 10px; font-family: var(--font-mono); font-size: 11px;
    line-height: 1.5; color: var(--text-secondary);
    overflow: auto; white-space: pre-wrap; word-break: break-word;
  }

  /* Token bar — 맨 위 prominent */
  .token-section {
    background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-secondary) 60%, var(--bg-secondary) 100%);
    border: 1px solid var(--border);
  }
  .token-section .section-title { font-size: 12px; color: var(--text-primary); }
  .token-bar-wrap { background: var(--bg-primary); border-radius: 6px; height: 22px; overflow: hidden;
                    position: relative; border: 1px solid var(--border); }
  .token-bar-fill { height: 100%; border-radius: 5px; transition: width 0.4s; }
  /* Threshold markers — 30만 (warn) / 40만 (critical) */
  .token-mark { position: absolute; top: -1px; bottom: -1px; width: 1px; pointer-events: none; }
  .token-mark-warn     { background: repeating-linear-gradient(to bottom, var(--accent-amber) 0 3px, transparent 3px 6px); }
  .token-mark-critical { background: repeating-linear-gradient(to bottom, var(--accent-red) 0 3px, transparent 3px 6px); }
  .token-mark-label { position: absolute; top: 50%; transform: translate(2px, -50%);
                      font-size: 9px; font-weight: 700; white-space: nowrap;
                      text-shadow: 0 0 3px var(--bg-primary); }
  .token-label { font-size: 12px; color: var(--text-secondary); margin-top: 6px; }
  .token-numbers { display: flex; justify-content: space-between; gap: 12px;
                   font-size: 11px; color: var(--text-dim); margin-top: 3px; flex-wrap: wrap; }
  .token-numbers b { color: var(--text-primary); font-weight: 700; }
  .token-numbers .warn-text    { color: var(--accent-amber); }
  .token-numbers .crit-text    { color: var(--accent-red); }

  /* Quota bars — 기본 행 (소형 카드용) */
  .quota-row { display: grid; grid-template-columns: 200px 60px 1fr 180px; gap: 10px;
               align-items: center; padding: 5px 0; border-bottom: 1px solid var(--bg-primary); }
  .quota-row:last-child { border: none; }
  .quota-row.claude-row .quota-label { color: var(--accent-blue); }
  .quota-row.codex-row  .quota-label { color: var(--accent-purple); }
  .quota-label { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden;
                 text-overflow: ellipsis; }
  .quota-pct { font-size: 13px; font-weight: 700; text-align: right; }
  .quota-bar-wrap { background: var(--bg-primary); border-radius: 4px; height: 10px; overflow: hidden; }
  .quota-bar-fill { height: 100%; border-radius: 4px; transition: width 0.4s; }
  .quota-reset { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden;
                 text-overflow: ellipsis; }
  @media (max-width: 720px) {
    .quota-row { grid-template-columns: 1fr 1fr; grid-auto-flow: dense; gap: 4px 10px; }
    .quota-row .quota-label { grid-column: 1; }
    .quota-row .quota-pct { grid-column: 2; }
    .quota-row .quota-bar-wrap { grid-column: 1 / span 2; }
    .quota-row .quota-reset { grid-column: 1 / span 2; }
  }

  /* 주간 all-models — 1차 지표, 큰 글씨 hero card */
  .quota-hero { background: var(--bg-primary); border-radius: 8px; padding: 12px 16px;
                border: 1px solid var(--border); margin-bottom: 10px; }
  .quota-hero-label { font-size: 11px; font-weight: 700; color: var(--accent-blue); text-transform: uppercase;
                      letter-spacing: 0.05em; margin-bottom: 4px; }
  .quota-hero-pct { font-size: 36px; font-weight: 800; line-height: 1.1; }
  .quota-hero-bar-wrap { background: var(--bg-secondary); border-radius: 6px; height: 14px; overflow: hidden;
                         margin: 8px 0 4px; }
  .quota-hero-bar-fill { height: 100%; border-radius: 6px; transition: width 0.5s; }
  .quota-hero-meta { font-size: 11px; color: var(--text-dim); }
  .quota-hero-stale { font-size: 11px; margin-top: 6px; }

  /* 소형 4-col 카드 그리드 */
  .quota-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 4px; }
  @media (max-width: 900px) { .quota-cards { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 480px) { .quota-cards { grid-template-columns: 1fr 1fr; } }
  .quota-card { background: var(--bg-primary); border-radius: 6px; padding: 8px 10px;
                border: 1px solid var(--border); }
  .quota-card-label { font-size: 10px; font-weight: 600; color: var(--text-secondary); margin-bottom: 3px;
                      white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .quota-card-pct { font-size: 20px; font-weight: 800; line-height: 1; }
  .quota-card-bar-wrap { background: var(--bg-secondary); border-radius: 3px; height: 6px; overflow: hidden; margin: 4px 0 3px; }
  .quota-card-bar-fill { height: 100%; border-radius: 3px; transition: width 0.4s; }
  .quota-card-reset { font-size: 10px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .quota-card-stale { font-size: 10px; margin-top: 3px; }

  /* Quota manual update form */
  .quota-update-toggle { font-size: 11px; color: var(--text-dim); cursor: pointer;
                         margin-left: 8px; user-select: none; }
  .quota-update-toggle:hover { color: var(--text-secondary); }
  .quota-update-form { display: none; background: var(--bg-secondary); border-radius: 6px;
                       padding: 10px 12px; margin-top: 8px; border: 2px solid var(--accent-blue); }
  .quota-update-form.open { display: block; }
  .quota-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; margin-bottom: 8px; }
  .quota-form-field { display: flex; flex-direction: column; gap: 2px; }
  .quota-form-field label { font-size: 10px; color: var(--text-dim); }
  .quota-form-field input { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 4px;
                             color: var(--text-primary); font-size: 12px; padding: 3px 6px; width: 100%; }
  .quota-form-field input:focus { outline: none; border-color: var(--accent-blue); }
  .quota-form-token { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
  .quota-form-token label { font-size: 10px; color: var(--text-dim); }
  .quota-form-token input { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 4px;
                             color: var(--text-secondary); font-size: 11px; padding: 3px 6px; width: 100%; }
  .quota-form-token input:focus { outline: none; border-color: var(--accent-blue); }
  .quota-form-actions { display: flex; gap: 8px; align-items: center; }
  .quota-form-submit { background: var(--accent-blue); color: white; border: none; border-radius: 4px;
                       padding: 0.5em 12px; font-size: 12px; cursor: pointer; }
  .quota-form-submit:hover { background: var(--accent-blue); }
  .quota-form-msg { font-size: 11px; color: var(--text-dim); }
  @media (max-width: 720px) { .quota-form-grid { grid-template-columns: 1fr; } }

  /* Grid shared */
  .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
  @media (max-width: 720px) { .row2 { grid-template-columns: 1fr; } }

  /* Agents — 5 columns × 2 rows (10 agent 정확히 5×2) */
  .agents-grid { display: grid; grid-template-columns: repeat(5, 1fr); grid-auto-rows: auto; gap: 4px; }
  .agent-card { background: var(--bg-primary); border-radius: 5px; padding: 4px 4px; text-align: center;
                border: 1px solid var(--border); position: relative; overflow: hidden;
                transition: border-color 0.3s, box-shadow 0.3s; }
  .agent-card.codex    { border-color: #a855f7; }
  .agent-card.redteam  { border-color: #ef4444; }

  /* ACTIVE agent card — 테두리·배경·박스-shadow 를 모두 애니메이션 */
  .agent-card.active {
    border-color: var(--accent-green);
    background: linear-gradient(135deg, var(--bg-primary) 0%, #0f2a1a 100%);
    box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.6), 0 0 16px rgba(34, 197, 94, 0.35);
    animation: card-glow 1.6s ease-in-out infinite;
  }
  .agent-card.active.codex {
    border-color: var(--accent-purple);
    background: linear-gradient(135deg, var(--bg-primary) 0%, #2a0f2a 100%);
    box-shadow: 0 0 0 1px rgba(216, 180, 254, 0.6), 0 0 16px rgba(216, 180, 254, 0.35);
  }
  @keyframes card-glow {
    0%, 100% { box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.6), 0 0 12px rgba(34, 197, 94, 0.3); }
    50%      { box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.9), 0 0 26px rgba(34, 197, 94, 0.6); }
  }

  /* 진행 bar — 카드 하단에 흐르는 애니메이션 */
  .agent-card.active::after {
    content: "";
    position: absolute; left: 0; right: 0; bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--accent-green), transparent);
    background-size: 200% 100%;
    animation: card-sweep 1.4s linear infinite;
  }
  .agent-card.active.codex::after {
    background: linear-gradient(90deg, transparent, var(--accent-purple), transparent);
    background-size: 200% 100%;
  }
  @keyframes card-sweep {
    0%   { background-position: 100% 0; }
    100% { background-position: -100% 0; }
  }

  .agent-name { font-weight: 700; font-size: 14px; color: var(--text-primary); }
  .agent-name.codex    { color: var(--accent-purple); }
  .agent-name.redteam  { color: #fca5a5; }
  .agent-role { font-size: 11px; color: var(--text-dim); margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .agent-model { font-size: 11px; color: var(--text-dim); margin-bottom: 2px; }

  /* 상태 표시자 — active 일 땐 JS 가 매 80ms 프레임 셔플 (스피너 문자 교체) + CSS 펄스 */
  .status-dot { font-size: 18px; line-height: 1; display: inline-block; }
  .status-dot.spinner { font-family: ui-monospace, monospace; color: #22c55e;
                        animation: spinner-pulse 0.9s ease-in-out infinite; }
  .status-dot.spinner.codex    { color: #d8b4fe; }
  .status-dot.spinner.redteam  { color: #ef4444; }
  .status-dot.pulse { animation: pulse 1.3s infinite; }
  @keyframes pulse {
    0%,100% { opacity: 1; transform: scale(1); }
    50%     { opacity: 0.45; transform: scale(1.3); }
  }
  @keyframes spinner-pulse {
    0%,100% { opacity: 1; text-shadow: 0 0 8px currentColor; }
    50%     { opacity: 0.7; text-shadow: 0 0 14px currentColor; }
  }

  .agent-last { font-size: 9px; color: var(--text-muted); margin-top: 2px; }
  .agent-last.active { color: var(--accent-green); font-weight: 600; }
  .agent-cur { font-size: 9px; color: var(--accent-amber); margin-top: 1px; white-space: nowrap;
               overflow: hidden; text-overflow: ellipsis; }
  @media (min-width: 721px) and (max-width: 1024px) { .agents-grid { grid-template-columns: repeat(5, 1fr); } }
  @media (max-width: 720px) { .agents-grid { grid-template-columns: repeat(5, 1fr); gap: 3px; } }
  @media (max-width: 480px) { .agents-grid { grid-template-columns: repeat(4, 1fr); gap: 3px; }
                               .agent-name { font-size: 10px; } .status-dot { font-size: 16px; } }

  /* Codex */
  .codex-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 6px; }
  .codex-stat  { background: var(--bg-primary); border-radius: 4px; padding: 6px; text-align: center; }
  .codex-stat-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; }
  .codex-stat-value { font-size: 16px; font-weight: 700; color: var(--accent-purple); }
  .codex-note { font-size: 10px; color: var(--text-dim); font-style: italic; margin-top: 6px; }

  /* Skills */
  .skill-row { display: flex; gap: 8px; padding: 5px 0; font-size: 12px;
               border-bottom: 1px solid var(--bg-primary); }
  .skill-row:last-child { border: none; }
  .skill-label { font-weight: 700; flex: 0 0 200px; white-space: nowrap; overflow: hidden;
                 text-overflow: ellipsis; }
  .skill-label.agent { color: var(--accent-green); }
  .skill-label.skill { color: var(--accent-blue); }
  .skill-label.sendmessage { color: var(--accent-amber); }
  .skill-detail { flex: 0 0 160px; color: var(--text-dim); white-space: nowrap; overflow: hidden;
                  text-overflow: ellipsis; font-size: 11px; }
  .skill-session { flex: 0 0 68px; color: var(--text-muted); font-family: ui-monospace, SFMono-Regular, monospace;
                   font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .skill-files { flex: 1; color: var(--accent-blue); font-family: ui-monospace, SFMono-Regular, monospace;
                 font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* Graph */
  .graph-row { display: flex; gap: 8px; padding: 4px 0; font-size: 12px;
               border-bottom: 1px solid var(--bg-primary); align-items: center; }
  .graph-row:last-child { border: none; }
  .edge { font-family: ui-monospace, monospace; min-width: 180px; }
  .edge-src { color: var(--text-primary); font-weight: 600; }
  .edge-arrow { color: #22d3ee; padding: 0 6px; }
  .edge-dst { color: var(--accent-green); font-weight: 700; }
  .edge-count { color: #22d3ee; font-weight: 700; min-width: 28px; text-align: right; }
  .edge-last { color: var(--text-muted); min-width: 48px; font-size: 11px; }
  .edge-session { color: var(--border); font-size: 10px; font-family: ui-monospace, monospace;
                  min-width: 64px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .edge-label { color: var(--text-dim); font-size: 11px; flex: 1;
                white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* TODO */
  .todo-row { display: flex; gap: 8px; padding: 6px 0; font-size: 13px;
              border-bottom: 1px solid var(--bg-primary); align-items: flex-start; }
  .todo-row:last-child { border: none; }
  .todo-pri { font-weight: 700; flex: 0 0 28px; text-align: center; padding-top: 2px; }
  .todo-pri.p1 { color: var(--accent-red); }
  .todo-pri.p2 { color: var(--accent-amber); }
  .todo-pri.p3 { color: var(--accent-green); }
  .todo-pri.p4, .todo-pri.p5 { color: var(--text-dim); }
  .todo-icon { flex: 0 0 24px; font-size: 16px; text-align: center; padding-top: 1px; }
  .todo-body { flex: 1; }
  .todo-title { color: var(--text-primary); font-weight: 500; }
  .todo-reason { color: var(--text-dim); font-size: 11px; margin-top: 2px; }

  /* Tasks / Changes / Notifications */
  .row { display: flex; align-items: center; gap: 8px; padding: 5px 0;
         border-bottom: 1px solid var(--bg-primary); font-size: 12px; }
  .row:last-child { border: none; }
  .monospace { font-family: ui-monospace, SFMono-Regular, monospace; }
  .dim { color: var(--text-muted); }
  .green { color: var(--accent-green); }
  .yellow { color: var(--accent-amber); }
  .red { color: var(--accent-red); }
  .magenta { color: var(--accent-purple); }

  /* ---------- Research Status Banner ---------- */
  .research-banner {
    background: var(--bg-secondary); border-radius: 6px; padding: 7px 12px;
    margin-bottom: 10px; border-left: 3px solid var(--accent-green);
    font-size: 12px; line-height: 1.5;
  }
  .research-banner.blocked { border-left-color: var(--accent-red); }
  .research-banner-item { display: flex; gap: 8px; align-items: baseline; }
  .research-banner-section { font-weight: 700; color: var(--text-secondary); min-width: 80px; font-size: 11px; text-transform: uppercase; }
  .research-banner-text { color: var(--text-primary); }

  /* ---------- Disk Bar ---------- */
  .disk-bar-wrap { background: var(--bg-primary); border-radius: 5px; height: 16px; overflow: hidden;
                   border: 1px solid var(--border); position: relative; margin: 4px 0; }
  .disk-bar-fill { height: 100%; border-radius: 4px; transition: width 0.5s; }
  .disk-bar-fill.critical { animation: disk-pulse 1.2s ease-in-out infinite; }
  @keyframes disk-pulse {
    0%,100% { opacity: 1; } 50% { opacity: 0.6; }
  }
  .disk-text { font-size: 11px; color: var(--text-secondary); margin-top: 4px; font-family: ui-monospace, monospace; }
  .disk-warn  { color: var(--accent-red); font-weight: 700; margin-left: 8px; }

  /* ---------- GPU Cards ---------- */
  .gpu-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
  @media (max-width: 800px) { .gpu-grid { grid-template-columns: repeat(2, 1fr); } }
  .gpu-card { background: var(--bg-primary); border-radius: 6px; padding: 8px 10px;
              border: 1px solid var(--border); transition: border-color 0.3s, box-shadow 0.3s; }
  .gpu-card.active-gpu { border-color: var(--accent-green);
    box-shadow: 0 0 0 1px rgba(34,197,94,0.4), 0 0 12px rgba(34,197,94,0.2); }
  .gpu-name { font-size: 10px; color: var(--text-dim); margin-bottom: 4px; white-space: nowrap;
              overflow: hidden; text-overflow: ellipsis; }
  .gpu-idx  { font-weight: 700; color: var(--accent-blue); margin-right: 4px; }
  .gpu-mini-bar { height: 6px; border-radius: 3px; background: var(--bg-primary);
                  border: 1px solid var(--border); overflow: hidden; margin: 3px 0; }
  .gpu-mini-fill { height: 100%; border-radius: 2px; transition: width 0.5s; }
  .gpu-stat { font-size: 10px; color: var(--text-dim); display: flex; justify-content: space-between; }
  .gpu-stat b { color: var(--text-primary); }
  .gpu-temp { font-size: 11px; font-weight: 700; }
  .gpu-empty { color: var(--text-muted); font-size: 12px; padding: 8px 0; }

  /* ---------- Training Run Table ---------- */
  .training-scroll { max-height: 260px; overflow-y: auto; }
  .training-table { width: 100%; border-collapse: collapse; font-size: 12px; }
  .training-table th { color: var(--text-dim); font-weight: 600; text-align: left;
                       padding: 3px 6px; border-bottom: 1px solid var(--border); font-size: 11px; }
  .training-table td { padding: 4px 6px; border-bottom: 1px solid var(--bg-primary); }
  .training-table tr:last-child td { border: none; }
  .training-run-name { color: var(--accent-green); font-family: ui-monospace, monospace; }
  .training-pid  { color: var(--text-muted); font-family: ui-monospace, monospace; font-size: 10px; }
  .training-epoch { color: var(--accent-blue); font-weight: 700; }
  .training-eta   { color: var(--accent-amber); }
  .training-age   { color: var(--text-dim); }

  /* ---------- Agent Token Usage ---------- */
  .atu-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; flex-wrap: wrap; gap: 4px; }
  .atu-tabs { display: flex; gap: 4px; }
  .atu-tab { font-size: var(--btn-font); padding: 0.5em 8px;
             border-radius: var(--r-sm); cursor: pointer;
             background: var(--bg-surface); color: var(--text-secondary);
             border: 1px solid var(--border-ui); font-family: inherit;
             display: inline-flex; align-items: center; }
  .atu-tab:hover { background: var(--border); color: var(--text-primary); }
  .atu-tab.active { background: var(--bg-card); color: var(--accent-blue); border-color: var(--accent-blue); }
  .atu-chart-wrap { position: relative; height: 180px; }
  .atu-summary { display: flex; gap: 16px; font-size: 11px; color: var(--text-dim); margin-top: 6px; flex-wrap: wrap; }
  .atu-summary b { color: var(--text-primary); }
  .atu-empty { color: var(--text-muted); font-size: 12px; padding: 12px 0; text-align: center; }

  /* ---------- Session Summaries ---------- */
  .sess-list { max-height: 280px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
  .sess-card { background: var(--bg-primary); border-radius: 6px; padding: 8px 10px;
               border-left: 3px solid var(--border); position: relative; cursor: pointer; }
  .sess-card:hover { border-left-color: var(--accent-blue); }
  .sess-meta { display: flex; justify-content: space-between; align-items: center;
               margin-bottom: 4px; }
  .sess-id { font-family: ui-monospace, monospace; font-size: 11px; color: var(--accent-blue);
             font-weight: 700; }
  .sess-time { font-size: 10px; color: var(--text-muted); }
  .sess-lines { font-size: 10px; color: var(--border); margin-left: 6px; }
  .sess-preview { font-size: 12px; color: var(--text-secondary); line-height: 1.45;
                  white-space: pre-wrap; word-break: break-word; max-height: 72px;
                  overflow: hidden; }
  .sess-empty { color: var(--text-muted); font-size: 12px; padding: 8px 0; }

  /* ---------- Console Tail (Phase 4) ---------- */
  .console-header { display: flex; justify-content: space-between; align-items: center;
                    margin-bottom: 6px; }
  .console-btn { font-size: var(--btn-font); padding: 0.5em var(--btn-px);
                 border-radius: var(--r-sm); cursor: pointer;
                 background: var(--bg-surface); color: var(--text-secondary);
                 border: 1px solid var(--border-ui); font-family: inherit;
                 display: inline-flex; align-items: center; white-space: nowrap; }
  .console-btn:hover { background: var(--border); color: var(--text-primary); }
  .console-btn.active { background: var(--bg-card); color: var(--accent-green); border-color: var(--accent-green); }
  .console-pre { background: var(--bg-raised); border-radius: var(--r-sm); padding: 8px 10px;
                 font-family: var(--font-mono);
                 font-size: 11px; line-height: 1.5; color: var(--text-secondary);
                 max-height: 340px; overflow-y: auto; white-space: pre-wrap;
                 word-break: break-word; border: 1px solid var(--border); }
  .console-pre .cl-epoch  { color: #86efac; }
  .console-pre .cl-loss   { color: #7dd3fc; }
  .console-pre .cl-warn   { color: #fde047; }
  .console-pre .cl-err    { color: #f87171; }
  .console-empty { color: var(--text-muted); font-size: 12px; padding: 8px 0; }
  .console-source { font-size: 10px; color: var(--border); margin-top: 4px; font-family: ui-monospace, monospace; }

  /* ---------- Checkpoint Table ---------- */
  .ckpt-table { width: 100%; border-collapse: collapse; font-size: 12px; }
  .ckpt-table th { color: var(--text-dim); font-weight: 600; text-align: left;
                   padding: 3px 6px; border-bottom: 1px solid var(--border); font-size: 11px; }
  .ckpt-table td { padding: 4px 6px; border-bottom: 1px solid var(--bg-primary); }
  .ckpt-table tr:last-child td { border: none; }
  .ckpt-name  { color: var(--text-primary); font-family: ui-monospace, monospace; font-size: 11px;
                max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ckpt-size  { color: var(--accent-blue); font-weight: 700; }
  .ckpt-savings { color: var(--accent-amber); }

  /* ---------- Eval Results Table ---------- */
  .eval-table { width: 100%; border-collapse: collapse; font-size: 12px; }
  .eval-table th { color: var(--text-dim); font-weight: 600; text-align: left;
                   padding: 3px 6px; border-bottom: 1px solid var(--border); font-size: 11px; }
  .eval-table td { padding: 4px 6px; border-bottom: 1px solid var(--bg-primary); }
  .eval-table tr:last-child td { border: none; }
  .eval-run   { color: var(--accent-green); font-family: ui-monospace, monospace; font-size: 11px; }
  .eval-val   { color: var(--accent-green); font-weight: 700; }
  .eval-qed   { color: var(--accent-blue); }

  /* ---------- Codex Collapsible ---------- */
  .codex-toggle { cursor: pointer; font-size: 11px; color: var(--text-dim); user-select: none;
                  padding: 1px 6px; border: 1px solid var(--border); border-radius: 3px; margin-left: 8px; }
  .codex-toggle:hover { color: var(--text-primary); border-color: var(--text-muted); }
  #codex-detail { display: none; margin-top: 8px; }
  #codex-detail.open { display: block; }

  /* ---------- VS Bar (multi-user weekly usage comparison) ---------- */
  .vs-section {
    background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 50%, var(--bg-primary) 100%);
    border: 1px solid var(--border); position: relative; overflow: hidden;
  }
  .vs-section::before {
    content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
    background: radial-gradient(circle at 50% 50%, rgba(251, 191, 36, 0.04), transparent 60%);
    pointer-events: none;
  }
  .vs-wrap {
    display: grid; grid-template-columns: 1fr 52px 1fr; gap: 8px;
    align-items: center; padding: 6px 2px; position: relative;
  }
  .vs-player { min-width: 0; }
  .vs-player.right { text-align: right; }
  .vs-name {
    font-size: 14px; font-weight: 700; letter-spacing: 0.02em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .vs-sub { font-size: 10px; color: var(--text-dim); margin-top: 2px; font-family: ui-monospace, monospace; }
  .vs-center {
    font-size: 22px; font-weight: 900; letter-spacing: 0.04em;
    text-align: center; color: var(--accent-amber);
    text-shadow: 0 0 12px rgba(251, 191, 36, 0.6), 0 0 4px rgba(239, 68, 68, 0.4);
    font-family: Impact, "Arial Black", sans-serif;
    transform: skewX(-8deg);
  }

  /* HP bars — 격투게임 느낌. 좌측 유저는 우→좌로 fill (empty from right), 우측은 좌→우 */
  .vs-hpbar {
    height: 24px; border-radius: 4px; background: #020617; border: 2px solid var(--bg-secondary);
    position: relative; overflow: hidden; margin-top: 6px;
    box-shadow: inset 0 2px 4px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.05);
  }
  .vs-hpbar.left  .vs-hpfill { float: right; }
  .vs-hpbar.right .vs-hpfill { float: left;  }
  .vs-hpfill {
    height: 100%; border-radius: 2px;
    background-image: linear-gradient(180deg, rgba(255,255,255,0.25) 0%, transparent 50%, rgba(0,0,0,0.25) 100%);
    transition: width 0.8s cubic-bezier(0.22, 1, 0.36, 1);
    position: relative;
  }
  .vs-hpfill::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.15) 50%, transparent 100%);
    background-size: 200% 100%;
    animation: hp-shimmer 2.5s linear infinite;
  }
  @keyframes hp-shimmer {
    0%   { background-position: -100% 0; }
    100% { background-position: 200% 0; }
  }
  .vs-hpbar.overflow { animation: overflow-flash 0.7s ease-in-out infinite alternate; }
  @keyframes overflow-flash {
    from { box-shadow: inset 0 0 0 2px rgba(239, 68, 68, 0.4), inset 0 2px 4px rgba(0,0,0,0.6); }
    to   { box-shadow: inset 0 0 0 2px rgba(239, 68, 68, 1.0),   inset 0 2px 4px rgba(0,0,0,0.6),
                                                                  0 0 14px rgba(239, 68, 68, 0.6); }
  }
  /* 사용량이 더 많은 쪽 player 카드는 살짝 shake */
  .vs-player.winning { animation: player-shake 0.35s ease-in-out infinite alternate; }
  @keyframes player-shake {
    from { transform: translateX(0); }
    to   { transform: translateX(2px); }
  }
  .vs-player.right.winning { animation-name: player-shake-right; }
  @keyframes player-shake-right {
    from { transform: translateX(0); }
    to   { transform: translateX(-2px); }
  }

  .vs-hosts {
    display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px;
    font-size: 10px; color: var(--text-dim);
  }
  .vs-host-chip {
    background: var(--bg-secondary); padding: 2px 6px; border-radius: 3px;
    border: 1px solid var(--border); font-family: ui-monospace, monospace;
  }
  .vs-player.right .vs-hosts { justify-content: flex-end; }
  .vs-meta {
    display: flex; gap: 10px; font-size: 11px; color: var(--text-secondary);
    margin-top: 4px; font-family: ui-monospace, monospace;
  }
  .vs-player.right .vs-meta { justify-content: flex-end; }
  .vs-meta b { color: var(--text-primary); }
  .vs-toggle {
    font-size: 10px; color: var(--text-dim); cursor: pointer; user-select: none;
    margin-left: 6px; padding: 1px 6px; border: 1px solid var(--border); border-radius: 3px;
  }
  .vs-toggle:hover { color: var(--text-primary); border-color: var(--text-muted); }

  @media (max-width: 520px) {
    .vs-wrap { grid-template-columns: 1fr 36px 1fr; gap: 4px; }
    .vs-center { font-size: 16px; }
    .vs-name { font-size: 12px; }
    .vs-hpbar { height: 18px; }
  }

  /* ---------- Activity Heatmap (GitHub contribution grid) ---------- */
  .heatmap-section {}
  /* heatmap-scroll: no overflow by default — let grid fill width; scroll only if cells shrink below min */
  .heatmap-scroll { padding-bottom: 4px; }
  .heatmap-grid-wrap { display: block; width: 100%; }
  /* Month row: grid matching hm-columns */
  .hm-month-row {
    display: grid; grid-template-columns: repeat(53, minmax(0, 1fr));
    gap: 2px; margin-bottom: 4px; padding-left: 24px;
    font-size: 10px; color: var(--text-dim);
  }
  .hm-month-label { text-align: center; white-space: nowrap;
                    font-size: 10px; color: var(--text-secondary); overflow: hidden; }
  .hm-body { display: flex; gap: 2px; }
  .hm-daynames { display: flex; flex-direction: column; gap: 2px;
                 margin-right: 4px; font-size: 9px; color: var(--text-dim); flex-shrink: 0; }
  .hm-dayname { height: 14px; line-height: 14px;
                text-align: right; padding-right: 2px; font-size: 9px; }
  .hm-dayname:nth-child(odd) { visibility: hidden; } /* Sun,Tue,Thu,Sat */
  /* Columns: stretch to fill remaining width */
  .hm-columns { display: grid; grid-template-columns: repeat(53, minmax(0, 1fr));
                gap: 2px; flex: 1 1 auto; min-width: 0; }
  .hm-col { display: flex; flex-direction: column; gap: 2px; }
  .hm-cell {
    width: 100%; aspect-ratio: 1 / 1; min-width: 10px;
    border-radius: 3px; cursor: default;
    flex-shrink: 0; position: relative;
  }
  /* Mobile: revert to horizontal scroll if cells would be too tiny */
  @media (max-width: 720px) {
    .heatmap-scroll { overflow-x: auto; }
    .heatmap-grid-wrap { display: inline-block; min-width: 560px; }
    .hm-month-row { grid-template-columns: repeat(53, minmax(10px, 1fr)); }
    .hm-columns  { grid-template-columns: repeat(53, minmax(10px, 1fr)); }
    .hm-cell { min-width: 10px; }
  }
  .hm-cell.lv0 { background: #161b22; }
  .hm-cell.lv1 { background: #0e4429; }
  .hm-cell.lv2 { background: #006d32; }
  .hm-cell.lv3 { background: #26a641; }
  .hm-cell.lv4 { background: #39d353; }
  .hm-cell.future { background: #0f172a; cursor: default; }
  /* Wednesday highlight — border only, fill color preserved by lv* class */
  .hm-cell.wed { border: 1px solid var(--hm-wed-border); border-radius: 3px; }
  .hm-cell:hover::after {
    content: attr(data-tip);
    position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%);
    background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border);
    border-radius: 4px; padding: 3px 8px; font-size: 11px; white-space: nowrap;
    z-index: 10; pointer-events: none;
  }
  .hm-legend { display: flex; align-items: center; gap: 5px; margin-top: 8px;
               font-size: 11px; color: var(--text-dim); }
  .hm-legend-cell { width: 12px; height: 12px; border-radius: 3px; }
  .hm-summary { font-size: 11px; color: var(--text-dim); margin-top: 6px; font-family: ui-monospace, monospace; }
  .hm-summary b { color: var(--text-secondary); }

  /* ── panel-title / subpanel helpers ──────────────────────────────────── */
  /* Used by bare <section class="section panel"> converted from raw <section style=...> */
  .panel-title {
    font-size: 11px; font-weight: 700; color: var(--text-secondary);
    text-transform: uppercase; letter-spacing: 0.05em;
    margin-bottom: 8px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    font-family: inherit;
  }
  .panel-label-sm {
    font-size: 11px; color: var(--text-dim); font-weight: 400; cursor: pointer;
  }
  .subpanel-label {
    font-size: 10px; font-weight: 600; color: var(--text-secondary);
    margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.04em;
  }
  .detail-summary {
    font-size: 12px; color: var(--text-dim); cursor: pointer;
    padding: 4px 0; user-select: none; list-style: none;
  }
  .detail-summary::-webkit-details-marker { display: none; }

  /* panel-select / panel-input — small form controls inside panels */
  .panel-select {
    background: var(--bg-surface); border: 1px solid var(--border-ui);
    color: var(--text-secondary); font-size: var(--btn-font); font-family: inherit;
    padding: 0.5em 6px; border-radius: var(--r-sm); cursor: pointer;
  }
  .panel-input {
    background: var(--bg-raised); border: 1px solid var(--border-ui);
    color: var(--text-primary); font-size: var(--btn-font); font-family: inherit;
    padding: 0.5em 8px; border-radius: var(--r-sm);
    min-width: 0; flex: 1 1 180px; max-width: 220px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .panel-input:focus { outline: none; border-color: var(--border-focus); }

  /* mini-metric-card — CK3 metric boxes */
  .mini-metric-card {
    background: var(--bg-raised); border: 1px solid var(--border-ui);
    border-radius: var(--r-sm); padding: 8px 10px;
  }
  .mini-metric-label { color: var(--text-secondary); font-size: 10px; margin-bottom: 4px; }
  .mini-metric-value { color: var(--text-primary); font-size: 13px; font-weight: 600; }
  .mini-metric-note  { color: var(--text-muted); font-size: 9px; margin-top: 2px; overflow-wrap: anywhere; }
  .mini-bar-wrap     { height: 8px; background: var(--border-ui); border-radius: 3px; overflow: hidden; margin-bottom: 4px; }

  /* v21-mini-card — Research Status panel cards */
  .v21-mini-card {
    background: var(--bg-raised); border: 1px solid var(--border-ui);
    border-radius: var(--r-sm); padding: 10px 12px;
  }

  /* report-card / report-link */
  .report-card {
    background: var(--bg-raised); border: 1px solid var(--border-ui);
    border-radius: var(--r-sm); padding: 8px 10px;
    display: flex; flex-direction: column; gap: 3px;
  }
  .report-link {
    display: block; color: var(--accent-blue); text-decoration: none; font-size: 12px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    overflow-wrap: anywhere; white-space: normal;
  }
  .report-link:hover { text-decoration: underline; }
  .report-link-purple { color: #a78bfa; }
  .report-link-green  { color: #86efac; }

  /* ── Overflow / word-break global safety net ─────────────────────────── */
  /* Any .section or .panel must not let long strings (PIDs, paths, cmds) overflow */
  .section, section.panel {
    overflow-wrap: anywhere;
    min-width: 0;
  }
  /* Monospace content cells — break long tokens but prefer word boundaries */
  .training-run-name, .training-pid,
  .ckpt-name, .eval-run,
  .edge, .edge-session, .edge-label {
    overflow-wrap: anywhere;
  }

  /* ── Tab buttons (Files / By Agent toggle) ───────────────────────────── */
  .tab-btn {
    display: inline-flex; align-items: center;
    font-size: 10px; padding: 0.5em 8px;
    border-radius: var(--r-sm); cursor: pointer;
    background: var(--bg-base); color: var(--text-dim);
    border: 1px solid var(--border-ui); user-select: none;
    transition: background 0.15s, color 0.15s;
  }
  .tab-btn.tab-active {
    background: rgba(34, 197, 94, 0.13); color: #22c55e;
    border-color: rgba(34, 197, 94, 0.27);
  }
  .tab-btn:hover:not(.tab-active) { background: var(--bg-surface); color: var(--text-secondary); }

  /* ── Todo Manager section overrides ─────────────────────────────────── */
  /* Column headers inside .tm-grid */
  .tm-col-header {
    font-size: 12px; font-weight: 600; margin-bottom: 6px;
    padding-bottom: 4px; border-bottom: 1px solid var(--border-subtle);
  }
  .tm-col-header.inbox    { color: var(--accent-purple); }
  .tm-col-header.longterm { color: var(--accent-amber); }

  /* ---------- Mobile-friendly responsive tuning ---------- */
  @media (max-width: 720px) {
    body { padding: 8px; font-size: 13px; }
    .header h1 { font-size: 15px; }
    .section { padding: 8px 10px; margin-bottom: 8px; }
    .section-title { font-size: 10px; margin-bottom: 6px; }
    .token-bar-wrap { height: 18px; }
    /* Skill rows — flex → wrap for narrow screens */
    .skill-row { flex-wrap: wrap; }
    .skill-label { flex: 1 1 100%; }
    .skill-detail { flex: 1 1 100%; }
    .skill-files { flex: 1 1 100%; font-size: 10px; }
    /* Graph rows — hide label column on small */
    .graph-row .edge-label { display: none; }
    /* Codex stats — 4 cols → 2 cols on mobile */
    .codex-stats { grid-template-columns: 1fr 1fr; gap: 6px; }
  }
  @media (max-width: 480px) {
    body { padding: 6px; font-size: 12px; }
    .header h1 { font-size: 14px; }
    .section { padding: 7px 9px; }
    .token-bar-wrap { height: 16px; }
    .token-numbers { font-size: 10px; }
    .agent-card { padding: 6px 4px; }
    .agent-name { font-size: 11px; }
    .agent-role { display: none; }   /* 너무 좁으면 역할 숨김, name+model+status 만 */
    .status-dot { font-size: 16px; }
    /* Tasks/Changes rows — compact */
    .row { gap: 6px; padding: 4px 0; font-size: 11px; }
    .task-id { width: 60px !important; }
    .change-time { width: 58px !important; }
    /* Todo rows */
    .todo-row { font-size: 12px; }
    .todo-reason { font-size: 10px; }
  }
  /* ---------- Loss Curves ---------- */
  .loss-panel-header { display: flex; justify-content: space-between; align-items: center;
                       margin-bottom: 6px; flex-wrap: wrap; gap: 4px; }
  .loss-source-badge { font-size: 10px; padding: 0.5em 7px; border-radius: 10px; font-weight: 700; }
  .loss-source-wandb     { background: #7c3aed22; color: #c4b5fd; border: 1px solid #7c3aed55; }
  .loss-source-log_regex { background: #0369a122; color: #7dd3fc; border: 1px solid #0369a155; }
  .loss-source-empty     { background: #33415522; color: #64748b;  border: 1px solid #33415555; }
  .loss-charts-stack { display: flex; flex-direction: column; gap: 6px; }
  .loss-chart-sub { position: relative; height: 150px; }
  .loss-chart-label { font-size: 10px; color: var(--text-muted); margin-bottom: 2px; font-weight: 600;
                      text-transform: uppercase; letter-spacing: 0.04em; }
  .loss-btn { font-size: var(--btn-font); padding: 0.5em var(--btn-px);
              border-radius: var(--r-sm); cursor: pointer;
              background: var(--bg-surface); color: var(--text-secondary);
              border: 1px solid var(--border-ui); font-family: inherit;
              display: inline-flex; align-items: center; }
  .loss-btn:hover { background: var(--border); color: var(--text-primary); }
  .loss-btn.active { background: var(--bg-card); color: var(--accent-blue); border-color: var(--accent-blue); }
  .loss-empty { color: var(--text-muted); font-size: 12px; padding: 20px 0; text-align: center; }

  /* ── Todo Hero: mobile horizontal scroll ────────────────────────────────── */
  @media (max-width: 768px) {
    #todo-list {
      overflow-x: auto;
    }
    .todo-item {
      white-space: nowrap;
      min-width: max-content;
    }
    .todo-item-text {
      white-space: nowrap;
    }
  }

  /* ── Todo Hero Card ──────────────────────────────────────────────────────── */
  .todo-hero {
    background: linear-gradient(135deg, var(--bg-primary) 0%, #1e1b4b 60%, var(--bg-primary) 100%);
    border: 1px solid var(--accent-purple);
    border-radius: 10px;
    padding: 14px 16px;
    position: relative;
    overflow: hidden;
  }
  .todo-hero::before {
    content: "";
    position: absolute; top: 0; left: 0; right: 0; height: 2px;
    background: linear-gradient(90deg, var(--accent-purple), var(--accent-purple), var(--accent-purple));
    background-size: 200% 100%;
    animation: todo-sweep 3s linear infinite;
  }
  @keyframes todo-sweep {
    0%   { background-position: 0% 0; }
    100% { background-position: 200% 0; }
  }
  .todo-counts {
    display: flex; gap: 16px; align-items: baseline; flex-wrap: wrap; margin-bottom: 10px;
  }
  .todo-count-big {
    font-size: 28px; font-weight: 800; line-height: 1;
  }
  .todo-count-big.red   { color: var(--accent-red); }
  .todo-count-big.green { color: var(--accent-green); }
  .todo-count-big.gray  { color: var(--text-dim); }
  .todo-count-label {
    font-size: 11px; color: var(--text-dim); margin-left: 4px;
  }
  .todo-stat-cell {
    background: var(--bg-primary); border: 1px solid var(--bg-secondary); border-radius: 6px;
    padding: 8px 10px; display: flex; flex-direction: column; align-items: center; gap: 3px;
  }
  .todo-stat-num {
    font-size: 22px; font-weight: 800; color: var(--accent-purple); line-height: 1;
  }
  .todo-stat-label {
    font-size: 10px; color: var(--text-dim); font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em;
  }
  .todo-input-row {
    display: flex; gap: 6px; margin-bottom: 10px; align-items: stretch;
  }
  .todo-input-row input {
    flex: 1; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 5px;
    padding: 0.5em 10px; color: var(--text-primary); font-size: 12px;
    font-family: inherit; outline: none;
  }
  .todo-input-row input:focus { border-color: var(--accent-purple); }
  .todo-prio-select {
    background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 5px;
    color: var(--text-secondary); font-size: 11px; padding: 0.5em 6px; cursor: pointer;
  }
  .todo-add-btn {
    background: var(--accent-purple); color: #fff; border: none; border-radius: 5px;
    padding: 0.5em 14px; font-size: 12px; cursor: pointer; font-weight: 600;
    white-space: nowrap;
  }
  .todo-add-btn:hover { background: var(--accent-purple); }
  .todo-list { display: flex; flex-direction: column; gap: 4px; max-height: 300px; overflow-y: auto; }
  .todo-item {
    display: flex; align-items: center; gap: 8px;
    padding: 5px 8px; border-radius: 5px; background: var(--bg-primary);
    border-left: 3px solid var(--border);
    transition: background 0.15s;
  }
  .todo-item:hover { background: var(--bg-secondary); }
  .todo-item.done { opacity: 0.45; }
  .todo-item.p1 { border-left-color: var(--accent-red); }
  .todo-item.p2 { border-left-color: var(--accent-amber); }
  .todo-item.p3 { border-left-color: var(--border); }
  .todo-item input[type="checkbox"] { cursor: pointer; accent-color: var(--accent-purple); flex-shrink: 0; }
  .todo-item-text {
    flex: 1; font-size: 12px; color: var(--text-primary); word-break: break-word;
    line-height: 1.4;
  }
  .todo-item.done .todo-item-text { text-decoration: line-through; color: var(--text-muted); }
  .todo-item-due {
    font-size: 10px; color: var(--text-dim); white-space: nowrap; flex-shrink: 0;
  }
  .todo-item-due.overdue { color: var(--accent-red); font-weight: 600; }
  .todo-prio-badge {
    font-size: 9px; font-weight: 700; padding: 1px 5px; border-radius: 3px;
    flex-shrink: 0;
  }
  .todo-prio-badge.p1 { background: #450a0a; color: #fca5a5; }
  .todo-prio-badge.p2 { background: #431407; color: #fdba74; }
  .todo-prio-badge.p3 { background: #1e293b; color: #64748b; }
  .todo-del-btn {
    background: none; border: none; color: var(--border); cursor: pointer;
    font-size: 14px; padding: 0 2px; flex-shrink: 0;
    transition: color 0.1s;
  }
  .todo-del-btn:hover { color: var(--accent-red); }
  .todo-carryover-badge {
    font-size: 0.7em; font-weight: 700; padding: 1px 6px; border-radius: 3px;
    background: #92400e; color: #fcd34d; flex-shrink: 0; white-space: nowrap;
  }
  .todo-empty-msg {
    text-align: center; padding: 16px 8px; color: var(--text-muted); font-size: 12px;
  }

  /* ── Todo Manager subtask tree ────────────────────────────────────────── */
  .tm-toggle {
    width: 16px; height: 16px; flex-shrink: 0; cursor: pointer;
    background: none; border: none; color: var(--text-muted); font-size: 9px;
    padding: 0; display: flex; align-items: center; justify-content: center;
    border-radius: 2px; transition: color 0.15s;
  }
  .tm-toggle:hover { color: var(--text-secondary); }
  .tm-toggle-placeholder { width: 16px; flex-shrink: 0; }
  .todo-promote-check { margin-right: 0.5em; }
  .tm-children {
    display: none; margin-left: 20px; border-left: 2px solid var(--bg-card);
    padding-left: 6px; margin-top: 2px; margin-bottom: 2px;
  }
  .tm-children.expanded { display: block; }
  .tm-child-row {
    display: flex; align-items: center; gap: 4px;
    padding: 3px 0; border-bottom: 1px solid var(--bg-primary); font-size: 10px;
    color: var(--text-secondary);
  }

  /* ── Mobile P0/P1 fixes (added 2026-05-11) ─────────────────────────────
     P0: skill-row fixed-width columns cause horizontal overflow on phones.
     P0: Todo Manager / v21-panels inline 2-col grid → 1 col on mobile.
     P0: A/B Compare inputs 200px fixed → fluid.
     P1: Agent Graph iframe 520px → 250px on phone.
     P1: todo-due-input 90px fixed → fluid.
     P1: touch targets — section-level buttons min-height 44px.
  ─────────────────────────────────────────────────────────────────────── */

  /* P0 — Skill rows: session column also hidden on tablet-down */
  @media (max-width: 720px) {
    .skill-session { display: none; }
  }

  /* P0 — Todo Manager two-column grid → single column on mobile */
  @media (max-width: 768px) {
    .tm-grid {
      display: flex !important;
      flex-direction: column !important;
      gap: 16px !important;
    }
  }

  /* P0 — v21-panels 2-col grid → single column on mobile */
  @media (max-width: 768px) {
    .v21-grid {
      display: flex !important;
      flex-direction: column !important;
    }
  }

  /* P0 — A/B Compare inputs: remove fixed width, let flex handle it */
  @media (max-width: 768px) {
    #ab-run-a,
    #ab-run-b {
      width: 100% !important;
      min-width: 0 !important;
    }
    .ab-input-row {
      flex-wrap: wrap !important;
    }
  }

  /* P1 — Agent Graph iframe: handled by .iframe-frame class rules in responsive section below */

  /* P1 — todo-due-input: remove fixed 90px width on mobile */
  @media (max-width: 480px) {
    #todo-due-input {
      width: auto !important;
      min-width: 72px !important;
      flex-shrink: 1 !important;
    }
    .todo-input-row {
      flex-wrap: wrap;
    }
    #todo-add-input {
      min-width: 0;
    }
  }

  /* P1 — Touch targets: padding-top/bottom always 2px (unified via global rule above).
     min-height removed so buttons stay text-height like LIVE badge. */

  /* P1 — Graph text fallback: inner 2-col grid → 1 col on mobile */
  @media (max-width: 768px) {
    .graph-detail-grid {
      display: flex !important;
      flex-direction: column !important;
    }
  }

  /* P1 — Recent Reports: 2-col grid → 1 col on mobile */
  @media (max-width: 768px) {
    .reports-grid {
      display: flex !important;
      flex-direction: column !important;
    }
  }

  /* P1 — Training table: horizontal scroll wrapper (applied via overflow-x on container) */
  @media (max-width: 768px) {
    .training-scroll {
      overflow-x: auto;
    }
    .training-table {
      min-width: 480px;
    }
  }

  /* [6] Checkpoint + Eval: 박스 내부 가로 스크롤 — 모든 해상도 */
  #checkpoints-list,
  #eval-list {
    overflow-x: auto;
    max-width: 100%;
  }

  /* P1 — Checkpoint + Eval tables: same horizontal scroll */
  @media (max-width: 768px) {
    .ckpt-table,
    .eval-table {
      min-width: 400px;
    }
  }

  /* [4] Mobile 640px — button padding horizontal 축소 (console tail / toolbar) */
  @media (max-width: 640px) {
    .console-btn,
    .btn {
      padding: 0.5em 0.8em !important;
    }
  }

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     RESPONSIVE — training-hub.html 전용 grid classes
     (inline style 을 class 로 교체하여 media query 제어 가능하게)
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

  /* Monitor / WandbOnline 탭: run-list(고정폭) + chart(가변) */
  .th-monitor-grid {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 10px;
  }
  .th-wandb-grid {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 10px;
  }
  @media (max-width: 768px) {
    .th-monitor-grid,
    .th-wandb-grid {
      grid-template-columns: 1fr;
    }
  }

  /* Schedule 탭: calendar + form side-by-side */
  .th-sched-grid {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 10px;
  }
  @media (max-width: 900px) {
    .th-sched-grid {
      grid-template-columns: 1fr;
    }
  }

  /* Schedule form — start/end datetime 2-col */
  .th-sched-datetime {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }
  /* Schedule form — metric/value/threshold 3-col */
  .th-sched-mvt {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 6px;
  }
  @media (max-width: 480px) {
    .th-sched-datetime { grid-template-columns: 1fr; }
    .th-sched-mvt      { grid-template-columns: 1fr; }
  }

  /* ── index.html inline 4-col grids: stats + training summary ── */
  /* todo completion stats 4-col → 2-col at 480px */
  #todo-stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin-top: 6px;
  }
  @media (max-width: 480px) {
    #todo-stats-grid { grid-template-columns: repeat(2, 1fr); }
  }

  /* training summary quick stats 4-col → 2-col at 480px */
  #training-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin-top: 8px;
  }
  @media (max-width: 480px) {
    #training-summary-grid { grid-template-columns: repeat(2, 1fr); }
  }

  /* training ETA grid 3-col → 1-col at 480px */
  #eta-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-top: 8px;
  }
  @media (max-width: 480px) {
    #eta-grid { grid-template-columns: 1fr; }
  }

  /* v21 claude_47_metrics 3-col → 1-col at 480px */
  #v21-panels .mini-metric-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    margin-top: 6px;
  }
  @media (max-width: 480px) {
    #v21-panels .mini-metric-grid { grid-template-columns: 1fr; }
  }

  /* ── Quick Actions wrap ── */
  #quick-prompt-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
  }
  @media (max-width: 480px) {
    #quick-prompt-buttons .btn { flex: 1 1 calc(50% - 8px); text-align: center; }
  }

  /* ── token-box: word-break for long session IDs ── */
  .token-box-title { word-break: break-all; }

  /* ── kpi-card responsive ── */
  .kpi-card {
    background: var(--bg-primary);
    border-radius: 6px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    text-align: center;
  }
  .kpi-value { font-size: 24px; font-weight: 800; line-height: 1.1; }
  .kpi-value-green  { color: var(--accent-green); }
  .kpi-value-purple { color: var(--accent-purple); }
  .kpi-value-blue   { color: var(--accent-blue); }
  .kpi-value-orange { color: var(--accent-amber); }
  .kpi-value-teal   { color: #2dd4bf; }
  .kpi-value-md  { font-size: 20px; }
  .kpi-value-sm  { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .kpi-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.03em; margin-top: 3px; }
  @media (max-width: 480px) {
    .kpi-value { font-size: 20px; }
    .kpi-value-md { font-size: 16px; }
  }

  /* ── console-mini in index.html training summary card ── */
  .console-mini {
    background: var(--bg-raised);
    border-radius: var(--r-sm);
    padding: 6px 8px;
    font-family: var(--font-mono);
    font-size: 10px;
    line-height: 1.5;
    color: var(--text-secondary);
    max-height: 80px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-break: break-word;
    border: 1px solid var(--border);
  }

  /* ── nc-banner (Next Choice sticky) — mobile ── */
  .nc-banner {
    background: var(--bg-secondary);
    border-bottom: 2px solid var(--accent-green);
    padding: 8px 14px;
    display: none;
    position: sticky;
    top: 0;
    z-index: 50;
  }
  .nc-banner.show { display: block; }
  @media (max-width: 480px) {
    .nc-banner { padding: 6px 10px; }
  }

  /* ── iframe-frame (Agent Graph embed) ── */
  .iframe-frame {
    width: 100%;
    height: 400px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
  }
  @media (max-width: 768px) { .iframe-frame { height: 300px; } }
  @media (max-width: 480px) { .iframe-frame { height: 220px; } }

  /* ── Mode Status chips (competition-mode / proposal-mode) ── */
  .mode-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: var(--r-sm);
    border: 1px solid var(--border);
    font-size: 12px;
    font-weight: 600;
    transition: background 0.2s, border-color 0.2s;
  }
  .mode-chip.mode-off {
    background: var(--bg-card);
    color: var(--text-dim);
  }
  .mode-chip.mode-on {
    background: color-mix(in srgb, var(--accent-green) 15%, var(--bg-card));
    border-color: var(--accent-green);
    color: var(--text-primary);
  }
  .mode-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
    flex-shrink: 0;
  }
  .mode-chip.mode-on .mode-dot {
    background: var(--accent-green);
    animation: pulse 1.5s infinite;
  }
  .mode-slug {
    font-size: 10px;
    font-weight: 400;
    color: var(--text-secondary);
    margin-left: 2px;
  }

  /* ── Worklog Panel ─────────────────────────────────────────── */
  .worklog-bar-wrap {
    height: 8px;
    background: #1e293b;
    border-radius: 4px;
    overflow: hidden;
  }
  .worklog-bar-fill {
    height: 100%;
    border-radius: 4px;
    transition: width 0.4s ease;
  }
  .mode-chip.mode-on .mode-slug { color: var(--accent-green); }
