/* AI 사용 인사이트 shell and its charts and tables (insights foundation). Every colour and size is a
   design-system token (style.css), so the dark theme follows without rules of its own. */
.insights-toolbar { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; }
/* A field's label sits on its field: the page's old margin for a form label (18px above, 7px below) left an
   empty band between the page's sentence and this row. */
.insights-toolbar label { display: inline-flex; flex-direction: column; gap: 4px; width: auto; margin: 0; font-size: var(--ds-fs-xs); color: var(--ds-text-2); }
.insights-toolbar select, .insights-toolbar input { width: auto; min-width: 160px; }
.insights-ranges { display: inline-flex; }
.insights-toolbar .ui-date { display: flex; }
/* A screen's lines are body text, 14px (user review 10-06, P2 12); the quiet colour says they are secondary. */
.insights-hint { color: var(--ds-text-2); font-size: var(--ds-fs-sm); margin: 4px 0; }
.insights-groups { display: flex; gap: 4px; border-bottom: 1px solid var(--ds-line); margin: 12px 0 8px; overflow-x: auto; }
.insights-groups button { background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 0; padding: 8px 14px; cursor: pointer; font-weight: 600; color: var(--ds-text-2); white-space: nowrap; }
.insights-groups button:hover { background: none; color: var(--ds-text); }
.insights-groups button[aria-selected="true"] { color: var(--ds-accent-text); border-bottom-color: var(--ds-accent); }
.insights-tabs { display: flex; gap: 6px; margin-bottom: 8px; flex-wrap: wrap; }
/* A group's own tabs choose which view is read; they do nothing else. The chosen one is tinted, not the filled
   primary of a button that acts: under the period's dark block and the groups' underline it read as a row of
   actions with one pressed (whole-review F-036). The markup (primary | ghost) is unchanged. */
.insights-tabs button { border-radius: 999px; }
.insights-tabs button.primary, .insights-tabs button.primary:hover { background: var(--ds-accent-soft); border-color: var(--ds-accent); color: var(--ds-accent-text); box-shadow: none; filter: none; }
/* The screen's row of a group's analyses is a segment (.lx-seg around .lx-chip, audit G1-56): the part draws it; the
   row only sits as wide as its items, with no gap of its own between them. */
.insights-tabs.lx-seg { display: inline-flex; gap: 0; margin-bottom: 8px; }
/* The kinds of number an answer holds, named: the words quiet, the badges after them. */
.insights-labels { margin: 0; font-size: var(--ds-fs-sm); color: var(--ds-text-2); }
/* Two kinds named side by side are two marks, not one word. */
.insights-labels .insights-badge + .insights-badge { margin-left: 4px; }
/* A figure tile inside a tab is as tall as what it says: the page's old floor for an `article` (235px, style.css)
   is a dashboard card's, and left half of every tile empty. */
.insights-panel article, #my-usage-root article { min-height: 0; }
/* A phone: the company and the time zone share a row, the period its own; the row of tabs scrolls sideways
   instead of taking three; and the line about how far back records go moves under the panel, so the first
   figures are on the first screen. */
@media (max-width: 600px) {
  #insights-root, .insights-place { display: flex; flex-direction: column; }
  #insights-root > .insights-hint, .insights-place > .insights-hint { order: 9; margin-top: var(--ds-space-3); }
  /* ... but the line that says which period a placed analysis uses stays under the period it is chosen in. */
  .insights-place > .insights-hint[data-insights-own-period] { order: 0; margin-top: 0; }
  .insights-toolbar { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px 10px; }
  .insights-toolbar label { display: flex; min-width: 0; }
  .insights-toolbar select, .insights-toolbar input { width: 100%; min-width: 0; }
  /* Company and zone first, the period under them, then (직접) the two days side by side and 적용. */
  .insights-toolbar > label:last-of-type { order: 1; }
  .insights-toolbar .insights-ranges { order: 2; grid-column: 1 / -1; justify-self: start; }
  .insights-toolbar > label:has(.ui-date) { order: 3; }
  .insights-toolbar > [data-insights-apply] { order: 4; grid-column: 1 / -1; justify-self: start; }
  .insights-groups { margin-top: var(--ds-space-2); }
  /* Every sub-tab stays in sight: the row wraps whole tabs onto a second line instead of scrolling one under a fade
     with nothing saying it goes on (consistency c3.78 at 390: Router › 진단's fourth tab, 일괄 처리 후보, cut). */
  .insights-tabs button { white-space: nowrap; }
}
.insights-panel { min-height: 120px; }
/* The figures being read take the tiles' own grid and height (insights-cost.css .insights-kinds), so the tiles
   land where their shapes were; a phone's tile is one short row. */
/* Four shapes at most to a row, as the four kinds: the label's full-width row keeps empty tracks from closing up. */
.insights-panel .ui-skeleton[data-skeleton="tiles"] { grid-template-columns: repeat(auto-fit, minmax(min(100%, max(220px, calc((100% - 3 * var(--ds-space-3)) / 4))), 1fr)); margin-top: var(--ds-space-2); }
.insights-panel .ui-skeleton[data-skeleton="tiles"] .ui-skeleton-label { margin-bottom: calc(-1 * var(--ds-space-2)); }
.insights-panel .ui-skeleton-tile { height: 163px; border-radius: var(--ds-radius); }
@media (max-width: 600px) { .insights-panel .ui-skeleton-tile { height: 92px; } }
@media (min-width: 1700px) { .insights-panel .ui-skeleton-tile { height: 190px; } }
.insights-envelope { display: grid; gap: 4px; margin-bottom: 8px; }
/* The clues a tab draws under its figures (view.clues): the same lines, parted from the figures over them. */
.insights-clues { margin-top: 8px; }
.insights-window { font-size: var(--ds-fs-xs); color: var(--ds-text-2); margin: 0; }
.insights-window > span { white-space: nowrap; }
.insights-state, .insights-missing, .insights-hidden, .insights-notice { margin: 0; padding: 6px 10px; border-radius: var(--ds-radius-xs); font-size: var(--ds-fs-sm); color: var(--ds-text); }
.insights-state { background: var(--ds-surface-2); }
.insights-state[data-state="forbidden"], .insights-state[data-state="failed"] { background: var(--ds-danger-soft); }
/* A tab's whole state is the shared frame (.ui-frame, style.css); only what insights' words add is here. */
/* ... and a failed read is the shared error frame in every part: the quiet body text, the room around it and
   a plain 다시 시도, as the frame of a list read elsewhere on the same page (notify-inbox.js). A danger edge on
   this button alone made one page show the same button in two shapes (router-diagnosis r2: 진단's frame above,
   기간별 분석 placed under it). */
/* An insights tab's state is the shared frame (style.css .ui-frame, 명세 6.8): a failure is told by its words. */
.ui-frame.insights-state { padding: 28px 20px; background: none; color: var(--ds-text-3); }
.insights-missing { background: var(--ds-unknown-soft); border-left: 3px dashed var(--ds-unknown); }
.insights-hidden { background: var(--ds-surface-2); color: var(--ds-text-2); }
.insights-notice { background: var(--ds-info-soft); }
/* A note's reason is part of its one sentence on a wide screen; its button is a phone's (below). */
.insights-more { display: none; }
/* A phone: a short sample and groups left out are each a short fact, side by side while they fit, and the reason
   opens under the fact by its button (the whole note is the button's target). The window and a warning that
   records are missing or deleted stay whole lines. The incidents tab's first row began at 801 of an 844 screen. */
@media (max-width: 600px) {
  .insights-envelope { display: flex; flex-wrap: wrap; }
  .insights-envelope > * { flex: 1 1 100%; }
  .insights-envelope > .insights-brief { flex: 0 1 auto; position: relative; padding: 4px 8px 4px 10px; }
  .insights-envelope > .insights-brief[data-open] { flex-basis: 100%; padding-bottom: 6px; }
  .insights-brief:not([data-open]) > .insights-why { display: none; }
  .insights-brief > .insights-why { display: block; color: var(--ds-text-2); }
  .insights-brief .insights-sep { display: none; }
  .insights-more { display: inline-block; width: 20px; height: 20px; margin: 0 0 0 4px; padding: 0; border: 0; border-radius: var(--ds-radius-xs); background: none; vertical-align: -5px; }
  /* No press shift (style.css button:active): a transform would make the button the box its target is laid in. */
  .insights-more:hover, .insights-more:active { background: none; transform: none; }
  .insights-more::before { content: ""; display: block; width: 100%; height: 100%; background: var(--ds-chevron) center / 12px no-repeat; transition: transform var(--ds-dur-fast, .12s) ease; }
  .insights-brief[data-open] .insights-more::before { transform: rotate(180deg); }
  .insights-more::after { content: ""; position: absolute; inset: 0; }
  .insights-brief[data-open] .insights-more::after { bottom: auto; height: 28px; }
}
.insights-badge { display: inline-block; font-size: var(--ds-fs-xs); font-weight: 600; padding: 1px 6px; border-radius: 999px; background: var(--ds-new-soft); color: var(--ds-new); }
/* 추정 is one shape wherever it is said: the caution chip a Gateway figure's head draws (.tag.amber, style.css) --
   one page showed the word as that chip and as this pill (cost-g6-r2). */
.insights-badge[data-label="estimated"] { padding: 3px 7px; border-radius: 4px; font-weight: 500; background: var(--ds-unknown-soft); color: var(--ds-unknown-text); outline: 1px dashed var(--ds-unknown); outline-offset: -1px; }
.insights-badge[data-label="synthetic"] { background: var(--ds-danger-soft); color: var(--ds-danger-text); }
.insights-badge[data-label="unmeasured"] { background: var(--ds-surface-2); color: var(--ds-text-2); }
.insights-unknown { color: var(--ds-text-3); font-style: normal; font-size: var(--ds-fs-xs); }
.insights-bars { margin: 8px 0; display: grid; gap: 6px; }
.insights-bar { display: grid; grid-template-columns: minmax(80px, 1fr) 3fr auto; gap: 8px; align-items: center; font-size: var(--ds-fs-xs); font-variant-numeric: tabular-nums; }
.insights-bar-track svg { width: 100%; height: 10px; }
.insights-bar-track rect, .insights-dist rect { fill: var(--ds-accent); }
.insights-spark polyline { fill: none; stroke: var(--ds-accent); stroke-width: 1.5; }
.insights-spark circle { fill: var(--ds-accent); }
.insights-spark .insights-spark-mark { stroke: var(--ds-text-2); stroke-width: 1; stroke-dasharray: 2 2; vector-effect: non-scaling-stroke; }
.insights-dist svg { width: 100%; height: 14px; }
.insights-dist line { stroke: var(--ds-text-2); stroke-width: 0.6; }
.insights-dist .insights-dist-median { stroke: var(--ds-danger); stroke-width: 1; }
/* A table here is the shared table (.table-wrap, style.css) with the same row: the sortable one is drawn inside
   the shared card (insights-chart.js); a tab's own table takes the same cell from these rules. */
.insights-table { width: 100%; border-collapse: collapse; font-size: var(--ds-fs-sm); text-align: left; font-variant-numeric: tabular-nums; }
.insights-table th { padding: 9px 14px; border-bottom: 1px solid var(--ds-line-strong); white-space: nowrap; }
.insights-table td { padding: 10px 14px; border-bottom: 1px solid var(--ds-line); vertical-align: middle; }
/* Its last cell is a figure or a sentence, never a row's action: it wraps (the shared .table-wrap keeps a last cell
   on one line for the action button). */
.table-wrap .insights-table td:last-child { white-space: normal; }
/* A column of figures (insights-chart.js `numeric`) is set to the right, header and cells, so the digits line up. */
.insights-table :is(th, td).insights-num { text-align: right; }
/* A row's 8% is its cells' (rf1, rm10): one on the row as well stacked to 15%, a grey – at 4.28:1 (UR32-1). */
.insights-table tbody tr:hover td { background: color-mix(in srgb,var(--ds-accent) 8%,transparent); }
/* A column's head is its name: the press that sorts by it is the name itself, with no box of its own in the
   head row, and the column sorted by says which way. */
.insights-table th button { padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; font: inherit; color: inherit; }
.insights-table th button:hover { text-decoration: underline; }
.insights-table th:is([aria-sort="ascending"], [aria-sort="descending"]) button::after { content: "▲"; margin-left: 4px; font-size: .7em; vertical-align: 1px; }
.insights-table th[aria-sort="descending"] button::after { content: "▼"; }
.insights-row-open { cursor: pointer; }
.insights-row-open:hover td { background: color-mix(in srgb,var(--ds-accent) 8%,transparent); }
.insights-pager { display: flex; gap: 8px; align-items: center; justify-content: flex-end; margin: 6px 0; font-size: var(--ds-fs-xs); }
/* No wider than its place: the input gives way down to its 220px (WebKit's own width for it, 300px, ended right of a 360 and a 320 page). */
.insights-search { display: inline-flex; gap: 6px; align-items: center; max-width: 100%; margin-bottom: 6px; font-size: var(--ds-fs-xs); white-space: nowrap; }
.insights-search input { width: auto; min-width: 220px; margin: 0; }
.insights-detail { border: 1px solid var(--ds-line); border-radius: var(--ds-radius-s); padding: 10px; margin-top: 8px; }
.insights-loading { color: var(--ds-text-2); font-size: var(--ds-fs-sm); }
/* A menu tab's placed insights (insights.js PLACES): a section at the end of that tab's page. */
.insights-place { margin-top: 20px; padding: 18px 19px; border: 1px solid var(--ds-line); border-radius: var(--ds-radius); background: var(--ds-surface); }
.insights-place:empty { display: none; }
/* A placed card's head (review gw-mcp-g8-r2 must_fix 4: three grey lines of one size over the table). The period the
   figures are of is the line read first, in the text's own colour; what the choice above means for it (a period other
   than the screen's, how far back records go) is the quieter note; a short sample keeps its box. Nothing is left out. */
.insights-place .insights-window { color: var(--ds-text); font-size: var(--ds-fs-sm); font-variant-numeric: tabular-nums; }
.insights-place > .insights-hint[data-insights-own-period] { color: var(--ds-text-3); }
/* 직전 기간 대비, one row a kind, on a screen that shows the amounts above it (insights-cost.js beside). */
.insights-beside { margin: 0 0 var(--ds-space-4); }
.insights-beside caption { padding: 0 0 var(--ds-space-2); text-align: left; font-size: var(--ds-fs-md); font-weight: 700; color: var(--ds-text); }
.insights-beside td:first-child { color: var(--ds-text-2); }
.insights-beside tbody tr:last-child td { border-bottom: 0; }
.insights-beside .insights-delta { white-space: nowrap; }
/* No record is said quieter than an amount (the screen's own table above draws it so). */
.insights-beside .insights-none { color: var(--ds-text-3); }
/* Five columns do not fit a phone: a row is the kind over its four values, two to a line, each with its column's
   name (the header row is not drawn; a screen reader still reads the cells in order). */
@media (max-width: 600px) {
  .insights-table.insights-beside, .insights-beside caption, .insights-beside tbody { display: block; }
  .insights-beside thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .insights-beside tbody tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--ds-space-3); padding: var(--ds-space-2) 0; border-bottom: 1px solid var(--ds-line); }
  .insights-beside tbody tr:last-child { border-bottom: 0; }
  .insights-beside tbody td { display: block; padding: 0; border: 0; }
  .insights-beside tbody td:first-child { grid-column: 1 / -1; color: var(--ds-text); font-weight: 600; }
  .insights-table.insights-beside td.insights-num { text-align: left; }
  .insights-beside td[data-label]::before { content: attr(data-label) " "; color: var(--ds-text-2); font-size: var(--ds-fs-xs); }
  /* A long change (an amount under a cent, nine places) wraps in its own half instead of running under the next value. */
  .insights-beside .insights-delta { white-space: normal; }
}

