.report-banner { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: 16px; background: linear-gradient(135deg, var(--blue-strong) 0%, var(--blue-dark) 100%); color: #fff; padding: 24px 26px 22px; border-radius: 14px; margin: 16px 0; }
.report-banner h1 { margin: 0; font-size: clamp(22px, 3vw, 32px); line-height: 1.2; letter-spacing: -.5px; text-transform: uppercase; font-weight: 800; }
.report-banner h1 em { color: #ffc38a; font-style: normal; }
.banner-sub { margin: 10px 0 5px; font-size: 13px; color: #dfeefd; max-width: 720px; line-height: 1.5; }
.banner-meta { margin: 0; font: 600 12px 'DM Mono', monospace; color: #bcd4f2; text-transform: uppercase; letter-spacing: .4px; }
.banner-illustration { flex-shrink: 0; align-self: stretch; max-width: 100px; min-height: 70px; }
.banner-logo-mark { width: 100%; height: 100%; object-fit: contain; object-position: right center; display: block; }

/* Two stacked .stat-row blocks (Aset Tower / Aset Span) instead of one — each block's
   own small uppercase label doubles as a section divider, and card padding/font-size
   below are trimmed slightly from their original single-row sizing so the doubled
   section doesn't cost twice the vertical space. */
.asset-stats { display: flex; flex-direction: column; gap: 8px; margin: 0 0 16px; }
.asset-stats-label { color: var(--muted); font: 700 10px 'DM Mono', monospace; text-transform: uppercase; letter-spacing: .4px; margin: 0 0 5px 2px; }
.stat-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.stat-card { position: relative; border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px 9px; text-align: left; background: #fff; transition: box-shadow .15s ease, transform .15s ease; }
.stat-card:hover { box-shadow: 0 6px 16px rgba(16,24,40,.08); transform: translateY(-1px); }
.stat-card-top { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
.stat-icon { display: grid; place-items: center; width: 16px; height: 16px; border-radius: 6px; flex-shrink: 0; }
.stat-icon svg { width: 9px; height: 9px; }
.stat-card .stat-label { display: block; font: 700 8.5px 'DM Mono', monospace; letter-spacing: .3px; }
.stat-card strong { display: block; font-size: 19px; font-weight: 800; margin-bottom: 1px; line-height: 1; }
.stat-card small { display: block; color: var(--muted); font-size: 8.5px; text-transform: uppercase; letter-spacing: .3px; }
/* Gauge sits BESIDE its card's text (count + %), not stacked below it — a stacked
   layout left each card noticeably taller than the Total card next to it for no real
   gain, since the gauge's own half-circle shape already leaves empty space under it
   that a side-by-side row absorbs instead of wasting vertically. */
.stat-card-body { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.stat-card-text { min-width: 0; flex: 1 1 auto; }
/* Segmented speedometer gauge (see gaugeSvg() in tower-dashboard.js) replacing the old
   linear .stat-bar/.stat-bar-fill strip — the SVG itself carries the fill colors
   (var(--critical) etc., picked per-tier inside gaugeSvg()), so unlike the old bar there
   are no separate .stat-card.<tier> .stat-bar-fill color rules left to keep here. */
.stat-gauge { flex-shrink: 0; }
.gauge-svg { display: block; width: 72px; height: auto; }
.stat-card.total { border-color: var(--line); background: var(--blue-soft); }
.stat-card.total .stat-label, .stat-card.total strong { color: var(--teal); }
.stat-card.total .stat-icon { background: rgba(255,255,255,.6); color: var(--teal); }
.stat-card.critical { border-color: #f6c8ca; background: #fdecec; }
.stat-card.critical .stat-label, .stat-card.critical strong { color: var(--critical); }
.stat-card.critical .stat-icon { background: rgba(255,255,255,.6); color: var(--critical); }
.stat-card.warning { border-color: #f9dfab; background: #fff4e0; }
.stat-card.warning .stat-label, .stat-card.warning strong { color: var(--warning-ink); }
.stat-card.warning .stat-icon { background: rgba(255,255,255,.6); color: var(--warning-ink); }
.stat-card.moderate { border-color: #c4dbf5; background: #eaf2fb; }
.stat-card.moderate .stat-label, .stat-card.moderate strong { color: var(--moderate); }
.stat-card.moderate .stat-icon { background: rgba(255,255,255,.6); color: var(--moderate); }
.stat-card.safe { border-color: #bfe6cf; background: #e8f7ef; }
.stat-card.safe .stat-label, .stat-card.safe strong { color: var(--safe); }
.stat-card.safe .stat-icon { background: rgba(255,255,255,.6); color: var(--safe); }

/* Summary text + the "Klasifikasi jarak" legend now share ONE box (previously two
   separate boxes stacked with their own margins/borders/shadows) — a plain divider line
   between them instead of a second full card is what actually saves the space, since
   the legend's own content (4 short dot+label pairs) never needed a card of its own. */
.summary-panel { padding: 12px 16px; border: 1px solid var(--line); border-radius: 10px; background: #fff; margin-bottom: 16px; box-shadow: 0 1px 2px rgba(16,24,40,.04); }
/* Overrides .mini-legend's own standalone-pill look (border/radius/background/shadow/
   margin — see hotspot-tower.css, still used as-is by anything else) now that it's
   nested inside .summary-panel instead of sitting on its own. */
.summary-panel .mini-legend { border: 0; border-radius: 0; background: none; box-shadow: none; margin: 0; padding: 0; }

.report-panel { margin-bottom: 16px; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); background: #fff; box-shadow: 0 1px 2px rgba(16,24,40,.04); }
.panel-title-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: linear-gradient(135deg, var(--blue-strong), var(--moderate)); color: #fff; padding: 11px 16px; font: 700 12px 'DM Mono', monospace; text-transform: uppercase; letter-spacing: .5px; }
/* Holds two separate .chart-mode-toggle groups side by side (asset type + bar/pie mode
   — see the Rekap kategori aset panel) instead of one toggle needing to encode both
   choices into a single control. */
.panel-title-toggles { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; flex-shrink: 0; }
.chart-mode-toggle { display: flex; gap: 3px; background: rgba(255,255,255,.16); border-radius: 999px; padding: 3px; flex-shrink: 0; }
.chart-mode-btn { border: 0; background: transparent; color: rgba(255,255,255,.85); font: 700 9px 'DM Mono', monospace; text-transform: uppercase; letter-spacing: .3px; padding: 5px 10px; border-radius: 999px; cursor: pointer; }
.chart-mode-btn.active { background: #fff; color: var(--blue-strong); }
.mini-map-mode-select { flex-shrink: 0; padding: 5px 10px; border: 0; border-radius: 999px; background: #fff; color: var(--blue-strong); font: 700 9px 'DM Mono', monospace; text-transform: uppercase; letter-spacing: .3px; cursor: pointer; }

.chart-body { padding: 16px; }
.chart-empty { padding: 6px 0; color: var(--muted); font-size: 13px; }

.bar-group { padding: 13px 15px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); margin-bottom: 10px; }
.bar-group:last-child { margin-bottom: 0; }
.bar-group-title { display: flex; align-items: center; justify-content: space-between; gap: 10px; font: 700 11px 'DM Mono', monospace; color: var(--ink); text-transform: uppercase; letter-spacing: .3px; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.bar-group-total { color: var(--muted); font-weight: 600; text-transform: none; letter-spacing: 0; }
.bar-row { display: grid; grid-template-columns: 92px 1fr 42px; align-items: center; gap: 10px; margin-bottom: 8px; }
.bar-row:last-child { margin-bottom: 0; }
.bar-label { display: flex; align-items: center; font-size: 11px; font-weight: 700; color: var(--ink); white-space: nowrap; }
.bar-track { position: relative; height: 16px; background: #fff; border: 1px solid var(--line); border-radius: 4px; overflow: hidden; }
.bar-fill { display: block; height: 100%; width: 0%; border-radius: 3px; min-width: 3px; transition: width .5s ease; }
.bar-value { text-align: right; font: 700 12px 'DM Mono', monospace; color: var(--ink); white-space: nowrap; }

.mini-map-layout { display: flex; align-items: flex-start; justify-content: center; gap: 18px; flex-wrap: wrap; }
.mini-map-svg { width: auto; height: auto; max-width: 100%; max-height: 450px; display: block; margin: 0; border: 1px solid var(--line); border-radius: 8px; flex: 0 0 auto; }
/* Flows horizontally (the base .chart-legend's own flex-wrap row — see
   renderMiniMap() in tower-dashboard.js, which no longer adds .chart-legend-vertical
   here) instead of one item per line — a fixed narrow 320px column was what forced 7
   legend entries into a tall single-file stack regardless of how much horizontal room
   the panel actually had. flex-basis 100% makes it claim the map's full row once
   .mini-map-layout wraps it below the map (its usual spot once the map itself is wide),
   so items can actually spread across multiple per line instead of staying cramped. */
.mini-map-legend { flex: 1 1 100%; margin-top: 10px; justify-content: center; }

.chart-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 14px; margin-top: 10px; font: 600 10px 'DM Mono', monospace; color: var(--ink); }
.chart-legend-item { display: inline-flex; align-items: center; white-space: nowrap; }
.chart-legend-item strong { margin-left: 4px; }
.chart-legend-item em { font-style: normal; color: var(--muted); margin-left: 4px; }
.chart-legend-vertical { flex-direction: column; align-items: flex-start; gap: 5px; margin-top: 10px; }

/* Rendered once above the grid (see renderPieChart() in tower-dashboard.js) instead of
   a full count+percentage legend repeated identically on every one of the 3 ULTG cards
   below — those numbers now sit directly on each pie's own slices, so this shared strip
   only needs to carry the color-to-tier mapping. */
.pie-shared-legend { justify-content: center; margin: 0 0 12px; }
/* min-width bumped from 190 to 340 — a dual-donut card (Tower + Span side by side, see
   pieDonutSvg()/renderPieChart() in tower-dashboard.js) needs roughly double a
   single-donut card's own room, or the two circles would get squeezed onto separate
   lines instead of actually sitting side by side. */
.pie-chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 14px; }
.pie-card { text-align: center; padding: 16px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); }
.pie-card-title { font: 700 11px 'DM Mono', monospace; color: var(--ink); text-transform: uppercase; letter-spacing: .3px; margin-bottom: 10px; }
.pie-chart-svg { width: 152px; height: 152px; }
/* Tower donut on the left, Span donut on the right of the same card — replaces a single
   centered donut that left most of a wide card's width empty regardless of which
   dataset (Tower or Span) the old toggle had picked. Wraps to stacked only if the card
   itself ever gets narrower than both circles can fit side by side. */
.pie-dual-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; }

/* Detail tower/span critical now reuse Inspection Report's own collapsible
   .target-ultg-*/.target-table look (see renderDetailGroupWrapper()/
   renderDetailTableShell() in tower-dashboard.js) instead of a bespoke dashboard
   table — .detail-panel just needs a little breathing room around that borrowed
   component, no table-specific rules of its own left to keep here. */
.detail-panel .chart-body { padding: 14px 16px; }
/* .target-list (hotspot-tower.css) caps at max-height:520px + overflow-y:auto for
   Inspection Report's own Target Inspeksi table — the dashboard's detail tables reuse
   that class for its flex/gap layout but, since every ULTG group here defaults expanded
   (see expandedJalurGroups in tower-dashboard.js), want the opposite: no inner
   scrollbar, ever — the panel just grows to fit everything and the page itself scrolls. */
.detail-panel .target-list { max-height: none; overflow-y: visible; }
.detail-group-count { font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--muted); margin-left: 6px; }
/* Jarak Terdekat's distance + its "which point/span" reference (.detail-group-count)
   sit in the same cell — under auto table layout that column can get squeezed
   narrower than their combined natural width by the (usually much wider) Titik
   column next to it, wrapping "104 m" and "T194-T195" onto two overlapping lines.
   Forcing this cell to stay on one line lets auto-layout do what it already does
   elsewhere: widen the column to fit instead of wrapping. */
.nowrap-cell { white-space: nowrap; }
/* .jalur-detail-table is .target-table (see hotspot-tower.css) plus its own column
   hints — Titik is deliberately NOT nowrap (contrast Jarak Terdekat above): its
   comma-separated point/span list can run long, and letting it wrap onto multiple
   lines within a generously-sized column is what keeps the table from ever needing a
   horizontal scrollbar, instead of forcing the whole table wider to fit one line. */
.jalur-detail-table .jalur-detail-rank { width: 30px; text-align: center; color: var(--muted); }
.jalur-detail-table .jalur-detail-name { width: 16%; }
.jalur-detail-table .jalur-detail-titik { width: 30%; white-space: normal; line-height: 1.6; }
.jalur-detail-table .jalur-detail-distance { width: 15%; }
.jalur-detail-table .jalur-detail-duration { width: 13%; }
.jalur-detail-table .jalur-detail-lastseen { width: 14%; }
.jalur-detail-table .jalur-detail-frp { width: 90px; }
/* Red-ellipse highlight for the word CRITICAL/Critical inside a Detail table group
   header's count label (e.g. "1 sirkit, 4 tower critical") — see highlightCriticalWord()
   in tower-dashboard.js. */
.critical-pill { display: inline-block; padding: 1px 8px; border-radius: 999px; background: var(--critical); color: #fff; font-weight: 700; text-transform: uppercase; font-size: 11px; letter-spacing: .3px; }
.jalur-detail-table td.jalur-detail-name strong { font-size: 11.5px; }
/* Each Titik in "Detail tower critical" deep-links to that point's own Map View
   location (see mapLink() in tower-dashboard.js) — styled like a normal inline text
   link (not a button/pill) since several sit comma-separated in one cell. */
.jalur-titik-link { color: var(--blue-strong); text-decoration: none; font: 600 11px 'DM Mono', monospace; }
.jalur-titik-link:hover { text-decoration: underline; }

.report-footer { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; background: linear-gradient(135deg, var(--blue-strong), var(--blue-dark)); color: #eaf3ff; padding: 13px 18px; border-radius: 10px; font: 500 12px 'DM Mono', monospace; margin-top: 4px; }
.report-footer strong { color: #ffc38a; }
.report-footer a { color: #fff; }

.trend-sub { margin: 0 0 8px; color: var(--muted); font-size: 11px; line-height: 1.5; }
/* Rendered once (see renderTrendDashboard() in dashboard-trend.js) instead of repeated
   on all 4 trend cards — left-aligned under the description text, not centered like the
   generic .chart-legend default, so it reads as this section's own shared key rather
   than a caption belonging to any one chart below it. */
.trend-shared-legend { justify-content: flex-start; margin: 0 0 12px; }
/* No explicit align-items — grid's own default (stretch) makes .trend-big and
   .trend-small-stack the same height (the row's tallest column), which is what lets
   .trend-insights below the big chart absorb the leftover vertical space instead of
   leaving it blank. */
.trend-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 14px; }
.trend-big { display: flex; flex-direction: column; gap: 14px; }
.trend-small-stack { display: flex; flex-direction: column; gap: 10px; }
.trend-card { border: 1px solid var(--line); border-radius: 10px; background: var(--paper); padding: 10px 12px 8px; flex: 0 0 auto; }
.trend-card-title { font: 700 10px 'DM Mono', monospace; text-transform: uppercase; letter-spacing: .3px; color: var(--ink); margin-bottom: 5px; }
.trend-chart-wrap { width: 100%; }
.trend-chart-svg { width: 100%; height: auto; display: block; }
.trend-card-big .trend-chart-svg { max-height: 300px; }
.trend-card-small .trend-chart-svg { max-height: 150px; }

.trend-insights { flex: 1 1 auto; min-height: 110px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); padding: 12px 14px; display: flex; flex-direction: column; }
.trend-insights-title { display: flex; align-items: center; gap: 6px; font: 700 10px 'DM Mono', monospace; text-transform: uppercase; letter-spacing: .3px; color: var(--ink); margin-bottom: 8px; }
.trend-insights-title .ai-badge { font: 700 8px 'DM Mono', monospace; color: #fff; background: var(--blue-strong); padding: 2px 6px; border-radius: 999px; letter-spacing: .3px; }
.trend-insights-list { margin: 0; padding-left: 18px; color: var(--ink); font-size: 12px; line-height: 1.55; flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; gap: 4px; }
.trend-insights-list li { padding-bottom: 8px; border-bottom: 1px dashed var(--line); }
.trend-insights-list li:last-child { padding-bottom: 0; border-bottom: none; }
.trend-insights .chart-empty { margin: auto; padding: 0; }

@media (max-width: 900px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .bar-row { grid-template-columns: 80px 1fr 36px; }
  .banner-illustration { display: none; }
  .trend-grid { grid-template-columns: 1fr; }
}
