<template>
  <div class="home-page">
    <div class="canvas" :class="{ 'is-left-closed': !leftOpen, 'is-right-closed': !rightOpen }">

      <header class="topbar">
        <div class="topbar-left"></div>
        <div class="topbar-center">
          <div class="model-title">{{ modelCenterStore.activeModelName }}</div>
        </div>
        <div class="topbar-right">
          <div class="status-chip">
            <div class="status-chip-track">
              <span class="countdown-label">距竣工</span>
            </div>
            <div class="countdown-value">
              <span class="countdown-days">{{ countdownDays }}</span>
              <span class="countdown-days-unit">天</span>
              <span class="countdown-time">{{ countdownTime }}</span>
            </div>
          </div>
        </div>
      </header>

      <section class="model-stage">
        <div class="model-shell"></div>
        <ModelPlaceholder show-construct-tree-button />
      </section>

      <button class="cards-toggle cards-toggle-left" type="button" aria-label="展开/收起左侧卡片" @click="leftOpen = !leftOpen">{{ leftOpen ? "◀" : "▶" }}</button>
      <button class="cards-toggle cards-toggle-right" type="button" aria-label="展开/收起右侧卡片" @click="rightOpen = !rightOpen">{{ rightOpen ? "▶" : "◀" }}</button>

      <aside class="cards cards-left" v-show="leftOpen">
        <section class="card">
          <header class="card-header"><div class="card-title">合同与利润</div></header>
          <div class="card-body">
            <div class="metrics">
              <div class="metric"><div class="metric-icon" data-icon="percent"></div><div><div class="metric-value">{{ formatPercent(mock.budgetProfitRate) }}</div><div class="metric-label">施工预算利润率</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="currency"></div><div><div class="metric-value">{{ formatMoney(mock.currentContractAmount) }}</div><div class="metric-label">当前合同额</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="currency"></div><div><div class="metric-value">{{ formatMoney(mock.bidContractAmount) }}</div><div class="metric-label">中标合同额</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="percent"></div><div><div class="metric-value">{{ formatPercent(mock.postBidBudgetProfitRate) }}</div><div class="metric-label">标后预算利润率</div></div></div>
            </div>
          </div>
        </section>

        <section class="card">
          <header class="card-header"><div class="card-title">进度管理</div><div class="seg"><button class="segbtn" :class="{ 'is-on': progressValueGrain === 'month' }" @click="progressValueGrain = 'month'">月</button><button class="segbtn" :class="{ 'is-on': progressValueGrain === 'quarter' }" @click="progressValueGrain = 'quarter'">季</button><button class="segbtn" :class="{ 'is-on': progressValueGrain === 'year' }" @click="progressValueGrain = 'year'">年</button></div></header>
          <div class="card-body">
            <div class="metrics">
              <div class="metric"><div class="metric-icon" data-icon="calendar"></div><div><div class="metric-value">{{ formatMoney(progressValueData.planValue) }}</div><div class="metric-label">计划产值</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="check"></div><div><div class="metric-value">{{ formatMoney(progressValueData.actualValue) }}</div><div class="metric-label">实际产值</div></div></div>
            </div>
            <div class="progressline">
              <div class="progressline-top"><div class="progressline-label">产值完成率</div><div class="progressline-value">{{ formatPercent(valueRate) }}</div></div>
              <div class="bar"><div class="bar-fill" :style="{ width: `${Math.max(0, Math.min(1, valueRate)) * 100}%` }"></div></div>
            </div>
          </div>
        </section>

        <section class="card">
          <header class="card-header"><div class="card-title">支出合同管理</div></header>
          <div class="card-body">
            <div class="expense-metrics">
              <div class="metric-row"><div class="metric-icon" data-icon="percent"></div><div><div class="metric-value">{{ formatPercent(mock.settlementRate) }}</div><div class="metric-label">结算比率</div></div></div>
              <div class="metric-row"><div class="metric-icon" data-icon="currency"></div><div><div class="metric-value">{{ formatMoney(mock.supplementAgreementAmount) }}</div><div class="metric-label">补充协议金额</div></div></div>
            </div>
            <div class="expense-breakdown">
              <div class="ring">
                <svg viewBox="0 0 120 120" class="ring-svg"><circle class="ring-bg" cx="60" cy="60" r="46"></circle><g class="ring-rot"><circle v-for="seg in ringSegments" :key="seg.name" class="ring-seg" cx="60" cy="60" r="46" :style="seg.style"></circle></g></svg>
                <div class="ring-center"><div class="ring-center-title">费用构成</div><div class="ring-center-sub">占比</div></div>
              </div>
              <div class="ring-legend"><div class="ring-item" v-for="row in expenseBreakdown" :key="row.name"><span class="ring-swatch" :style="{ background: row.color }"></span><span>{{ row.name }}</span><span>{{ row.pct }}%</span></div></div>
            </div>
          </div>
        </section>
      </aside>

      <aside class="cards cards-right" v-show="rightOpen">
        <section class="card">
          <header class="card-header"><div class="card-title">营收产值</div></header>
          <div class="card-body">
            <div class="metrics">
              <div class="metric"><div class="metric-icon" data-icon="currency"></div><div><div class="metric-value">{{ formatMoney(mock.changeClaimAmount) }}</div><div class="metric-label">变更索赔额</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="percent"></div><div><div class="metric-value">{{ formatPercent(mock.changeApprovalRate) }}</div><div class="metric-label">变更批复率</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="delta"></div><div><div class="metric-value">{{ formatPercent(mock.revenueValueRatioDiffRate) }}</div><div class="metric-label">营收产值比差异率</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="percent"></div><div><div class="metric-value">{{ formatPercent(mock.revenueValueRatio) }}</div><div class="metric-label">营收产值比</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="target"></div><div><div class="metric-value">{{ formatPercent(mock.dataCompleteness) }}</div><div class="metric-label">数据完整性</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="percent"></div><div><div class="metric-value">{{ formatPercent(mock.profitDiffRate) }}</div><div class="metric-label">财务利润差异率</div></div></div>
            </div>
          </div>
        </section>

        <section class="card">
          <header class="card-header"><div class="card-title">进度管理</div><div class="seg"><button class="segbtn" :class="{ 'is-on': progressTimeGrain === 'month' }" @click="progressTimeGrain = 'month'">月</button><button class="segbtn" :class="{ 'is-on': progressTimeGrain === 'quarter' }" @click="progressTimeGrain = 'quarter'">季</button><button class="segbtn" :class="{ 'is-on': progressTimeGrain === 'year' }" @click="progressTimeGrain = 'year'">年</button></div></header>
          <div class="card-body">
            <div class="metrics">
              <div class="metric"><div class="metric-icon" data-icon="sum"></div><div><div class="metric-value">{{ formatMoney(progressTimeData.cumValue) }}</div><div class="metric-label">开累产值</div></div></div>
              <div class="metric"><div class="metric-icon" data-icon="time"></div><div><div class="metric-value">{{ progressTimeData.elapsedDays.toLocaleString("zh-CN") }}天</div><div class="metric-label">已消耗工期</div></div></div>
            </div>
            <div class="progressline">
              <div class="progressline-top"><div class="progressline-label">产值完成率</div><div class="progressline-value">{{ formatPercent(cumRate) }}</div></div>
              <div class="bar"><div class="bar-fill" :style="{ width: `${Math.max(0, Math.min(1, cumRate)) * 100}%` }"></div></div>
            </div>
          </div>
        </section>

        <section class="card">
          <header class="card-header"><div class="card-title">物资管理</div><div class="seg"><button class="segbtn" :class="{ 'is-on': materialsGrain === 'month' }" @click="materialsGrain = 'month'">月</button><button class="segbtn" :class="{ 'is-on': materialsGrain === 'quarter' }" @click="materialsGrain = 'quarter'">季</button><button class="segbtn" :class="{ 'is-on': materialsGrain === 'year' }" @click="materialsGrain = 'year'">年</button></div></header>
          <div class="card-body">
            <div class="barchart">
              <div class="barrow" v-for="row in materialsRows" :key="row.key" :data-kind="row.key"><div class="barname">{{ row.name }}</div><div class="bartrack"><div class="barval" :style="{ width: `${(row.value / materialsMax) * 100}%` }"></div></div><div class="barlabel">{{ row.value.toLocaleString("zh-CN") }}吨</div></div>
            </div>
          </div>
        </section>
      </aside>
    </div>
  </div>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
import ModelPlaceholder from "../../components/model-placeholder/index.vue";
import { useModelCenterStore } from "../../stores/modelCenter.js";

const modelCenterStore = useModelCenterStore();

const mock = {
  finishDate: "2027-12-30",
  budgetProfitRate: 0.153,
  currentContractAmount: 162500000,
  bidContractAmount: 148800000,
  postBidBudgetProfitRate: 0.128,
  planValue: 6380000,
  actualValue: 5710000,
  cumValue: 98200000,
  elapsedDays: 476,
  settlementRate: 0.62,
  supplementAgreementAmount: 3600000,
  changeClaimAmount: 2850000,
  changeApprovalRate: 0.74,
  revenueValueRatioDiffRate: -0.013,
  revenueValueRatio: 0.986,
  dataCompleteness: 0.912,
  profitDiffRate: 0.027,
  materials: { received: 2350, issued: 2112, consumed: 1843, settled: 1520, stock: 538 },
};

const expenseBreakdown = [
  { name: "设备租赁", pct: 0.2, color: "#6e7d96" },
  { name: "物资购销", pct: 44.3, color: "#156cff" },
  { name: "施工协作分包", pct: 43.3, color: "#2cc8ff" },
  { name: "拌合", pct: 1.5, color: "#2f8f2f" },
  { name: "临设分包", pct: 0.6, color: "#d48806" },
  { name: "其他", pct: 9.9, color: "#6b5cff" },
];

const countdownDays = ref("--");
const countdownTime = ref("--:--");
const leftOpen = ref(true);
const rightOpen = ref(true);
const progressValueGrain = ref("month");
const progressTimeGrain = ref("month");
const materialsGrain = ref("month");

let timer = null;

const progressValueMap = {
  month: { planValue: 6380000, actualValue: 5710000 },
  quarter: { planValue: 18900000, actualValue: 17260000 },
  year: { planValue: 72400000, actualValue: 67800000 },
};

const progressTimeMap = {
  month: { cumValue: 98200000, elapsedDays: 476 },
  quarter: { cumValue: 101600000, elapsedDays: 492 },
  year: { cumValue: 114300000, elapsedDays: 538 },
};

const materialsMap = {
  month: { received: 2350, issued: 2112, consumed: 1843, settled: 1520, stock: 538 },
  quarter: { received: 7190, issued: 6810, consumed: 5995, settled: 5240, stock: 1084 },
  year: { received: 29100, issued: 27540, consumed: 24120, settled: 20800, stock: 3840 },
};

const progressValueData = computed(() => progressValueMap[progressValueGrain.value]);
const progressTimeData = computed(() => progressTimeMap[progressTimeGrain.value]);
const materialsData = computed(() => materialsMap[materialsGrain.value]);

const valueRate = computed(() => (progressValueData.value.planValue > 0 ? progressValueData.value.actualValue / progressValueData.value.planValue : 0));
const cumRate = computed(() => (mock.currentContractAmount > 0 ? progressTimeData.value.cumValue / mock.currentContractAmount : 0));
const materialsRows = computed(() => [
  { key: "received", name: "收料", value: materialsData.value.received },
  { key: "issued", name: "领料", value: materialsData.value.issued },
  { key: "consumed", name: "消耗", value: materialsData.value.consumed },
  { key: "settled", name: "结算", value: materialsData.value.settled },
  { key: "stock", name: "库存", value: materialsData.value.stock },
]);
const materialsMax = computed(() => Math.max(...materialsRows.value.map((row) => row.value), 1));

const ringSegments = computed(() => {
  const r = 46;
  const C = 2 * Math.PI * r;
  const total = expenseBreakdown.reduce((sum, row) => sum + row.pct, 0);
  let offset = 0;
  return expenseBreakdown.map((row) => {
    const ratio = row.pct / total;
    const len = C * ratio;
    const seg = {
      name: row.name,
      style: {
        stroke: row.color,
        strokeDasharray: `${len.toFixed(1)} ${(C - len).toFixed(1)}`,
        strokeDashoffset: `${(-offset).toFixed(1)}`,
      },
    };
    offset += len;
    return seg;
  });
});

function clamp(n, min, max) {
  return Math.min(max, Math.max(min, n));
}

function formatMoney(value) {
  const abs = Math.abs(value);
  if (abs >= 100000000) return `${(value / 100000000).toFixed(2)}亿`;
  if (abs >= 10000) return `${(value / 10000).toFixed(2)}万`;
  return `${value.toFixed(2)}元`;
}

function formatPercent(value) {
  return `${(value * 100).toFixed(1)}%`;
}

function updateCountdown() {
  const end = new Date(`${mock.finishDate}T00:00:00`);
  const now = new Date();
  const diffMs = Math.max(0, end.getTime() - now.getTime());
  const totalMinutes = Math.floor(diffMs / 60000);
  const days = Math.floor(totalMinutes / (24 * 60));
  const hours = Math.floor((totalMinutes - days * 24 * 60) / 60);
  const minutes = totalMinutes % 60;
  countdownDays.value = String(days);
  countdownTime.value = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
}

onMounted(() => {
  updateCountdown();
  timer = setInterval(updateCountdown, 30000);
});

onBeforeUnmount(() => {
  if (timer) clearInterval(timer);
});
</script>

<style scoped>
.home-page {
  --text: rgba(245, 252, 255, 0.92);
  --muted: rgba(223, 241, 246, 0.72);
  --panel: rgba(18, 29, 35, 0.9);
  --panel-soft: rgba(16, 25, 31, 0.8);
  --accent: #08c7bc;
  --accent2: #20e2d5;
  --line: rgba(42, 190, 182, 0.34);
  --line-soft: rgba(42, 190, 182, 0.2);
  --bar-track: rgba(255, 255, 255, 0.12);
  --bar-fill: linear-gradient(90deg, #0eb7ff, #1ce0c5);
  --font-cn: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", sans-serif;
  --font-num: "DIN Alternate", "Bahnschrift", "Segoe UI", "Arial Narrow", sans-serif;
  font-family: var(--font-cn);
}

* {
  box-sizing: border-box;
}

.canvas {
  position: relative;
  width: 100%;
  min-height: 100vh;
  overflow: hidden;
  border-radius: 24px;
  border: 1px solid rgba(98, 191, 206, 0.34);
  background: radial-gradient(circle at 50% 30%, #bcc9d6 0%, #b2c3d2 60%, #a8b8c9 100%);
  box-shadow: inset 0 0 0 8px rgba(214, 230, 241, 0.55);
}

.topbar {
  position: absolute;
  inset: 0 0 auto;
  height: 92px;
  padding: 18px 20px 0;
  z-index: 30;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  align-items: flex-start;
}

.topbar-left,
.topbar-center,
.topbar-right {
  display: flex;
  align-items: flex-start;
}

.topbar-left {
  gap: 10px;
}

.topbar-center {
  justify-content: center;
  padding-top: 8px;
}

.topbar-right {
  justify-content: flex-end;
  padding-right: 6px;
  margin-right: 100px;
}

.model-title {
  font-size: 26px;
  letter-spacing: 1px;
  font-weight: 700;
  color: rgba(255, 128, 52, 0.95);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

.status-chip {
  position: relative;
  min-width: 220px;
  display: grid;
  gap: 4px;
  padding: 9px 14px 10px;
  border-radius: 16px;
  border: 1px solid rgba(103, 204, 216, 0.32);
  background: linear-gradient(180deg, rgba(16, 45, 57, 0.9), rgba(14, 31, 42, 0.86));
  box-shadow: 0 18px 36px rgba(4, 20, 31, 0.32);
  overflow: hidden;
}

.status-chip-track {
  height: 18px;
  border-radius: 10px;
  margin-bottom:10px;
}

.countdown-label {
  font-size: 12px;
  color: rgba(220, 238, 244, 0.78);
  font-weight: 800;
  line-height: 1;
}

.countdown-value {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font-weight: 900;
  font-family: var(--font-num);
  padding-left: 2px;
}

.countdown-days {
  font-size: 22px;
  color: #f2fbff;
  line-height: 1;
}

.countdown-days-unit {
  font-size: 12px;
  color: rgba(203, 229, 236, 0.85);
}

.countdown-time {
  font-size: 18px;
  color: var(--accent2);
  line-height: 1;
  text-shadow: 0 0 18px rgba(32, 226, 213, 0.26);
}

.model-stage {
  position: absolute;
  inset: 0;
}

.model-shell {
  position: absolute;
  inset: 0;
  background: radial-gradient(900px 600px at 50% 50%, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0));
}

.cards-toggle {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 21;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  border: 1px solid rgba(97, 203, 213, 0.3);
  background: linear-gradient(180deg, rgba(17, 45, 56, 0.95), rgba(13, 29, 39, 0.9));
  color: rgba(202, 236, 244, 0.92);
  cursor: pointer;
}

.cards-toggle-left {
  left: 360px;
}

.cards-toggle-right {
  right: 360px;
}

.canvas.is-left-closed .cards-toggle-left {
  left: 24px;
}

.canvas.is-right-closed .cards-toggle-right {
  right: 24px;
}

.cards {
  position: absolute;
  top: 110px;
  width: 320px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.cards-left {
  left: 24px;
}

.cards-right {
  right: 24px;
}

.card {
  border-radius: 14px;
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(13, 30, 39, 0.95), rgba(28, 43, 52, 0.9));
  box-shadow: 0 16px 30px rgba(6, 16, 24, 0.35), inset 0 0 0 1px rgba(26, 121, 121, 0.16);
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(180deg, rgba(4, 128, 123, 0.86), rgba(5, 93, 98, 0.8));
}

.card-title {
  font-size: 15px;
  font-weight: 600;
  color: #d4f7ff;
  letter-spacing: 0.5px;
  font-family: var(--font-cn);
}

.card-body {
  padding: 10px 12px 10px;
}

.seg {
  display: inline-flex;
  border-radius: 999px;
  padding: 3px;
  background: rgba(0, 44, 54, 0.8);
  border: 1px solid rgba(98, 200, 211, 0.2);
}

.segbtn {
  border: 0;
  background: transparent;
  color: rgba(210, 236, 241, 0.8);
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 999px;
  font-weight: 600;
  font-size: 12px;
  font-family: var(--font-cn);
}

.segbtn.is-on {
  background: rgba(0, 170, 232, 0.86);
  color: #d8f8ff;
  box-shadow: 0 0 0 1px rgba(65, 233, 229, 0.3) inset;
}

.metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.metric,
.metric-row {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid rgba(76, 181, 194, 0.18);
  background: linear-gradient(180deg, rgba(31, 46, 55, 0.86), rgba(24, 38, 47, 0.86));
}

.metric-row {
  margin-top: 10px;
}

.metric-icon {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(19, 201, 194, 0.55);
  background: rgba(4, 70, 81, 0.8);
  color: #00d5d0;
  flex: 0 0 auto;
}

.metric-icon[data-icon] {
  font-size: 0;
}

.metric-icon[data-icon]::before {
  content: "";
  width: 16px;
  height: 16px;
  background: currentColor;
  -webkit-mask: var(--metric-icon-mask) no-repeat center / contain;
  mask: var(--metric-icon-mask) no-repeat center / contain;
}

.metric-icon[data-icon="percent"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Ccircle%20cx='7'%20cy='7'%20r='2.2'%20fill='black'/%3E%3Ccircle%20cx='17'%20cy='17'%20r='2.2'%20fill='black'/%3E%3Cpath%20d='M7%2017L17%207'%20stroke='black'%20stroke-width='2.4'%20stroke-linecap='round'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="currency"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20fill='black'%20d='M8%203l4%206%204-6h2l-5%207h4v2h-5v2h5v2h-5v5h-2v-5H7v-2h5v-2H7v-2h4L6%203h2z'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="calendar"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20fill='black'%20d='M7%202h2v2h6V2h2v2h2a2%202%200%200%201%202%202v14a3%203%200%200%201-3%203H6a3%203%200%200%201-3-3V6a2%202%200%200%201%202-2h2V2zm14%208H5v10a1%201%200%200%200%201%201h14a1%201%200%200%200%201-1V10zM6%206a1%201%200%200%200-1%201v1h16V7a1%201%200%200%200-1-1H6z'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="check"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M20%206L9%2017l-5-5'%20fill='none'%20stroke='black'%20stroke-width='2.8'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="delta"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20fill='black'%20d='M12%204l8%2016H4l8-16z'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="target"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20fill='black'%20fill-rule='evenodd'%20d='M12%204a8%208%200%201%200%200%2016a8%208%200%200%200%200-16zm0%205a3%203%200%201%200%200%206a3%203%200%200%200%200-6z'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="sum"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M18%205H8l5%207-5%207h10'%20fill='none'%20stroke='black'%20stroke-width='2.6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E"); }
.metric-icon[data-icon="time"] { --metric-icon-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M10%202h4v2h-4V2zm2%205a7%207%200%201%200%200%2014a7%207%200%200%200%200-14zm0%203v4l3%202'%20fill='none'%20stroke='black'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E"); }

.metric-value {
  font-weight: 700;
  letter-spacing: 0.2px;
  color: var(--text);
  font-size: 16px;
  line-height: 1.05;
  font-family: var(--font-num);
}

.metric-label {
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
  font-family: var(--font-cn);
}

.progressline {
  margin-top: 12px;
  padding: 10px;
  border-radius: 14px;
  border: 1px solid rgba(84, 197, 208, 0.2);
  background: linear-gradient(180deg, rgba(27, 39, 47, 0.86), rgba(22, 34, 43, 0.86));
}

.progressline-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 8px;
}

.progressline-label {
  font-size: 11px;
  color: var(--muted);
  font-family: var(--font-cn);
}

.progressline-value {
  font-weight: 700;
  color: var(--text);
  font-size: 16px;
  font-family: var(--font-num);
}

.bar {
  height: 12px;
  border-radius: 999px;
  background: var(--bar-track);
  overflow: hidden;
  border: 1px solid rgba(104, 209, 220, 0.16);
}

.bar-fill,
.barval {
  height: 100%;
  width: 0%;
  background: var(--bar-fill);
  box-shadow: 0 0 18px rgba(27, 229, 206, 0.2);
}

.expense-metrics {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
  margin-bottom: 12px;
}

.expense-breakdown {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: 12px;
  align-items: center;
}

.ring {
  display: grid;
  place-items: center;
  position: relative;
}

.ring-svg {
  width: 140px;
  height: 140px;
}

.ring-bg {
  fill: none;
  stroke: rgba(108, 209, 219, 0.18);
  stroke-width: 12;
}

.ring-rot {
  transform: rotate(-90deg);
  transform-origin: 60px 60px;
}

.ring-seg {
  fill: none;
  stroke-width: 12;
  stroke-linecap: round;
  stroke-dasharray: 0 999;
  filter: drop-shadow(0 0 8px rgba(21, 108, 255, 0.2));
}

.ring-center {
  position: absolute;
  text-align: center;
}

.ring-center-title {
  font-weight: 700;
  letter-spacing: 0.4px;
  font-size: 12px;
  color: var(--text);
  font-family: var(--font-cn);
}

.ring-center-sub {
  margin-top: 2px;
  font-size: 11px;
  color: var(--muted);
  font-family: var(--font-cn);
}

.ring-legend {
  display: grid;
  gap: 8px;
}

.ring-item {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  gap: 8px;
  align-items: center;
  font-size: 9px;
  color: rgba(213, 237, 243, 0.86);
  font-family: var(--font-cn);
}

.ring-swatch {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  border: 1px solid rgba(238, 250, 252, 0.16);
}

.barchart {
  display: grid;
  gap: 10px;
}

.barrow {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  align-items: center;
  gap: 10px;
}

.barname {
  font-size: 11px;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-cn);
}

.barname::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 3px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: #1a87ff;
}

.bartrack {
  height: 10px;
  border-radius: 999px;
  background: var(--bar-track);
  border: 1px solid rgba(113, 211, 221, 0.15);
  overflow: hidden;
}

.barlabel {
  font-weight: 700;
  color: var(--text);
  font-size: 10px;
  font-family: var(--font-num);
}

.barrow[data-kind="received"] .barname::before,
.barrow[data-kind="received"] .barval {
  background: linear-gradient(90deg, #1d87ff, #2280ea);
}

.barrow[data-kind="issued"] .barname::before,
.barrow[data-kind="issued"] .barval {
  background: linear-gradient(90deg, #0bb8ff, #17a9ea);
}

.barrow[data-kind="consumed"] .barname::before,
.barrow[data-kind="consumed"] .barval {
  background: linear-gradient(90deg, #15b964, #1ca56c);
}

.barrow[data-kind="settled"] .barname::before,
.barrow[data-kind="settled"] .barval {
  background: linear-gradient(90deg, #d88b06, #c67806);
}

.barrow[data-kind="stock"] .barname::before,
.barrow[data-kind="stock"] .barval {
  background: linear-gradient(90deg, #6f7e98, #5f708a);
}

@media (max-width: 1300px) {
  .cards {
    position: static;
    width: auto;
  }

  .cards-toggle {
    display: none;
  }

  .canvas {
    overflow-y: auto;
    padding: 16px;
    border-radius: 0;
  }

  .topbar {
    position: static;
    height: auto;
    padding: 0 0 14px;
  }

  .model-stage {
    position: relative;
    height: 460px;
    border-radius: 18px;
    overflow: hidden;
  }

  .cards-left,
  .cards-right {
    left: auto;
    right: auto;
    margin-top: 16px;
  }
}
</style>
