/* Pieces particular to one screen. Everything shared lives in components.css. */

/* 탐지: the columns that are not the detection itself keep to a share of
   the row, so the table fits the window instead of scrolling sideways. */
.col-where { width: 22%; }
.col-who { width: 15%; }
.col-service { width: 14%; }

/* 단말: the list's columns, so it fits the window rather than scrolling. */
.col-health { width: 150px; }
.col-group { width: 22%; }
.col-platform { width: 18%; }
.col-address { width: 17%; }
.col-seen { width: 110px; }
/* The host name takes what the other columns leave. Below this the list
   scrolls inside its frame rather than squeezing the name to nothing -- while
   it is a grid: at 860px and under its rows are cards (dataTable's stack). */
.col-host { min-width: 140px; }
@media (min-width: 861px) {
  table.data.fixed:has(th.col-host) { min-width: 920px; }
}

/* 개요: the attention list reads as a list of links. */
.card .list-plain a:hover { text-decoration: none; }
.card .list-plain a:hover .grow { color: var(--accent-hover); }

/* 정책 편집: sections on the left, the section on the right, and the bar
   that holds an unsaved draft along the bottom. */
.status-strip { gap: var(--s-2) var(--s-3); margin: calc(-1 * var(--s-2)) 0 var(--s-5); }
.editor { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: var(--s-6); align-items: start; }
.editor-nav { position: sticky; top: var(--s-4); display: flex; flex-direction: column; gap: 2px; }
.editor-nav a { display: flex; align-items: center; gap: var(--s-2); padding: 8px 10px; border-radius: var(--radius); color: var(--text-2); font-size: var(--t-sm); }
.editor-nav a:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.editor-nav a.on { background: var(--accent-soft); color: var(--text); font-weight: 600; }
.editor-content { min-width: 0; }
.editor-panel .card-body { gap: var(--s-4); }
@media (max-width: 1100px) {
  .editor { grid-template-columns: minmax(0, 1fr); }
  .editor-nav { position: static; flex-direction: row; flex-wrap: wrap; }
}

.publish-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin: var(--s-6) calc(-1 * var(--s-8)) 0;
  padding: var(--s-3) var(--s-8);
  background: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 18px rgb(0 0 0 / .14);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.publish-bar.dirty { border-top: 2px solid var(--warn); }
.publish-row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.publish-what { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); flex: 1 1 280px; min-width: 0; }
.publish-row input { flex: 0 1 320px; min-width: 200px; }
/* The page's side padding shrinks to --s-4 at this width (base.css); the bar's
   bleed follows it, or it pokes past the window and scrolls it sideways. */
@media (max-width: 860px) {
  .publish-bar { margin-left: calc(-1 * var(--s-4)); margin-right: calc(-1 * var(--s-4)); padding: var(--s-3) var(--s-4); }
  .publish-row input { flex: 1 1 100%; min-width: 0; }
}

.rules-table .col-switch { width: 64px; }
.rules-table .col-direction { width: 120px; }
.rules-table .col-action { width: 96px; }
.rules-table .col-severity { width: 96px; }
.col-expiry { width: 120px; }

.catalog { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius); max-height: 52vh; overflow: auto; }
.catalog-item { display: flex; align-items: center; gap: var(--s-3); padding: 10px 14px; border-bottom: 1px solid var(--line); cursor: pointer; }
.catalog-item:last-child { border-bottom: 0; }
.catalog-item:hover { background: var(--surface-hover); }
.catalog-item.taken { cursor: default; opacity: .6; }
.catalog-item .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.catalog-name { font-weight: 500; }

.try-result { display: flex; flex-direction: column; gap: var(--s-3); }
.try-result:empty { display: none; }
/* Wide enough for its example, in both languages, before anything is typed. */
.try-site { width: 300px; max-width: 100%; }

.window-row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; padding: var(--s-2) 0; border-bottom: 1px dashed var(--line); }
.day-picker { display: inline-flex; gap: 4px; }
.day-picker button { width: 32px; height: 32px; padding: 0; border-radius: 50%; font-size: var(--t-sm); justify-content: center; }
.day-picker button.on { background: var(--accent-soft); border-color: var(--accent); color: var(--text); font-weight: 600; }
/* The schedule's 24-hour picker: hour and minute, digits lined up. */
.clock .clock-part { padding-left: var(--s-2); font-variant-numeric: tabular-nums; }

.versions { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.versions li { display: flex; flex-direction: column; gap: 4px; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
.versions li:last-child { border-bottom: 0; }

.notice-preview { border: 1px solid var(--line-strong); border-left: 3px solid var(--danger); border-radius: var(--radius); padding: var(--s-3) var(--s-4); background: var(--surface-sunken); display: flex; flex-direction: column; gap: 6px; font-size: var(--t-sm); }
.notice-preview-title { font-weight: 700; font-size: var(--t-xs); letter-spacing: .04em; color: var(--danger); }

/* AI 사용량: the live token trace, in the frame of 서버 자원's traces (.live,
   below). The stretch whose events are still arriving is washed out, not
   drawn as a dip -- the difference between an honest chart and one
   everybody reports as broken. */
.live.stale { opacity: .55; }
.live-lag { font-size: var(--t-xs); color: var(--text-3); font-variant-numeric: tabular-nums; }
.live-settling { fill: var(--surface); opacity: .6; }
.live-edge { stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; animation: pulse-beat 1.6s ease-in-out infinite; }
@keyframes pulse-beat { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .live-edge { animation: none; opacity: .9; } }

/* 내 계정: the QR stays black on white in either theme -- a reader pointed at
   an inverted code sees nothing. */
.totp-qr { background: #fff; padding: 8px; border-radius: 8px; line-height: 0; }
.totp-qr img { width: 180px; height: 180px; }
.recovery-codes { font-size: var(--t-sm); letter-spacing: .04em; columns: 2; }

/* 정책 > 파일 > 임베디드 이미지 OCR: 계열별 카드로 확실히 구분.
   기존 flat 리스트는 4~8개 체크박스가 세로로 붙어 계열 경계가 흐릿했다.
   각 계열을 border/배경 색으로 감싸고, 헤더 tri-state 는 크게, 하위 변형은
   들여쓰기 + 흐린 라벨 + 2열 그리드 (Word 4개, Excel 4개, PPT 8개, Hancom 2, PDF 1).
   군을 보고 필요한 것만 눈으로 찾을 수 있게. */
.ocr-format-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: var(--s-4);
}
.ocr-family {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--s-3) var(--s-4) var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.ocr-family-row {
  gap: 8px;
  align-items: center;
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--line);
  font-weight: 600;
  color: var(--text);
}
.ocr-family-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
}
.ocr-family-row span {
  font-size: var(--t-sm);
  letter-spacing: .01em;
}
.ocr-variant-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 12px;
  padding-left: var(--s-2);
}
/* PowerPoint 계열은 변형이 8개라 좁은 화면에서 3열이 필요할 수도. */
.ocr-family.ocr-family-powerpoint .ocr-variant-list { grid-template-columns: 1fr 1fr; }
.ocr-variant-list label {
  gap: 6px;
  align-items: center;
  font-size: var(--t-sm);
  color: var(--text-2);
  padding: 2px 0;
}
.ocr-variant-list label:hover { color: var(--text); }
.ocr-variant-list input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: var(--accent);
}

/* /flow — one-line stat strip below the primary KPI grid. Small, subtle,
 * numbers next to their label so the fleet-shape context is one glance. */
.flow-stat-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 24px;
  padding: 4px 2px 2px;
  color: var(--text-3);
  font-size: var(--t-sm);
}
.flow-stat {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.flow-stat-label {
  color: var(--text-3);
}
.flow-stat-value {
  color: var(--text);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* /flow — CISO data-flow dashboard. A department × AI-service table with
 * sticky first column and honest horizontal scroll when a tenant has more
 * services than the viewport can carry, so cell text never leaks and the
 * row/column labels stay pinned as an operator scrolls. */
.flow-heat {
  overflow-x: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
}
.flow-heat-table {
  border-collapse: collapse;
  width: 100%;
  min-width: 640px;
  font-variant-numeric: tabular-nums;
}
.flow-heat-table th,
.flow-heat-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  text-align: right;
  vertical-align: middle;
  font-size: var(--t-sm);
}
.flow-heat-table thead th {
  background: var(--surface-sunken);
  color: var(--text-2);
  font-weight: 500;
  text-align: right;
}
.flow-heat-table .flow-th-corner {
  min-width: 160px;
  max-width: 220px;
  background: var(--surface-sunken);
  position: sticky;
  left: 0;
  z-index: 2;
  border-right: 1px solid var(--line-strong);
}
.flow-heat-table .flow-th-service {
  min-width: 96px;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.flow-heat-table .flow-th-dept {
  min-width: 160px;
  max-width: 220px;
  background: var(--surface);
  color: var(--text);
  font-weight: 500;
  text-align: left;
  position: sticky;
  left: 0;
  z-index: 1;
  border-right: 1px solid var(--line-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.flow-heat-table .flow-td {
  min-width: 96px;
  max-width: 140px;
}
.flow-heat-table .flow-cell-num {
  font-weight: 500;
  color: var(--text);
}
.flow-heat-table .flow-cell-empty {
  color: var(--text-3);
}
.flow-heat-table .flow-cell-block {
  display: inline-flex;
  vertical-align: -1px;
  margin-left: 6px;
  color: var(--danger);
}

/* 콘솔 사용 안내 (/help) */
.help-link { display: inline-flex; align-items: center; gap: 6px; }
@media (max-width: 720px) { .help-link-label { display: none; } }
.help-search { width: 100%; max-width: 560px; }
.help-cards { grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); }
.help-card { display: block; color: inherit; transition: border-color .12s ease; }
.help-card:hover { border-color: var(--accent); text-decoration: none; }
.help-card .card-body { display: flex; flex-direction: column; gap: var(--s-2); }
.help-card-title { display: flex; align-items: center; gap: var(--s-2); font-weight: 600; color: var(--text); }
.help-card-sub { color: var(--text-2); font-size: var(--t-sm); line-height: 1.6; }
.help-results .card-body { padding: 0; }
.help-result { display: block; padding: 10px 16px; border-bottom: 1px solid var(--line); color: inherit; }
.help-result:last-child { border-bottom: 0; }
.help-result:hover { background: var(--surface-hover); text-decoration: none; }
.help-result-path { font-size: var(--t-xs); color: var(--text-3); margin-bottom: 2px; }
.help-jump { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.help-intro { margin: 0; color: var(--text-2); line-height: 1.7; }
/* Above table.data's fixed one-line rows: a description runs to several lines. */
table.data.help-items td { height: auto; padding-top: 11px; padding-bottom: 11px; vertical-align: top; line-height: 1.65; overflow-wrap: anywhere; }
.help-items .help-label { width: 22%; min-width: 150px; }
.help-items .col-kind { width: 84px; white-space: nowrap; }
.help-opts { margin: var(--s-2) 0 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: 3px; color: var(--text-2); }
.help-flash { animation: help-flash 1.8s ease-out; }
@keyframes help-flash { from { background: var(--accent-soft); } to { background: transparent; } }

/* 관리 → 시스템 정보 → 서버 자원: gauges, live traces, cores. */
.resources { display: flex; flex-direction: column; gap: var(--s-4); }
.res-gauges { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); gap: var(--s-4); }
.gauge {
  --gauge: var(--ok);
  display: flex; flex-direction: column; align-items: center; gap: var(--s-2);
  padding: var(--s-5) var(--s-3) var(--s-4);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--gauge) 9%, var(--surface)) 0%, var(--surface) 70%);
  transition: background var(--dur-slow) var(--ease);
}
.gauge.warn { --gauge: var(--warn); }
.gauge.danger { --gauge: var(--danger); }
.gauge-dial { position: relative; width: 124px; height: 124px; }
.gauge-ring { width: 100%; height: 100%; display: block; }
.gauge-track { fill: none; stroke: var(--surface-sunken); stroke-width: 11; }
.gauge-arc {
  fill: none; stroke: var(--gauge); stroke-width: 11; stroke-linecap: round;
  transition: stroke-dashoffset .8s var(--ease-out), stroke .4s var(--ease);
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--gauge) 55%, transparent));
}
.gauge-center { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 1px; }
.gauge-value { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.gauge-unit { font-size: var(--t-sm); color: var(--text-3); margin-top: 8px; }
.gauge-label { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: var(--text); }
.gauge-label .icon { color: var(--gauge); }
.gauge-caption { font-size: var(--t-xs); color: var(--text-3); text-align: center; min-height: 1.3em; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.res-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--s-4); }
.res-lower { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: var(--s-4); align-items: start; }
.res-panel { padding: var(--s-4); border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); gap: var(--s-3); }
.res-panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); min-width: 0; }
.res-panel-head h4 { margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--text-2); }

.live { display: flex; flex-direction: column; gap: var(--s-2); }
.live-legend { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); font-size: var(--t-xs); color: var(--text-3); }
.live-key { display: inline-flex; align-items: center; gap: 6px; }
.live-key strong { color: var(--text); font-size: var(--t-sm); }
.live-swatch { width: 10px; height: 3px; border-radius: 2px; background: var(--series); }
.live-frame { position: relative; border-radius: var(--radius); background: var(--surface-sunken); overflow: hidden; }
.live-chart { display: block; width: 100%; height: 132px; }
.live-scale { position: absolute; top: 4px; right: 8px; font-size: 11px; color: var(--text-3); }
.live-axis { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-3); }
.live-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 5; vector-effect: non-scaling-stroke; }
.live-line { fill: none; stroke: var(--series); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.live-area { fill: var(--series); stroke: none; opacity: .14; }
.s1 { --series: var(--accent); }
.s2 { --series: var(--cat-3); }
.s3 { --series: var(--info); }
.s4 { --series: var(--cat-4); }
.s5 { --series: var(--cat-5); }

.cores { display: flex; justify-content: center; gap: 5px; height: 132px; align-items: stretch; }
.core { --gauge: var(--ok); flex: 1 1 0; min-width: 6px; max-width: 44px; height: 100%; display: flex; align-items: flex-end; border-radius: 5px; overflow: hidden; background: var(--surface-sunken); }
.core.warn { --gauge: var(--warn); }
.core.danger { --gauge: var(--danger); }
.core-fill {
  display: block; width: 100%; height: 0; border-radius: 5px 5px 0 0;
  background: linear-gradient(to top, var(--gauge), color-mix(in srgb, var(--gauge) 45%, transparent));
  transition: height .8s var(--ease-out);
}

.disk-row { display: flex; flex-direction: column; gap: var(--s-1); padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.disk-row:last-of-type { border-bottom: 0; padding-bottom: 0; }
.disk-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-3); min-width: 0; }
.disk-mount { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.res-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
.res-tile { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: var(--s-3); border-radius: var(--radius); background: var(--surface-sunken); }
.res-tile-label { font-size: var(--t-xs); color: var(--text-3); }
.res-tile-value { font-size: 19px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.res-tile-sub { font-size: var(--t-xs); color: var(--text-3); }

.live-badge { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-xs); font-weight: 600; color: var(--ok); }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; animation: live-ping 1.8s ease-out infinite; }
.live-badge.paused { color: var(--text-3); }
.live-badge.paused .live-dot { animation: none; }
@keyframes live-ping {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 55%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .live-dot { animation: none; }
  .gauge-arc, .core-fill { transition: none; }
}

/* ---------------------------------------------------------------- phone */

@media (max-width: 600px) {
  /* The page's side padding is --s-3 here (base.css); the bar's bleed follows. */
  .publish-bar { margin-left: calc(-1 * var(--s-3)); margin-right: calc(-1 * var(--s-3)); padding: var(--s-3); }
  .editor-nav a { padding: 6px 10px; }
  /* 시스템 정보: the four gauges two by two rather than one under another. */
  .res-gauges { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
  .gauge { padding: var(--s-4) var(--s-2) var(--s-3); }
  .gauge-dial { width: 104px; height: 104px; }
  .gauge-value { font-size: 24px; }
  /* 도움말: an item reads down the screen -- its name and kind, then what
     it does -- instead of three columns a phone has no room for. */
  table.data.help-items, table.data.help-items tbody, table.data.help-items tr, table.data.help-items td { display: block; }
  table.data.help-items thead { display: none; }
  table.data.help-items tr { padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); }
  table.data.help-items tr:last-child { border-bottom: 0; }
  table.data.help-items td { height: auto; width: auto; min-width: 0; padding: 0; border-bottom: 0; }
  table.data.help-items td.help-label, table.data.help-items td.col-kind { display: inline-block; vertical-align: middle; }
  table.data.help-items td.col-kind { margin-left: var(--s-2); }
  table.data.help-items td:last-child { margin-top: var(--s-2); }
}
