<template>
  <div class="page">
    <div class="grid-bg"></div>

    <!-- ─── HEADER ─── -->
    <header>
      <div class="header-left">
        <div>
          <div class="datetime">{{ currentDay }} {{ currentTime }}</div>
          <div style="display:flex;align-items:center;gap:6px;margin-top:4px">
            <div class="status-dot"></div>
            <span class="status-label">系统运行中</span>
          </div>
        </div>
      </div>
      <div class="header-title">洁 净 车 间 看 板</div>
      <div class="header-right">
        <!-- <span class="shift-badge">白班</span> -->
        <div class="user-badge">
          <div class="user-avatar">张</div>
          <span style="font-size:13px">张三</span>
        </div>
      </div>
    </header>

    <!-- ─── KPI ROW ─── -->
    <div class="kpi-row">
      <div class="kpi-card cyan">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="kpi-icon">📦</div>
        <div class="kpi-label">今日工序报工量</div>
        <div class="kpi-value">3470</div>
        <div class="kpi-trend up">↑ 较昨日 +12.4%</div>
        <div class="kpi-progress"><div class="kpi-progress-fill" style="width:86%"></div></div>
      </div>
      <div class="kpi-card teal">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="kpi-icon">✅</div>
        <div class="kpi-label">产品合格率</div>
        <div class="kpi-value">98.6<span style="font-size:0.55em">%</span></div>
        <div class="kpi-trend up">↑ 较上周 +0.3%</div>
        <div class="kpi-progress"><div class="kpi-progress-fill" style="width:98.6%"></div></div>
      </div>
      <div class="kpi-card amber">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="kpi-icon">🎯</div>
        <div class="kpi-label">今日目标完成率</div>
        <div class="kpi-value">86<span style="font-size:0.55em">%</span></div>
        <div class="kpi-trend neutral">目标 4000件</div>
        <div class="kpi-progress"><div class="kpi-progress-fill" style="width:86%"></div></div>
      </div>
      <div class="kpi-card blue">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="kpi-icon">⚙️</div>
        <div class="kpi-label">设备综合利用率</div>
        <div class="kpi-value">91<span style="font-size:0.55em">%</span></div>
        <div class="kpi-trend up">↑ 较昨日 +2.1%</div>
        <div class="kpi-progress"><div class="kpi-progress-fill" style="width:91%"></div></div>
      </div>
      <div class="kpi-card coral">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="kpi-icon">⚠️</div>
        <div class="kpi-label">今日故障次数</div>
        <div class="kpi-value">2</div>
        <div class="kpi-trend down">↑ 较昨日 +1次</div>
        <div class="kpi-progress"><div class="kpi-progress-fill" style="width:20%"></div></div>
      </div>
    </div>

    <!-- ─── MAIN GRID ─── -->
    <div class="main-grid">

      <!-- LEFT: Donut + Target -->
      <div class="panel">
        <div class="scan-line"></div>
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="panel-title">产品种类占比</div>

        <div class="donut-wrap">
          <div id="donutChart" style="width:100%;height:100%"></div>
          <div class="donut-center">
            <div class="donut-center-num">3470</div>
            <div class="donut-center-label">总产量</div>
          </div>
        </div>

        <div style="margin-top:4px">
          <div class="legend-row" v-for="item in donutLegend" :key="item.name">
            <div class="legend-dot" :style="{background: item.color}"></div>
            <span class="legend-name">{{ item.name }}</span>
            <span class="legend-pct">{{ item.pct }}</span>
            <span class="legend-val">{{ item.val }}</span>
          </div>
        </div>

        <div class="target-section">
          <div class="panel-title" style="margin-top:1vh;margin-bottom:0.8vh">今日生产进度</div>
          <div class="target-header"><span>已完成 3470件</span><span>目标 4000件</span></div>
          <div class="target-bar"><div class="target-fill" style="width:86.75%"></div></div>
          <div class="target-header"><span>班次进度</span><span>当前班 74%</span></div>
          <div class="target-bar"><div class="target-fill" style="width:74%;background:linear-gradient(90deg,#ffc107,#ff9800)"></div></div>
          <div class="target-header"><span>周计划</span><span>本周 62%</span></div>
          <div class="target-bar"><div class="target-fill" style="width:62%;background:linear-gradient(90deg,#bb86fc,#4fc3f7)"></div></div>
        </div>
      </div>

      <!-- CENTER: Realtime Chart -->
      <div class="panel panel-flex">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-tr"></div>
        <div class="corner-deco corner-bl"></div><div class="corner-deco corner-br"></div>
        <div class="panel-title">
          设备实时检测曲线
          <span style="color:#00e5ff;font-size:11px;margin-left:4px">{{ activeWorkstation }}</span>
          <div class="panel-badge">每5s采集 · 实时更新</div>
        </div>

        <div class="chart-toolbar">
          <div
            v-for="ws in workstations"
            :key="ws"
            class="device-tab"
            :class="{ active: activeWorkstation === ws }"
            @click="switchWorkstation(ws)"
          >{{ ws }}</div>
          <span class="chart-info">实时刷新 ● LIVE</span>
        </div>

        <div class="realtime-wrap">
          <div id="realtimeChart" style="width:100%;height:100%"></div>
        </div>

        <div class="chart-stats">
          <div class="chart-stat">
            <div class="chart-stat-label">当前值</div>
            <div class="chart-stat-val" style="color:#00e5ff">{{ rtStats.current }}</div>
          </div>
          <div class="chart-stat">
            <div class="chart-stat-label">均值</div>
            <div class="chart-stat-val" style="color:#1de9b6">{{ rtStats.avg }}</div>
          </div>
          <div class="chart-stat">
            <div class="chart-stat-label">峰值</div>
            <div class="chart-stat-val" style="color:#ffc107">{{ rtStats.max }}</div>
          </div>
          <div class="chart-stat">
            <div class="chart-stat-label">谷值</div>
            <div class="chart-stat-val" style="color:#5a8a9f">{{ rtStats.min }}</div>
          </div>
        </div>
      </div>

      <!-- RIGHT: Personnel -->
      <div class="panel">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="panel-title">
          人员周产量
          <div class="panel-badge" style="margin-left:auto">本周排行</div>
        </div>

        <div class="person-row" v-for="(p, i) in persons" :key="p.name">
          <div class="person-meta">
            <span class="person-name" style="display:flex;align-items:center;gap:6px">
              <span :style="{fontFamily:'monospace',fontSize:'10px',color:i<3?p.color:'#3a6070',width:'16px',display:'inline-block'}">{{ String(i+1).padStart(2,'0') }}</span>
              {{ p.name }}
            </span>
            <span class="person-val" :style="{color: p.color}">{{ p.val }}</span>
          </div>
          <div class="person-bar">
            <div class="person-fill" :style="{width:(p.val/maxPersonVal*100)+'%',background:p.color,opacity:i===0?1:0.7}"></div>
          </div>
        </div>
      </div>

    </div>

    <!-- ─── BOTTOM ROW ─── -->
    <div class="bottom-grid">

      <!-- Equipment Status -->
      <div class="panel">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="panel-title">设备运行状态</div>
        <table class="equip-table">
          <thead>
            <tr>
              <th>设备名称</th>
              <th>状态</th>
              <th>利用率</th>
              <th>今日产量</th>
              <th>运行时长</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="eq in equipments" :key="eq.name">
              <td style="color:#00e5ff">{{ eq.name }}</td>
              <td>
                <span class="status-tag" :class="eq.statusClass">
                  <span class="status-dot-sm" :class="eq.dotClass"></span>{{ eq.statusText }}
                </span>
              </td>
              <td>
                <div style="display:inline-flex;align-items:center;gap:4px">
                  <div class="util-bar"><div class="util-fill" :style="{width:eq.util+'%',background:eq.utilColor}"></div></div>
                  {{ eq.util }}%
                </div>
              </td>
              <td :style="{color: eq.statusClass==='status-err'?'#ff6b6b':'#cce8f4'}">{{ eq.output }}</td>
              <td style="color:#5a8a9f">{{ eq.duration }}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- Hourly Output Chart -->
      <div class="panel panel-flex">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="panel-title">今日每小时产量</div>
        <div class="hourly-wrap">
          <div id="hourlyChart" style="width:100%;height:100%"></div>
        </div>
      </div>

      <!-- Stock List -->
      <div class="panel">
        <div class="corner-deco corner-tl"></div><div class="corner-deco corner-br"></div>
        <div class="panel-title">
          库存列表
          <div class="panel-badge" style="margin-left:auto">实时库存</div>
        </div>
        <table class="equip-table">
          <thead>
            <tr>
              <th>物料名称</th>
              <th>工段</th>
              <th>库存量</th>
              <th>状态</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="s in stockList" :key="s.name">
              <td style="color:#cce8f4">{{ s.name }}</td>
              <td style="color:#5a8a9f">{{ s.dept }}</td>
              <td style="font-family:'Orbitron',monospace" :style="{color: s.statusColor}">{{ s.count }}</td>
              <td>
                <span class="status-tag" :class="s.statusClass">
                  <span class="status-dot-sm" :class="s.dotClass"></span>{{ s.statusText }}
                </span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>

    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'JiejingDept',
  data() {
    return {
      currentTime: '',
      currentDay: '',
      dayInterval: null,
      rtInterval: null,
      rtChart: null,
      charts: [],
      rtLabels: [],
      rtValues: [],
      rtStats: { current: '24.3', avg: '22.1', max: '29.7', min: '16.2' },

      activeWorkstation: '拉单丝',
      workstations: ['拉单丝', '一次复丝', '二次复丝', '洗棒'],

      donutLegend: [
        { name: '倒像器', color: '#4fc3f7', pct: '41.0%', val: 1423 },
        { name: '直板',   color: '#69f0ae', pct: '27.7%', val: 960 },
        { name: '光锥',   color: '#ffc107', pct: '20.6%', val: 714 },
        { name: '其他',   color: '#ff6b6b', pct: '9.8%',  val: 340 },
        { name: '光棒',   color: '#bb86fc', pct: '0.9%',  val: 33 },
      ],

      persons: [
        { name: '张三', val: 920, color: '#4fc3f7' },
        { name: '李四', val: 796, color: '#ff6b6b' },
        { name: '王五', val: 734, color: '#00e5ff' },
        { name: '赵六', val: 661, color: '#ffc107' },
        { name: '钱七', val: 594, color: '#bb86fc' },
        { name: '孙八', val: 508, color: '#4fc3f7' },
        { name: '周九', val: 438, color: '#ff6b6b' },
        { name: '吴十', val: 360, color: '#69f0ae' },
      ],

      equipments: [
        { name: '拉单丝-01',   statusClass: 'status-run',  statusText: '运行中', dotClass: 'run-dot',  util: 94, utilColor: '#1de9b6', output: 924, duration: '7h12m' },
        { name: '拉单丝-02',   statusClass: 'status-run',  statusText: '运行中', dotClass: 'run-dot',  util: 88, utilColor: '#1de9b6', output: 876, duration: '7h08m' },
        { name: '一次复丝-01', statusClass: 'status-idle', statusText: '待机',   dotClass: 'idle-dot', util: 71, utilColor: '#ffc107', output: 712, duration: '5h45m' },
        { name: '二次复丝-01', statusClass: 'status-run',  statusText: '运行中', dotClass: 'run-dot',  util: 95, utilColor: '#1de9b6', output: 958, duration: '7h15m' },
        { name: '洗棒-01',     statusClass: 'status-err',  statusText: '故障',   dotClass: 'err-dot',  util: 32, utilColor: '#ff6b6b', output: 324, duration: '2h41m' },
      ],

      stockList: [
        { name: '倒像器毛坯',   dept: '拉单丝',   count: 1423, statusClass: 'status-run',  statusText: '充足', dotClass: 'run-dot',  statusColor: '#1de9b6' },
        { name: '直板半成品',   dept: '一次复丝', count: 960,  statusClass: 'status-run',  statusText: '充足', dotClass: 'run-dot',  statusColor: '#1de9b6' },
        { name: '光锥坯料',     dept: '二次复丝', count: 714,  statusClass: 'status-run',  statusText: '正常', dotClass: 'run-dot',  statusColor: '#4fc3f7' },
        { name: '光棒原材料',   dept: '洗棒',     count: 128,  statusClass: 'status-idle', statusText: '偏低', dotClass: 'idle-dot', statusColor: '#ffc107' },
        { name: '倒像器成品',   dept: '拉单丝',   count: 836,  statusClass: 'status-run',  statusText: '充足', dotClass: 'run-dot',  statusColor: '#1de9b6' },
        { name: '直板成品',     dept: '一次复丝', count: 54,   statusClass: 'status-err',  statusText: '告急', dotClass: 'err-dot',  statusColor: '#ff6b6b' },
        { name: '光锥成品',     dept: '二次复丝', count: 392,  statusClass: 'status-run',  statusText: '正常', dotClass: 'run-dot',  statusColor: '#4fc3f7' },
      ],
    };
  },
  computed: {
    maxPersonVal() {
      return Math.max(...this.persons.map(p => p.val));
    },
  },
  mounted() {
    this.showTime();
    this.dayInterval = setInterval(this.showTime, 1000);
    this.$nextTick(() => {
      this.initDonut();
      this.initRealtime();
      this.initHourly();
    });
    window.addEventListener('resize', this.resizeCharts);
  },
  beforeDestroy() {
    clearInterval(this.dayInterval);
    clearInterval(this.rtInterval);
    window.removeEventListener('resize', this.resizeCharts);
    this.charts.forEach(c => c && c.dispose());
  },
  methods: {
    showTime() {
      const now = new Date();
      const pad = n => String(n).padStart(2, '0');
      this.currentTime = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
      this.currentDay = `${now.getFullYear()}年${pad(now.getMonth() + 1)}月${pad(now.getDate())}日`;
    },

    switchWorkstation(ws) {
      this.activeWorkstation = ws;
    },

    resizeCharts() {
      this.charts.forEach(c => c && c.resize());
    },

    initDonut() {
      const el = document.getElementById('donutChart');
      if (!el) return;
      const chart = echarts.init(el);
      this.charts.push(chart);
      chart.setOption({
        backgroundColor: 'transparent',
        tooltip: {
          backgroundColor: '#071e32',
          borderColor: '#00e5ff',
          borderWidth: 1,
          textStyle: { color: '#cce8f4' },
          formatter: params => `${params.name}: ${params.value}件 (${params.percent.toFixed(1)}%)`,
        },
        series: [{
          type: 'pie',
          radius: ['68%', '85%'],
          data: this.donutLegend.map(d => ({
            name: d.name, value: d.val,
            itemStyle: { color: d.color },
          })),
          label: { show: false },
          itemStyle: { borderWidth: 2, borderColor: '#041525' },
        }],
      });
    },

    initRealtime() {
      const el = document.getElementById('realtimeChart');
      if (!el) return;

      const pad = n => String(n).padStart(2, '0');
      const base = new Date();
      base.setHours(0, 12, 0, 0);
      for (let i = 0; i < 80; i++) {
        const t = new Date(base.getTime() + i * 18000);
        this.rtLabels.push(`${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`);
        const noise = Math.sin(i * 0.4) * 3 + Math.sin(i * 0.7) * 2 + Math.sin(i * 0.13) * 4 + (Math.random() - 0.5) * 2;
        this.rtValues.push(parseFloat((22 + noise).toFixed(1)));
      }
      this.calcRtStats();

      this.rtChart = echarts.init(el);
      this.charts.push(this.rtChart);
      this.rtChart.setOption({
        backgroundColor: 'transparent',
        animation: false,
        grid: { left: '3%', right: '3%', top: '8%', bottom: '15%', containLabel: true },
        tooltip: {
          trigger: 'axis',
          backgroundColor: '#071e32',
          borderColor: '#00e5ff',
          borderWidth: 1,
          textStyle: { color: '#00e5ff' },
          axisPointer: { lineStyle: { color: 'rgba(0,229,255,0.3)' } },
        },
        xAxis: {
          type: 'category',
          data: this.rtLabels,
          boundaryGap: false,
          axisLabel: { color: '#3a6070', fontSize: 9, interval: 9 },
          axisLine: { lineStyle: { color: 'rgba(0,229,255,0.1)' } },
          splitLine: { lineStyle: { color: 'rgba(0,229,255,0.05)' } },
        },
        yAxis: {
          type: 'value',
          min: 5, max: 35,
          axisLabel: { color: '#3a6070', fontSize: 9 },
          axisLine: { lineStyle: { color: 'rgba(0,229,255,0.1)' } },
          splitLine: { lineStyle: { color: 'rgba(0,229,255,0.06)' } },
        },
        series: [{
          type: 'line',
          data: this.rtValues,
          smooth: 0.4,
          symbol: 'none',
          lineStyle: { color: '#00e5ff', width: 1.5 },
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(0,229,255,0.12)' },
              { offset: 1, color: 'rgba(0,229,255,0.01)' },
            ]),
          },
        }],
      });

      this.rtInterval = setInterval(() => {
        const newVal = parseFloat((22 + Math.sin(Date.now() * 0.001) * 3 + (Math.random() - 0.5) * 3).toFixed(1));
        this.rtValues.push(newVal);
        this.rtValues.shift();
        const now = new Date();
        this.rtLabels.push(`${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`);
        this.rtLabels.shift();
        this.calcRtStats();
        this.rtChart.setOption({
          xAxis: { data: this.rtLabels },
          series: [{ data: this.rtValues }],
        });
      }, 1000);
    },

    calcRtStats() {
      const vals = this.rtValues;
      if (!vals.length) return;
      const current = vals[vals.length - 1];
      const avg = (vals.reduce((a, b) => a + b, 0) / vals.length).toFixed(1);
      const max = Math.max(...vals).toFixed(1);
      const min = Math.min(...vals).toFixed(1);
      this.rtStats = {
        current: typeof current === 'number' ? current.toFixed(1) : current,
        avg, max, min,
      };
    },

    initHourly() {
      const el = document.getElementById('hourlyChart');
      if (!el) return;
      const hours = ['8时', '9时', '10时', '11时', '12时', '13时', '14时', '15时', '16时'];
      const vals = [312, 428, 445, 410, 180, 430, 452, 441, 372];
      const chart = echarts.init(el);
      this.charts.push(chart);
      chart.setOption({
        backgroundColor: 'transparent',
        animation: false,
        grid: { left: '3%', right: '3%', top: '8%', bottom: '10%', containLabel: true },
        tooltip: {
          trigger: 'axis',
          backgroundColor: '#071e32',
          borderColor: '#00e5ff',
          borderWidth: 1,
          textStyle: { color: '#cce8f4' },
          formatter: params => `${params[0].axisValue}: ${params[0].value}件`,
        },
        xAxis: {
          type: 'category',
          data: hours,
          axisLabel: { color: '#3a6070', fontSize: 10 },
          axisLine: { lineStyle: { color: 'rgba(0,229,255,0.1)' } },
          splitLine: { show: false },
        },
        yAxis: {
          type: 'value',
          axisLabel: { color: '#3a6070', fontSize: 9 },
          axisLine: { lineStyle: { color: 'rgba(0,229,255,0.1)' } },
          splitLine: { lineStyle: { color: 'rgba(0,229,255,0.06)' } },
        },
        series: [{
          type: 'bar',
          data: vals.map((v, i) => ({
            value: v,
            itemStyle: {
              color: i === vals.length - 1 ? 'rgba(0,229,255,0.7)' : 'rgba(0,229,255,0.25)',
              borderColor: i === vals.length - 1 ? '#00e5ff' : 'rgba(0,229,255,0.4)',
              borderWidth: 1,
              borderRadius: [3, 3, 0, 0],
            },
          })),
        }],
      });
    },
  },
};
</script>

<style scoped>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Noto+Sans+SC:wght@300;400;500;700&display=swap');

/* ─── PAGE ROOT: flex column, strict 100vh ─── */
.page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-sizing: border-box;
  padding: 0 1vw 0.5vh;
  font-family: 'Noto Sans SC', 'Microsoft Yahei', sans-serif;
  background: #020d1a;
  color: #cce8f4;
  background-image:
    radial-gradient(ellipse 80% 40% at 50% 0%, rgba(0,80,120,0.3) 0%, transparent 70%),
    linear-gradient(180deg, #020d1a 0%, #031422 100%);
}

.grid-bg {
  position: fixed; inset: 0;
  background-image:
    linear-gradient(rgba(0,229,255,0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,229,255,0.03) 1px, transparent 1px);
  background-size: 40px 40px;
  pointer-events: none;
  z-index: 0;
}

/* ─── HEADER ─── */
header {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0.8vh 0.5vw 0.6vh;
  border-bottom: 1px solid rgba(0,229,255,0.07);
  margin-bottom: 0.8vh;
}

.header-left { display: flex; align-items: center; }
.datetime { font-family: 'Orbitron', monospace; font-size: 1.1vh; color: #5a8a9f; letter-spacing: 1px; }
.status-dot { width: 0.8vh; height: 0.8vh; border-radius: 50%; background: #1de9b6; box-shadow: 0 0 8px #1de9b6; animation: pulse 2s infinite; }
.status-label { font-size: 1vh; color: #1de9b6; letter-spacing: 1px; }

.header-title {
  text-align: center;
  font-family: 'Orbitron', monospace;
  font-size: 2.2vw;
  font-weight: 900;
  letter-spacing: 0.5vw;
  color: #00e5ff;
  text-shadow: 0 0 30px rgba(0,229,255,0.5), 0 0 60px rgba(0,229,255,0.2);
  position: relative;
}
.header-title::before, .header-title::after {
  content: '';
  position: absolute; top: 50%;
  width: 2vw; height: 1px;
  background: linear-gradient(90deg, transparent, #00e5ff);
}
.header-title::before { right: calc(100% + 0.8vw); }
.header-title::after  { left:  calc(100% + 0.8vw); background: linear-gradient(90deg, #00e5ff, transparent); }

.header-right { display: flex; align-items: center; justify-content: flex-end; gap: 1vw; }
.user-badge {
  display: flex; align-items: center; gap: 0.5vw;
  background: #071e32; border: 1px solid rgba(0,229,255,0.18);
  border-radius: 2vh; padding: 0.3vh 1vw 0.3vh 0.5vw;
  font-size: 1.2vh;
}
.user-avatar {
  width: 2.4vh; height: 2.4vh; border-radius: 50%;
  background: linear-gradient(135deg, #00e5ff, #1de9b6);
  display: flex; align-items: center; justify-content: center;
  font-size: 1vh; font-weight: 700; color: #020d1a;
}
.shift-badge {
  font-size: 1vh; color: #ffc107; border: 1px solid rgba(255,193,7,0.3);
  border-radius: 4px; padding: 0.2vh 0.6vw; letter-spacing: 1px;
}

/* ─── KPI ROW ─── */
.kpi-row {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.7vw;
  margin-bottom: 0.8vh;
}

.kpi-card {
  background: #071e32;
  border: 1px solid rgba(0,229,255,0.18);
  border-radius: 8px;
  padding: 1.2vh 1.2vw;
  position: relative;
  overflow: hidden;
  transition: border-color 0.3s;
}
.kpi-card::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
}
.kpi-card.cyan::before  { background: linear-gradient(90deg, transparent, #00e5ff, transparent); }
.kpi-card.teal::before  { background: linear-gradient(90deg, transparent, #1de9b6, transparent); }
.kpi-card.amber::before { background: linear-gradient(90deg, transparent, #ffc107, transparent); }
.kpi-card.coral::before { background: linear-gradient(90deg, transparent, #ff6b6b, transparent); }
.kpi-card.blue::before  { background: linear-gradient(90deg, transparent, #4fc3f7, transparent); }
.kpi-card:hover { border-color: rgba(0,229,255,0.4); }

.kpi-icon {
  width: 3.2vh; height: 3.2vh; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.6vh; margin-bottom: 0.7vh;
}
.kpi-card.cyan  .kpi-icon { background: rgba(0,229,255,0.1); }
.kpi-card.teal  .kpi-icon { background: rgba(29,233,182,0.1); }
.kpi-card.amber .kpi-icon { background: rgba(255,193,7,0.1); }
.kpi-card.coral .kpi-icon { background: rgba(255,107,107,0.1); }
.kpi-card.blue  .kpi-icon { background: rgba(79,195,247,0.1); }

.kpi-label { font-size: 1vh; color: #5a8a9f; letter-spacing: 1px; margin-bottom: 0.4vh; }
.kpi-value {
  font-family: 'Orbitron', monospace;
  font-size: 2.6vh; font-weight: 700;
  line-height: 1; margin-bottom: 0.5vh;
}
.kpi-card.cyan  .kpi-value { color: #00e5ff; }
.kpi-card.teal  .kpi-value { color: #1de9b6; }
.kpi-card.amber .kpi-value { color: #ffc107; }
.kpi-card.coral .kpi-value { color: #ff6b6b; }
.kpi-card.blue  .kpi-value { color: #4fc3f7; }

.kpi-trend { font-size: 1vh; display: flex; align-items: center; gap: 4px; }
.kpi-trend.up      { color: #1de9b6; }
.kpi-trend.down    { color: #ff6b6b; }
.kpi-trend.neutral { color: #5a8a9f; }

.kpi-progress {
  position: absolute; bottom: 0; left: 0; right: 0;
  height: 3px; background: rgba(255,255,255,0.05);
  border-radius: 0 0 8px 8px;
}
.kpi-progress-fill { height: 100%; border-radius: 0 0 8px 8px; }
.cyan  .kpi-progress-fill { background: #00e5ff; }
.teal  .kpi-progress-fill { background: #1de9b6; }
.amber .kpi-progress-fill { background: #ffc107; }
.coral .kpi-progress-fill { background: #ff6b6b; }
.blue  .kpi-progress-fill { background: #4fc3f7; }

/* ─── MAIN GRID: fills remaining height ─── */
.main-grid {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 22vw 1fr 23vw;
  gap: 0.7vw;
  margin-bottom: 0.8vh;
}

/* ─── PANELS ─── */
.panel {
  background: #071e32;
  border: 1px solid rgba(0,229,255,0.18);
  border-radius: 8px;
  padding: 1.2vh 1.2vw;
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
  height: 100%;
}

/* Center & hourly chart panels use flex column so charts can flex-grow */
.panel-flex {
  display: flex;
  flex-direction: column;
}

.panel-title {
  flex-shrink: 0;
  font-size: 1.1vh;
  color: #00e5ff;
  letter-spacing: 2px;
  margin-bottom: 1vh;
  display: flex;
  align-items: center;
  gap: 0.5vw;
}
.panel-title::before {
  content: '';
  width: 3px; height: 1.4vh;
  background: #00e5ff;
  border-radius: 2px;
  box-shadow: 0 0 8px #00e5ff;
  flex-shrink: 0;
}

.panel-badge {
  margin-left: auto;
  font-size: 0.9vh; color: #5a8a9f;
  background: #0a2540;
  border: 1px solid rgba(0,229,255,0.07);
  border-radius: 4px; padding: 0.2vh 0.5vw;
  white-space: nowrap;
}

/* ─── DONUT ─── */
.donut-wrap { position: relative; width: 16vh; height: 16vh; margin: 0 auto 1vh; flex-shrink: 0; }
.donut-center {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  pointer-events: none;
}
.donut-center-num { font-family: 'Orbitron', monospace; font-size: 1.8vh; color: #00e5ff; }
.donut-center-label { font-size: 0.9vh; color: #5a8a9f; margin-top: 2px; }

.legend-row {
  display: flex; align-items: center; gap: 0.4vw;
  padding: 0.45vh 0;
  border-bottom: 1px solid rgba(0,229,255,0.07);
  font-size: 1.1vh;
}
.legend-row:last-child { border-bottom: none; }
.legend-dot { width: 0.7vh; height: 0.7vh; border-radius: 2px; flex-shrink: 0; }
.legend-name { flex: 1; color: #5a8a9f; }
.legend-pct { color: #cce8f4; font-weight: 500; }
.legend-val { color: #5a8a9f; font-size: 1vh; width: 3vw; text-align: right; }

/* ─── TARGET PROGRESS ─── */
.target-section { margin-top: 0.8vh; }
.target-header { display: flex; justify-content: space-between; margin-bottom: 0.4vh; font-size: 1vh; color: #5a8a9f; }
.target-bar { height: 0.6vh; background: rgba(255,255,255,0.05); border-radius: 3px; overflow: hidden; margin-bottom: 0.8vh; }
.target-fill {
  height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, #00e5ff, #1de9b6);
  position: relative; overflow: hidden;
  transition: width 1.5s ease;
}
.target-fill::after {
  content: '';
  position: absolute; top: 0; left: -100%; width: 60%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
  animation: shimmer 2s infinite;
}

/* ─── REALTIME CHART ─── */
.chart-toolbar {
  flex-shrink: 0;
  display: flex; align-items: center; gap: 0.5vw;
  margin-bottom: 0.8vh;
}
.device-tab {
  padding: 0.3vh 0.7vw; border-radius: 4px; cursor: pointer;
  border: 1px solid rgba(0,229,255,0.07);
  color: #5a8a9f; font-size: 1vh; letter-spacing: 1px;
  transition: all 0.2s; white-space: nowrap;
}
.device-tab.active {
  background: rgba(0,229,255,0.15); border-color: #00e5ff; color: #00e5ff;
}
.chart-info { margin-left: auto; color: #3a6070; font-size: 0.9vh; letter-spacing: 1px; }

/* realtime wrap grows to fill center panel */
.realtime-wrap { flex: 1; min-height: 0; position: relative; }

.chart-stats {
  flex-shrink: 0;
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 0.5vw; margin-top: 0.8vh;
}
.chart-stat {
  background: #0a2540; border-radius: 6px;
  padding: 0.6vh 0.5vw; text-align: center;
}
.chart-stat-label { font-size: 0.9vh; color: #5a8a9f; margin-bottom: 0.3vh; }
.chart-stat-val { font-family: 'Orbitron', monospace; font-size: 1.3vh; }

/* ─── PERSONNEL ─── */
.person-row { margin-bottom: 0.9vh; }
.person-meta { display: flex; justify-content: space-between; margin-bottom: 0.3vh; font-size: 1.1vh; }
.person-name { color: #cce8f4; }
.person-val { font-family: 'Orbitron', monospace; font-size: 1.1vh; }
.person-bar { height: 0.7vh; background: rgba(255,255,255,0.06); border-radius: 4px; overflow: hidden; }
.person-fill { height: 100%; border-radius: 4px; }

/* ─── BOTTOM GRID: fixed height ─── */
.bottom-grid {
  flex-shrink: 0;
  height: 26vh;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0.7vw;
}

/* ─── EQUIPMENT TABLE ─── */
.equip-table { width: 100%; border-collapse: collapse; font-size: 1.1vh; }
.equip-table th {
  color: #5a8a9f; font-weight: 400; letter-spacing: 1px;
  padding: 0.5vh 0.5vw; border-bottom: 1px solid rgba(0,229,255,0.07);
  text-align: left; font-size: 0.9vh;
}
.equip-table td { padding: 0.6vh 0.5vw; border-bottom: 1px solid rgba(0,229,255,0.07); }
.equip-table tr:last-child td { border-bottom: none; }
.equip-table tr:hover td { background: rgba(0,229,255,0.07); }

.status-tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 0.2vh 0.5vw; border-radius: 4px; font-size: 0.9vh;
}
.status-run  { background: rgba(29,233,182,0.12); color: #1de9b6; border: 1px solid rgba(29,233,182,0.3); }
.status-idle { background: rgba(255,193,7,0.12);  color: #ffc107; border: 1px solid rgba(255,193,7,0.3); }
.status-err  { background: rgba(255,107,107,0.12); color: #ff6b6b; border: 1px solid rgba(255,107,107,0.3); }
.status-dot-sm { width: 5px; height: 5px; border-radius: 50%; display: inline-block; }
.run-dot  { background: #1de9b6; box-shadow: 0 0 4px #1de9b6; animation: pulse 2s infinite; }
.idle-dot { background: #ffc107; }
.err-dot  { background: #ff6b6b; box-shadow: 0 0 4px #ff6b6b; animation: pulse 1s infinite; }

.util-bar { height: 4px; background: rgba(255,255,255,0.06); border-radius: 2px; width: 4vw; display: inline-block; overflow: hidden; vertical-align: middle; }
.util-fill { height: 100%; border-radius: 2px; }

/* ─── HOURLY CHART: grows in panel-flex ─── */
.hourly-wrap { flex: 1; min-height: 0; position: relative; }


/* ─── CORNER DECORATIONS ─── */
.corner-deco {
  position: absolute; width: 12px; height: 12px;
  border-color: #00e5ff; opacity: 0.5;
}
.corner-tl { top: 0; left: 0; border-top: 1px solid; border-left: 1px solid; }
.corner-tr { top: 0; right: 0; border-top: 1px solid; border-right: 1px solid; }
.corner-bl { bottom: 0; left: 0; border-bottom: 1px solid; border-left: 1px solid; }
.corner-br { bottom: 0; right: 0; border-bottom: 1px solid; border-right: 1px solid; }

/* ─── SCAN LINE ─── */
.scan-line {
  position: absolute; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(0,229,255,0.2), transparent);
  animation: scan 4s linear infinite; pointer-events: none;
}

@keyframes scan    { from { top: 0; } to { top: 100%; } }
@keyframes pulse   { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes shimmer { to { left: 200%; } }
</style>
