<!-- 关键监控点位管理 -->
<template>
  <div class="app-container point-page">
    <div class="summary-grid">
      <el-card shadow="hover" class="summary-card primary">
        <div class="summary-label">点位总数</div>
        <div class="summary-value">{{ summary.totalPoints }}</div>
        <div class="summary-desc">平台已接入关键监控点位</div>
      </el-card>
      <el-card shadow="hover" class="summary-card success">
        <div class="summary-label">正常点位</div>
        <div class="summary-value">{{ summary.normalPoints }}</div>
        <div class="summary-desc">状态为正常或启用的点位</div>
      </el-card>
      <el-card shadow="hover" class="summary-card warning">
        <div class="summary-label">异常点位</div>
        <div class="summary-value">{{ summary.warningPoints }}</div>
        <div class="summary-desc">状态需关注的关键监控点</div>
      </el-card>
      <el-card shadow="hover" class="summary-card info">
        <div class="summary-label">已绑设备</div>
        <div class="summary-value">{{ summary.boundEquipments }}</div>
        <div class="summary-desc">监控点位已关联感知设备数量</div>
      </el-card>
    </div>

    <el-card shadow="never" class="query-card">
      <el-form ref="queryRef" :model="queryParams" :inline="true" v-show="showSearch">
        <el-form-item label="监测点编码" prop="pointCode">
          <el-input
            v-model="queryParams.pointCode"
            placeholder="请输入监测点编码"
            clearable
            style="width: 220px"
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item label="监测点名称" prop="pointName">
          <el-input
            v-model="queryParams.pointName"
            placeholder="请输入监测点名称"
            clearable
            style="width: 220px"
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item label="监测类型" prop="pointType">
          <el-select
            v-model="queryParams.pointType"
            placeholder="请选择监测类型"
            clearable
            filterable
            allow-create
            default-first-option
            style="width: 220px"
          >
            <el-option v-for="item in pointTypeOptions" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select
            v-model="queryParams.status"
            placeholder="请选择状态"
            clearable
            filterable
            allow-create
            default-first-option
            style="width: 180px"
          >
            <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-row :gutter="16" class="main-row">
      <el-col :xs="24" :lg="10">
        <el-card shadow="never" class="list-card">
          <template #header>
            <div class="card-header-row">
              <div>
                <div class="card-title">点位清单</div>
                <div class="card-subtitle">关键监控点位的查询、维护与定位管理</div>
              </div>
              <div class="card-actions">
                <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
                <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
                <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
                <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" />
              </div>
            </div>
          </template>

          <el-table
            v-loading="loading"
            :data="pointList"
            highlight-current-row
            @selection-change="handleSelectionChange"
            @current-change="handleCurrentChange"
            @row-click="handleRowClick"
          >
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="监测点名称" prop="pointName" min-width="170" show-overflow-tooltip />
            <el-table-column label="监测类型" prop="pointType" min-width="110" />
            <el-table-column label="状态" width="90">
              <template #default="scope">
                <el-tag :type="getStatusTagType(scope.row.status)" size="small">
                  {{ scope.row.status || "-" }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="设施" min-width="140" show-overflow-tooltip>
              <template #default="scope">
                {{ networkNameMap[scope.row.networkId] || "-" }}
              </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="150">
              <template #default="scope">
                <el-button link type="primary" icon="Connection" @click.stop="openBindDialog(scope.row)">
                  关联设备
                </el-button>
                <el-button link type="primary" icon="Edit" @click.stop="handleUpdate(scope.row)">修改</el-button>
              </template>
            </el-table-column>
          </el-table>

          <pagination
            v-show="total > 0"
            :total="total"
            v-model:page="queryParams.pageNum"
            v-model:limit="queryParams.pageSize"
            @pagination="getList"
          />
        </el-card>
      </el-col>

      <el-col :xs="24" :lg="14">
        <el-card shadow="never" class="detail-card">
          <template #header>
            <div class="card-header-row">
              <div>
                <div class="card-title">点位详情与关联设备</div>
                <div class="card-subtitle">突出点位基础信息、所属设施和已绑定感知设备</div>
              </div>
              <div class="detail-top-actions" v-if="selectedPoint.pointInfo">
                <el-button link type="primary" icon="Connection" @click="openBindDialog(selectedPoint.pointInfo)">
                  设备关联
                </el-button>
                <el-button link type="primary" icon="Edit" @click="handleUpdate(selectedPoint.pointInfo)">编辑</el-button>
              </div>
            </div>
          </template>

          <el-empty v-if="!selectedPoint.pointInfo" description="请从左侧选择一个关键监控点位" />

          <template v-else>
            <div class="point-hero">
              <div class="hero-main">
                <div class="hero-title">{{ selectedPoint.pointInfo.pointName }}</div>
                <div class="hero-code">{{ selectedPoint.pointInfo.pointCode }}</div>
              </div>
              <div class="hero-tags">
                <el-tag>{{ selectedPoint.pointInfo.pointType || "未分类" }}</el-tag>
                <el-tag :type="getStatusTagType(selectedPoint.pointInfo.status)">
                  {{ selectedPoint.pointInfo.status || "未设置状态" }}
                </el-tag>
              </div>
            </div>

            <div class="detail-panels">
              <el-card shadow="never" class="mini-panel">
                <template #header>
                  <div class="mini-panel-title">点位基础信息</div>
                </template>
                <el-descriptions :column="1" border size="small">
                  <el-descriptions-item label="关联设施">
                    {{ selectedPoint.networkInfo?.networkName || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="位置描述">
                    {{ selectedPoint.pointInfo.location || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="安装日期">
                    {{ selectedPoint.pointInfo.installationDate || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="经纬度">
                    {{ selectedPoint.pointInfo.longitude ?? "-" }} / {{ selectedPoint.pointInfo.latitude ?? "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="备注">
                    {{ selectedPoint.pointInfo.remark || "-" }}
                  </el-descriptions-item>
                </el-descriptions>
              </el-card>

              <el-card shadow="never" class="mini-panel">
                <template #header>
                  <div class="mini-panel-title">所属设施概况</div>
                </template>
                <el-descriptions :column="1" border size="small">
                  <el-descriptions-item label="设施名称">
                    {{ selectedPoint.networkInfo?.networkName || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="设施编码">
                    {{ selectedPoint.networkInfo?.networkCode || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="设施类型">
                    {{ selectedPoint.networkInfo?.networkType || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="管养单位">
                    {{ selectedPoint.networkInfo?.managementUnit || "-" }}
                  </el-descriptions-item>
                  <el-descriptions-item label="设施状态">
                    {{ selectedPoint.networkInfo?.status || "-" }}
                  </el-descriptions-item>
                </el-descriptions>
              </el-card>
            </div>

            <el-card shadow="never" class="equipment-panel">
              <template #header>
                <div class="card-header-row">
                  <div>
                    <div class="mini-panel-title">关联监测设备</div>
                    <div class="panel-tip">
                      当前共 {{ selectedEquipmentList.length }} 台设备，支持在右上角进行绑定和解绑
                    </div>
                  </div>
                  <el-button type="primary" plain icon="Connection" @click="openBindDialog(selectedPoint.pointInfo)">
                    关联设备
                  </el-button>
                </div>
              </template>

              <el-table :data="selectedEquipmentList" border size="small" max-height="320">
                <el-table-column label="设备编码" prop="equipmentCode" min-width="140" />
                <el-table-column label="设备名称" prop="equipmentName" min-width="160" show-overflow-tooltip />
                <el-table-column label="设备型号" prop="equipmentModel" min-width="120" />
                <el-table-column label="制造商" prop="manufacturer" min-width="120" show-overflow-tooltip />
                <el-table-column label="设备位置" prop="equipmentLocation" min-width="160" show-overflow-tooltip />
                <el-table-column label="操作" width="90" align="center">
                  <template #default="scope">
                    <el-button link type="danger" icon="Close" @click="handleUnbind(scope.row)">解绑</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-card>
          </template>
        </el-card>
      </el-col>
    </el-row>

    <el-dialog :title="title" v-model="open" width="780px" append-to-body>
      <el-form ref="pointRef" :model="form" :rules="rules" label-width="110px">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="监测点编码" prop="pointCode">
              <el-input v-model="form.pointCode" placeholder="请输入监测点编码" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="监测点名称" prop="pointName">
              <el-input v-model="form.pointName" placeholder="请输入监测点名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="关联设施" prop="networkId">
              <el-select v-model="form.networkId" clearable placeholder="请选择管网设施" style="width: 100%">
                <el-option
                  v-for="item in networkOptions"
                  :key="item.networkId"
                  :label="`${item.networkName}（${item.networkCode}）`"
                  :value="item.networkId"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="监测类型" prop="pointType">
              <el-select
                v-model="form.pointType"
                placeholder="请选择或输入监测类型"
                filterable
                allow-create
                default-first-option
                style="width: 100%"
              >
                <el-option v-for="item in pointTypeOptions" :key="item" :label="item" :value="item" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态" prop="status">
              <el-select
                v-model="form.status"
                placeholder="请选择或输入状态"
                filterable
                allow-create
                default-first-option
                style="width: 100%"
              >
                <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="安装日期" prop="installationDate">
              <el-date-picker
                v-model="form.installationDate"
                type="date"
                value-format="YYYY-MM-DD"
                placeholder="请选择安装日期"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="位置描述" prop="location">
              <el-input v-model="form.location" placeholder="请输入位置描述" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="经度" prop="longitude">
              <el-input-number v-model="form.longitude" :precision="6" :step="0.000001" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="纬度" prop="latitude">
              <el-input-number v-model="form.latitude" :precision="6" :step="0.000001" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog title="关联监测设备" v-model="bindOpen" width="860px" append-to-body>
      <el-form label-width="90px">
        <el-form-item label="当前点位">
          <span>{{ currentRow.pointName || "-" }}</span>
        </el-form-item>
        <el-form-item label="选择设备">
          <el-select
            v-model="bindForm.equipmentId"
            filterable
            clearable
            placeholder="请选择设备"
            style="width: 100%"
          >
            <el-option
              v-for="item in unboundEquipmentOptions"
              :key="item.equipmentId"
              :label="`${item.equipmentName}（${item.equipmentCode}）`"
              :value="item.equipmentId"
            />
          </el-select>
        </el-form-item>
      </el-form>

      <div class="bind-toolbar">
        <el-button type="primary" @click="submitBind">添加关联</el-button>
      </div>

      <el-table :data="bindDetail.equipmentList || []" border>
        <el-table-column label="设备编码" prop="equipmentCode" min-width="140" />
        <el-table-column label="设备名称" prop="equipmentName" min-width="180" show-overflow-tooltip />
        <el-table-column label="设备型号" prop="equipmentModel" min-width="120" />
        <el-table-column label="制造商" prop="manufacturer" min-width="140" show-overflow-tooltip />
        <el-table-column label="设备位置" prop="equipmentLocation" min-width="180" show-overflow-tooltip />
        <el-table-column label="操作" align="center" width="100">
          <template #default="scope">
            <el-button link type="danger" icon="Close" @click="handleUnbind(scope.row)">解绑</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, getCurrentInstance, onMounted, reactive, ref, toRefs } from "vue";
import {
  addMonitorPoint,
  bindPointEquipment,
  delMonitorPoint,
  getMonitorPoint,
  getMonitorPointDetail,
  listEquipment,
  listMonitorPoint,
  listMonitorPointAll,
  listPipeNetworkAll,
  unbindPointEquipment,
  updateMonitorPoint
} from "@/api/pipeNetwork/pdeviceInform";

const { proxy } = getCurrentInstance();

const pointList = ref([]);
const networkOptions = ref([]);
const equipmentOptions = ref([]);
const loading = ref(false);
const open = ref(false);
const bindOpen = ref(false);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const currentRow = ref({});

const pointTypeOptions = ["水质监测", "空气质量", "压力监测", "流量监测", "温度监测", "泄漏检测"];
const statusOptions = ["正常", "启用", "停用", "维修中", "预警"];

const summary = reactive({
  totalPoints: 0,
  normalPoints: 0,
  warningPoints: 0,
  boundEquipments: 0
});

const networkNameMap = computed(() => {
  return networkOptions.value.reduce((acc, item) => {
    acc[item.networkId] = item.networkName;
    return acc;
  }, {});
});

const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    pointCode: undefined,
    pointName: undefined,
    pointType: undefined,
    status: undefined
  },
  form: {},
  selectedPoint: {},
  bindDetail: {},
  bindForm: {
    equipmentId: undefined
  },
  rules: {
    pointCode: [{ required: true, message: "监测点编码不能为空", trigger: "blur" }],
    pointName: [{ required: true, message: "监测点名称不能为空", trigger: "blur" }],
    pointType: [{ required: true, message: "监测类型不能为空", trigger: "change" }]
  }
});

const { queryParams, form, selectedPoint, bindDetail, bindForm, rules } = toRefs(data);

const selectedEquipmentList = computed(() => {
  return selectedPoint.value.equipmentList || [];
});

const unboundEquipmentOptions = computed(() => {
  const boundIds = new Set((bindDetail.value.equipmentList || []).map((item) => item.equipmentId));
  return equipmentOptions.value.filter((item) => !boundIds.has(item.equipmentId));
});

function createEmptyForm() {
  return {
    pointId: undefined,
    pointCode: undefined,
    pointName: undefined,
    networkId: undefined,
    pointType: undefined,
    location: undefined,
    longitude: undefined,
    latitude: undefined,
    installationDate: undefined,
    status: "正常",
    remark: undefined
  };
}

function getStatusTagType(status) {
  if (["正常", "启用"].includes(status)) {
    return "success";
  }
  if (status === "预警") {
    return "warning";
  }
  if (["停用", "禁用"].includes(status)) {
    return "info";
  }
  if (["故障", "异常"].includes(status)) {
    return "danger";
  }
  return "";
}

function getList() {
  loading.value = true;
  return listMonitorPoint(queryParams.value)
    .then((response) => {
      pointList.value = response.records || [];
      total.value = response.total || 0;
      if (!selectedPoint.value.pointInfo && pointList.value.length) {
        return selectPoint(pointList.value[0]);
      }
      return undefined;
    })
    .finally(() => {
      loading.value = false;
    });
}

function loadAssistData() {
  return Promise.all([
    listPipeNetworkAll(),
    listEquipment({
      pageNum: 1,
      pageSize: 1000
    }),
    listMonitorPointAll()
  ]).then(([networkRes, equipmentRes, pointRes]) => {
    networkOptions.value = networkRes.data || [];
    equipmentOptions.value = equipmentRes.records || [];
    const allPoints = pointRes.data || [];
    summary.totalPoints = allPoints.length;
    summary.normalPoints = allPoints.filter((item) => ["正常", "启用"].includes(item.status)).length;
    summary.warningPoints = allPoints.filter((item) => !["正常", "启用"].includes(item.status)).length;
  });
}

function loadPointDetail(pointId, targetRef) {
  return getMonitorPointDetail(pointId).then((response) => {
    targetRef.value = response.data || {};
  });
}

function refreshBoundCount() {
  return listMonitorPoint({
    pageNum: 1,
    pageSize: 1000
  }).then((response) => {
    const records = response.records || [];
    const detailRequests = records.map((item) => getMonitorPointDetail(item.pointId));
    return Promise.all(detailRequests).then((detailResponses) => {
      summary.boundEquipments = detailResponses.reduce((count, item) => {
        return count + ((item.data?.equipmentList || []).length || 0);
      }, 0);
    });
  });
}

function selectPoint(row) {
  if (!row?.pointId) {
    return;
  }
  return loadPointDetail(row.pointId, selectedPoint);
}

function reset() {
  form.value = createEmptyForm();
  proxy.resetForm("pointRef");
}

function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}

function resetQuery() {
  proxy.resetForm("queryRef");
  handleQuery();
}

function handleSelectionChange(selection) {
  ids.value = selection.map((item) => item.pointId);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
}

function handleCurrentChange(currentRow) {
  if (currentRow?.pointId) {
    selectPoint(currentRow);
  }
}

function handleRowClick(row) {
  selectPoint(row);
}

function handleAdd() {
  reset();
  open.value = true;
  title.value = "新增关键监控点位";
}

function handleUpdate(row) {
  reset();
  const pointId = row?.pointId || row?.pointInfo?.pointId || ids.value[0];
  if (!pointId) {
    return;
  }
  getMonitorPoint(pointId).then((response) => {
    form.value = { ...createEmptyForm(), ...(response.data || {}) };
    open.value = true;
    title.value = "修改关键监控点位";
  });
}

function cancel() {
  open.value = false;
  reset();
}

function submitForm() {
  proxy.$refs.pointRef.validate((valid) => {
    if (!valid) {
      return;
    }
    const request = form.value.pointId ? updateMonitorPoint(form.value) : addMonitorPoint(form.value);
    request.then(() => {
      proxy.$modal.msgSuccess(form.value.pointId ? "修改成功" : "新增成功");
      open.value = false;
      Promise.all([getList(), loadAssistData(), refreshBoundCount()]).then(() => {
        if (form.value.pointId) {
          selectPoint({ pointId: form.value.pointId });
        }
      });
    });
  });
}

function handleDelete(row) {
  const deleteIds = row?.pointId ? [row.pointId] : ids.value;
  if (!deleteIds.length) {
    return;
  }
  proxy.$modal
    .confirm(`是否确认删除选中的 ${deleteIds.length} 个监测点？`)
    .then(() => Promise.all(deleteIds.map((id) => delMonitorPoint(id))))
    .then(() => {
      proxy.$modal.msgSuccess("删除成功");
      if (deleteIds.includes(selectedPoint.value?.pointInfo?.pointId)) {
        selectedPoint.value = {};
      }
      return Promise.all([getList(), loadAssistData(), refreshBoundCount()]);
    });
}

function openBindDialog(row) {
  const pointId = row?.pointId || row?.pointInfo?.pointId;
  if (!pointId) {
    return;
  }
  currentRow.value = row.pointInfo ? row.pointInfo : row;
  bindForm.value.equipmentId = undefined;
  loadPointDetail(pointId, bindDetail).then(() => {
    bindOpen.value = true;
  });
}

function submitBind() {
  if (!bindForm.value.equipmentId) {
    proxy.$modal.msgError("请选择要关联的设备");
    return;
  }
  bindPointEquipment(currentRow.value.pointId, [bindForm.value.equipmentId]).then(() => {
    proxy.$modal.msgSuccess("关联成功");
    bindForm.value.equipmentId = undefined;
    Promise.all([
      loadPointDetail(currentRow.value.pointId, bindDetail),
      loadPointDetail(currentRow.value.pointId, selectedPoint),
      refreshBoundCount()
    ]);
  });
}

function handleUnbind(row) {
  const pointId = currentRow.value.pointId || selectedPoint.value?.pointInfo?.pointId;
  if (!pointId) {
    return;
  }
  proxy.$modal
    .confirm(`是否确认解绑设备“${row.equipmentName}”？`)
    .then(() => unbindPointEquipment(pointId, [row.equipmentId]))
    .then(() => {
      proxy.$modal.msgSuccess("解绑成功");
      return Promise.all([
        loadPointDetail(pointId, bindDetail),
        loadPointDetail(pointId, selectedPoint),
        refreshBoundCount()
      ]);
    });
}

onMounted(() => {
  reset();
  Promise.all([getList(), loadAssistData(), refreshBoundCount()]);
});
</script>

<style scoped>
.point-page {
  background: #f5f8fc;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

.summary-card {
  border: none;
  color: #fff;
}

.summary-card :deep(.el-card__body) {
  padding: 20px;
}

.summary-card.primary {
  background: linear-gradient(135deg, #2563eb, #5b93ff);
}

.summary-card.success {
  background: linear-gradient(135deg, #059669, #34d399);
}

.summary-card.warning {
  background: linear-gradient(135deg, #d97706, #f7b955);
}

.summary-card.info {
  background: linear-gradient(135deg, #7c3aed, #9d72ff);
}

.summary-label {
  font-size: 14px;
  opacity: 0.9;
}

.summary-value {
  margin: 8px 0 10px;
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
}

.summary-desc {
  font-size: 12px;
  opacity: 0.9;
}

.query-card,
.list-card,
.detail-card {
  border-radius: 16px;
}

.query-card {
  margin-bottom: 16px;
}

.card-header-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.card-title {
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}

.card-subtitle,
.panel-tip {
  margin-top: 4px;
  font-size: 12px;
  color: #6b7280;
}

.card-actions,
.detail-top-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.point-hero {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  border-radius: 14px;
  background: linear-gradient(135deg, #eff6ff, #f8fbff);
  border: 1px solid #dbeafe;
  margin-bottom: 16px;
}

.hero-title {
  font-size: 18px;
  font-weight: 700;
  color: #1d4ed8;
}

.hero-code {
  margin-top: 8px;
  font-size: 13px;
  color: #4b5563;
}

.hero-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: flex-start;
}

.detail-panels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

.mini-panel,
.equipment-panel {
  border-radius: 14px;
}

.mini-panel-title {
  font-size: 15px;
  font-weight: 600;
  color: #1f2937;
}

.bind-toolbar {
  margin-bottom: 12px;
}

@media (max-width: 1200px) {
  .summary-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .summary-grid,
  .detail-panels {
    grid-template-columns: 1fr;
  }

  .card-header-row,
  .point-hero {
    flex-direction: column;
    align-items: flex-start;
  }
}
</style>
