From 308e2cc3b78e6f8351e4f3fb0ad1ca191ae0db48 Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期二, 02 六月 2026 17:45:13 +0800
Subject: [PATCH] fix: 更新入库的源单号不显示问题

---
 src/views/systemArchitecture/index.vue | 1034 +++++++++++++++++++++-----------------------------------
 1 files changed, 393 insertions(+), 641 deletions(-)

diff --git a/src/views/systemArchitecture/index.vue b/src/views/systemArchitecture/index.vue
index c3c6c49..6ed31f6 100644
--- a/src/views/systemArchitecture/index.vue
+++ b/src/views/systemArchitecture/index.vue
@@ -1,658 +1,410 @@
 <template>
-  <div class="architecture-page">
-    <div class="page-header">
-      <span class="header-line"></span>
-      <h1 class="page-title">绯荤粺鏋舵瀯鍥�</h1>
-    </div>
-
-    <section ref="canvasRef" class="canvas">
-      <svg
-        v-if="svgSize.width && svgSize.height"
-        class="link-overlay"
-        :width="svgSize.width"
-        :height="svgSize.height"
-        aria-hidden="true"
-      >
-        <defs>
-          <marker
-            id="erp-link-arrow"
-            markerWidth="10"
-            markerHeight="10"
-            refX="7"
-            refY="4.5"
-            orient="auto"
-            markerUnits="strokeWidth"
-          >
-            <path d="M0,0 L0,7 L7,3.5 z" fill="#a7bdda" />
-          </marker>
-        </defs>
-
-        <path
-          v-for="path in aiPaths"
-          :key="path.key"
-          :d="path.d"
-          class="link-overlay__path link-overlay__path--ai"
-        />
-
-        <path
-          v-if="flowPath"
-          :d="flowPath"
-          class="link-overlay__path"
-          marker-end="url(#erp-link-arrow)"
-        />
-      </svg>
-
-      <section
-        v-for="row in architectureRows"
-        :key="row.key"
-        class="lane"
-      >
-        <aside class="lane__aside">
-          <div class="lane__aside-card" :class="`lane__aside-card--${row.key}`">
-            <div class="lane__aside-icon">
-              <svg-icon :icon-class="row.icon" class="lane__icon" />
-            </div>
-            <div class="lane__aside-content">
-              <h2>{{ row.label }}</h2>
+  <div class="scale-container">
+    <div class="scroll-content"
+         :style="{ 
+           height: `${designHeight * scaleRatio}px`,
+           width: `${designWidth * scaleRatio}px` 
+         }">
+      <div class="architecture-scaling-container"
+           :style="{ transform: `scale(${scaleRatio})` }">
+        <div class="architecture-container">
+          <div class="header">
+            <span class="title-bar"></span>
+            <h1 class="title-text">绯荤粺鏋舵瀯鍥�</h1>
+          </div>
+          <div class="image-wrapper">
+            <div class="hotspot-container">
+              <img :src="architectureImg"
+                   alt="绯荤粺鏋舵瀯鍥�"
+                   class="architecture-img" />
+              <!-- 鐑偣鍖哄煙 -->
+              <div v-for="spot in hotspots"
+                   :key="spot.id"
+                   class="hotspot"
+                   :style="{ top: spot.top, left: spot.left, width: spot.width, height: spot.height }"
+                   @click="handleSpotClick(spot)"
+                   :title="'璺宠浆鑷�: ' + spot.name">
+              </div>
             </div>
           </div>
-        </aside>
-
-        <div class="lane__flow" :class="`lane__flow--${row.key}`">
-          <template v-for="(item, index) in row.items" :key="item.name">
-            <div
-              class="node-wrap"
-              :class="{ 'node-wrap--spacer': item.spacer }"
-            >
-              <template v-if="item.isCore">
-                <article ref="coreRef" class="ai-core">
-                  <div class="ai-core__halo"></div>
-                  <div class="ai-core__brain">
-                    <img :src="aiHead" alt="AI 鏍稿績" class="ai-core__head-image" />
-                  </div>
-                </article>
-              </template>
-
-              <template v-else>
-                <article
-                  class="node"
-                  :class="{ 'node--accent': item.accent, 'node--small-gap': item.compact }"
-                  :ref="setNodeRef(item)"
-                >
-                  <div class="node__icon-wrapper">
-                    <svg-icon :icon-class="item.icon" class="node__icon" />
-                  </div>
-                  <h3>{{ item.name }}</h3>
-                </article>
-              </template>
-
-              <span
-                v-if="index < row.items.length - 1"
-                class="flow-arrow"
-                :class="{ 'flow-arrow--hidden': item.hideArrowAfter }"
-              ></span>
-            </div>
-          </template>
         </div>
-      </section>
-    </section>
+      </div>
+    </div>
   </div>
 </template>
 
 <script setup>
-import { nextTick, onBeforeUnmount, onMounted, onUpdated, ref } from 'vue'
-import aiHead from '@/assets/images/head.svg'
+  import { ref, onMounted, onBeforeUnmount, nextTick } from "vue";
+  import { useRouter } from "vue-router";
+  import architectureImg from "@/assets/images/xitongjiagou.svg";
 
-const architectureRows = [
-  {
-    key: 'basic',
-    label: '鍩虹閰嶇疆',
-    description: '绯荤粺鍩虹淇℃伅绠$悊',
-    icon: 'system',
-    items: [
-      { name: '瑙掕壊鐢ㄦ埛绠$悊', icon: 'user' },
-      { name: '浜у搧缁存姢', icon: 'monitor' },
-      { name: '瀹℃壒绠$悊', icon: 'tree', accent: true }
-    ]
-  },
-  {
-    key: 'sale',
-    label: '閿�鍞厤缃�',
-    description: '瀹㈡埛涓庨攢鍞鐞�',
-    icon: 'chart',
-    items: [
-      { name: '瀹㈡埛妗f', icon: 'peoples' },
-      { name: '閿�鍞姤浠�', icon: 'form' },
-      { name: '閿�鍞姤浠�', icon: 'chart' },
-      { name: '閿�鍞彴璐�', icon: 'table' },
-      { name: '鍙戣揣鍙拌处', icon: 'clipboard', accent: true, linkSource: true, aiLink: true },
-      { name: '閿�鍞��璐�', icon: 'nested', accent: true, aiLink: true },
-      { name: '瀹㈡埛寰�鏉�', icon: 'money' },
-      { name: '鎸囨爣缁熻', icon: 'pie-chart' }
-    ]
-  },
-  {
-    key: 'purchase',
-    label: '閲囪喘閰嶇疆',
-    description: '閲囪喘涓庝緵搴斿晢绠$悊',
-    icon: 'shopping',
-    items: [
-      { name: '渚涘簲鍟嗘。妗�', icon: 'people' },
-      { name: '閲囪喘鍙拌处', icon: 'table' },
-      { name: '閲囪喘閫�璐�', icon: 'nested', accent: true, aiLink: true },
-      { isCore: true, hideArrowAfter: true },
-      { name: '渚涘簲鍟嗗線鏉�', icon: 'money' },
-      { name: '閲囪喘鎶ヨ〃', icon: 'chart' }
-    ]
-  },
-  {
-    key: 'produce',
-    label: '鐢熶骇閰嶇疆',
-    description: '鐢熶骇杩囩▼绠$悊',
-    icon: 'build',
-    items: [
-      { name: '宸ュ簭', icon: 'tree' },
-      { name: 'BOM', icon: 'list' },
-      { name: '宸ヨ壓璺嚎', icon: 'guide', accent: true },
-      { name: '鐢熶骇璁㈠崟', icon: 'peoples', aiLink: true },
-      { name: '鐢熶骇鎺掍骇', icon: 'date' },
-      { name: '鐢熶骇鎶ュ伐', icon: 'edit' },
-      { name: '鎶ュ伐鍙拌处', icon: 'clipboard' },
-      { name: '鐢熶骇鏍哥畻', icon: 'money', accent: true }
-    ]
-  },
-  {
-    key: 'store',
-    label: '浠撳偍鐗╂祦',
-    description: '搴撳瓨涓庡嚭鍏ュ簱绠$悊',
-    icon: 'redis',
-    items: [
-      { name: '鍏ュ簱绠$悊', icon: 'download' },
-      { name: '鍑哄簱绠$悊', icon: 'upload', linkTarget: true },
-      { name: '搴撳瓨绠$悊', icon: 'redis-list' }
-    ]
+  const router = useRouter();
+
+  // 鐑偣鍖哄煙瀹氫箟
+  const hotspots = ref([
+    {
+      id: 1,
+      name: "瑙掕壊绠$悊",
+      top: "3%",
+      left: "19%",
+      width: "9%",
+      height: "11%",
+      path: "/system/role",
+    },
+    {
+      id: 2,
+      name: "鑱屼笟绠$悊",
+      top: "1.6%",
+      left: "36.5%",
+      width: "9%",
+      height: "11%",
+      path: "/system/user",
+    },
+    {
+      id: 3,
+      name: "宀椾綅绠$悊",
+      top: "1.6%",
+      left: "56%",
+      width: "9%",
+      height: "11%",
+      path: "/system/post",
+    },
+    {
+      id: 4,
+      name: "閮ㄩ棬绠$悊",
+      top: "3%",
+      left: "73%",
+      width: "9%",
+      height: "11%",
+      path: "/system/dept",
+    },
+    {
+      id: 5,
+      name: "瀹㈡埛妗f",
+      top: "42%",
+      left: "17%",
+      width: "9%",
+      height: "3%",
+      path: "/salesManagement/customerFileOpenSea",
+    },
+    {
+      id: 6,
+      name: "閿�鍞姤浠�",
+      top: "46%",
+      left: "17%",
+      width: "9%",
+      height: "3%",
+      path: "/salesManagement/salesQuotation",
+    },
+    {
+      id: 7,
+      name: "閿�鍞彴璐�",
+      top: "51%",
+      left: "17%",
+      width: "9%",
+      height: "3%",
+      path: "/salesManagement/salesLedger",
+    },
+    {
+      id: 8,
+      name: "鍙戣揣鍙拌处",
+      top: "55%",
+      left: "17%",
+      width: "9%",
+      height: "3%",
+      path: "/salesManagement/deliveryLedger",
+    },
+    {
+      id: 9,
+      name: "閿�鍞��璐�",
+      top: "59%",
+      left: "17%",
+      width: "9%",
+      height: "3%",
+      path: "/salesManagement/returnOrder",
+    },
+    {
+      id: 10,
+      name: "渚涘簲鍟嗘。妗�",
+      top: "42%",
+      left: "75%",
+      width: "9%",
+      height: "3%",
+      path: "/salesManagement/customerFileOpenSea",
+    },
+    {
+      id: 11,
+      name: "閲囪喘鍙拌处",
+      top: "47%",
+      left: "75%",
+      width: "9%",
+      height: "3%",
+      path: "/procurementManagement/procurementLedger",
+    },
+    {
+      id: 12,
+      name: "閲囪喘閫�璐�",
+      top: "51%",
+      left: "75%",
+      width: "9%",
+      height: "3%",
+      path: "/procurementManagement/purchaseReturnOrder",
+    },
+    {
+      id: 13,
+      name: "渚涘簲鍟嗗線鏉�",
+      top: "56%",
+      left: "75%",
+      width: "9%",
+      height: "3%",
+      path: "/procurementManagement/paymentLedger",
+    },
+    {
+      id: 14,
+      name: "閲囪喘鎶ヨ〃",
+      top: "60%",
+      left: "75%",
+      width: "9%",
+      height: "3%",
+      path: "/procurementManagement/procurementReport",
+    },
+    {
+      id: 15,
+      name: "鐢熶骇鎺掍骇",
+      top: "77%",
+      left: "19%",
+      width: "15%",
+      height: "3%",
+      path: "/productionManagement/productionManagement/workOrderEdit/index",
+    },
+    {
+      id: 16,
+      name: "鐢熶骇璁㈠崟",
+      top: "76%",
+      left: "43%",
+      width: "15%",
+      height: "3%",
+      path: "/productionManagement/productionOrder",
+    },
+    {
+      id: 17,
+      name: "bom",
+      top: "77%",
+      left: "70%",
+      width: "15%",
+      height: "3%",
+      path: "/processDesign/productionManagement/productStructure/index",
+    },
+    {
+      id: 18,
+      name: "鐢熶骇璁㈠崟",
+      top: "82%",
+      left: "32%",
+      width: "15%",
+      height: "3%",
+      path: "/productionManagement/productionOrder",
+    },
+    {
+      id: 19,
+      name: "宸ヨ壓璺嚎",
+      top: "82%",
+      left: "57%",
+      width: "15%",
+      height: "3%",
+      path: "/processDesign/processRoute",
+    },
+    {
+      id: 20,
+      name: "宸ュ簭",
+      top: "87%",
+      left: "17%",
+      width: "9%",
+      height: "4%",
+      path: "/processDesign/productionManagement/productionProcess/index",
+    },
+    {
+      id: 21,
+      name: "鐢熶骇鎶ュ伐",
+      top: "89%",
+      left: "32%",
+      width: "17%",
+      height: "4%",
+      path: "/productionManagement/workOrderManagement",
+    },
+    {
+      id: 22,
+      name: "鐢熶骇鏍哥畻",
+      top: "89%",
+      left: "56%",
+      width: "19%",
+      height: "4%",
+      path: "/productionManagement/productionCosting",
+    },
+  ]);
+
+  const handleSpotClick = spot => {
+    if (spot.path) {
+      router.push(spot.path);
+    }
+  };
+
+  // 缂╂斁姣斾緥
+  const scaleRatio = ref(1);
+  // 璁捐灏哄锛堝熀鍑嗗昂瀵革級
+  const designWidth = 1920;
+  const designHeight = 980;
+
+  // 璁$畻缂╂斁姣斾緥
+  const calculateScale = () => {
+    const container = document.querySelector(".scale-container");
+    if (!container) return;
+
+    // 鑾峰彇瀹瑰櫒鐨勫疄闄呭昂瀵�
+    const containerWidth = container.clientWidth;
+    const containerHeight = container.clientHeight;
+
+    if (containerWidth === 0 || containerHeight === 0) {
+      // 濡傛灉杩樻病娓叉煋鍑烘潵锛屽欢杩熶竴涓嬪啀璁$畻
+      setTimeout(calculateScale, 100);
+      return;
+    }
+
+    // 璁$畻缂╂斁姣斾緥锛屽彇瀹介珮姣斾緥涓殑杈冨ぇ鍊硷紝纭繚濮嬬粓鎾戞弧鏁翠釜瀹瑰櫒
+    const scaleX = containerWidth / designWidth;
+    const scaleY = containerHeight / designHeight;
+    scaleRatio.value = Math.max(scaleX, scaleY);
+  };
+
+  // 绐楀彛澶у皬鍙樺寲澶勭悊
+  const handleResize = () => {
+    calculateScale();
+  };
+
+  // 鐢熷懡鍛ㄦ湡
+  let resizeObserver = null;
+  onMounted(() => {
+    // 璁$畻鍒濆缂╂斁姣斾緥
+    nextTick(() => {
+      calculateScale();
+    });
+
+    // 鐩戝惉绐楀彛澶у皬鍙樺寲
+    window.addEventListener("resize", handleResize);
+
+    // 浣跨敤 ResizeObserver 鐩戝惉瀹瑰櫒灏哄鍙樺寲锛堣В鍐充晶杈规爮鍒囨崲闂锛�
+    const container = document.querySelector(".scale-container");
+    if (container && window.ResizeObserver) {
+      resizeObserver = new ResizeObserver(() => {
+        calculateScale();
+      });
+      resizeObserver.observe(container);
+    }
+  });
+
+  onBeforeUnmount(() => {
+    window.removeEventListener("resize", handleResize);
+    if (resizeObserver) {
+      resizeObserver.disconnect();
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  .scale-container {
+    position: relative;
+    width: 100%;
+    height: calc(100vh - 84px);
+    background-color: #f5f7fa;
+    overflow: auto;
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
   }
-]
 
-const canvasRef = ref(null)
-const coreRef = ref(null)
-const sourceNodeRef = ref(null)
-const targetNodeRef = ref(null)
-const svgSize = ref({ width: 0, height: 0 })
-const flowPath = ref('')
-const aiPaths = ref([])
-const aiNodeRefs = []
-let resizeObserver = null
+  .scroll-content {
+    position: relative;
+    flex-shrink: 0;
+  }
 
-function setNodeRef(item) {
-  return (el) => {
-    if (item.linkSource) sourceNodeRef.value = el
-    if (item.linkTarget) targetNodeRef.value = el
+  .architecture-scaling-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 1920px;
+    height: 980px;
+    transform-origin: left top;
+    background-color: #f5f7fa;
+    transition: transform 0.3s;
+  }
 
-    if (item.aiLink) {
-      if (el && !aiNodeRefs.some((entry) => entry.key === item.name && entry.el === el)) {
-        aiNodeRefs.push({ key: item.name, el })
+  .architecture-container {
+    padding: 20px;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .header {
+      display: flex;
+      align-items: center;
+      margin-bottom: 20px;
+      padding: 10px 20px;
+      background: #fff;
+      border-radius: 8px;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+
+      .title-bar {
+        width: 4px;
+        height: 20px;
+        background-color: #409eff;
+        margin-right: 12px;
+        border-radius: 2px;
+      }
+
+      .title-text {
+        margin: 0;
+        font-size: 20px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+
+    .image-wrapper {
+      flex: 1;
+      background: #fff;
+      border-radius: 8px;
+      padding: 20px 40px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      overflow: hidden;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+
+      .hotspot-container {
+        position: relative;
+        display: inline-block;
+        max-width: 100%;
+        max-height: 100%;
+
+        .architecture-img {
+          display: block;
+          max-width: 100%;
+          max-height: 100%;
+          object-fit: contain;
+        }
+
+        .hotspot {
+          position: absolute;
+          cursor: pointer;
+          background: rgba(64, 158, 255, 0);
+          transition: background 0.3s;
+          border-radius: 4px;
+
+          // &:hover {
+          //   background: rgba(64, 158, 255, 0.15);
+          //   box-shadow: 0 0 10px rgba(64, 158, 255, 0.3);
+          // }
+        }
       }
     }
   }
-}
-
-function resetLines() {
-  flowPath.value = ''
-  aiPaths.value = []
-}
-
-function getCenter(rect) {
-  return {
-    x: rect.left + rect.width / 2,
-    y: rect.top + rect.height / 2
-  }
-}
-
-function getEdgePoint(sourceRect, targetRect) {
-  const sourceCenter = getCenter(sourceRect)
-  const targetCenter = getCenter(targetRect)
-  const deltaX = targetCenter.x - sourceCenter.x
-  const deltaY = targetCenter.y - sourceCenter.y
-
-  if (Math.abs(deltaX) > Math.abs(deltaY)) {
-    return {
-      x: deltaX > 0 ? sourceRect.right : sourceRect.left,
-      y: sourceCenter.y
-    }
-  }
-
-  return {
-    x: sourceCenter.x,
-    y: deltaY > 0 ? sourceRect.bottom : sourceRect.top
-  }
-}
-
-function updateLinkLines() {
-  if (!canvasRef.value) {
-    resetLines()
-    return
-  }
-
-  svgSize.value = {
-    width: Math.ceil(canvasRef.value.scrollWidth),
-    height: Math.ceil(canvasRef.value.scrollHeight)
-  }
-
-  if (window.innerWidth <= 1200 || !coreRef.value) {
-    resetLines()
-    return
-  }
-
-  const canvasRect = canvasRef.value.getBoundingClientRect()
-  const coreRect = coreRef.value.getBoundingClientRect()
-  const validAiNodes = aiNodeRefs.filter((entry) => entry.el?.isConnected)
-
-  aiPaths.value = validAiNodes.map((entry) => {
-    const nodeRect = entry.el.getBoundingClientRect()
-    const corePoint = getEdgePoint(coreRect, nodeRect)
-    const nodePoint = getEdgePoint(nodeRect, coreRect)
-    const startX = nodePoint.x - canvasRect.left
-    const startY = nodePoint.y - canvasRect.top
-    const endX = corePoint.x - canvasRect.left
-    const endY = corePoint.y - canvasRect.top
-    const controlY = startY < endY ? startY + (endY - startY) * 0.45 : startY - (startY - endY) * 0.45
-    const controlX = (startX + endX) / 2
-
-    return {
-      key: entry.key,
-      d: `M ${startX} ${startY} C ${controlX} ${controlY}, ${controlX} ${controlY}, ${endX} ${endY}`
-    }
-  })
-
-  if (!sourceNodeRef.value || !targetNodeRef.value) {
-    flowPath.value = ''
-    return
-  }
-
-  const sourceRect = sourceNodeRef.value.getBoundingClientRect()
-  const targetRect = targetNodeRef.value.getBoundingClientRect()
-  const startX = sourceRect.left + sourceRect.width / 2 - canvasRect.left
-  const startY = sourceRect.bottom - canvasRect.top + 2
-  const endX = targetRect.left + targetRect.width / 2 - canvasRect.left
-  const endY = targetRect.top - canvasRect.top - 4
-  const middleY = startY + (endY - startY) / 2
-
-  flowPath.value = `M ${startX} ${startY} C ${startX} ${middleY}, ${endX} ${middleY}, ${endX} ${endY}`
-}
-
-function handleResize() {
-  requestAnimationFrame(() => {
-    requestAnimationFrame(updateLinkLines)
-  })
-}
-
-onMounted(async () => {
-  await nextTick()
-  handleResize()
-  window.addEventListener('resize', handleResize)
-  if (window.ResizeObserver && canvasRef.value) {
-    resizeObserver = new ResizeObserver(handleResize)
-    resizeObserver.observe(canvasRef.value)
-  }
-})
-
-onUpdated(() => {
-  nextTick(handleResize)
-})
-
-onBeforeUnmount(() => {
-  window.removeEventListener('resize', handleResize)
-  if (resizeObserver) resizeObserver.disconnect()
-})
-</script>
-
-<style scoped>
-.architecture-page {
-  min-height: calc(100vh - 84px);
-  padding: 24px;
-  background: #f0f4fb;
-}
-
-.page-header {
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  margin-bottom: 24px;
-}
-
-.header-line {
-  width: 4px;
-  height: 20px;
-  background: #2563eb;
-  border-radius: 2px;
-}
-
-.page-title {
-  margin: 0;
-  font-size: 18px;
-  font-weight: 700;
-  color: #1f2937;
-}
-
-.canvas {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  gap: 20px;
-  padding: 28px 24px;
-  background: #fff;
-  border: 1px solid rgba(219, 234, 254, 0.9);
-  border-radius: 18px;
-  box-shadow: 0 10px 30px rgba(30, 64, 175, 0.06);
-}
-
-.lane {
-  display: grid;
-  grid-template-columns: 190px 1fr;
-  gap: 18px;
-  align-items: stretch;
-}
-
-.lane__aside-card {
-  height: 100%;
-  min-height: 138px;
-  padding: 22px 20px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  gap: 14px;
-  background: linear-gradient(180deg, #f8fbff 0%, #eef5ff 100%);
-  border: 1px solid rgba(219, 234, 254, 0.95);
-  border-radius: 18px;
-  box-shadow: inset 0 1px 8px rgba(255, 255, 255, 0.9);
-}
-
-.lane__aside-card--sale .lane__aside-icon {
-  background: linear-gradient(180deg, #f3e8ff 0%, #e9d5ff 100%);
-  color: #9333ea;
-}
-
-.lane__aside-card--purchase .lane__aside-icon {
-  background: linear-gradient(180deg, #e0f2fe 0%, #bae6fd 100%);
-  color: #0284c7;
-}
-
-.lane__aside-card--produce .lane__aside-icon {
-  background: linear-gradient(180deg, #ecfdf5 0%, #d1fae5 100%);
-  color: #16a34a;
-}
-
-.lane__aside-card--store .lane__aside-icon {
-  background: linear-gradient(180deg, #eef2ff 0%, #dbeafe 100%);
-  color: #2563eb;
-}
-
-.lane__aside-icon {
-  width: 44px;
-  height: 44px;
-  flex-shrink: 0;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  border-radius: 14px;
-  background: linear-gradient(180deg, #e0ecff 0%, #dbeafe 100%);
-  color: #2563eb;
-  box-shadow: 0 8px 18px rgba(37, 99, 235, 0.12);
-}
-
-.lane__icon {
-  font-size: 24px;
-}
-
-.lane__aside-content h2 {
-  margin: 0;
-  font-size: 18px;
-  font-weight: 700;
-  color: #1d4ed8;
-  line-height: 1.2;
-  text-align: center;
-}
-
-.lane__aside-content p {
-  margin: 0;
-  font-size: 13px;
-  color: #7c8aa5;
-}
-
-.lane__flow {
-  position: relative;
-  z-index: 2;
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  min-height: 138px;
-  padding: 18px 22px;
-  background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
-  border: 1px solid rgba(219, 234, 254, 0.9);
-  border-radius: 18px;
-  box-shadow: inset 0 1px 10px rgba(255, 255, 255, 0.92);
-}
-
-.lane__flow--purchase,
-.lane__flow--produce {
-  padding-left: 28px;
-  padding-right: 28px;
-}
-
-.node-wrap {
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  flex-shrink: 0;
-}
-
-.node {
-  width: 96px;
-  min-height: 86px;
-  padding: 8px 6px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  gap: 8px;
-  background: transparent;
-}
-
-.node__icon-wrapper {
-  width: 58px;
-  height: 58px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  border-radius: 16px;
-  background: linear-gradient(180deg, #ffffff 0%, #f2f7ff 100%);
-  border: 1px solid rgba(191, 219, 254, 0.95);
-  box-shadow:
-    0 8px 18px rgba(37, 99, 235, 0.08),
-    inset 0 1px 8px rgba(255, 255, 255, 0.95);
-}
-
-.node__icon {
-  font-size: 26px;
-  color: #2563eb;
-}
-
-.node--accent .node__icon-wrapper {
-  background: linear-gradient(180deg, #ffffff 0%, #eef4ff 100%);
-}
-
-.node h3 {
-  margin: 0;
-  font-size: 12px;
-  line-height: 1.35;
-  font-weight: 600;
-  color: #334155;
-  text-align: center;
-}
-
-.flow-arrow {
-  width: 36px;
-  height: 1px;
-  position: relative;
-  background: repeating-linear-gradient(
-    to right,
-    #bfd7ff 0,
-    #bfd7ff 4px,
-    transparent 4px,
-    transparent 8px
-  );
-}
-
-.flow-arrow::after {
-  content: '';
-  position: absolute;
-  top: 50%;
-  right: -1px;
-  width: 6px;
-  height: 6px;
-  border-top: 1px solid #9ec5ff;
-  border-right: 1px solid #9ec5ff;
-  transform: translateY(-50%) rotate(45deg);
-}
-
-.flow-arrow--hidden {
-  visibility: hidden;
-}
-
-.ai-core {
-  position: relative;
-  width: 252px;
-  height: 176px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.ai-core__halo {
-  position: absolute;
-  inset: 14px 28px 32px;
-  border-radius: 50%;
-  background: radial-gradient(circle, rgba(96, 165, 250, 0.12) 0%, rgba(96, 165, 250, 0) 72%);
-  transform: scale(1.08);
-}
-
-.ai-core__brain {
-  position: absolute;
-  inset: 6px 0 0;
-  left: 50%;
-  width: 232px;
-  height: 156px;
-  transform: translateX(-50%);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  filter: drop-shadow(0 10px 18px rgba(96, 165, 250, 0.18));
-}
-
-.ai-core__head-image {
-  width: 100%;
-  height: 100%;
-  object-fit: contain;
-}
-
-.link-overlay {
-  position: absolute;
-  inset: 0;
-  z-index: 3;
-  pointer-events: none;
-}
-
-.link-overlay__path {
-  fill: none;
-  stroke: #bfd2ea;
-  stroke-width: 1.2;
-  stroke-dasharray: 4 5;
-  stroke-linecap: round;
-  stroke-linejoin: round;
-}
-
-.link-overlay__path--ai {
-  stroke: #bfd7ff;
-  stroke-width: 1.4;
-}
-
-@media (max-width: 1200px) {
-  .architecture-page {
-    padding: 16px;
-  }
-
-  .lane {
-    grid-template-columns: 1fr;
-  }
-
-  .lane__aside-card,
-  .lane__flow {
-    min-height: auto;
-  }
-
-  .lane__flow {
-    flex-wrap: wrap;
-  }
-
-  .ai-core {
-    order: 99;
-    width: 100%;
-    max-width: 268px;
-    margin: 0 auto;
-  }
-
-  .link-overlay {
-    display: none;
-  }
-}
-
-@media (max-width: 768px) {
-  .canvas {
-    padding: 16px;
-    gap: 16px;
-  }
-
-  .lane__aside-card {
-    min-height: auto;
-    padding: 18px 16px;
-  }
-
-  .lane__flow {
-    padding: 16px;
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
-    gap: 12px;
-  }
-
-  .node-wrap {
-    flex-direction: column;
-    gap: 8px;
-  }
-
-  .node {
-    width: 100%;
-  }
-
-  .flow-arrow {
-    width: 1px;
-    height: 16px;
-    margin: 0 auto;
-    background: repeating-linear-gradient(
-      to bottom,
-      #bfd7ff 0,
-      #bfd7ff 4px,
-      transparent 4px,
-      transparent 8px
-    );
-  }
-
-  .flow-arrow::after {
-    top: auto;
-    right: 50%;
-    bottom: -1px;
-    transform: translateX(50%) rotate(135deg);
-  }
-}
 </style>

--
Gitblit v1.9.3