|  |  | 
 |  |  | <template> | 
 |  |  |   <div class="container"> | 
 |  |  |     <Breadcrumb :items="['大模型', '大模型管理']" /> | 
 |  |  |     <Breadcrumb :items="['大模型', '模型管理']" /> | 
 |  |  |  | 
 |  |  |     <a-row :gutter="20" align="stretch"> | 
 |  |  |       <a-col :span="24"> | 
 |  |  | 
 |  |  |                   :title="index" | 
 |  |  |                   :closable="Object.keys(tabData).length >= 4" | 
 |  |  |                 > | 
 |  |  |                   <div | 
 |  |  |                     style="display: flex; flex-wrap: wrap" | 
 |  |  |                     class="card_content" | 
 |  |  |                   <a-scrollbar | 
 |  |  |                     style="height: calc(100vh - 320px); overflow: auto" | 
 |  |  |                   > | 
 |  |  |                     <div class="card-wrap"> | 
 |  |  |                       <div class="card_wrap_box"> | 
 |  |  |                         <div class="card_wrap_box_img"> | 
 |  |  |                           <img | 
 |  |  |                             :style="{ | 
 |  |  |                               width: '100%', | 
 |  |  |                             }" | 
 |  |  |                             alt="dessert" | 
 |  |  |                             :src="'http://' + item.logo" | 
 |  |  |                           /> | 
 |  |  |                         </div> | 
 |  |  |                         <a-card :bordered="false" hoverable> | 
 |  |  |                           <div class="arco-card-body-content"> | 
 |  |  |                             <div | 
 |  |  |                               class="arco-card-body-content-title" | 
 |  |  |                               style="word-wrap: break-word" | 
 |  |  |                             > | 
 |  |  |                               {{ item.tags }} | 
 |  |  |                             </div> | 
 |  |  |                             <!-- <div class="arco-card-body-content-dec">{{ | 
 |  |  |                     <div | 
 |  |  |                       style="display: flex; flex-wrap: wrap" | 
 |  |  |                       class="card_content" | 
 |  |  |                     > | 
 |  |  |                       <div class="card-wrap"> | 
 |  |  |                         <div class="card_wrap_box"> | 
 |  |  |                           <div class="card_wrap_box_img"> | 
 |  |  |                             <img | 
 |  |  |                               :style="{ | 
 |  |  |                                 width: '100%', | 
 |  |  |                               }" | 
 |  |  |                               alt="暂无图片" | 
 |  |  |                               :src="item.logo ? httpUrl + item.logo : pdfImg" | 
 |  |  |                             /> | 
 |  |  |                           </div> | 
 |  |  |                           <a-card :bordered="false" hoverable> | 
 |  |  |                             <div class="arco-card-body-content"> | 
 |  |  |                               <div | 
 |  |  |                                 class="arco-card-body-content-title" | 
 |  |  |                                 style="word-wrap: break-word" | 
 |  |  |                               > | 
 |  |  |                                 {{ item.tags }} | 
 |  |  |                               </div> | 
 |  |  |                               <!-- <div class="arco-card-body-content-dec">{{ | 
 |  |  |                             list.type | 
 |  |  |                           }}</div> --> | 
 |  |  |                           </div> | 
 |  |  |                             </div> | 
 |  |  |                           </a-card> | 
 |  |  |                           <div class="arco-btn-group"> | 
 |  |  |                             <a-space class="btn-group"> | 
 |  |  |                               <!-- <editModel></editModel> --> | 
 |  |  |                               <a-button type="primary" @click="handleEditModel"> | 
 |  |  |                               <a-button @click="handleDeleteModel(item, 1)"> | 
 |  |  |                                 删除 | 
 |  |  |                               </a-button> | 
 |  |  |                               <a-button | 
 |  |  |                                 type="primary" | 
 |  |  |                                 @click="handleEditModel(item, 1)" | 
 |  |  |                               > | 
 |  |  |                                 编辑 | 
 |  |  |                               </a-button> | 
 |  |  |                             </a-space> | 
 |  |  |                           </div> | 
 |  |  |                         </a-card> | 
 |  |  |                       </div> | 
 |  |  |                     </div> | 
 |  |  |                     <div | 
 |  |  |                       class="card-wrap" | 
 |  |  |                       v-for="(list, index) of item.llm" | 
 |  |  |                       :key="index" | 
 |  |  |                     > | 
 |  |  |                       <div class="card_wrap_box"> | 
 |  |  |                         <div> | 
 |  |  |                           <img | 
 |  |  |                             :style="{ | 
 |  |  |                               width: '100%', | 
 |  |  |                               transform: 'translateY(-20px)', | 
 |  |  |                             }" | 
 |  |  |                             alt="dessert" | 
 |  |  |                             :src="list.logo" | 
 |  |  |                           /> | 
 |  |  |                           <!--   src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" --> | 
 |  |  |                         </div> | 
 |  |  |                         <a-card :bordered="false" hoverable> | 
 |  |  |                           <div class="arco-card-body-content"> | 
 |  |  |                             <div class="arco-card-body-content-title"> | 
 |  |  |                               {{ list.name }} | 
 |  |  |                             </div> | 
 |  |  |                             <div class="arco-card-body-content-dec">{{ | 
 |  |  |                               list.type | 
 |  |  |                             }}</div> | 
 |  |  |                       </div> | 
 |  |  |                       <div | 
 |  |  |                         class="card-wrap" | 
 |  |  |                         v-for="(list, index) of item.llm" | 
 |  |  |                         :key="index" | 
 |  |  |                       > | 
 |  |  |                         <div class="card_wrap_box"> | 
 |  |  |                           <div class="card_wrap_box_img"> | 
 |  |  |                             <img | 
 |  |  |                               :style="{ | 
 |  |  |                                 width: '100%', | 
 |  |  |                               }" | 
 |  |  |                               alt="暂无图片" | 
 |  |  |                               :src="list.logo ? httpUrl + list.logo : pdfImg" | 
 |  |  |                             /> | 
 |  |  |                             <!--   src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" --> | 
 |  |  |                           </div> | 
 |  |  |                           <a-card :bordered="false" hoverable> | 
 |  |  |                             <div class="arco-card-body-content"> | 
 |  |  |                               <div class="arco-card-body-content-title"> | 
 |  |  |                                 {{ list.name }} | 
 |  |  |                               </div> | 
 |  |  |                               <div class="arco-card-body-content-dec">{{ | 
 |  |  |                                 list.type | 
 |  |  |                               }}</div> | 
 |  |  |                             </div> | 
 |  |  |                           </a-card> | 
 |  |  |                           <div class="arco-btn-group"> | 
 |  |  |                             <a-space class="btn-group"> | 
 |  |  |                               <a-button @click="handleDeleteModel(list)"> | 
 |  |  |                                 删除 | 
 |  |  |                               </a-button> | 
 |  |  |                               <a-button | 
 |  |  |                               <!-- <a-button | 
 |  |  |                                 type="primary" | 
 |  |  |                                 @click="handleEditModel(list)" | 
 |  |  |                               > | 
 |  |  |                                 编辑 | 
 |  |  |                               </a-button> | 
 |  |  |                               </a-button> --> | 
 |  |  |  | 
 |  |  |                               <!-- <editModel></editModel> --> | 
 |  |  |                             </a-space> | 
 |  |  |                           </div> | 
 |  |  |                         </a-card> | 
 |  |  |                         </div> | 
 |  |  |                       </div> | 
 |  |  |                     </div> | 
 |  |  |                   </div> | 
 |  |  |                   </a-scrollbar> | 
 |  |  |                 </a-tab-pane> | 
 |  |  |               </a-tabs> | 
 |  |  |             </a-col> | 
 |  |  |             <div> </div> | 
 |  |  |             <div class="box_right"> | 
 |  |  |               <div class="search_input"> | 
 |  |  |             <div class="box_right" v-if="Object.keys(tabData).length > 0"> | 
 |  |  |               <!-- <div class="search_input"> | 
 |  |  |                 <a-input-search | 
 |  |  |                   :placeholder="$t('cardList.searchInput.placeholder')" | 
 |  |  |                   style="width: 240px" | 
 |  |  |                 /> | 
 |  |  |               </div> | 
 |  |  |               </div> --> | 
 |  |  |               <div> | 
 |  |  |                 <!-- <addModel></addModel> --> | 
 |  |  |                 <a-button | 
 |  |  |                   type="primary" | 
 |  |  |                   :loading="loading2" | 
 |  |  |                   @click="handleAddModel" | 
 |  |  |                   :disabled="addBtn" | 
 |  |  |                 > | 
 |  |  |                   <template #icon> | 
 |  |  |                     <icon-plus /> | 
 |  |  | 
 |  |  |         </a-card> | 
 |  |  |       </a-col> | 
 |  |  |     </a-row> | 
 |  |  |     <!-- 添加模型 --> | 
 |  |  |     <addPageModel | 
 |  |  |       v-model:show="show" | 
 |  |  |       :task_id="task_id" | 
 |  |  |       :type="modelType" | 
 |  |  |       :title="title" | 
 |  |  |       :editList="editList" | 
 |  |  |       @refresh-parent="refreshParentMethod" | 
 |  |  |       v-if="show" | 
 |  |  |     ></addPageModel> | 
 |  |  |     <!-- 添加tab模式 --> | 
 |  |  |     <addTableName | 
 |  |  |       v-model:tabShow="tabShow" | 
 |  |  |       :nameList="editList" | 
 |  |  |       :title="title" | 
 |  |  |       @refresh-parent="refreshParentMethod" | 
 |  |  |       v-if="tabShow" | 
 |  |  |     ></addTableName> | 
 |  |  |   </div> | 
 |  |  |   <!-- 添加模型 --> | 
 |  |  |   <addPageModel | 
 |  |  |     v-model:show="show" | 
 |  |  |     :task_id="task_id" | 
 |  |  |     :type="modelType" | 
 |  |  |     :title="title" | 
 |  |  |     :editList="editList" | 
 |  |  |     @refresh-parent="refreshParentMethod" | 
 |  |  |     v-if="show" | 
 |  |  |   ></addPageModel> | 
 |  |  |   <!-- 添加tab模式 --> | 
 |  |  |   <addTableName | 
 |  |  |     v-model:tabShow="tabShow" | 
 |  |  |     :nameList="editList" | 
 |  |  |     @refresh-parent="refreshParentMethod" | 
 |  |  |     v-if="tabShow" | 
 |  |  |   ></addTableName> | 
 |  |  | </template> | 
 |  |  |  | 
 |  |  | <script lang="ts" setup> | 
 |  |  |   import { ref, reactive, nextTick } from 'vue'; | 
 |  |  |   import addModel from '@/views/dmx/model/components/addModel.vue'; | 
 |  |  |   import editModel from '@/views/dmx/model/components/editModel.vue'; | 
 |  |  |   import addPageModel from './components/addPageModel.vue'; | 
 |  |  |   import addTableName from './components/addTableName.vue'; | 
 |  |  | 
 |  |  |     modelmyLlms, | 
 |  |  |     deleteLlm, | 
 |  |  |     deleteLlmFactory, | 
 |  |  |     getFactoryDetail, | 
 |  |  |   } from '@/api/model'; | 
 |  |  |   import { Modal, Message } from '@arco-design/web-vue'; | 
 |  |  |   import { userModelState } from '@/store'; | 
 |  |  |  | 
 |  |  |   import pdfImg from '@/assets/images/icon-chart.png'; | 
 |  |  |  | 
 |  |  |   const modelStore = userModelState(); | 
 |  |  |   let count = 5; | 
 |  |  |   const addBtn = ref(false); | 
 |  |  |   const activeKey = ref(1); | 
 |  |  |   const data = ref([ | 
 |  |  |     { | 
 |  |  | 
 |  |  |     key: { | 
 |  |  |       tags: '添加key', | 
 |  |  |       id: 1, | 
 |  |  |       live: 1, | 
 |  |  |     }, | 
 |  |  |   }); | 
 |  |  |  | 
 |  |  |   const isDeleteDialogVisible = ref(false); //删除提醒 | 
 |  |  |   const apiUrl = ref('http://127.0.0.1:5173'); | 
 |  |  |   // const httpUrl = import.meta.env.VITE_API_BASE_URL; | 
 |  |  |   // console.log(apiUrl.value, 777); | 
 |  |  |  | 
 |  |  |   const modalList = ref({}); | 
 |  |  |   const tabKey = ref('key'); | 
 |  |  |   const changeTabs = (val) => { | 
 |  |  |   const changeTabs = async (val) => { | 
 |  |  |     tabKey.value = val; | 
 |  |  |     await getFactory(); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const httpUrl = modelStore.hrefUrl; | 
 |  |  |   const show = ref(false); | 
 |  |  |   const tabShow = ref(false); | 
 |  |  |   const title = ref('添加模式'); | 
 |  |  | 
 |  |  |   const modelType = ref(1); | 
 |  |  |   const handleAdd = () => { | 
 |  |  |     tabShow.value = true; | 
 |  |  |     title.value = '添加模型'; | 
 |  |  |     editList.value.llm_factory = tabKey.value; | 
 |  |  |   }; | 
 |  |  |   const editList = ref({ llm_factory: '' }); | 
 |  |  |   const editList = ref<any>({ llm_factory: '' }); | 
 |  |  |   //增加模型子类 | 
 |  |  |   const handleAddModel = () => { | 
 |  |  |     if (tabKey.value == 'key') { | 
 |  |  |       tabShow.value = true; | 
 |  |  |     } else { | 
 |  |  |       modelType.value = 2; | 
 |  |  |       editList.value.llm_factory = tabKey.value; | 
 |  |  |       show.value = true; | 
 |  |  |       title.value = '添加模式'; | 
 |  |  |     } | 
 |  |  |     modelType.value = 2; | 
 |  |  |     editList.value = [{ llm_factory: '' }]; | 
 |  |  |     editList.value.llm_factory = tabKey.value; | 
 |  |  |     show.value = true; | 
 |  |  |     title.value = '添加模式'; | 
 |  |  |   }; | 
 |  |  |   //编辑模型子类 | 
 |  |  |   const handleEditModel = (val) => { | 
 |  |  |     if (tabKey.value == 'key') { | 
 |  |  |   const handleEditModel = (val, type) => { | 
 |  |  |     console.log(val, 6766); | 
 |  |  |     if (type == 1) { | 
 |  |  |       tabShow.value = true; | 
 |  |  |       editList.value = val; | 
 |  |  |       title.value = '编辑模型'; | 
 |  |  |       editList.value.llm_factory = tabKey.value; | 
 |  |  |     } else { | 
 |  |  |       modelType.value = 2; | 
 |  |  |       task_id.value = val.id; | 
 |  |  | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   //删除模型 | 
 |  |  |   const handleDeleteModel = (val) => { | 
 |  |  |     Modal.confirm({ | 
 |  |  |       title: '警告', | 
 |  |  |       content: '确认删除吗', | 
 |  |  |       okText: '确定', | 
 |  |  |       cancelText: '取消', | 
 |  |  |       onOk: async () => { | 
 |  |  |         const factory = tabKey.value; | 
 |  |  |         const res = await deleteLlm({ | 
 |  |  |           llm_factory: tabKey.value, | 
 |  |  |           llm_name: val.name, | 
 |  |  |         }); | 
 |  |  |   const handleDeleteModel = (val, type) => { | 
 |  |  |     if (type == 1) { | 
 |  |  |       handleDelete(val); | 
 |  |  |     } else { | 
 |  |  |       Modal.confirm({ | 
 |  |  |         title: '警告', | 
 |  |  |         content: '确认删除吗', | 
 |  |  |         okText: '确定', | 
 |  |  |         cancelText: '取消', | 
 |  |  |         onOk: async () => { | 
 |  |  |           const factory = tabKey.value; | 
 |  |  |           const res = await deleteLlm({ | 
 |  |  |             llm_factory: tabKey.value, | 
 |  |  |             llm_name: val.name, | 
 |  |  |           }); | 
 |  |  |  | 
 |  |  |         if ((res as any).code == 0) { | 
 |  |  |           queryModel(); | 
 |  |  |           tabKey.value = factory; | 
 |  |  |         } else { | 
 |  |  |         } | 
 |  |  |       }, | 
 |  |  |       onCancel: () => {}, | 
 |  |  |     }); | 
 |  |  |           if ((res as any).code == 0) { | 
 |  |  |             queryModel(); | 
 |  |  |             tabKey.value = factory; | 
 |  |  |           } else { | 
 |  |  |           } | 
 |  |  |         }, | 
 |  |  |         onCancel: () => {}, | 
 |  |  |       }); | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   //父级模型 | 
 |  |  |   const handleDelete = async (key: any) => { | 
 |  |  |     console.log(key, 45455); | 
 |  |  |     // tabData.value = tabData.value.filter((item) => item.key !== key); | 
 |  |  |     Reflect.deleteProperty(tabData.value, key); | 
 |  |  |     await deleteLlmFactory(key); | 
 |  |  |     queryModel(); | 
 |  |  |     console.log(tabData.value[key]); | 
 |  |  |     if (tabData.value[key].llm.length > 0) { | 
 |  |  |       Message.error('请先删除子模型'); | 
 |  |  |       return; | 
 |  |  |     } | 
 |  |  |     if (key !== 'key') { | 
 |  |  |       const res = await deleteLlmFactory(key); | 
 |  |  |       if ((res as any).code == 200) { | 
 |  |  |         Reflect.deleteProperty(tabData.value, key); | 
 |  |  |         queryModel(); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const visible = ref(false); | 
 |  |  |   const formRef = ref(null); | 
 |  |  |   const formRef = ref(); | 
 |  |  |  | 
 |  |  |   const form = reactive({ | 
 |  |  |     size: 'medium', | 
 |  |  | 
 |  |  |     }); | 
 |  |  |     return false; | 
 |  |  |   }; | 
 |  |  |   // const handleCancel = () => { | 
 |  |  |   //   formRef.value.resetFields(); | 
 |  |  |   //   visible.value = false; | 
 |  |  |   // }; | 
 |  |  |   // const handleSubmit = ({ values, errors }) => { | 
 |  |  |   //   this.$refs.formRef.validate().then((res, a, b) => { | 
 |  |  |   //     debugger; | 
 |  |  |   //     console.log('values', values); | 
 |  |  |   //   }); | 
 |  |  |   // }; | 
 |  |  |  | 
 |  |  |   //获取模型列表 | 
 |  |  |   const loading = ref(false); | 
 |  |  | 
 |  |  |     modalList.value = res.data; | 
 |  |  |     loading.value = true; | 
 |  |  |     tabData.value = Object.assign({}, tabData.value, res.data); | 
 |  |  |     tabData.value = filterObject(tabData.value, 1); | 
 |  |  |     tabKey.value = Object.keys(tabData.value)[0]; | 
 |  |  |     await getFactory(); | 
 |  |  |   }; | 
 |  |  |   queryModel(); | 
 |  |  |   //返回满足条件的对象 | 
 |  |  |   const filterObject = (obj, threshold) => { | 
 |  |  |     return Object.keys(obj) | 
 |  |  |       .filter((key) => obj[key].added == 1) | 
 |  |  |       .reduce((result, key) => { | 
 |  |  |         result[key] = obj[key]; | 
 |  |  |         return result; | 
 |  |  |       }, {}); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const refreshParentMethod = () => { | 
 |  |  |     queryModel(); | 
 |  |  |     // 这里执行需要的操作 | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const getFactory = async () => { | 
 |  |  |     const { data } = await getFactoryDetail({ | 
 |  |  |       factory_name: tabKey.value, | 
 |  |  |     }); | 
 |  |  |  | 
 |  |  |     if (data.set_type == 2) { | 
 |  |  |       addBtn.value = true; | 
 |  |  |     } else { | 
 |  |  |       addBtn.value = false; | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  | </script> | 
 |  |  |  | 
 |  |  | 
 |  |  |       font-size: 14px; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   :deep(.arco-list-col) { | 
 |  |  |     display: flex; | 
 |  |  |     flex-direction: row; | 
 |  |  | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   :deep(.arco-tabs-nav-tab) { | 
 |  |  |     flex: none; | 
 |  |  |     width: 60%; | 
 |  |  |   } | 
 |  |  |   .table_add_clore { | 
 |  |  |     :deep(.arco-tabs-nav-add-btn .arco-icon-hover::before) { | 
 |  |  |       top: 50%; | 
 |  |  | 
 |  |  |     :deep(.arco-tabs-nav-add-btn .arco-icon-hover .arco-icon) { | 
 |  |  |       color: #fff; | 
 |  |  |     } | 
 |  |  |     :deep(.arco-tabs-nav) { | 
 |  |  |       max-width: 60%; | 
 |  |  |     } | 
 |  |  |     // :deep(.arco-tabs-nav) { | 
 |  |  |     //   max-width: 60%; | 
 |  |  |     // } | 
 |  |  |  | 
 |  |  |     :deep(.arco-icon-hover::before) { | 
 |  |  |       top: 50%; | 
 |  |  | 
 |  |  |       transform: translate(-50%, -50%); | 
 |  |  |       // border-radius: 0; | 
 |  |  |       // background-color: #eee; | 
 |  |  |     } | 
 |  |  |     :deep(.arco-tabs-tab-close-btn) { | 
 |  |  |       display: none; | 
 |  |  |     } | 
 |  |  |     :deep(.arco-tabs-tab-close-btn .arco-icon) { | 
 |  |  |       color: #666; | 
 |  |  | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   .card_content { | 
 |  |  |     position: relative; | 
 |  |  |     .arco-btn-group { | 
 |  |  |       position: absolute; | 
 |  |  |       right: 10px; | 
 |  |  |       top: 90px; | 
 |  |  |     } | 
 |  |  |     .card_wrap_box_img { | 
 |  |  |       min-height: 200px; | 
 |  |  |       max-height: 240px; | 
 |  |  |       // min-height: 200px; | 
 |  |  |       height: 200px; | 
 |  |  |       width: 100%; | 
 |  |  |       img { | 
 |  |  |         width: 100%; /* 或者其他固定宽度 */ | 
 |  |  |         height: 100%; /* 或者其他固定高度 */ | 
 |  |  |         object-fit: cover; /* 不会变形,但可能裁剪图片 */ | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |     .card_wrap_box { | 
 |  |  |       // position: relative; | 
 |  |  |       .arco-btn-group { | 
 |  |  |         position: absolute; | 
 |  |  |         right: 10px; | 
 |  |  |         top: 87%; | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   .card-wrap { | 
 |  |  |     width: 320px; | 
 |  |  |     height: 350px; | 
 |  |  |     margin: 30px; | 
 |  |  |     transition: all 0.3s; | 
 |  |  |     border: 1px solid var(--color-neutral-3); | 
 |  |  |     border-radius: 4px; | 
 |  |  |     position: relative; | 
 |  |  |     &:hover { | 
 |  |  |       transform: translateY(-4px); | 
 |  |  |       // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   .card-wrap { | 
 |  |  |     width: 320px; | 
 |  |  |     height: 350px; | 
 |  |  |     margin: 30px; | 
 |  |  |     transition: all 0.3s; | 
 |  |  |     border: 1px solid var(--color-neutral-3); | 
 |  |  |     border-radius: 4px; | 
 |  |  |     position: relative; | 
 |  |  |     &:hover { | 
 |  |  |       transform: translateY(-4px); | 
 |  |  |       // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   .card-wrap { | 
 |  |  |     width: 320px; | 
 |  |  |     height: 350px; | 
 |  |  |     margin: 30px; | 
 |  |  |     margin: 20px 30px; | 
 |  |  |     transition: all 0.3s; | 
 |  |  |     border: 1px solid var(--color-neutral-3); | 
 |  |  |     border-radius: 4px; |