<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { RDMS_OBJECT_DIRECTION_DICT_CODE } from '@/constants/dict';
import {
  fetchGetProduct,
  fetchGetProductMembers,
  fetchGetProductRequirementDashboard,
  fetchGetProductSettings
} from '@/service/api';
import { useDict } from '@/hooks/business/dict';
import { useCurrentProduct } from '../shared/use-current-product';
import ProductActivityTimelinePanel from './modules/product-activity-timeline-panel.vue';
import {
  buildProductHomepageBanner,
  buildRequirementPoolRecentChanges,
  buildRequirementPoolSummary,
  getProductHomepageExtensionModules
} from './homepage';
import { productHomepageExtensionMock } from './mock';

defineOptions({ name: 'ProductDashboard' });

const { currentObjectId } = useCurrentProduct();
const { getLabel: getDirectionDictLabel } = useDict(RDMS_OBJECT_DIRECTION_DICT_CODE);

const pageLoading = ref(false);
const productDetail = ref<Api.Product.Product | null>(null);
const settings = ref<Api.Product.ProductSettings | null>(null);
const members = ref<Api.Product.ProductMember[]>([]);
const requirementDashboard = ref<Api.Product.ProductRequirementDashboard | null>(null);
const latestActivityTime = ref('');

const requirementPoolSummary = computed(() => buildRequirementPoolSummary(requirementDashboard.value?.summary));
const requirementPoolRecentChanges = computed(() =>
  buildRequirementPoolRecentChanges(requirementDashboard.value?.recentChanges)
);
const homepageBanner = computed(() =>
  buildProductHomepageBanner({
    product: productDetail.value,
    settings: settings.value,
    members: members.value,
    requirementSummary: requirementPoolSummary.value,
    latestActivityTime: latestActivityTime.value
  })
);
const extensionModules = computed(() => getProductHomepageExtensionModules(productHomepageExtensionMock));
const directionLabel = computed(() => getDirectionDictLabel(homepageBanner.value.identity.directionCode, '--'));

const managerFact = computed(() => homepageBanner.value.identity.facts[0]);
const roleFact = computed(() => homepageBanner.value.identity.facts[1]);

const identityToneClass = computed(() => {
  const statusCode = homepageBanner.value.identity.statusCode;
  return statusCode ? `product-overview__identity--${statusCode}` : 'product-overview__identity--default';
});

const statusBadgeClass = computed(() => {
  const statusCode = homepageBanner.value.identity.statusCode;
  return statusCode ? `product-overview__identity-status--${statusCode}` : 'product-overview__identity-status--default';
});

interface KpiCard {
  key: string;
  label: string;
  value: string;
  hint: string;
  icon: string;
  tone: 'teal' | 'emerald' | 'amber' | 'slate';
  compact: boolean;
}

const kpiTones: Array<KpiCard['tone']> = ['teal', 'emerald', 'amber', 'slate'];
const kpiIcons = [
  'mdi:account-group-outline',
  'mdi:clipboard-list-outline',
  'mdi:timer-sand',
  'mdi:clock-time-eight-outline'
];

const kpiCards = computed<KpiCard[]>(() =>
  homepageBanner.value.metrics.map((metric, index) => ({
    key: metric.label,
    label: metric.label,
    value: metric.value,
    hint: metric.hint,
    icon: kpiIcons[index] || 'mdi:chart-line',
    tone: kpiTones[index] || 'slate',
    compact: index === 3
  }))
);

const distributionIcons: Record<string, string> = {
  等待处理: 'mdi:timer-sand',
  等待认领: 'mdi:magnify-scan',
  等待评审: 'mdi:calendar-check-outline',
  等待指派: 'mdi:check-circle-outline'
};

const distributionHints: Record<string, string> = {
  等待处理: '需要执行认领、评审、指派动作的重要需求。',
  等待认领: '需要执行认领动作的需求，一般来自工单流转。',
  等待评审: '需要执行评审动作的需求。',
  等待指派: '需要执行指派动作的需求，包括“待指派”和“已评审”两种状态。'
};

const distributionWithIcons = computed(() =>
  requirementPoolSummary.value.distribution.map((item, index) => ({
    ...item,
    icon: distributionIcons[item.label] || 'mdi:circle-outline',
    hint: distributionHints[item.label] || '',
    tone: ['amber', 'sky', 'violet', 'emerald'][index] || 'slate'
  }))
);

function getRecentChangeClass(actionType: Api.Product.ProductRequirementDashboardRecentChangeActionType) {
  return `product-overview__change--${actionType.replace(/_/g, '-')}`;
}

const poolCompletionRate = computed(() => requirementPoolSummary.value.completionRate);

const poolProgressColor = computed(() => [
  { color: '#f59e0b', percentage: 30 },
  { color: '#0ea5e9', percentage: 60 },
  { color: '#10b981', percentage: 100 }
]);

const extensionMeta: Record<string, { icon: string; tone: 'amber' | 'rose' | 'sky' }> = {
  milestone: { icon: 'mdi:flag-checkered', tone: 'amber' },
  risk: { icon: 'mdi:alert-octagon-outline', tone: 'rose' },
  document: { icon: 'mdi:file-document-outline', tone: 'sky' }
};

function getExtensionMeta(key: string) {
  return extensionMeta[key] || { icon: 'mdi:dots-grid', tone: 'sky' };
}

function handleLatestActivityTimeChange(value: string) {
  latestActivityTime.value = value;
}

async function loadDashboardData(objectId: string) {
  pageLoading.value = true;

  try {
    const [productResult, settingsResult, membersResult, requirementDashboardResult] = await Promise.all([
      fetchGetProduct(objectId),
      fetchGetProductSettings(objectId),
      fetchGetProductMembers(objectId),
      fetchGetProductRequirementDashboard(objectId)
    ]);

    productDetail.value = productResult.error ? null : productResult.data || null;
    settings.value = settingsResult.error ? null : settingsResult.data || null;
    members.value = membersResult.error ? [] : membersResult.data || [];
    requirementDashboard.value = requirementDashboardResult.error ? null : requirementDashboardResult.data || null;
  } finally {
    pageLoading.value = false;
  }
}

watch(
  () => currentObjectId.value,
  async objectId => {
    if (!objectId) {
      productDetail.value = null;
      settings.value = null;
      members.value = [];
      requirementDashboard.value = null;
      latestActivityTime.value = '';
      return;
    }

    await loadDashboardData(objectId);
  },
  { immediate: true }
);
</script>

<template>
  <div v-loading="pageLoading" class="product-overview">
    <!-- Row A: Hero (身份大卡 + 4 张 KPI) -->
    <section class="product-overview__hero">
      <article class="product-overview__identity" :class="identityToneClass">
        <div class="product-overview__identity-glow product-overview__identity-glow--a" />
        <div class="product-overview__identity-glow product-overview__identity-glow--b" />
        <div class="product-overview__identity-watermark">
          <SvgIcon icon="mdi:cube-outline" />
        </div>

        <header class="product-overview__identity-head">
          <span class="product-overview__identity-eyebrow">PRODUCT · OVERVIEW</span>
          <span class="product-overview__identity-status" :class="statusBadgeClass">
            <span class="product-overview__identity-status-dot" />
            {{ homepageBanner.identity.statusLabel }}
          </span>
        </header>

        <h1 class="product-overview__identity-name">{{ homepageBanner.identity.name }}</h1>

        <div class="product-overview__identity-code">
          <SvgIcon icon="mdi:pound" />
          <span>{{ homepageBanner.identity.code }}</span>
        </div>

        <p v-if="homepageBanner.identity.description" class="product-overview__identity-desc">
          {{ homepageBanner.identity.description }}
        </p>

        <div class="product-overview__identity-chips">
          <div class="product-overview__chip">
            <span class="product-overview__chip-icon"><SvgIcon icon="mdi:compass-outline" /></span>
            <div class="product-overview__chip-body">
              <em>产品方向</em>
              <strong>{{ directionLabel }}</strong>
            </div>
          </div>
          <div class="product-overview__chip">
            <span class="product-overview__chip-icon"><SvgIcon icon="mdi:account-star-outline" /></span>
            <div class="product-overview__chip-body">
              <em>{{ managerFact?.label || '产品经理' }}</em>
              <strong>{{ managerFact?.value || '--' }}</strong>
            </div>
          </div>
          <div class="product-overview__chip product-overview__chip--wide">
            <span class="product-overview__chip-icon"><SvgIcon icon="mdi:account-multiple-outline" /></span>
            <div class="product-overview__chip-body">
              <em>{{ roleFact?.label || '角色摘要' }}</em>
              <strong>{{ roleFact?.value || '--' }}</strong>
            </div>
          </div>
        </div>
      </article>

      <div class="product-overview__kpi-grid">
        <article
          v-for="kpi in kpiCards"
          :key="kpi.key"
          class="product-overview__kpi"
          :class="`product-overview__kpi--${kpi.tone}`"
        >
          <div class="product-overview__kpi-bg" />
          <div class="product-overview__kpi-head">
            <span class="product-overview__kpi-label">{{ kpi.label }}</span>
            <span class="product-overview__kpi-icon">
              <SvgIcon :icon="kpi.icon" />
            </span>
          </div>
          <strong class="product-overview__kpi-value" :class="{ 'product-overview__kpi-value--compact': kpi.compact }">
            {{ kpi.value }}
          </strong>
          <p class="product-overview__kpi-hint">{{ kpi.hint }}</p>
        </article>
      </div>
    </section>

    <!-- Row B: 时间线（左 8）+ 需求池概览（右 4） -->
    <section class="product-overview__middle">
      <div class="product-overview__timeline-wrap">
        <ProductActivityTimelinePanel
          :product-id="currentObjectId || ''"
          :max-items="5"
          @latest-time-change="handleLatestActivityTimeChange"
        />
      </div>

      <ElCard class="product-overview__pool card-wrapper" shadow="never">
        <template #header>
          <div class="product-overview__panel-head">
            <span class="product-overview__panel-head-icon product-overview__panel-head-icon--teal">
              <SvgIcon icon="mdi:clipboard-list-outline" />
            </span>
            <div class="product-overview__panel-head-text">
              <h3>需求池管理概览</h3>
              <p>规模、状态结构与待处理压力一览</p>
            </div>
          </div>
        </template>

        <div class="product-overview__pool-progress">
          <ElProgress
            type="circle"
            :percentage="poolCompletionRate"
            :width="124"
            :stroke-width="10"
            :color="poolProgressColor"
          >
            <template #default="{ percentage }">
              <div class="product-overview__pool-progress-inner">
                <strong>{{ percentage }}%</strong>
                <span>完成率</span>
              </div>
            </template>
          </ElProgress>

          <div class="product-overview__pool-numbers">
            <div class="product-overview__pool-number">
              <em>需求总量</em>
              <strong>{{ requirementPoolSummary.total }}</strong>
            </div>
            <div class="product-overview__pool-number">
              <em>高优先待处理</em>
              <strong :class="{ 'is-warn': requirementPoolSummary.highPriorityTodo > 0 }">
                {{ requirementPoolSummary.highPriorityTodo }}
              </strong>
            </div>
          </div>
        </div>

        <ul class="product-overview__pool-distribution">
          <ElTooltip v-for="item in distributionWithIcons" :key="item.label" :content="item.hint" placement="top">
            <li :class="`product-overview__pool-distribution-item--${item.tone}`">
              <span class="product-overview__pool-distribution-icon">
                <SvgIcon :icon="item.icon" />
              </span>
              <span class="product-overview__pool-distribution-label">{{ item.label }}</span>
              <strong class="product-overview__pool-distribution-value">{{ item.value }}</strong>
            </li>
          </ElTooltip>
        </ul>
      </ElCard>
    </section>

    <!-- Row C: 最近变化（左 7）+ 扩展模块（右 5） -->
    <section class="product-overview__bottom">
      <ElCard class="product-overview__changes card-wrapper" shadow="never">
        <template #header>
          <div class="product-overview__panel-head">
            <span class="product-overview__panel-head-icon product-overview__panel-head-icon--sky">
              <SvgIcon icon="mdi:swap-horizontal-circle-outline" />
            </span>
            <div class="product-overview__panel-head-text">
              <h3>需求池最新重要变化</h3>
              <p>需求新增、需求删除、状态流转</p>
            </div>
          </div>
        </template>

        <div v-if="requirementPoolRecentChanges.length" class="product-overview__changes-list">
          <article
            v-for="item in requirementPoolRecentChanges"
            :key="item.id"
            class="product-overview__change"
            :class="getRecentChangeClass(item.actionType)"
          >
            <div class="product-overview__change-meta">
              <span class="product-overview__change-action">{{ item.actionLabel }}</span>
              <time class="product-overview__change-time">{{ item.time }}</time>
            </div>
            <strong class="product-overview__change-title">{{ item.title }}</strong>
            <span class="product-overview__change-status">
              <SvgIcon icon="mdi:circle-medium" />
              {{ item.content }}
            </span>
          </article>
        </div>
        <ElEmpty v-else description="当前暂无需求池最近变化" :image-size="64" />
      </ElCard>

      <ElCard class="product-overview__extensions card-wrapper" shadow="never">
        <template #header>
          <div class="product-overview__panel-head">
            <span class="product-overview__panel-head-icon product-overview__panel-head-icon--amber">
              <SvgIcon icon="mdi:rocket-launch-outline" />
            </span>
            <div class="product-overview__panel-head-text">
              <h3>关键扩展模块</h3>
              <p>里程碑 · 风险 · 文档</p>
            </div>
          </div>
        </template>

        <div class="product-overview__extension-list">
          <div
            v-for="moduleItem in extensionModules"
            :key="moduleItem.key"
            class="product-overview__extension"
            :class="`product-overview__extension--${getExtensionMeta(moduleItem.key).tone}`"
          >
            <div class="product-overview__extension-head">
              <span class="product-overview__extension-icon">
                <SvgIcon :icon="getExtensionMeta(moduleItem.key).icon" />
              </span>
              <div class="product-overview__extension-title">
                <strong>{{ moduleItem.title }}</strong>
                <p>{{ moduleItem.description }}</p>
              </div>
            </div>
            <ul class="product-overview__extension-items">
              <li v-for="item in moduleItem.items" :key="item">
                <span class="product-overview__extension-bullet" />
                <span>{{ item }}</span>
              </li>
            </ul>
          </div>
        </div>
      </ElCard>
    </section>
  </div>
</template>

<style scoped>
.product-overview {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ============ Row A: Hero ============ */
.product-overview__hero {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(360px, 5fr);
  gap: 16px;
}

.product-overview__identity {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 30px 24px 36px;
  border: 1px solid rgb(226 232 240 / 92%);
  border-radius: 24px;
  overflow: hidden;
  color: rgb(15 23 42 / 98%);
  background:
    radial-gradient(circle at 100% 0%, rgb(20 184 166 / 14%), transparent 50%),
    radial-gradient(circle at 0% 100%, rgb(16 185 129 / 10%), transparent 50%),
    linear-gradient(135deg, #ffffff 0%, #f0fdfa 100%);
}

.product-overview__identity::before {
  content: '';
  position: absolute;
  top: 18px;
  bottom: 18px;
  left: 0;
  width: 5px;
  border-radius: 0 6px 6px 0;
  background: linear-gradient(180deg, #14b8a6, #10b981);
}

.product-overview__identity--paused {
  background:
    radial-gradient(circle at 100% 0%, rgb(245 158 11 / 14%), transparent 50%),
    radial-gradient(circle at 0% 100%, rgb(217 119 6 / 10%), transparent 50%),
    linear-gradient(135deg, #ffffff 0%, #fffbeb 100%);
}

.product-overview__identity--paused::before {
  background: linear-gradient(180deg, #fbbf24, #d97706);
}

.product-overview__identity--archived {
  background:
    radial-gradient(circle at 100% 0%, rgb(148 163 184 / 14%), transparent 50%),
    radial-gradient(circle at 0% 100%, rgb(100 116 139 / 10%), transparent 50%),
    linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
}

.product-overview__identity--archived::before {
  background: linear-gradient(180deg, #94a3b8, #475569);
}

.product-overview__identity--abandoned {
  background:
    radial-gradient(circle at 100% 0%, rgb(244 63 94 / 14%), transparent 50%),
    radial-gradient(circle at 0% 100%, rgb(225 29 72 / 10%), transparent 50%),
    linear-gradient(135deg, #ffffff 0%, #fff1f2 100%);
}

.product-overview__identity--abandoned::before {
  background: linear-gradient(180deg, #fb7185, #be123c);
}

.product-overview__identity-glow,
.product-overview__identity-glow--a,
.product-overview__identity-glow--b {
  display: none;
}

.product-overview__identity-watermark {
  position: absolute;
  top: 24px;
  right: 28px;
  font-size: 132px;
  line-height: 1;
  color: rgb(15 118 110 / 6%);
  pointer-events: none;
}

.product-overview__identity--paused .product-overview__identity-watermark {
  color: rgb(180 83 9 / 7%);
}

.product-overview__identity--archived .product-overview__identity-watermark {
  color: rgb(71 85 105 / 7%);
}

.product-overview__identity--abandoned .product-overview__identity-watermark {
  color: rgb(190 18 60 / 7%);
}

.product-overview__identity-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.product-overview__identity-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.28em;
  color: rgb(15 118 110 / 88%);
}

.product-overview__identity--paused .product-overview__identity-eyebrow {
  color: rgb(180 83 9 / 88%);
}

.product-overview__identity--archived .product-overview__identity-eyebrow {
  color: rgb(71 85 105 / 88%);
}

.product-overview__identity--abandoned .product-overview__identity-eyebrow {
  color: rgb(190 18 60 / 88%);
}

.product-overview__identity-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  background: rgb(20 184 166 / 12%);
  color: #0f766e;
  border: 1px solid rgb(20 184 166 / 22%);
}

.product-overview__identity-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #14b8a6;
  box-shadow: 0 0 0 3px rgb(20 184 166 / 22%);
}

.product-overview__identity-status--paused {
  background: rgb(245 158 11 / 14%);
  color: #b45309;
  border-color: rgb(245 158 11 / 28%);
}

.product-overview__identity-status--paused .product-overview__identity-status-dot {
  background: #f59e0b;
  box-shadow: 0 0 0 3px rgb(245 158 11 / 22%);
}

.product-overview__identity-status--archived {
  background: rgb(148 163 184 / 14%);
  color: #475569;
  border-color: rgb(148 163 184 / 28%);
}

.product-overview__identity-status--archived .product-overview__identity-status-dot {
  background: #94a3b8;
  box-shadow: 0 0 0 3px rgb(148 163 184 / 22%);
}

.product-overview__identity-status--abandoned {
  background: rgb(244 63 94 / 14%);
  color: #be123c;
  border-color: rgb(244 63 94 / 28%);
}

.product-overview__identity-status--abandoned .product-overview__identity-status-dot {
  background: #f43f5e;
  box-shadow: 0 0 0 3px rgb(244 63 94 / 22%);
}

.product-overview__identity-name {
  position: relative;
  margin: 0;
  font-size: 32px;
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: rgb(15 23 42 / 98%);
  word-break: break-word;
}

.product-overview__identity-code {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px 3px 8px;
  width: fit-content;
  border-radius: 999px;
  background: rgb(241 245 249 / 96%);
  color: rgb(71 85 105 / 96%);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.product-overview__identity-desc {
  position: relative;
  max-width: 78%;
  margin: 2px 0 0;
  color: rgb(71 85 105 / 94%);
  font-size: 13px;
  line-height: 1.75;
}

.product-overview__identity-chips {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 6px;
}

.product-overview__chip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-radius: 14px;
  background: rgb(255 255 255 / 78%);
  border: 1px solid rgb(226 232 240 / 92%);
  min-height: 56px;
}

.product-overview__chip--wide {
  grid-column: 1 / -1;
}

.product-overview__chip-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 10px;
  background: linear-gradient(135deg, #14b8a6, #0f766e);
  color: #fff;
  font-size: 16px;
  flex-shrink: 0;
}

.product-overview__chip-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.product-overview__chip-body em {
  font-style: normal;
  font-size: 11px;
  color: rgb(100 116 139 / 92%);
  letter-spacing: 0.04em;
}

.product-overview__chip-body strong {
  font-size: 13px;
  font-weight: 600;
  color: rgb(15 23 42 / 98%);
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.product-overview__chip--wide .product-overview__chip-body strong {
  white-space: normal;
}

/* ---- KPI 2x2 ---- */
.product-overview__kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.product-overview__kpi {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 18px 18px;
  border-radius: 20px;
  border: 1px solid rgb(226 232 240 / 92%);
  overflow: hidden;
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

.product-overview__kpi::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
}

.product-overview__kpi--teal {
  background: linear-gradient(135deg, #f0fdfa 0%, #ffffff 100%);
}

.product-overview__kpi--teal::after {
  background: linear-gradient(90deg, #14b8a6, #0f766e);
}

.product-overview__kpi--emerald {
  background: linear-gradient(135deg, #ecfdf5 0%, #ffffff 100%);
}

.product-overview__kpi--emerald::after {
  background: linear-gradient(90deg, #10b981, #047857);
}

.product-overview__kpi--amber {
  background: linear-gradient(135deg, #fffbeb 0%, #ffffff 100%);
}

.product-overview__kpi--amber::after {
  background: linear-gradient(90deg, #f59e0b, #b45309);
}

.product-overview__kpi--slate {
  background: linear-gradient(135deg, #f8fafc 0%, #ffffff 100%);
}

.product-overview__kpi--slate::after {
  background: linear-gradient(90deg, #64748b, #334155);
}

.product-overview__kpi:hover {
  transform: translateY(-2px);
}

.product-overview__kpi--teal:hover {
  box-shadow: 0 14px 26px -18px rgb(15 118 110 / 50%);
}

.product-overview__kpi--emerald:hover {
  box-shadow: 0 14px 26px -18px rgb(4 120 87 / 50%);
}

.product-overview__kpi--amber:hover {
  box-shadow: 0 14px 26px -18px rgb(180 83 9 / 50%);
}

.product-overview__kpi--slate:hover {
  box-shadow: 0 14px 26px -18px rgb(51 65 85 / 50%);
}

.product-overview__kpi-bg {
  position: absolute;
  top: -35%;
  right: -25%;
  width: 150px;
  height: 150px;
  border-radius: 50%;
  pointer-events: none;
}

.product-overview__kpi--teal .product-overview__kpi-bg {
  background: radial-gradient(circle, rgb(20 184 166 / 32%), transparent 65%);
}

.product-overview__kpi--emerald .product-overview__kpi-bg {
  background: radial-gradient(circle, rgb(16 185 129 / 32%), transparent 65%);
}

.product-overview__kpi--amber .product-overview__kpi-bg {
  background: radial-gradient(circle, rgb(245 158 11 / 32%), transparent 65%);
}

.product-overview__kpi--slate .product-overview__kpi-bg {
  background: radial-gradient(circle, rgb(100 116 139 / 26%), transparent 65%);
}

.product-overview__kpi-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.product-overview__kpi-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.product-overview__kpi--teal .product-overview__kpi-label {
  color: #0f766e;
}

.product-overview__kpi--emerald .product-overview__kpi-label {
  color: #047857;
}

.product-overview__kpi--amber .product-overview__kpi-label {
  color: #b45309;
}

.product-overview__kpi--slate .product-overview__kpi-label {
  color: #475569;
}

.product-overview__kpi-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  font-size: 17px;
  color: #fff;
  box-shadow: 0 6px 14px -8px rgb(15 23 42 / 32%);
}

.product-overview__kpi--teal .product-overview__kpi-icon {
  background: linear-gradient(135deg, #14b8a6, #0f766e);
}

.product-overview__kpi--emerald .product-overview__kpi-icon {
  background: linear-gradient(135deg, #10b981, #047857);
}

.product-overview__kpi--amber .product-overview__kpi-icon {
  background: linear-gradient(135deg, #f59e0b, #b45309);
}

.product-overview__kpi--slate .product-overview__kpi-icon {
  background: linear-gradient(135deg, #64748b, #334155);
}

.product-overview__kpi-value {
  position: relative;
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  word-break: break-word;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.product-overview__kpi--teal .product-overview__kpi-value {
  background-image: linear-gradient(135deg, #0f766e 0%, #14b8a6 100%);
}

.product-overview__kpi--emerald .product-overview__kpi-value {
  background-image: linear-gradient(135deg, #047857 0%, #10b981 100%);
}

.product-overview__kpi--amber .product-overview__kpi-value {
  background-image: linear-gradient(135deg, #b45309 0%, #f59e0b 100%);
}

.product-overview__kpi--slate .product-overview__kpi-value {
  background-image: linear-gradient(135deg, #334155 0%, #64748b 100%);
}

.product-overview__kpi-value--compact {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0;
}

.product-overview__kpi-hint {
  position: relative;
  margin: 0;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  line-height: 1.6;
}

/* ============ Row B: 中部 ============ */
.product-overview__middle {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(320px, 4fr);
  gap: 16px;
  align-items: start;
}

.product-overview__timeline-wrap {
  min-width: 0;
}

.product-overview__pool {
  display: flex;
  flex-direction: column;
}

/* 公共面板头部 */
.product-overview__panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.product-overview__panel-head-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  font-size: 19px;
  color: #fff;
  flex-shrink: 0;
}

.product-overview__panel-head-icon--teal {
  background: linear-gradient(135deg, #14b8a6, #0f766e);
  box-shadow: 0 6px 14px -8px rgb(15 118 110 / 55%);
}

.product-overview__panel-head-icon--sky {
  background: linear-gradient(135deg, #38bdf8, #0284c7);
  box-shadow: 0 6px 14px -8px rgb(2 132 199 / 55%);
}

.product-overview__panel-head-icon--amber {
  background: linear-gradient(135deg, #fbbf24, #d97706);
  box-shadow: 0 6px 14px -8px rgb(217 119 6 / 55%);
}

.product-overview__panel-head-text h3 {
  margin: 0;
  color: rgb(15 23 42 / 98%);
  font-size: 16px;
  font-weight: 700;
}

.product-overview__panel-head-text p {
  margin: 3px 0 0;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  line-height: 1.6;
}

/* 需求池概览 */
.product-overview__pool-progress {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 4px 4px 16px;
  border-bottom: 1px dashed rgb(226 232 240 / 80%);
}

.product-overview__pool-progress-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.product-overview__pool-progress-inner strong {
  font-size: 22px;
  font-weight: 700;
  color: rgb(15 23 42 / 98%);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.product-overview__pool-progress-inner span {
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
}

.product-overview__pool-numbers {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.product-overview__pool-number {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  background: rgb(241 245 249 / 70%);
}

.product-overview__pool-number em {
  font-style: normal;
  color: rgb(71 85 105 / 96%);
  font-size: 13px;
}

.product-overview__pool-number strong {
  font-size: 18px;
  font-weight: 700;
  color: rgb(15 23 42 / 98%);
  font-variant-numeric: tabular-nums;
}

.product-overview__pool-number strong.is-warn {
  color: rgb(220 38 38 / 96%);
}

.product-overview__pool-distribution {
  list-style: none;
  margin: 0;
  padding: 16px 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.product-overview__pool-distribution li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgb(248 250 252 / 96%);
  border: 1px solid rgb(226 232 240 / 60%);
  transition: background 0.18s ease;
}

.product-overview__pool-distribution li:hover {
  background: rgb(241 245 249 / 96%);
}

.product-overview__pool-distribution-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 10px;
  font-size: 15px;
  color: #fff;
  flex-shrink: 0;
}

.product-overview__pool-distribution-item--amber .product-overview__pool-distribution-icon {
  background: linear-gradient(135deg, #fbbf24, #d97706);
}

.product-overview__pool-distribution-item--sky .product-overview__pool-distribution-icon {
  background: linear-gradient(135deg, #38bdf8, #0284c7);
}

.product-overview__pool-distribution-item--violet .product-overview__pool-distribution-icon {
  background: linear-gradient(135deg, #a78bfa, #7c3aed);
}

.product-overview__pool-distribution-item--emerald .product-overview__pool-distribution-icon {
  background: linear-gradient(135deg, #34d399, #059669);
}

.product-overview__pool-distribution-item--slate .product-overview__pool-distribution-icon {
  background: linear-gradient(135deg, #94a3b8, #475569);
}

.product-overview__pool-distribution-label {
  flex: 1;
  color: rgb(51 65 85 / 96%);
  font-size: 14px;
}

.product-overview__pool-distribution-value {
  font-size: 16px;
  font-weight: 700;
  color: rgb(15 23 42 / 98%);
  font-variant-numeric: tabular-nums;
}

/* ============ Row C: 底部 ============ */
.product-overview__bottom {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(320px, 5fr);
  gap: 16px;
  align-items: start;
}

.product-overview__changes-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.product-overview__change {
  position: relative;
  padding: 14px 16px 14px 18px;
  border: 1px solid rgb(226 232 240 / 90%);
  border-radius: 14px;
  background: linear-gradient(180deg, rgb(255 255 255 / 99%), rgb(248 250 252 / 90%));
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease,
    border-color 0.18s ease;
}

.product-overview__change::before {
  content: '';
  position: absolute;
  top: 14px;
  bottom: 14px;
  left: 0;
  width: 3px;
  border-radius: 0 4px 4px 0;
  background: linear-gradient(180deg, #14b8a6, #10b981);
}

.product-overview__change--delete::before {
  background: linear-gradient(180deg, #b91c1c, #991b1b);
}

.product-overview__change--status-terminal::before {
  background: linear-gradient(180deg, #1d4ed8, #1e40af);
}

.product-overview__change:hover {
  transform: translateX(2px);
  border-color: rgb(20 184 166 / 40%);
  box-shadow: 0 10px 20px -16px rgb(15 118 110 / 35%);
}

.product-overview__change--delete:hover {
  border-color: rgb(185 28 28 / 34%);
  box-shadow: 0 10px 20px -16px rgb(153 27 27 / 30%);
}

.product-overview__change--status-terminal:hover {
  border-color: rgb(29 78 216 / 34%);
  box-shadow: 0 10px 20px -16px rgb(30 64 175 / 30%);
}

.product-overview__change-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.product-overview__change-action {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: rgb(20 184 166 / 12%);
  color: #0f766e;
}

.product-overview__change--delete .product-overview__change-action {
  background: rgb(185 28 28 / 10%);
  color: #991b1b;
}

.product-overview__change--status-terminal .product-overview__change-action {
  background: rgb(29 78 216 / 10%);
  color: #1e40af;
}

.product-overview__change-time {
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.product-overview__change-title {
  display: block;
  margin: 8px 0 6px;
  color: rgb(15 23 42 / 98%);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.6;
}

.product-overview__change-status {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  color: rgb(71 85 105 / 94%);
  font-size: 12px;
}

/* 扩展模块 */
.product-overview__extension-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.product-overview__extension {
  padding: 14px 16px;
  border: 1px solid rgb(226 232 240 / 90%);
  border-radius: 16px;
  background: #fff;
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

.product-overview__extension:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 22px -16px rgb(15 23 42 / 24%);
}

.product-overview__extension-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.product-overview__extension-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  font-size: 17px;
  color: #fff;
  flex-shrink: 0;
}

.product-overview__extension--amber .product-overview__extension-icon {
  background: linear-gradient(135deg, #fbbf24, #d97706);
}

.product-overview__extension--rose .product-overview__extension-icon {
  background: linear-gradient(135deg, #fb7185, #be123c);
}

.product-overview__extension--sky .product-overview__extension-icon {
  background: linear-gradient(135deg, #38bdf8, #0284c7);
}

.product-overview__extension-title strong {
  display: block;
  color: rgb(15 23 42 / 98%);
  font-size: 14px;
  font-weight: 700;
}

.product-overview__extension-title p {
  margin: 2px 0 0;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  line-height: 1.5;
}

.product-overview__extension-items {
  list-style: none;
  margin: 0;
  padding: 8px 0 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.product-overview__extension-items li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 10px;
  background: rgb(248 250 252 / 96%);
  color: rgb(51 65 85 / 96%);
  font-size: 13px;
  line-height: 1.5;
}

.product-overview__extension-bullet {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentcolor;
  opacity: 0.4;
  flex-shrink: 0;
}

.product-overview__extension--amber .product-overview__extension-items li {
  color: rgb(120 53 15 / 92%);
  background: rgb(254 243 199 / 60%);
}

.product-overview__extension--rose .product-overview__extension-items li {
  color: rgb(136 19 55 / 92%);
  background: rgb(255 228 230 / 60%);
}

.product-overview__extension--sky .product-overview__extension-items li {
  color: rgb(7 89 133 / 94%);
  background: rgb(224 242 254 / 60%);
}

/* ============ 响应式 ============ */
@media (width <= 1280px) {
  .product-overview__hero,
  .product-overview__middle,
  .product-overview__bottom {
    grid-template-columns: 1fr;
  }

  .product-overview__identity-desc {
    max-width: 100%;
  }
}

@media (width <= 768px) {
  .product-overview__identity {
    padding: 22px;
  }

  .product-overview__identity-name {
    font-size: 28px;
  }

  .product-overview__identity-chips {
    grid-template-columns: 1fr;
  }

  .product-overview__chip--wide {
    grid-column: 1;
  }

  .product-overview__kpi-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
  }

  .product-overview__pool-progress {
    flex-direction: column;
    align-items: stretch;
  }
}
</style>
