diff --git a/index.html b/index.html index 8388c4b..5772f43 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,17 @@ - + - + - Vite + Vue + + 年糕崽崽的个人页面合集 + + +
diff --git a/package.json b/package.json index 3c82eaa..005484d 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,6 @@ "preview": "vite preview" }, "dependencies": { - "tailwindcss": "^4.1.4", - "vue": "^3.5.13", "@ant-design-vue/pro-layout": "^3.2.5", "@ant-design/icons-vue": "^7.0.1", "@fortawesome/fontawesome-free": "^6.7.2", @@ -21,6 +19,9 @@ "lucide-vue-next": "^0.507.0", "pinia": "^2.1.7", "swiper": "^11.0.5", + "tailwindcss": "^4.1.4", + "three": "^0.185.1", + "vue": "^3.5.13", "vue-router": "^4.2.5" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 061cee9..ceabea2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@ant-design/icons-vue': specifier: ^7.0.1 version: 7.0.1(vue@3.5.13) + '@fortawesome/fontawesome-free': + specifier: ^6.7.2 + version: 6.7.2 '@tailwindcss/vite': specifier: ^4.1.4 version: 4.1.4(vite@6.3.3(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.88.0)) @@ -23,9 +26,6 @@ importers: ant-design-vue: specifier: ^4.1.1 version: 4.2.6(vue@3.5.13) - aos: - specifier: ^2.3.4 - version: 2.3.4 axios: specifier: ^1.6.2 version: 1.9.0 @@ -41,6 +41,9 @@ importers: tailwindcss: specifier: ^4.1.4 version: 4.1.4 + three: + specifier: ^0.185.1 + version: 0.185.1 vue: specifier: ^3.5.13 version: 3.5.13 @@ -263,6 +266,10 @@ packages: cpu: [x64] os: [win32] + '@fortawesome/fontawesome-free@6.7.2': + resolution: {integrity: sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==} + engines: {node: '>=6'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} @@ -632,9 +639,6 @@ packages: peerDependencies: vue: '>=3.2.0' - aos@2.3.4: - resolution: {integrity: sha512-zh/ahtR2yME4I51z8IttIt4lC1Nw0ktsFtmeDzID1m9naJnWXhCoARaCgNOGXb5CLy3zm+wqmRAEgMYB5E2HUw==} - array-tree-filter@2.1.0: resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==} @@ -659,9 +663,6 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - classlist-polyfill@1.2.0: - resolution: {integrity: sha512-GzIjNdcEtH4ieA2S8NmrSxv7DfEV5fmixQeyTmqmRmRJPGpRBaSnA2a0VrCjyT8iW8JjEdMbKzDotAJf+ajgaQ==} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -893,12 +894,6 @@ packages: lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - - lodash.throttle@4.1.1: - resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -1015,6 +1010,9 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + three@0.185.1: + resolution: {integrity: sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==} + throttle-debounce@5.0.2: resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} @@ -1229,6 +1227,8 @@ snapshots: '@esbuild/win32-x64@0.25.3': optional: true + '@fortawesome/fontawesome-free@6.7.2': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@parcel/watcher-android-arm64@2.5.1': @@ -1547,12 +1547,6 @@ snapshots: vue-types: 3.0.2(vue@3.5.13) warning: 4.0.3 - aos@2.3.4: - dependencies: - classlist-polyfill: 1.2.0 - lodash.debounce: 4.0.8 - lodash.throttle: 4.1.1 - array-tree-filter@2.1.0: {} async-validator@4.2.5: {} @@ -1581,8 +1575,6 @@ snapshots: dependencies: readdirp: 4.1.2 - classlist-polyfill@1.2.0: {} - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -1787,10 +1779,6 @@ snapshots: lodash-es@4.17.21: {} - lodash.debounce@4.0.8: {} - - lodash.throttle@4.1.1: {} - lodash@4.17.21: {} loose-envify@1.4.0: @@ -1907,6 +1895,8 @@ snapshots: tapable@2.2.1: {} + three@0.185.1: {} + throttle-debounce@5.0.2: {} tinyglobby@0.2.13: diff --git a/public/models/README.txt b/public/models/README.txt new file mode 100644 index 0000000..0491625 --- /dev/null +++ b/public/models/README.txt @@ -0,0 +1,8 @@ +把下载好的小米 YU7 模型(GLB 格式)放到这个目录,命名为 yu7.glb, +/lab/car-3d 页面会自动加载它。 + +推荐来源(免费,需登录 Sketchfab 账号下载): +https://sketchfab.com/3d-models/2025-xiaomi-yu7-3b8daf98bbe54e1389e6bb107575105f +下载时选择 glTF Binary (.glb) 格式;授权 CC BY-NC-SA(非商用、署名)。 + +没有该文件时页面会展示内置演示车模;也可以直接把任意 .glb 拖进页面加载。 diff --git a/public/models/yu7.glb b/public/models/yu7.glb new file mode 100644 index 0000000..4631dd5 Binary files /dev/null and b/public/models/yu7.glb differ diff --git a/src/App.vue b/src/App.vue index 3602e60..881c44c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,10 +1,201 @@ - diff --git a/src/components/CollectionSwitch.vue b/src/components/CollectionSwitch.vue new file mode 100644 index 0000000..1f3e9c0 --- /dev/null +++ b/src/components/CollectionSwitch.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/src/components/CommandPalette.vue b/src/components/CommandPalette.vue new file mode 100644 index 0000000..d04ecd2 --- /dev/null +++ b/src/components/CommandPalette.vue @@ -0,0 +1,324 @@ + + + + + diff --git a/src/components/PromptSkillFab.vue b/src/components/PromptSkillFab.vue new file mode 100644 index 0000000..7a8a9d1 --- /dev/null +++ b/src/components/PromptSkillFab.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/components/StyleGallery.vue b/src/components/StyleGallery.vue new file mode 100644 index 0000000..cf20984 --- /dev/null +++ b/src/components/StyleGallery.vue @@ -0,0 +1,1217 @@ + + + + + diff --git a/src/data/corpProfiles.js b/src/data/corpProfiles.js new file mode 100644 index 0000000..bebfdbc --- /dev/null +++ b/src/data/corpProfiles.js @@ -0,0 +1,372 @@ +// 企业官网合集:9 大行业各一家虚构公司,供 43 个风格页共用 +const img = (seed) => `https://picsum.photos/seed/${seed}/640/420` + +export const corpProfiles = { + ecom: { + industry: 'ecom', + industryLabel: '电商', + name: '年糕严选', + nameEn: 'NIANGAO SELECT', + logo: '🛍️', + slogan: '把好物,挑到你心上', + subSlogan: '10 年买手团队 · 全球直采 · 假一赔十', + desc: '年糕严选是一家品质生活电商平台,坚持「少而精」的选品哲学,从全球 32 个国家直采好物,每一件商品都要闯过 27 道质检工序才能上架。', + services: [ + { icon: '🌏', name: '全球直采', desc: '32 国原产地直连,砍掉所有中间商' }, + { icon: '🔬', name: '严选质检', desc: '27 道质检工序,批批抽检全覆盖' }, + { icon: '🚚', name: '次日送达', desc: '全国 89 城当日发货、次日送达' }, + { icon: '💝', name: '无忧售后', desc: '30 天无理由退换,假一赔十' }, + ], + stats: [ + { value: '3200万', label: '注册用户' }, + { value: '98.6%', label: '好评率' }, + { value: '32 国', label: '直采供应链' }, + { value: '24h', label: '客服在线' }, + ], + cases: [ + { name: '云朵羽绒被', tag: '居家', desc: '95% 白鹅绒,轻若云朵,暖如拥抱', image: img('ng-ecom-quilt'), price: '¥599' }, + { name: '晨光手冲壶', tag: '厨房', desc: '细口控流,在家复刻咖啡馆的清晨', image: img('ng-ecom-kettle'), price: '¥239' }, + { name: '山野露营灯', tag: '户外', desc: '三档暖光,续航 72 小时的小太阳', image: img('ng-ecom-lamp'), price: '¥129' }, + { name: '绵云棉袜礼盒', tag: '服饰', desc: '新疆长绒棉,一盒装下整个冬天', image: img('ng-ecom-socks'), price: '¥89' }, + ], + testimonials: [ + { text: '在严选买东西不用做功课,闭眼下单就行,省下的时间又能摸鱼了。', author: '阿糕', role: '五年老用户' }, + { text: '售后是真的快,羽绒被有个线头,客服直接补发了一床新的。', author: '团子妈', role: '母婴买家' }, + ], + partners: ['顺丰速运', '中检集团', '太平洋保险', '菜鸟仓配', '银联安付'], + contacts: { phone: '400-880-2501', email: 'hi@ngselect.shop', addr: '杭州市西湖区严选大厦 25F' }, + founded: 2016, + }, + + art: { + industry: 'art', + industryLabel: '艺术', + name: '拾光美术馆', + nameEn: 'LUMINA GALLERY', + logo: '🖼️', + slogan: '让光,落在每一件作品上', + subSlogan: '当代艺术展览 · 馆藏研究 · 公共教育', + desc: '拾光美术馆成立于 2012 年,是一家专注当代艺术的独立美术馆。我们相信艺术不该被锁进仓库,每年 12 场特展、680 余件馆藏轮流与观众见面。', + services: [ + { icon: '🖼', name: '特展策划', desc: '年均 12 场特展,从策展到布光全自制' }, + { icon: '📚', name: '馆藏研究', desc: '680+ 件馆藏的整理、修复与出版' }, + { icon: '🎨', name: '公共教育', desc: '儿童美育、夜场导览与艺术家对谈' }, + { icon: '🛍', name: '艺术衍生', desc: '与艺术家联名的版画与生活好物' }, + ], + stats: [ + { value: '680+', label: '馆藏作品' }, + { value: '12 场', label: '年度特展' }, + { value: '45万', label: '年观展人次' }, + { value: '30 城', label: '巡展足迹' }, + ], + cases: [ + { name: '未完成的蓝', tag: '绘画特展', desc: '17 位艺术家对「蓝」的 63 次追问', image: img('ng-art-blue'), year: '2026' }, + { name: '纸上山水', tag: '水墨新语', desc: '当代水墨的褶皱、留白与呼吸', image: img('ng-art-ink'), year: '2025' }, + { name: '机器梦境', tag: '新媒体', desc: '算法生成影像的沉浸式六幕剧场', image: img('ng-art-dream'), year: '2025' }, + { name: '童年再来一次', tag: '互动装置', desc: '可以踩、可以躺、可以尖叫的展厅', image: img('ng-art-child'), year: '2024' }, + ], + testimonials: [ + { text: '每次来拾光都像被人轻轻拍了拍肩膀:嘿,生活还有别的可能。', author: '林小满', role: '年卡观众' }, + { text: '他们是少数真的会为作品重新改造展厅的美术馆。', author: '陈屿', role: '参展艺术家' }, + ], + partners: ['央美设计学院', '青年艺术基金', '城市文化局', 'ART LAB', '拾光文创'], + contacts: { phone: '0571-8890-1206', email: 'hello@lumina.gallery', addr: '杭州市滨江区拾光艺术园区 A 馆' }, + founded: 2012, + }, + + pharma: { + industry: 'pharma', + industryLabel: '医药', + name: '本草汇制药', + nameEn: 'HERBAHUI PHARMA', + logo: '🌿', + slogan: '古方新制,本草如汇', + subSlogan: '现代中药研发 · 制造 · 全链路溯源', + desc: '本草汇制药始建于 1958 年,深耕经典名方的现代化制剂。三座 GMP 基地、120 余个药品批文,让老药方以更精准、更安全的方式抵达今天的药箱。', + services: [ + { icon: '📜', name: '经典名方', desc: '32 首经典名方的现代化复方制剂' }, + { icon: '⚗️', name: '现代制剂', desc: '颗粒、软胶囊、缓释片全剂型产线' }, + { icon: '🔗', name: '全程溯源', desc: '从药田到药房,一物一码可追溯' }, + { icon: '🎓', name: '学术共建', desc: '与 9 所中医药大学联合实验室' }, + ], + stats: [ + { value: '120+', label: '药品批文' }, + { value: '3 座', label: 'GMP 基地' }, + { value: '27 项', label: '发明专利' }, + { value: '66 年', label: '制药历史' }, + ], + cases: [ + { name: '安神定志丸', tag: '经典名方', desc: '古方安神,现代工艺微丸缓释', image: img('ng-pharma-anshen') }, + { name: '川贝润肺膏', tag: '呼吸系统', desc: '川贝母道地直采,低温熬制', image: img('ng-pharma-runfei') }, + { name: '小儿健脾颗粒', tag: '儿科用药', desc: '口感重新调配,孩子不抗拒', image: img('ng-pharma-jianpi') }, + { name: '三七通络片', tag: '心脑血管', desc: '文山三七,指纹图谱批批质控', image: img('ng-pharma-sanqi') }, + ], + testimonials: [ + { text: '他们的溯源码是真的能扫出药田坐标,采购验收特别踏实。', author: '刘主任', role: '连锁药房采购' }, + { text: '同一个方子,本草汇的批间一致性做得最稳。', author: '周教授', role: '中医药大学' }, + ], + partners: ['省中医院', '国家药检院', '同济药学院', '华东医药储运', '道地药材联盟'], + contacts: { phone: '400-996-1958', email: 'contact@herbahui.cn', addr: '亳州市高新区本草汇产业园' }, + founded: 1958, + }, + + medical: { + industry: 'medical', + industryLabel: '医疗', + name: '安和医疗', + nameEn: 'ANHE HEALTH', + logo: '🏥', + slogan: '把安心,交给专业', + subSlogan: '综合医疗集团 · 12 家分院 · 互联网医院', + desc: '安和医疗是一家覆盖预防、诊疗、康复全周期的综合医疗集团。1600 余名医护、12 家分院与一家互联网医院,让专业的照护离家更近一点。', + services: [ + { icon: '🩺', name: '全科门诊', desc: '常见病一站式诊疗,平均候诊 15 分钟' }, + { icon: '❤️', name: '专科中心', desc: '心血管、骨科、妇儿等 9 大专科中心' }, + { icon: '📱', name: '互联网医院', desc: '在线复诊、开方与药品配送到家' }, + { icon: '📋', name: '健康管理', desc: '体检、随访与慢病管理长期陪伴' }, + ], + stats: [ + { value: '12 家', label: '连锁分院' }, + { value: '1600+', label: '执业医护' }, + { value: '98.2%', label: '患者满意度' }, + { value: '24h', label: '急诊值守' }, + ], + cases: [ + { name: '心血管中心', tag: '重点专科', desc: '胸痛中心认证,绿色通道 30 分钟响应', image: img('ng-med-heart') }, + { name: '骨科与运动医学', tag: '特色专科', desc: '关节镜微创,运动员同款康复方案', image: img('ng-med-bone') }, + { name: '妇儿健康中心', tag: '温馨专区', desc: '从产检到儿保的一条走廊', image: img('ng-med-mom') }, + { name: '口腔医学中心', tag: '舒适化诊疗', desc: '无痛种植与儿童早期矫治', image: img('ng-med-dental') }, + ], + testimonials: [ + { text: '夜里孩子发烧,线上问诊十分钟出方案,药一早就送到了。', author: '糕爸', role: '互联网医院用户' }, + { text: '术前谈话讲得明明白白,这种被尊重的感觉很难得。', author: '王阿姨', role: '骨科患者' }, + ], + partners: ['市医保定点', '三甲协作网络', '红十字会', '平安健康险', '急救中心 120'], + contacts: { phone: '400-120-1200', email: 'care@anhe.health', addr: '杭州市拱墅区安和医疗城' }, + founded: 2008, + }, + + tech: { + industry: 'tech', + industryLabel: '科技', + name: '量子跃迁科技', + nameEn: 'QUANTUM LEAP TECH', + logo: '⚛️', + slogan: '让算力,跃迁到下一个数量级', + subSlogan: '智能芯片 · 星载计算 · 边缘基础设施', + desc: '量子跃迁科技是一家硬科技公司,自研芯片架构与星载计算平台。我们相信算力是新时代的水电煤,而我们的工作是把发电厂做小、做快、做上天。', + services: [ + { icon: '🔲', name: '跃迁智能芯片', desc: '自研架构 NPU,能效比提升 4.2 倍' }, + { icon: '🛰', name: '星载计算', desc: '抗辐照设计,在轨稳定运行 5 年+' }, + { icon: '📦', name: '边缘服务器', desc: '-40℃~85℃ 宽温,工业现场即插即用' }, + { icon: '🧑‍💻', name: '开发者平台', desc: '一套工具链,从云端编译到端侧部署' }, + ], + stats: [ + { value: '2000+', label: '授权专利' }, + { value: '4.2×', label: '能效比提升' }, + { value: '40+', label: '国家与地区部署' }, + { value: '12亿', label: '设备搭载量' }, + ], + cases: [ + { name: '跃迁 X1 芯片', tag: '旗舰芯片', desc: '7nm 制程,128 TOPS 端侧算力', image: img('ng-tech-chip') }, + { name: '星尘卫星载荷', tag: '航天计算', desc: '在轨 AI 推理,图像即拍即析', image: img('ng-tech-sat') }, + { name: '磐石边缘服务器', tag: '工业边缘', desc: '产线质检延迟压到 8ms', image: img('ng-tech-edge') }, + { name: '跃迁开发者云', tag: '工具链', desc: '3 行命令完成模型端侧化', image: img('ng-tech-cloud') }, + ], + testimonials: [ + { text: '同样的模型,跑在 X1 上功耗直接砍半,我们的无人机续航多了 11 分钟。', author: '张工', role: '无人机厂商 CTO' }, + { text: '星载那套东西是真的敢想敢做,联调时像在看科幻片。', author: '李研究员', role: '航天院所' }, + ], + partners: ['航天五院', '中科寒武纪谷', '极目无人机', '智造工业联盟', '高校 AI 实验室'], + contacts: { phone: '010-8890-2077', email: 'biz@qleap.tech', addr: '北京市海淀区跃迁大厦' }, + founded: 2017, + }, + + travel: { + industry: 'travel', + industryLabel: '景区', + name: '云栖山谷', + nameEn: 'CLOUD VALLEY', + logo: '⛰️', + slogan: '把日子,过进山水里', + subSlogan: '国家 5A 级景区 · 86km² 山水秘境', + desc: '云栖山谷坐落于群山褶皱之间,86 平方公里内藏着竹海、云瀑、星空营地与千年古枫。四季各有一副面孔,随时来,都是好时候。', + services: [ + { icon: '🚡', name: '云顶索道', desc: '20 分钟直上 1800 米云海观景台' }, + { icon: '🥾', name: '山脊栈道', desc: '12km 全木栈道,坡缓景美老少皆宜' }, + { icon: '♨️', name: '温泉民宿', desc: '古枫林间的 9 家山宿与露天汤池' }, + { icon: '🎑', name: '四季节庆', desc: '春樱、夏萤、秋枫、冬雪各一场大戏' }, + ], + stats: [ + { value: '5A', label: '国家级景区' }, + { value: '86km²', label: '景区面积' }, + { value: '280万', label: '年游客量' }, + { value: '320 种', label: '动植物记录' }, + ], + cases: [ + { name: '云顶日出', tag: '观景台', desc: '海拔 1800 米,云海翻涌如潮', image: img('ng-travel-sunrise') }, + { name: '雾漫竹海', tag: '徒步线', desc: '晨雾里的十里竹廊与鸟鸣', image: img('ng-travel-bamboo') }, + { name: '星空营地', tag: '过夜体验', desc: '零光污染,银河肉眼可见', image: img('ng-travel-star') }, + { name: '古枫温泉', tag: '温泉区', desc: '千年枫树下的露天暖汤', image: img('ng-travel-spring') }, + ], + testimonials: [ + { text: '在星空营地看到银河的那一刻,孩子安静了整整十分钟。', author: '一家四口', role: '亲子游客' }, + { text: '栈道修得很良心,我爸七十岁走完全程还想再来。', author: '橘子', role: '徒步爱好者' }, + ], + partners: ['携程旅行', '飞猪度假', '同程旅游', '省文旅厅', '山地救援队'], + contacts: { phone: '400-560-8600', email: 'visit@cloudvalley.cn', addr: '云栖市山谷镇景区游客中心' }, + founded: 1999, + }, + + home: { + industry: 'home', + industryLabel: '家政', + name: '到家帮', + nameEn: 'DAOJIABANG', + logo: '🧹', + slogan: '家里的事,交给到家帮', + subSlogan: '一站式家政 · 5 万认证阿姨 · 58 城覆盖', + desc: '到家帮是一站式家政服务平台。从两小时的日常保洁到 26 天的金牌月嫂,每一位服务者都经过背景核验、技能实操与礼仪培训三关认证。', + services: [ + { icon: '🧽', name: '日常保洁', desc: '两小时焕新,厨卫重点深洁' }, + { icon: '🛋', name: '深度除螨', desc: '床品沙发高温除螨,眼见为净' }, + { icon: '🗄', name: '收纳整理', desc: '注册整理师上门,衣柜重获新生' }, + { icon: '🍼', name: '母婴护理', desc: '金牌月嫂与育儿嫂,持证上岗' }, + ], + stats: [ + { value: '58 城', label: '服务覆盖' }, + { value: '5万+', label: '认证服务者' }, + { value: '4.9 分', label: '平均评分' }, + { value: '300万', label: '服务家庭' }, + ], + cases: [ + { name: '全屋大扫除', tag: '爆款套餐', desc: '4 小时两人组,年前焕新首选', image: img('ng-home-clean'), price: '¥299 起' }, + { name: '开荒保洁', tag: '新居必备', desc: '装修交付后的第一次深呼吸', image: img('ng-home-new'), price: '¥6/㎡' }, + { name: '衣橱整理', tag: '整理收纳', desc: '注册整理师陪你告别乱衣山', image: img('ng-home-closet'), price: '¥499 起' }, + { name: '金牌月嫂', tag: '母婴护理', desc: '10 年经验,26 天贴身照护', image: img('ng-home-baby'), price: '¥12800 起' }, + ], + testimonials: [ + { text: '阿姨来之前发了健康证和实名认证,干完活厨房亮得能照镜子。', author: '年糕妈', role: '包月用户' }, + { text: '月嫂王姐走的那天,全家都舍不得,孩子睡整觉全靠她。', author: '新手爸爸', role: '月嫂客户' }, + ], + partners: ['人社职业认证', '平安雇主险', '链家社区站', '妇联巾帼驿站', '保险无忧赔'], + contacts: { phone: '400-666-5858', email: 'service@daojiabang.com', addr: '杭州市余杭区到家帮运营中心' }, + founded: 2015, + }, + + ai: { + industry: 'ai', + industryLabel: 'AI', + name: '深思智能', + nameEn: 'DEEPTHINK AI', + logo: '🧠', + slogan: '让每个行业,都长出会思考的大脑', + subSlogan: '深思大模型 · 行业智能体 · 私有化部署', + desc: '深思智能以自研大模型为底座,为医疗、工业、金融等 40 多个行业构建开箱即用的智能体。模型可以很大,落地必须很轻。', + services: [ + { icon: '💬', name: '深思大模型', desc: '128K 上下文,中文理解行业领先' }, + { icon: '🤖', name: '行业智能体', desc: '40+ 行业模板,两周内上线' }, + { icon: '👁', name: '多模态理解', desc: '文本、图像、语音、视频一网打尽' }, + { icon: '🔒', name: '私有化部署', desc: '数据不出域,一体机开箱即用' }, + ], + stats: [ + { value: '128K', label: '上下文长度' }, + { value: '40+', label: '行业解决方案' }, + { value: '3000+', label: '企业客户' }, + { value: '99.99%', label: '服务可用性' }, + ], + cases: [ + { name: '深思·问答', tag: '通用助手', desc: '企业知识库秒答,引用可溯源', image: img('ng-ai-chat') }, + { name: '深思·代码', tag: '研发提效', desc: '补全、评审、重构一条龙', image: img('ng-ai-code') }, + { name: '深思·医疗', tag: '行业模型', desc: '病历结构化与辅助诊断建议', image: img('ng-ai-med') }, + { name: '深思·质检', tag: '工业视觉', desc: '产线缺陷检出率 99.7%', image: img('ng-ai-qc') }, + ], + testimonials: [ + { text: '知识库问答上线一个月,客服工单量降了 43%。', author: '运营 VP', role: '连锁零售集团' }, + { text: '私有化一体机是真的省心,插电、导数据、开用。', author: '信息科主任', role: '三甲医院' }, + ], + partners: ['智源研究院', '信通院可信 AI', '华东算力中心', '开源社区 NGOSS', '行业数据联盟'], + contacts: { phone: '400-870-1024', email: 'bd@deepthink.ai', addr: '上海市徐汇区西岸智塔 40F' }, + founded: 2021, + }, + + saas: { + industry: 'saas', + industryLabel: 'SaaS', + name: '团子云', + nameEn: 'TUANZI CLOUD', + logo: '☁️', + slogan: '一个工作台,装下整个团队', + subSlogan: '项目 · 文档 · 审批 · 数据,一站式协作', + desc: '团子云是一体化协作云平台。项目看板、多人文档、自动化审批与数据看板长在同一个工作台里,5 分钟上手,告别在八个软件间反复横跳。', + services: [ + { icon: '📌', name: '项目协作', desc: '看板、甘特、迭代,敏捷开箱即用' }, + { icon: '📝', name: '云端文档', desc: '多人实时协同,评论划词即达' }, + { icon: '✅', name: '流程审批', desc: '拖拽搭建审批流,手机一键批' }, + { icon: '📈', name: '数据看板', desc: '业务数据自动汇总成可视化报表' }, + ], + stats: [ + { value: '12万+', label: '企业客户' }, + { value: '99.95%', label: 'SLA 保障' }, + { value: '5 min', label: '平均上手时间' }, + { value: '46 项', label: '生态集成' }, + ], + cases: [ + { name: '敏捷研发看板', tag: '研发团队', desc: '需求到发布全流程在线追踪', image: img('ng-saas-kanban') }, + { name: '多人协同文档', tag: '全员协作', desc: '一篇文档承载会议到复盘', image: img('ng-saas-doc') }, + { name: '自动化审批', tag: '行政人事', desc: '报销单据 OCR 自动填写', image: img('ng-saas-flow') }, + { name: '经营数据看板', tag: '管理层', desc: '每天早上一张全局驾驶舱', image: img('ng-saas-bi') }, + ], + testimonials: [ + { text: '把 Jira、飞书文档、钉钉审批合成一个,新人培训成本几乎为零。', author: '效能负责人', role: '200 人研发团队' }, + { text: '老板终于不在群里要日报了,他自己看看板。', author: '项目经理', role: '广告公司' }, + ], + partners: ['企业微信', '钉钉开放平台', '飞书集成', 'AWS 中国', '阿里云市场'], + pricing: [ + { name: '免费版', price: '0', unit: '永久免费', desc: '10 人以下小团队', feats: ['3 个项目空间', '1GB 文档存储', '基础看板'] }, + { name: '团队版', price: '39', unit: '人/月', desc: '成长期团队首选', feats: ['无限项目', '100GB 存储', '自动化审批', '数据看板'], hot: true }, + { name: '企业版', price: '99', unit: '人/月', desc: '安全合规进阶', feats: ['私有化选项', '审计日志', 'SSO 单点登录', '专属客成'] }, + ], + contacts: { phone: '400-800-8642', email: 'sales@tuanzi.cloud', addr: '深圳市南山区团子云大厦 18F' }, + founded: 2019, + }, + furniture: { + industry: 'furniture', + industryLabel: '家具', + name: '序木家居', + nameEn: 'XUMU LIVING', + logo: '🪑', + slogan: '家的秩序,由木开始', + subSlogan: '原创设计 · 实木榫卯 · 整件五年质保', + desc: '序木家居是一家原创设计家具品牌,与 12 位独立设计师长期合作。我们坚持使用可溯源的 FSC 认证木材与传统榫卯工艺,相信一件好家具应该陪一个家至少二十年。', + services: [ + { icon: '🌳', name: '可溯源选材', desc: 'FSC 认证林场直采,每块木料都有身份档案' }, + { icon: '🪵', name: '榫卯工艺', desc: '37 道手工工序,整件不见一颗多余螺钉' }, + { icon: '📐', name: '空间定制', desc: '驻店设计师上门量尺,一比一手绘出图' }, + { icon: '🧤', name: '白手套配送', desc: '入户安装调平,包装废料当场带走' }, + ], + stats: [ + { value: '12 位', label: '合作设计师' }, + { value: '37 道', label: '手工工序' }, + { value: '5 年', label: '整件质保' }, + { value: '9 城', label: '线下展厅' }, + ], + products: [ + { id: 'cloud-sofa', name: '云栖沙发', en: 'CLOUD SOFA', cat: '客厅', price: 28800, material: '白蜡木 · 羊毛混纺', size: 'W2400 × D980 × H820', desc: '把一朵云安放在客厅正中央,坐感松弛而不失支撑。', seed: 'xumu-sofa' }, + { id: 'ridge-table', name: '山形茶几', en: 'RIDGE LOW TABLE', cat: '客厅', price: 9600, material: '黑胡桃木整板', size: 'W1200 × D600 × H360', desc: '一整块黑胡桃顺纹开料,桌沿保留山形原木边。', seed: 'xumu-ridge' }, + { id: 'moon-chair', name: '月洞圈椅', en: 'MOON CHAIR', cat: '书房', price: 12400, material: '黑胡桃木 · 手工藤编', size: 'W620 × D580 × H780', desc: '圈椅的月洞轮廓削到最薄,藤面透气,久坐生凉。', seed: 'xumu-moon' }, + { id: 'strata-table', name: '叠影餐桌', en: 'STRATA TABLE', cat: '餐厨', price: 19800, material: '鱼肚白大理石 · 黄铜', size: 'W1800 × D900 × H750', desc: '石纹如水波叠影,黄铜桌脚在灯下泛暖光。', seed: 'xumu-strata' }, + { id: 'veil-shelf', name: '屏风书架', en: 'VEIL SHELF', cat: '书房', price: 15200, material: '白橡木 · 长虹玻璃', size: 'W900 × D350 × H1900', desc: '一半是书架,一半是屏风,光透过长虹玻璃变得朦胧。', seed: 'xumu-veil' }, + { id: 'halo-lamp', name: '拾光落地灯', en: 'HALO LAMP', cat: '客厅', price: 4900, material: '拉丝黄铜 · 亚麻灯罩', size: 'Φ450 × H1620', desc: '灯罩手工裱亚麻,开灯时像屋里升起一轮小月亮。', seed: 'xumu-halo' }, + { id: 'nimbus-bed', name: '眠云大床', en: 'NIMBUS BED', cat: '卧室', price: 32000, material: '白蜡木 · 头层牛皮', size: 'W1800 × D2100 × H1050', desc: '床头以牛皮软包裹木,倚靠时是恰到好处的温柔。', seed: 'xumu-nimbus' }, + { id: 'pebble-side', name: '石纹边几', en: 'PEBBLE SIDE', cat: '客厅', price: 6800, material: '罗马洞石', size: 'Φ500 × H520', desc: '像从河滩捡回的一枚卵石,孔隙里藏着时间。', seed: 'xumu-pebble' }, + ], + testimonials: [ + { text: '沙发到家那天,师傅调平用了半小时。这种较真,让我相信它真能用二十年。', author: '室内设计师 林女士', role: '上海 · 云栖沙发用户' }, + { text: '月洞圈椅摆在书房,客人来了总要坐一坐再问在哪买的。', author: '建筑师 陈先生', role: '杭州 · 全屋定制客户' }, + ], + partners: ['FSC 认证林场', '米兰家具展', '设计上海', 'AD 安邸', '原创设计师联盟'], + contacts: { phone: '400-620-1207', email: 'hello@xumu.living', addr: '上海市徐汇区序木之家旗舰展厅' }, + founded: 2012, + }, +} diff --git a/src/data/corpStyles.js b/src/data/corpStyles.js new file mode 100644 index 0000000..233e04b --- /dev/null +++ b/src/data/corpStyles.js @@ -0,0 +1,881 @@ +// 企业官网合集:48 种风格注册表(10 大行业) +// cover.kind 封面装修:guofeng 国风框印 / postcard 明信片 / ticket 票券 / terminal 终端 +// window 系统窗口 / pixelframe 像素框 / neonbox 霓虹 / paper 报纸 / blueprintgrid 蓝图 +// tape 胶带 / gilt 鎏金 / crayon 蜡笔 / hud 角标扫描 / holo 流光 / frame 细线框 +// pop 波普贴纸 / grid 细网格 / departure 翻牌屏 +export const corpIndustries = [ + { key: 'ecom', label: '电商' }, + { key: 'art', label: '艺术' }, + { key: 'pharma', label: '医药' }, + { key: 'medical', label: '医疗' }, + { key: 'tech', label: '科技' }, + { key: 'travel', label: '景区' }, + { key: 'home', label: '家政' }, + { key: 'ai', label: 'AI' }, + { key: 'saas', label: 'SaaS' }, + { key: 'furniture', label: '家具' }, +] + +export const corpStyleList = [ + /* ---------- 电商 · 年糕严选 ---------- */ + { + id: 'ecom-sale', + num: '01', + industry: 'ecom', + industryLabel: '电商', + title: '大促狂欢', + intro: '红橙渐变、优惠券墙与真的在走的秒杀倒计时', + cover: { + kind: 'ticket', + ck: '#ffd76a', + sub: '限时券 COUPON', + bg: 'radial-gradient(circle at 80% 20%, rgba(255,214,0,.55), transparent 45%), linear-gradient(135deg, #ff3d2e, #ff7a18)', + motif: '¥5折', + style: { color: '#fff', fontWeight: 900, fontSize: '36px', textShadow: '0 4px 0 rgba(160,20,0,.4)', transform: 'translateX(-16px)' }, + }, + component: () => import('../pages/corp/EcomSalePage.vue'), + }, + { + id: 'ecom-premium', + num: '02', + industry: 'ecom', + industryLabel: '电商', + title: '极简精品', + intro: '黑白大图、衬线标题与可点进详情页的臻选橱窗', + cover: { + kind: 'frame', + ck: 'rgba(17,17,17,.55)', + sub: 'N° 02 — THE EDIT', + bg: '#f5f4f2', + motif: 'SELECT', + style: { color: '#141414', fontFamily: '"Playfair Display", serif', fontSize: '26px', letterSpacing: '0.3em' }, + }, + component: () => import('../pages/corp/EcomPremiumPage.vue'), + subPages: [ + { path: 'product/:idx', title: '商品详情', component: () => import('../pages/corp/ecom/PremiumDetail.vue') }, + ], + }, + { + id: 'ecom-fresh', + num: '03', + industry: 'ecom', + industryLabel: '电商', + title: '生鲜集市', + intro: '果绿圆角、满减标签与清单式商品行', + cover: { + kind: 'ticket', + ck: 'rgba(255,255,255,.9)', + sub: '今日价 ¥9.9/斤', + bg: 'radial-gradient(circle at 22% 24%, rgba(255,255,255,.28) 0 10px, transparent 11px), radial-gradient(circle at 58% 76%, rgba(255,255,255,.2) 0 13px, transparent 14px), linear-gradient(150deg, #58c04d, #2e9e4f)', + motif: '🥬', + style: { fontSize: '50px', transform: 'translateX(-16px)', filter: 'drop-shadow(0 6px 10px rgba(20,90,30,.35))' }, + }, + component: () => import('../pages/corp/EcomFreshPage.vue'), + }, + { + id: 'ecom-toy', + num: '04', + industry: 'ecom', + industryLabel: '电商', + title: '潮玩盲盒', + intro: '撞色贴纸、波普图形与会摇晃的「抽一个」', + cover: { + kind: 'pop', + ck: '#fff', + sub: 'NEW!', + bg: 'radial-gradient(circle at 24% 70%, #ffd93d 26px, transparent 27px), radial-gradient(circle at 78% 30%, #4d96ff 30px, transparent 31px), #ff6b9d', + motif: '?', + style: { color: '#fff', fontWeight: 900, fontSize: '56px', textShadow: '4px 4px 0 #2b2b2b' }, + }, + component: () => import('../pages/corp/EcomToyPage.vue'), + }, + { + id: 'ecom-dutyfree', + num: '05', + industry: 'ecom', + industryLabel: '电商', + title: '全球免税', + intro: '机场信息板风格、航线图与汇率翻牌器', + cover: { + kind: 'departure', + ck: '#ffd76a', + sub: 'GATE 05 · TAX FREE', + bg: '#10265c', + motif: '✈ DUTY FREE', + style: { color: '#ffd76a', fontFamily: 'Consolas, monospace', fontSize: '18px', letterSpacing: '0.16em', transform: 'translateY(24px)' }, + }, + component: () => import('../pages/corp/EcomDutyFreePage.vue'), + }, + + /* ---------- 艺术 · 拾光美术馆 ---------- */ + { + id: 'art-whitebox', + num: '06', + industry: 'art', + industryLabel: '艺术', + title: '白盒画廊', + intro: '纯白展厅、大幅作品与安静的展签排版', + cover: { + kind: 'frame', + ck: 'rgba(28,28,28,.7)', + sub: 'GALLERY · No.001', + bg: 'linear-gradient(rgba(28,28,28,.35) 0 0) 50% 0/1.5px 17% no-repeat, linear-gradient(#e8e6e1 0 0) 50% 43%/32% 40% no-repeat, linear-gradient(#20201e 0 0) 50% 43%/37% 49% no-repeat, linear-gradient(#d8d5cf 0 0) 50% 82%/14% 5% no-repeat, #fcfcfa', + motif: '□', + style: { color: '#1c1c1c', fontSize: '44px', fontWeight: 200, transform: 'translateY(-9px)' }, + }, + component: () => import('../pages/corp/ArtWhiteboxPage.vue'), + }, + { + id: 'art-avantgarde', + num: '07', + industry: 'art', + industryLabel: '艺术', + title: '先锋实验', + intro: '粗野主义海报、超大字与故障色偏', + cover: { + kind: 'pop', + ck: '#f4f4f4', + sub: 'NO MEANING', + bg: 'linear-gradient(90deg, #ff2e63 0 8px, transparent 8px) 12% 0/100% 100% no-repeat, #101010', + motif: 'ART?', + style: { color: '#f4f4f4', fontWeight: 900, fontSize: '44px', letterSpacing: '-0.04em', textShadow: '3px 0 #ff2e63, -3px 0 #08d9d6' }, + }, + component: () => import('../pages/corp/ArtAvantgardePage.vue'), + }, + { + id: 'art-auction', + num: '08', + industry: 'art', + industryLabel: '艺术', + title: '拍卖专场', + intro: '深色鎏金、衬线拍品编号与跳动的叫价', + cover: { + kind: 'gilt', + ck: '#d4af37', + sub: '秋拍 · 夜场', + bg: 'radial-gradient(ellipse at 50% 0%, rgba(212,175,55,.28), transparent 55%), #17130e', + motif: 'LOT 08', + style: { color: '#d4af37', fontFamily: '"Playfair Display", serif', fontSize: '30px', letterSpacing: '0.12em' }, + }, + component: () => import('../pages/corp/ArtAuctionPage.vue'), + }, + { + id: 'art-kids', + num: '09', + industry: 'art', + industryLabel: '艺术', + title: '儿童美育', + intro: '蜡笔涂鸦边框与彩纸拼贴的快乐教室', + cover: { + kind: 'crayon', + ck: '#e05c8a', + sub: '3-12 岁美术课', + bg: 'radial-gradient(circle at 20% 30%, #ffd93d 18px, transparent 19px), radial-gradient(circle at 80% 26%, #6bcb77 15px, transparent 16px), radial-gradient(circle at 68% 76%, #4d96ff 20px, transparent 21px), #fff7e8', + motif: '🖍️', + style: { fontSize: '50px', transform: 'rotate(-10deg)' }, + }, + component: () => import('../pages/corp/ArtKidsPage.vue'), + }, + { + id: 'art-digital', + num: '10', + industry: 'art', + industryLabel: '艺术', + title: '数字艺术馆', + intro: '暗底霓虹渐变与藏品卡片的流光 hover', + cover: { + kind: 'holo', + ck: '#00e0ff', + sub: 'TOKEN #010', + bg: 'conic-gradient(from 210deg at 60% 40%, #7b2ff7, #00e0ff, #ff2fd6, #7b2ff7), #0a0714', + motif: '◈', + style: { color: '#fff', fontSize: '50px', textShadow: '0 0 26px rgba(255,255,255,.8)' }, + }, + component: () => import('../pages/corp/ArtDigitalPage.vue'), + }, + + /* ---------- 医药 · 本草汇制药 ---------- */ + { + id: 'pharma-modern', + num: '11', + industry: 'pharma', + industryLabel: '医药', + title: '现代制药', + intro: '蓝白洁净、分子链示意与 GMP 数据条', + cover: { + kind: 'grid', + ck: 'rgba(29,99,200,.45)', + sub: 'GMP 认证车间', + bg: '#f4f8fd', + motif: '⬡', + style: { color: '#1d63c8', fontSize: '52px' }, + }, + component: () => import('../pages/corp/PharmaModernPage.vue'), + }, + { + id: 'pharma-tcm', + num: '12', + industry: 'pharma', + industryLabel: '医药', + title: '中药老字号', + intro: '宣纸朱框、可翻页的伤寒古方书与药柜抽屉', + cover: { + kind: 'guofeng', + ck: '#8b3122', + seal: '本', + bg: 'radial-gradient(ellipse at 82% 88%, rgba(139,49,34,.12), transparent 55%), #efe6d3', + motif: '本草', + style: { color: '#5a4632', fontFamily: '"Ma Shan Zheng", cursive', fontSize: '42px' }, + }, + component: () => import('../pages/corp/PharmaTcmPage.vue'), + subPages: [ + { path: 'fangshu', title: '伤寒古方书', component: () => import('../pages/corp/pharma/TcmFangshu.vue') }, + ], + }, + { + id: 'pharma-biotech', + num: '13', + industry: 'pharma', + industryLabel: '医药', + title: '生物实验室', + intro: '青色科技感、DNA 双螺旋与研究数据', + cover: { + kind: 'hud', + ck: 'rgba(0,229,255,.75)', + sub: 'BSL-2 · LAB', + bg: 'repeating-linear-gradient(62deg, transparent 0 9px, rgba(0,229,255,.5) 9px 11px) 82% 50%/54px 72% no-repeat, repeating-linear-gradient(-62deg, transparent 0 9px, rgba(77,255,176,.4) 9px 11px) 82% 50%/54px 72% no-repeat, repeating-linear-gradient(60deg, transparent 0 18px, rgba(0,229,255,.07) 18px 19px), #061b22', + motif: 'DNA', + style: { color: '#00e5ff', fontFamily: 'Consolas, monospace', fontSize: '30px', letterSpacing: '0.22em', textShadow: '0 0 18px rgba(0,229,255,.7)', transform: 'translateX(-26px)' }, + }, + component: () => import('../pages/corp/PharmaBiotechPage.vue'), + }, + { + id: 'pharma-store', + num: '14', + industry: 'pharma', + industryLabel: '医药', + title: '连锁药房', + intro: '绿十字、便民价签与门店查询列表', + cover: { + kind: 'frame', + ck: 'rgba(46,164,79,.6)', + sub: '医保定点 · 860 店', + bg: 'linear-gradient(#2ea44f 0 0) 50% 44%/26% 9% no-repeat, linear-gradient(#2ea44f 0 0) 50% 44%/9% 26% no-repeat, #f2faf4', + motif: '', + style: {}, + }, + component: () => import('../pages/corp/PharmaStorePage.vue'), + }, + + /* ---------- 医疗 · 安和医疗 ---------- */ + { + id: 'med-hospital', + num: '15', + industry: 'medical', + industryLabel: '医疗', + title: '综合医院', + intro: '信任蓝、科室宫格与能填的预约挂号表单', + cover: { + kind: 'grid', + ck: 'rgba(255,255,255,.4)', + sub: '急诊 24H · 医保', + bg: 'linear-gradient(#fff 0 0) 50% 46%/24% 8.5% no-repeat, linear-gradient(#fff 0 0) 50% 46%/8.5% 24% no-repeat, radial-gradient(ellipse 70% 50% at 50% 46%, rgba(255,255,255,.14), transparent 65%), linear-gradient(165deg, #1667d9, #0b4ea8)', + motif: '', + style: {}, + }, + component: () => import('../pages/corp/MedHospitalPage.vue'), + }, + { + id: 'med-clinic', + num: '16', + industry: 'medical', + industryLabel: '医疗', + title: '高端诊所', + intro: '米色暖调、衬线字与一对一管家式服务', + cover: { + kind: 'gilt', + ck: '#a4784a', + sub: 'PRIVATE CLINIC', + bg: '#f4ede2', + motif: '✚', + style: { color: '#a4784a', fontSize: '44px', fontWeight: 300 }, + }, + component: () => import('../pages/corp/MedClinicPage.vue'), + }, + { + id: 'med-dental', + num: '17', + industry: 'medical', + industryLabel: '医疗', + title: '口腔诊所', + intro: '薄荷白净、笑容曲线与洁牙套餐价目', + cover: { + kind: 'frame', + ck: 'rgba(46,196,182,.6)', + sub: '洁牙 ¥199 起', + bg: 'radial-gradient(circle at 50% 130%, rgba(46,196,182,.35), transparent 55%), #f6fffd', + motif: '◡', + style: { color: '#2ec4b6', fontSize: '64px', fontWeight: 700, textShadow: '0 6px 20px rgba(46,196,182,.4)', transform: 'translateY(-10px)' }, + }, + component: () => import('../pages/corp/MedDentalPage.vue'), + }, + { + id: 'med-online', + num: '18', + industry: 'medical', + industryLabel: '医疗', + title: '互联网问诊', + intro: 'App 风对话气泡与自动播放的模拟问诊', + cover: { + kind: 'window', + os: 'mac', + winTitle: '安和互联网医院 — 问诊中', + bg: 'linear-gradient(#fff 0 0) 18% 44%/38% 16% no-repeat, linear-gradient(#1c86e0 0 0) 76% 70%/42% 16% no-repeat, linear-gradient(170deg, #eaf6ff, #d6ecff)', + motif: '···', + style: { color: '#fff', fontSize: '30px', fontWeight: 900, letterSpacing: '0.1em', transform: 'translate(62px, 34px)' }, + }, + component: () => import('../pages/corp/MedOnlinePage.vue'), + }, + { + id: 'med-family', + num: '19', + industry: 'medical', + industryLabel: '医疗', + title: '妇儿医院', + intro: '柔粉鹅黄、圆角插画感与成长档案', + cover: { + kind: 'crayon', + ck: '#e5628f', + sub: '妇儿友好医院', + bg: 'radial-gradient(circle at 76% 26%, #ffe3a3 30px, transparent 31px), linear-gradient(160deg, #ffe9f0, #fff6e8)', + motif: '🤱', + style: { fontSize: '48px' }, + }, + component: () => import('../pages/corp/MedFamilyPage.vue'), + }, + + /* ---------- 科技 · 量子跃迁 ---------- */ + { + id: 'tech-enterprise', + num: '20', + industry: 'tech', + industryLabel: '科技', + title: '企业大厂', + intro: '蓝紫 hero、解决方案矩阵与合作伙伴墙', + cover: { + kind: 'grid', + ck: 'rgba(157,182,255,.4)', + sub: 'ENTERPRISE OS', + bg: 'radial-gradient(ellipse at 20% 110%, rgba(64,120,255,.5), transparent 55%), linear-gradient(135deg, #101a3c, #2b1a5e)', + motif: '⚛', + style: { color: '#9db6ff', fontSize: '50px' }, + }, + component: () => import('../pages/corp/TechEnterprisePage.vue'), + }, + { + id: 'tech-hardware', + num: '21', + industry: 'tech', + industryLabel: '科技', + title: '硬件发布会', + intro: '纯黑居中产品大图与滚动参数横条', + cover: { + kind: 'frame', + ck: 'rgba(232,232,238,.3)', + sub: 'KEYNOTE · 10.24', + bg: 'radial-gradient(ellipse at 50% 60%, rgba(120,130,150,.35), transparent 60%), #050507', + motif: 'X1', + style: { color: '#e8e8ee', fontWeight: 800, fontSize: '46px', letterSpacing: '0.1em' }, + }, + component: () => import('../pages/corp/TechHardwarePage.vue'), + }, + { + id: 'tech-opensource', + num: '22', + industry: 'tech', + industryLabel: '科技', + title: '开源社区', + intro: '终端 README 风、代码块与会涨的 star', + cover: { + kind: 'terminal', + ck: '#3fb950', + sub: 'git push --all', + bg: '#0d1117', + motif: '$ _', + style: { color: '#3fb950', fontFamily: 'Consolas, monospace', fontSize: '38px' }, + }, + component: () => import('../pages/corp/TechOpensourcePage.vue'), + }, + { + id: 'tech-space', + num: '23', + industry: 'tech', + industryLabel: '科技', + title: '航天深空', + intro: '星空、任务时间线与发射窗口倒计时', + cover: { + kind: 'hud', + ck: 'rgba(157,182,255,.55)', + sub: 'T-00:42:19', + bg: 'radial-gradient(circle at 24% 30%, #fff 1.2px, transparent 2px), radial-gradient(circle at 70% 60%, #fff 1px, transparent 1.8px), radial-gradient(circle at 46% 78%, #fff 1.4px, transparent 2.2px), radial-gradient(circle at 50% 50%, transparent 31%, rgba(157,182,255,.35) 31.5% 32.5%, transparent 33%), #030818', + motif: 'DS-01', + style: { color: '#f5f7ff', fontFamily: 'Consolas, monospace', fontSize: '28px', letterSpacing: '0.2em', textShadow: '0 0 20px rgba(160,180,255,.8)' }, + }, + component: () => import('../pages/corp/TechSpacePage.vue'), + }, + { + id: 'tech-chip', + num: '24', + industry: 'tech', + industryLabel: '科技', + title: '半导体', + intro: '电路蓝图线条、晶圆图形与制程数据', + cover: { + kind: 'blueprintgrid', + ck: 'rgba(80,220,255,.6)', + sub: 'QLEAP X1 · 7nm', + bg: 'repeating-linear-gradient(0deg, transparent 0 20px, rgba(80,220,255,.12) 20px 21px), repeating-linear-gradient(90deg, transparent 0 20px, rgba(80,220,255,.12) 20px 21px), #041220', + motif: '▣', + style: { color: '#50dcff', fontSize: '48px' }, + }, + component: () => import('../pages/corp/TechChipPage.vue'), + }, + + /* ---------- 景区 · 云栖山谷 ---------- */ + { + id: 'travel-ink', + num: '25', + industry: 'travel', + industryLabel: '景区', + title: '山水国风', + intro: '水墨山峦、竖排诗句与四季图集', + cover: { + kind: 'guofeng', + ck: '#3c4842', + seal: '雲', + bg: 'radial-gradient(ellipse 62% 34% at 50% 86%, rgba(60,72,66,.55), transparent 70%), radial-gradient(ellipse 46% 26% at 28% 80%, rgba(60,72,66,.4), transparent 70%), #f2efe6', + motif: '雲栖', + style: { color: '#3c4842', fontFamily: '"Ma Shan Zheng", cursive', fontSize: '42px', letterSpacing: '0.2em' }, + }, + component: () => import('../pages/corp/TravelInkPage.vue'), + }, + { + id: 'travel-park', + num: '26', + industry: 'travel', + industryLabel: '景区', + title: '主题乐园', + intro: '高饱和撞色、门票选择卡与吉祥物', + cover: { + kind: 'ticket', + ck: 'rgba(255,255,255,.85)', + sub: '入园票 ADMIT ONE', + bg: 'radial-gradient(circle at 78% 24%, #ffd93d 24px, transparent 25px), linear-gradient(150deg, #ff5da2, #7b6cff)', + motif: '🎢', + style: { fontSize: '48px', transform: 'translateX(-14px)' }, + }, + component: () => import('../pages/corp/TravelParkPage.vue'), + }, + { + id: 'travel-island', + num: '27', + industry: 'travel', + industryLabel: '景区', + title: '海岛度假', + intro: '明信片式日落海景与酒店房型卡', + cover: { + kind: 'postcard', + ck: 'rgba(255,255,255,.85)', + stamp: '屿', + sub: 'FROM 云屿岛', + bg: 'linear-gradient(175deg, #ff9a62 0%, #ff6392 46%, #4059ad 100%)', + motif: 'Greetings!', + style: { color: '#fff', fontFamily: 'Pacifico, cursive', fontSize: '28px', textShadow: '0 3px 10px rgba(64,25,60,.4)', transform: 'rotate(-4deg)' }, + }, + component: () => import('../pages/corp/TravelIslandPage.vue'), + }, + { + id: 'travel-oldtown', + num: '28', + industry: 'travel', + industryLabel: '景区', + title: '古镇文旅', + intro: '木刻版画、灯笼与节庆活动日历', + cover: { + kind: 'guofeng', + ck: '#c73e2e', + seal: '游', + bg: 'radial-gradient(circle at 24% 28%, #c73e2e 13px, transparent 14px), radial-gradient(circle at 24% 28%, #8a2418 13px 14px, transparent 15px), #2e2a24', + motif: '古鎮', + style: { color: '#e8ddc4', fontFamily: '"Long Cang", cursive', fontSize: '42px', letterSpacing: '0.16em' }, + }, + component: () => import('../pages/corp/TravelOldtownPage.vue'), + }, + { + id: 'travel-ski', + num: '29', + industry: 'travel', + industryLabel: '景区', + title: '冰雪滑雪场', + intro: '冰蓝白、雪道难度色标与雪具租赁', + cover: { + kind: 'ticket', + ck: 'rgba(20,80,140,.6)', + sub: 'LIFT PASS 全日', + bg: 'radial-gradient(circle at 66% 74%, #2f9e63 0 6.5px, transparent 7.5px), linear-gradient(#2b6cb8 0 0) 78% 82%/11px 11px no-repeat, linear-gradient(150deg, transparent 55%, rgba(255,255,255,.85) 55.5%), linear-gradient(170deg, #b9e4ff, #5aa7e8)', + motif: '⛷️', + style: { fontSize: '46px', transform: 'translateX(-14px)' }, + }, + component: () => import('../pages/corp/TravelSkiPage.vue'), + }, + + /* ---------- 家政 · 到家帮 ---------- */ + { + id: 'home-warm', + num: '30', + industry: 'home', + industryLabel: '家政', + title: '温馨到家', + intro: '暖橙、四步服务流程与阿姨资质卡', + cover: { + kind: 'crayon', + ck: 'rgba(255,255,255,.85)', + sub: '4.98★ · 2360 单', + bg: 'radial-gradient(circle at 80% 20%, #ffdf8e 0 22px, rgba(255,223,142,.35) 23px 30px, transparent 31px), radial-gradient(ellipse 90% 30% at 20% 105%, rgba(255,255,255,.4), transparent 60%), radial-gradient(ellipse 70% 24% at 85% 108%, rgba(255,255,255,.28), transparent 60%), linear-gradient(150deg, #ff9f45, #ff7043)', + motif: '🏡', + style: { fontSize: '48px', filter: 'drop-shadow(0 8px 14px rgba(160,60,10,.4))' }, + }, + component: () => import('../pages/corp/HomeWarmPage.vue'), + }, + { + id: 'home-butler', + num: '31', + industry: 'home', + industryLabel: '家政', + title: '高端管家', + intro: '藏青金、英式管家与私宅定制服务', + cover: { + kind: 'gilt', + ck: '#d4af37', + sub: 'PRIVATE BUTLER', + bg: 'repeating-linear-gradient(115deg, transparent 0 11px, rgba(212,175,55,.07) 11px 12px), radial-gradient(ellipse 70% 46% at 50% -12%, rgba(212,175,55,.22), transparent 65%), #101c33', + motif: 'B', + style: { color: '#d4af37', fontFamily: '"Playfair Display", serif', fontStyle: 'italic', fontSize: '54px', textShadow: '0 4px 18px rgba(212,175,55,.45)' }, + }, + component: () => import('../pages/corp/HomeButlerPage.vue'), + }, + { + id: 'home-clean', + num: '32', + industry: 'home', + industryLabel: '家政', + title: '极净保洁', + intro: '清爽蓝白与逐项打勾的清单动画', + cover: { + kind: 'frame', + ck: 'rgba(29,155,240,.5)', + sub: '48 项验收标准', + bg: 'radial-gradient(circle at 13px 0px, rgba(125,205,255,.4) 0 9px, transparent 10px) 0 calc(100% - 8px)/26px 12px repeat-x, linear-gradient(rgba(125,205,255,.32) 0 0) 0 100%/100% 9px no-repeat, radial-gradient(circle at 24% 26%, rgba(125,205,255,.4) 0 13px, rgba(125,205,255,.14) 14px 17px, transparent 18px), radial-gradient(circle at 74% 18%, rgba(125,205,255,.3) 0 8px, transparent 9px), radial-gradient(circle at 62% 62%, rgba(125,205,255,.35) 0 10px, transparent 11px), linear-gradient(170deg, #ffffff, #ecf7ff)', + motif: '✓', + style: { color: '#1d9bf0', fontSize: '52px', fontWeight: 800, textShadow: '0 8px 22px rgba(29,155,240,.35)' }, + }, + component: () => import('../pages/corp/HomeCleanPage.vue'), + }, + { + id: 'home-baby', + num: '33', + industry: 'home', + industryLabel: '家政', + title: '母婴护理', + intro: '奶油粉、月嫂档案卡与护理套餐对比', + cover: { + kind: 'crayon', + ck: '#ffb7cd', + sub: '月嫂持证上岗', + bg: 'radial-gradient(circle at 78% 22%, #ffe9b0 0 15px, transparent 16px) , radial-gradient(circle at 84% 16%, #fff3d6 0 11px, transparent 12px), radial-gradient(rgba(224,92,138,.14) 2px, transparent 2.5px) 0 0/24px 24px, linear-gradient(160deg, #ffdde6, #fff3d6)', + motif: '🍼', + style: { fontSize: '48px', filter: 'drop-shadow(0 6px 12px rgba(224,92,138,.3))' }, + }, + component: () => import('../pages/corp/HomeBabyPage.vue'), + }, + + /* ---------- AI · 深思智能 ---------- */ + { + id: 'ai-llm', + num: '34', + industry: 'ai', + industryLabel: 'AI', + title: '大模型官网', + intro: '深空光晕渐变与打字回答的对话演示', + cover: { + kind: 'holo', + ck: '#7c6cff', + sub: 'DEEPTHINK v5.2', + bg: 'radial-gradient(ellipse at 50% 120%, rgba(124,108,255,.6), transparent 60%), radial-gradient(ellipse at 80% 0%, rgba(0,224,255,.25), transparent 50%), #07070f', + motif: '✦', + style: { color: '#c9c2ff', fontSize: '48px', textShadow: '0 0 30px rgba(124,108,255,.9)' }, + }, + component: () => import('../pages/corp/AiLlmPage.vue'), + }, + { + id: 'ai-robot', + num: '35', + industry: 'ai', + industryLabel: 'AI', + title: '机器人公司', + intro: '工业深灰、机械臂参数与场景方案', + cover: { + kind: 'hud', + ck: 'rgba(255,176,32,.75)', + sub: 'CYCLE 0.38s · IP67', + bg: 'repeating-linear-gradient(45deg, transparent 0 16px, rgba(255,176,32,.14) 16px 18px), #1c1e22', + motif: 'ARM-6', + style: { color: '#ffb020', fontFamily: 'Consolas, monospace', fontSize: '30px', fontWeight: 700, letterSpacing: '0.14em', textShadow: '0 0 16px rgba(255,176,32,.45)' }, + }, + component: () => import('../pages/corp/AiRobotPage.vue'), + }, + { + id: 'ai-paint', + num: '36', + industry: 'ai', + industryLabel: 'AI', + title: 'AI 绘画', + intro: '多彩创意、作品瀑布流与 prompt 输入框', + cover: { + kind: 'tape', + ck: '#fff', + sub: 'PROMPT → ART', + bg: 'conic-gradient(from 0deg at 30% 70%, #ff6b9d, #ffd93d, #6bcb77, #4d96ff, #b06bff, #ff6b9d)', + motif: '🎨', + style: { fontSize: '50px', filter: 'drop-shadow(0 6px 12px rgba(0,0,0,.3))' }, + }, + component: () => import('../pages/corp/AiPaintPage.vue'), + }, + { + id: 'ai-voice', + num: '37', + industry: 'ai', + industryLabel: 'AI', + title: '语音助手', + intro: '声波动画与极简圆形主视觉', + cover: { + kind: 'frame', + ck: 'rgba(46,196,182,.55)', + sub: '响应 0.3s', + bg: 'linear-gradient(90deg, transparent 0 12%, rgba(46,196,182,.8) 12% 13%, transparent 13% 20%, rgba(46,196,182,.5) 20% 21%, transparent 21% 28%, rgba(46,196,182,.9) 28% 29%, transparent 29%) 50% 50%/56% 30% no-repeat, #f7fbfa', + motif: '◉', + style: { color: '#2ec4b6', fontSize: '46px' }, + }, + component: () => import('../pages/corp/AiVoicePage.vue'), + }, + { + id: 'ai-vision', + num: '38', + industry: 'ai', + industryLabel: 'AI', + title: '视觉安防', + intro: 'HUD 扫描框动画与识别数据面板', + cover: { + kind: 'hud', + ck: 'rgba(0,255,170,.8)', + sub: 'CAM-07 ● LIVE', + bg: 'radial-gradient(circle at 50% 50%, transparent 22%, rgba(0,255,170,.5) 22.5% 23.5%, transparent 24% 30%, rgba(0,255,170,.25) 30.5% 31.5%, transparent 32%), linear-gradient(rgba(0,255,170,.5) 0 0) 50% 50%/1.5px 18% no-repeat, linear-gradient(rgba(0,255,170,.5) 0 0) 50% 50%/18% 1.5px no-repeat, #04120c', + motif: '', + style: {}, + }, + component: () => import('../pages/corp/AiVisionPage.vue'), + }, + + /* ---------- SaaS · 团子云 ---------- */ + { + id: 'saas-classic', + num: '39', + industry: 'saas', + industryLabel: 'SaaS', + title: '经典 SaaS', + intro: '清爽白、三栏定价表与月付/年付切换', + cover: { + kind: 'window', + os: 'mac', + winTitle: 'tuanzi.cloud — 工作台', + bg: 'linear-gradient(#dfe5ff 0 0) 26% 62%/17% 44% no-repeat, linear-gradient(#4c5cff 0 0) 26% 44%/17% 8% no-repeat, linear-gradient(#e8ecff 0 0) 50% 68%/17% 32% no-repeat, linear-gradient(#8b96ff 0 0) 50% 54%/17% 8% no-repeat, linear-gradient(#eef1ff 0 0) 74% 74%/17% 20% no-repeat, linear-gradient(#c3cbff 0 0) 74% 66%/17% 8% no-repeat, #ffffff', + motif: '', + style: {}, + }, + component: () => import('../pages/corp/SaasClassicPage.vue'), + }, + { + id: 'saas-collab', + num: '40', + industry: 'saas', + industryLabel: 'SaaS', + title: '协作办公', + intro: 'Notion 式黑白与块编辑器示意', + cover: { + kind: 'window', + os: 'mac', + winTitle: '发布计划 · 3 人编辑中', + bg: 'linear-gradient(#ededea 0 0) 20% 44%/50% 7% no-repeat, linear-gradient(#ededea 0 0) 20% 58%/64% 7% no-repeat, linear-gradient(#ededea 0 0) 20% 72%/44% 7% no-repeat, #fbfbfa', + motif: '▤', + style: { color: '#37352f', fontSize: '46px', transform: 'translateY(8px)' }, + }, + component: () => import('../pages/corp/SaasCollabPage.vue'), + }, + { + id: 'saas-bi', + num: '41', + industry: 'saas', + industryLabel: 'SaaS', + title: '数据分析 BI', + intro: '暗色仪表盘与纯 CSS 图表卡片', + cover: { + kind: 'window', + os: 'mac', + winTitle: '经营驾驶舱 — 实时', + bg: 'linear-gradient(#31d0aa 0 0) 22% 82%/9% 24% no-repeat, linear-gradient(#5b8def 0 0) 38% 82%/9% 40% no-repeat, linear-gradient(#ffb020 0 0) 54% 82%/9% 16% no-repeat, linear-gradient(#ef5da8 0 0) 70% 82%/9% 32% no-repeat, #10131c', + motif: '', + style: {}, + }, + component: () => import('../pages/corp/SaasBiPage.vue'), + }, + { + id: 'saas-crm', + num: '42', + industry: 'saas', + industryLabel: 'SaaS', + title: '客服 CRM', + intro: '亲和气泡对话与工单流转看板', + cover: { + kind: 'window', + os: 'mac', + winTitle: '客服工作台 · 平均 8s 响应', + bg: 'linear-gradient(#fff 0 0) 24% 46%/40% 18% no-repeat, linear-gradient(#ffe1ec 0 0) 72% 70%/40% 18% no-repeat, linear-gradient(165deg, #fff0f5, #ffe9f8)', + motif: '💬', + style: { fontSize: '38px', transform: 'translateY(34px)' }, + }, + component: () => import('../pages/corp/SaasCrmPage.vue'), + }, + { + id: 'saas-builder', + num: '43', + industry: 'saas', + industryLabel: 'SaaS', + title: '建站平台', + intro: '拖拽积木示意与模板橱窗网格', + cover: { + kind: 'window', + os: 'win11', + winTitle: 'mysite.tuanzi.site — 已发布', + bg: 'linear-gradient(#c7f0ff 0 0) 26% 42%/26% 20% no-repeat, linear-gradient(#ffe3c7 0 0) 26% 72%/26% 20% no-repeat, linear-gradient(#e3d1ff 0 0) 62% 56%/26% 36% no-repeat, #f6f8ff', + motif: '⌗', + style: { color: '#4c5cff', fontSize: '44px', transform: 'translateY(8px)' }, + }, + component: () => import('../pages/corp/SaasBuilderPage.vue'), + }, + { + id: 'saas-medlink', + num: '44', + industry: 'saas', + industryLabel: 'SaaS', + title: '医联体 SaaS', + intro: '给诊所药店赋能:挂号引流、私域、煎药中心,含产品/文章/视频多页', + cover: { + kind: 'window', + os: 'mac', + winTitle: '杏林云 · 医联体驾驶舱', + bg: 'linear-gradient(#d9f7ef 0 0) 20% 46%/30% 18% no-repeat, linear-gradient(#dbeafe 0 0) 58% 66%/34% 18% no-repeat, linear-gradient(165deg, #f0fdf9, #e7f3ff)', + motif: '⚕', + style: { color: '#0f766e', fontSize: '46px', fontWeight: 700, transform: 'translateY(10px)' }, + }, + component: () => import('../pages/corp/saas/MedlinkHome.vue'), + subPages: [ + { path: 'product', title: '产品介绍', component: () => import('../pages/corp/saas/MedlinkProduct.vue') }, + { path: 'revisit', title: '在线复诊', component: () => import('../pages/corp/saas/MedlinkRevisit.vue') }, + { path: 'articles', title: '教程文章', component: () => import('../pages/corp/saas/MedlinkArticles.vue') }, + { path: 'videos', title: '教程视频', component: () => import('../pages/corp/saas/MedlinkVideos.vue') }, + ], + }, + + /* ---------- 家具 · 序木家居(每款含首页 + 产品页) ---------- */ + { + id: 'furn-wabi', + num: '45', + industry: 'furniture', + industryLabel: '家具', + title: '侘寂原木', + intro: '亚麻底色、木纹与留白,首页 + 产品页的慢节奏双页官网', + cover: { + kind: 'frame', + ck: 'rgba(107,78,55,.45)', + sub: '侘寂 · WABI-SABI', + bg: 'repeating-linear-gradient(94deg, rgba(107,78,55,.07) 0 2px, transparent 2px 18px), radial-gradient(ellipse 30px 16px at 72% 34%, rgba(107,78,55,.22) 0 40%, rgba(107,78,55,.1) 55%, transparent 70%), radial-gradient(ellipse 20px 11px at 26% 72%, rgba(107,78,55,.16) 0 40%, transparent 70%), linear-gradient(160deg, #f2ece1, #e3dac8)', + motif: '木', + style: { color: '#6b4e37', fontFamily: '"Noto Serif SC", serif', fontSize: '52px', fontWeight: 600 }, + }, + component: () => import('../pages/corp/furn/WabiHome.vue'), + subPages: [ + { path: 'products', title: '产品系列', component: () => import('../pages/corp/furn/WabiProducts.vue') }, + ], + }, + { + id: 'furn-milano', + num: '46', + industry: 'furniture', + industryLabel: '家具', + title: '意式轻奢', + intro: '墨绿鎏金、大理石与杂志式排版,带产品编辑页的双页官网', + cover: { + kind: 'gilt', + ck: '#c9a227', + sub: 'MILANO · 1987', + bg: 'radial-gradient(circle at 72% 24%, rgba(201,162,39,.42), transparent 50%), repeating-radial-gradient(circle at 118% -18%, transparent 0 42px, rgba(232,220,180,.06) 42px 44px), linear-gradient(115deg, transparent 46%, rgba(201,162,39,.14) 47% 47.6%, transparent 48.6%), linear-gradient(150deg, #101512, #1d2b25)', + motif: 'M', + style: { color: '#c9a227', fontFamily: '"Playfair Display", serif', fontStyle: 'italic', fontSize: '56px' }, + }, + component: () => import('../pages/corp/furn/MilanoHome.vue'), + subPages: [ + { path: 'products', title: '产品系列', component: () => import('../pages/corp/furn/MilanoProducts.vue') }, + ], + }, + { + id: 'furn-ming', + num: '47', + industry: 'furniture', + industryLabel: '家具', + title: '新中式', + intro: '宣纸墨色、月洞借景,含展品式产品页与可筛选的商品册报价单', + cover: { + kind: 'guofeng', + ck: '#23201b', + seal: '木', + bg: 'radial-gradient(circle at 50% 62%, transparent 0 33%, rgba(35,32,27,.45) 33.5% 35%, transparent 35.5%), radial-gradient(circle at 50% 118%, rgba(35,32,27,.4), transparent 58%), #f7f3ea', + motif: '榫', + style: { color: '#23201b', fontFamily: '"Noto Serif SC", serif', fontSize: '54px', fontWeight: 600 }, + }, + component: () => import('../pages/corp/furn/MingHome.vue'), + subPages: [ + { path: 'products', title: '产品系列', component: () => import('../pages/corp/furn/MingProducts.vue') }, + { path: 'catalog', title: '商品册 · 报价单', component: () => import('../pages/corp/furn/MingCatalog.vue') }, + ], + }, + { + id: 'furn-atelier', + num: '48', + industry: 'furniture', + industryLabel: '家具', + title: '收藏级画廊', + intro: '纯白展厅、超大字号与限量编号,产品页是一张作品索引表', + cover: { + kind: 'frame', + ck: 'rgba(17,17,17,.75)', + sub: 'OBJ. INDEX', + bg: 'linear-gradient(#ff4d00 0 0) 0% 0%/34% 22% no-repeat, linear-gradient(rgba(17,17,17,.8) 0 0) 50% 76%/44% 2px no-repeat, radial-gradient(ellipse 44% 5% at 50% 79%, rgba(17,17,17,.14), transparent 70%), #fbfbfa', + motif: 'OBJ.', + style: { color: '#111', fontWeight: 900, fontSize: '44px', letterSpacing: '-0.03em' }, + }, + component: () => import('../pages/corp/furn/AtelierHome.vue'), + subPages: [ + { path: 'products', title: '作品索引', component: () => import('../pages/corp/furn/AtelierProducts.vue') }, + ], + }, +] diff --git a/src/data/labStyles.js b/src/data/labStyles.js new file mode 100644 index 0000000..e8f5678 --- /dev/null +++ b/src/data/labStyles.js @@ -0,0 +1,181 @@ +// 实验室 Lab:功能演示合集(第三入口) +// 分类沿用 StyleGallery 的通用字段约定:key 写进条目的 industry,label 用于筛选钮与卡片徽章。 +export const labCategories = [ + { key: 'visual', label: '视觉动效' }, + { key: 'three', label: '3D 交互' }, + { key: 'tool', label: '趣味工具' }, + { key: 'app', label: '应用仿真' }, +] + +export const labList = [ + { + id: 'motion-lab', + num: 'L1', + industry: 'visual', + industryLabel: '视觉动效', + title: '动效实验室', + intro: '微交互、loader 与缓动曲线的可视化陈列馆,每件展品都能触发', + cover: { + kind: 'hud', + ck: 'rgba(94,234,212,.7)', + sub: 'cubic-bezier(.22,1,.36,1)', + bg: 'repeating-linear-gradient(90deg, transparent 0 34px, rgba(94,234,212,.08) 34px 35px), radial-gradient(ellipse at 30% 80%, rgba(94,234,212,.14), transparent 55%), #0b0e14', + motif: 'ease', + style: { color: '#5eead4', fontFamily: '"Space Grotesk", Consolas, monospace', fontStyle: 'italic', fontSize: '40px', fontWeight: 600, textShadow: '0 0 24px rgba(94,234,212,.5)' }, + }, + component: () => import('../pages/lab/MotionLab.vue'), + }, + { + id: 'exploded-view', + num: 'L2', + industry: 'three', + industryLabel: '3D 交互', + title: '产品分解交互', + intro: '滚动驱动爆炸拆解:小米 YU7 真车模(GLB · three.js)+ 无线耳机 SVG,部件散开、再合体', + cover: { + kind: 'blueprintgrid', + ck: 'rgba(245,158,11,.65)', + sub: 'SCROLL TO DISASSEMBLE', + bg: 'radial-gradient(circle at 50% 46%, transparent 0 13%, rgba(245,158,11,.5) 13.5% 14.5%, transparent 15% 22%, rgba(245,158,11,.32) 22.5% 23.5%, transparent 24% 31%, rgba(245,158,11,.18) 31.5% 32.5%, transparent 33%), #10131a', + motif: '', + style: {}, + }, + component: () => import('../pages/lab/ExplodedView.vue'), + }, + { + id: 'premium-showcase', + num: 'L3', + industry: 'visual', + industryLabel: '视觉动效', + title: '高质感设计', + intro: 'Awwwards 风奢品落地页:噪点光影、鼠标视差、磁性按钮、逐字浮现', + cover: { + kind: 'gilt', + ck: '#b8a06a', + sub: 'HAUTE HORLOGERIE', + bg: 'radial-gradient(circle at 50% 42%, rgba(184,160,106,.35) 0 1px, transparent 2px 26%, rgba(184,160,106,.4) 26.5% 27.5%, transparent 28%), radial-gradient(ellipse at 50% -20%, rgba(184,160,106,.14), transparent 60%), #08080a', + motif: 'OBSIDIAN', + style: { color: '#e8dcc0', fontFamily: '"Playfair Display", serif', fontSize: '20px', letterSpacing: '0.42em', transform: 'translateX(4px)' }, + }, + component: () => import('../pages/lab/PremiumShowcase.vue'), + }, + { + id: 'api-playground', + num: 'L4', + industry: 'app', + industryLabel: '应用仿真', + title: 'API 接口文档', + intro: 'Swagger 风文档 + localStorage 当真后端:Try it out 真实增删改查', + cover: { + kind: 'terminal', + ck: '#3fb950', + sub: '200 OK · localStorage', + bg: 'linear-gradient(#1f6feb 0 0) 14% 44%/17% 9% no-repeat, linear-gradient(#238636 0 0) 14% 60%/17% 9% no-repeat, linear-gradient(#b08800 0 0) 14% 76%/17% 9% no-repeat, #0d1117', + motif: '/api', + style: { color: '#3fb950', fontFamily: 'Consolas, monospace', fontSize: '34px', transform: 'translateX(20px)' }, + }, + component: () => import('../pages/lab/ApiPlayground.vue'), + }, + { + id: 'dev-docs', + num: 'L5', + industry: 'app', + industryLabel: '应用仿真', + title: '开发文档站', + intro: 'VitePress 风前台 + 可增删改的后台编辑模式,文档存在本地', + cover: { + kind: 'window', + os: 'mac', + winTitle: 'ng-docs — v2.0 · 已同步', + bg: 'linear-gradient(#eef1f6 0 0) 0 100%/26% 76% no-repeat, linear-gradient(#dfe5f0 0 0) 6% 38%/14% 5% no-repeat, linear-gradient(#dfe5f0 0 0) 6% 50%/16% 5% no-repeat, linear-gradient(#dfe5f0 0 0) 6% 62%/12% 5% no-repeat, linear-gradient(#e4e9f2 0 0) 38% 42%/50% 5% no-repeat, linear-gradient(#e4e9f2 0 0) 38% 54%/56% 5% no-repeat, linear-gradient(#e4e9f2 0 0) 38% 66%/44% 5% no-repeat, linear-gradient(#4c6ef5 0 0) 38% 30%/22% 7% no-repeat, #ffffff', + motif: '', + style: {}, + }, + component: () => import('../pages/lab/DevDocs.vue'), + }, + { + id: 'typing-test', + num: 'L6', + industry: 'tool', + industryLabel: '趣味工具', + title: '打字测速', + intro: '中文 / 英文 / 代码三种题库,实时字速与准确率,成绩存本地', + cover: { + kind: 'terminal', + ck: '#5eead4', + sub: '87 字符/分 · 98%', + bg: 'linear-gradient(rgba(94,234,212,.55) 0 0) 12% 46%/38% 3px no-repeat, linear-gradient(rgba(94,234,212,.3) 0 0) 12% 60%/56% 3px no-repeat, linear-gradient(rgba(251,113,133,.5) 0 0) 52% 46%/9% 3px no-repeat, #0b0e14', + motif: 'WPM_', + style: { color: '#5eead4', fontFamily: '"Space Grotesk", Consolas, monospace', fontSize: '34px', letterSpacing: '0.1em', textShadow: '0 0 20px rgba(94,234,212,.4)' }, + }, + component: () => import('../pages/lab/TypingTest.vue'), + }, + { + id: 'pixel-painter', + num: 'L7', + industry: 'tool', + industryLabel: '趣味工具', + title: '像素画板', + intro: '16×16 像素编辑器:画笔油漆桶取色器、撤销、导出 PNG、作品库', + cover: { + kind: 'pixelframe', + ck: '#818cf8', + sub: '16 × 16 CANVAS', + bg: 'linear-gradient(#fb7185 0 0) 30% 34%/8% 14% no-repeat, linear-gradient(#fcd34d 0 0) 38% 34%/8% 14% no-repeat, linear-gradient(#5eead4 0 0) 46% 48%/8% 14% no-repeat, linear-gradient(#818cf8 0 0) 54% 34%/8% 14% no-repeat, linear-gradient(#f472b6 0 0) 62% 48%/8% 14% no-repeat, repeating-conic-gradient(rgba(255,255,255,.04) 0 25%, transparent 0 50%) 0 0/16% 22%, #0d1118', + motif: '', + style: {}, + }, + component: () => import('../pages/lab/PixelPainter.vue'), + }, + { + id: 'im-oa', + num: 'L8', + industry: 'app', + industryLabel: '应用仿真', + title: 'imOA 协同办公', + intro: '飞书钉钉风 OA:IM 聊天、圆钮打卡、请假报销审批流自动流转,全程 UI 动效', + cover: { + kind: 'window', + os: 'mac', + winTitle: '糕效办公 — 3 条新消息 · 审批流转中', + bg: 'linear-gradient(#20305e 0 0) 0 0/13% 100% no-repeat, linear-gradient(#eef3ff 0 0) 13% 0/28% 100% no-repeat, linear-gradient(120deg,#3370ff,#5b8cff) 88% 30%/34% 11% no-repeat, linear-gradient(#eef2f9 0 0) 48% 48%/40% 11% no-repeat, linear-gradient(120deg,#3370ff,#5b8cff) 78% 66%/24% 11% no-repeat, linear-gradient(#22c55e 0 0) 15.5% 12%/3% 5% no-repeat, #ffffff', + motif: '', + style: {}, + }, + component: () => import('../pages/lab/ImOaPage.vue'), + }, + { + id: 'palette-lab', + num: 'L9', + industry: 'tool', + industryLabel: '趣味工具', + title: '配色实验室', + intro: '空格生成和谐配色:邻近互补三角单色,可锁定、复制、导出 CSS 变量', + cover: { + kind: 'frame', + ck: 'rgba(244,114,182,.55)', + sub: 'SPACE TO SHUFFLE', + bg: 'linear-gradient(90deg, #1d2a4a 0 20%, #2f5d8a 0 40%, #3aa6a0 0 60%, #f2c94c 0 80%, #ef6a6a 0 100%) 50% 44%/72% 34% no-repeat, #0b0e14', + motif: '', + style: {}, + }, + component: () => import('../pages/lab/PaletteLab.vue'), + }, + { + id: 'car-3d', + num: 'L10', + industry: 'three', + industryLabel: '3D 交互', + title: '真 3D 车模拆解', + intro: 'three.js 加载 GLB 真模型:拖拽环绕、滚轮缩放、滑杆径向爆炸,可拖入任意 .glb', + cover: { + kind: 'hud', + ck: 'rgba(94,234,212,.7)', + sub: 'GLB · three.js · WebGL', + bg: 'radial-gradient(circle at 50% 58%, rgba(30,144,104,.55) 0 9%, transparent 10% 21%, rgba(94,234,212,.18) 21.5% 22.5%, transparent 23.5% 32%, rgba(94,234,212,.1) 32.5% 33.5%, transparent 34%), linear-gradient(rgba(94,234,212,.06) 1px, transparent 1px) 0 0/100% 24px, #0a0d13', + motif: '3D', + style: { color: '#5eead4', fontFamily: '"Space Grotesk", Consolas, monospace', fontSize: '44px', fontWeight: 700, textShadow: '0 0 26px rgba(94,234,212,.5)' }, + }, + component: () => import('../pages/lab/Car3dPage.vue'), + }, +] diff --git a/src/data/profile.js b/src/data/profile.js new file mode 100644 index 0000000..9f033b1 --- /dev/null +++ b/src/data/profile.js @@ -0,0 +1,74 @@ +// 所有风格页面共用的个人资料与作品数据 +export const profile = { + name: '年糕崽崽', + nameEn: 'NianGao ZaiZai', + job: '程序员', + jobEn: 'Software Engineer', + age: 25, + location: '中国 · 杭州', + motto: '把代码写得像年糕一样,软糯又有韧性。', + bio: '25 岁的前端程序员。白天写 Vue 和 TypeScript,晚上折腾终端主题和小游戏。相信好的界面应该像刚出锅的年糕:温润、扎实、让人惊喜。', + bioShort: '写代码的年糕,一个热爱把玩界面与终端的 25 岁程序员。', + + avatars: { + default: + 'https://api.dicebear.com/9.x/notionists/svg?seed=niangao&backgroundColor=ffdfbf', + pixel: 'https://api.dicebear.com/9.x/pixel-art/svg?seed=niangao', + bot: 'https://api.dicebear.com/9.x/bottts/svg?seed=niangao', + cute: 'https://api.dicebear.com/9.x/adventurer/svg?seed=niangao&backgroundColor=ffd5dc', + }, + + skills: [ + { name: 'Vue / 前端工程', en: 'Vue & Frontend', level: 92 }, + { name: 'TypeScript', en: 'TypeScript', level: 88 }, + { name: 'Node.js', en: 'Node.js', level: 80 }, + { name: 'UI / 交互设计', en: 'UI & Interaction', level: 76 }, + { name: 'Rust / CLI 工具', en: 'Rust & CLI', level: 72 }, + { name: 'Canvas / 小游戏', en: 'Canvas & Games', level: 68 }, + ], + + projects: [ + { + name: 'CodeMochi', + alias: '代码年糕', + desc: '开源代码片段管理工具,支持全文搜索、标签体系与一键分享,已收获 2.3k Star。', + tags: ['Vue 3', 'TypeScript', 'IndexedDB'], + year: '2025', + stars: '2.3k', + image: 'https://picsum.photos/seed/codemochi/640/420', + }, + { + name: '糯米终端', + alias: 'NuomiTerm', + desc: '终端美化主题与 CLI 工具集:一条命令换主题、自带年糕色板与状态栏组件。', + tags: ['Rust', 'Shell', 'CLI'], + year: '2024', + stars: '1.1k', + image: 'https://picsum.photos/seed/nuomiterm/640/420', + }, + { + name: 'TodoRice', + alias: '饭粒清单', + desc: '极简待办 Web 应用,离线可用的 PWA,把每件小事都当作一粒米认真对待。', + tags: ['Vue 3', 'Pinia', 'PWA'], + year: '2024', + stars: '860', + image: 'https://picsum.photos/seed/todorice/640/420', + }, + { + name: '像素厨房', + alias: 'Pixel Kitchen', + desc: '用 Canvas 手搓的做饭小游戏:翻锅、颠勺、摆盘,全凭手速与直觉。', + tags: ['Canvas', 'TypeScript', 'Game'], + year: '2023', + stars: '540', + image: 'https://picsum.photos/seed/pixelkitchen/640/420', + }, + ], + + contacts: [ + { label: 'GitHub', value: 'github.com/niangao-zaizai' }, + { label: 'Email', value: 'hi@niangao.dev' }, + { label: 'Blog', value: 'blog.niangao.dev' }, + ], +} diff --git a/src/data/promptSkills.js b/src/data/promptSkills.js new file mode 100644 index 0000000..cfc6ef1 --- /dev/null +++ b/src/data/promptSkills.js @@ -0,0 +1,180 @@ +// 每个风格的「提示词 + Skill」生成器 +// 通过 /kl 口令解锁后,风格详情页可查看与复制 +import { styleList } from './styles' +import { corpStyleList } from './corpStyles' +import { labList } from './labStyles' + +/* 各风格的交互与细节要点(模板兜底之外的手写补充) */ +const extras = { + /* ---- 个人 ---- */ + terminal: '实现一个可输入的终端:支持 help/about/works/contact 等命令、命令历史(↑↓)、Tab 补全、打字机输出与闪烁光标。', + pixel: '8-bit 游戏 UI:血条/金币 HUD、Press Start 2P 字体、按钮按下有像素位移,装饰用阶梯状边框。', + win98: '完整还原开机 → 登录 → 桌面流程:可拖拽窗口、任务栏、开始菜单、双击图标开窗,灰色立体边框用 outset/inset。', + macos: '开机进度条 → 登录屏 → 桌面:菜单栏、可拖拽窗口、Dock 放大悬停,桌面图标双击打开对应窗口。', + win11: '开机动画 → 登录 → 云母质感桌面:居中任务栏、开始菜单面板、亚克力毛玻璃(backdrop-filter)。', + vinyl: '黑胶唱机可播放/暂停/切歌:唱片旋转动画、唱臂抬起落下的过渡、曲目列表高亮当前曲目。', + receipt: '热敏小票逐行打印动画(撕纸锯齿边、等宽字体、条码),提供"再打一张"重新触发打印。', + 'boarding-pass': '登机牌版式:主券+副券,副券可以"撕下来"(点击分离动画),登机口/座位等信息用等宽字排版。', + telegram: '电报机逐条拍发文字(STOP 结尾),电文打字机节奏出现,支持重发,纸带与铆钉细节。', + polaroid: '软木板上散布拍立得相片:胶带/图钉固定、随机微旋转,点击放大查看,白框下写手写体注释。', + ide: '代码编辑器界面:文件树可点击切换文件、标签页、行号、语法高亮配色,把简历写成 profile.ts。', + dashboard: 'GitHub 风仪表盘:确定性伪随机的贡献热力图(mulberry32)、统计卡、仓库列表。', + 'neon-sign': '夜晚砖墙上的霓虹灯管字:多层 text-shadow 辉光、偶发闪烁 keyframes、营业中招牌元素。', + gameboy: '掌机壳 + 绿液晶屏:十字键/AB 键可点按(切换卡带/移动光标)、开机 logo 下落动画、按键有按下位移。', + ipod: 'Click Wheel 可点:MENU 返回列表、中键进入、⏮⏭ 切换或快进;列表视图与"正在播放"视图切换。', + 'crt-tv': '木壳电视:旋钮与遥控器换台(4 个频道 + 雪花彩蛋台),切台时 240ms 静电噪声,常驻扫描线与暗角。', + tamagotchi: '蛋形宠物机三按钮:喂食/状态/陪玩,像素宠物有待机/进食/跳跃动画,互动次数存 localStorage。', + pager: 'BB 机单色屏翻留言:▲▼ 翻页、蜂鸣时 LED 闪烁 + 机身震动动画,留言自动每 9 秒送达一条。', + wrapped: 'Spotify Wrapped 式全屏卡片:点击/空格翻页、顶部分段进度条、大字号数据卡与榜单错峰入场。', + danmaku: 'B 站风播放页:弹幕从右向左飘(随机轨道/时长/字号)、输入框发弹幕即时飘过、一键三连点亮动画。', + 'wechat-chat': '微信对话流逐条播放:对方输入中指示、语音条、项目名片卡片、可点击拆开的红包(拆后变已领取)。', + steam: 'Steam 资料页:成就展柜(稀有度彩色描边)、游戏时长条、+rep 留言板可发言、等级徽章。', + lockscreen: 'iOS 锁屏:实时时钟、通知堆叠错峰入场、按住向上拖拽超过阈值才解锁进入主屏图标网格,可重新锁定。', + passport: '护照双页:证件页(照片防伪纹 + MRZ 机读码)+ 签证章页(多枚旋转印章弹性盖下),可翻页换一批章。', + checkup: '体检报告单:检验表格逐行入场、超标项红色↑、结论栏、医师签名 + 红章盖章动画、条码与水印。', + credits: '电影片尾滚动字幕:自动上滚(约 50s)、悬停暂停、上下渐隐遮罩,滚完出现彩蛋画面可重播。', + wiki: '维基百科版式:消歧义提示、右侧信息框、可折叠目录锚点跳转、引用上标与一本正经的参考资料。', + guofeng: '朱红黛青国风:竖排文案、印章、回纹边框与烫金书法字,卷轴式展开动画。', + zen: '日式禅意:大量留白、竖排、墨色层次与一枚朱印,滚动时元素缓慢淡入。', + + /* ---- 企业 ---- */ + 'ecom-sale': '大促页:真实走动的翻牌倒计时、优惠券墙(齿孔票券 + 领取状态)、爆款卡带抢购进度条。', + 'ecom-premium': '极简精品:编辑部错位橱窗(比例不一 + 列位下沉)、商品可点进详情页(图册切换、规格选择、加入购物袋)。', + 'ecom-fresh': '生鲜集市:货架价签式商品行(打孔、撕线票根、条码)、木箱数据区、手写便签引言。', + 'ecom-toy': '潮玩盲盒:漫画标题牌、可以抽的盲盒机(结果弹出 + 彩带)、贴纸卡片与波普点底纹。', + 'ecom-dutyfree': '免税店:翻牌屏标题逐字翻转、走秒的候机楼时钟、航线虚线流动动画、登机牌式指南卡。', + 'art-auction': '拍卖行:鎏金双线画框、拍卖倒计时格、之字形拍品排布、举牌按钮落槌动画与"已破高估价"角标。', + 'art-whitebox': '白盒美术馆:错落挂画(钢丝 + 射灯 hover 点亮)、展签编号系统、楼层索引式条目。', + 'art-kids': '儿童美育:晾衣绳挂作品(夹子为轴摆动)、彩纸剪贴课程卡、蜡笔框与颜料泼点。', + 'art-digital': '数字艺术馆:NFT 卡 3D 倾斜跟随鼠标 + 独立霓虹色相 + 全息扫光,链上编号跑马灯。', + 'pharma-tcm': '中药老字号:hover 拉开的药柜抽屉(弹出药性签条)、宣纸纹理、朱印、可跳转的线装古方书子页。', + 'pharma-modern': '现代药企:SVG 分子结构(游走电子动画)、研发管线进度条带相位刻度、洁净蓝白版式。', + 'med-online': '互联网问诊:完整手机壳(状态栏/输入栏)、对话自动播放带"正在输入"、结束弹出电子处方卡。', + 'med-hospital': '综合医院:导视标识牌式科室宫格、挂号窗口式表单(撕线票据)、心电图绘制动画。', + 'travel-ink': '山水国风:手绘宋代山水 SVG(多层远山 + 雾气漂移)、手卷横排、题跋与印章、纸纹覆层。', + 'travel-oldtown': '古镇文旅:徽派天际线 SVG 夜景(窗火闪烁)、灯笼摇曳、木版画装裱四景卡(题签 + 朱印)。', + 'travel-park': '主题乐园:SVG 摩天轮旋转 + 过山车沿轨道跑(SMIL)、齿孔门票选择卡、灯泡跑马灯数据板。', + 'travel-ski': '滑雪场:雪山全景 SVG + 缆车沿索道滑动、缆车吊牌式雪道卡(国际难度标识形状)、斜切雪坡分隔。', + 'travel-island': '海岛度假:日落海景 SVG(帆船起伏 + 波光)、明信片式玩乐卡(邮票邮戳)、拱顶房型卡。', + 'tech-opensource': '开源社区:GitHub 风 README、贡献热力图、repo 列表行、终端配色与等宽字。', + 'tech-hardware': '硬件发布会:纯黑舞台、芯片旋转流光包边 + 扫光、参数横条、预约按钮状态切换。', + 'tech-chip': '半导体:SVG die-shot(电路走线 + 信号脉冲沿路径流动)、蓝图网格、制程参数表。', + 'tech-space': '航天:星空 HUD、火箭发射台 SVG(火焰抖动)、任务时间线与倒计时。', + 'ai-llm': '大模型官网:打字机对话演示(思考中三点 → 逐字回答,可重播)、神经网络星图背景。', + 'ai-robot': '机器人公司:SVG 六轴机械臂三级关节联动 + 传送带纸箱循环、设备铭牌式场景卡。', + 'ai-paint': 'AI 绘画:prompt 输入生成(扩散噪点 → 图像渐显 + 进度百分比)、瀑布流画廊。', + 'ai-voice': '语音助手:呼吸圆钮唤醒(声呐扩散环),先出用户指令再出回复的对话节奏。', + 'ai-vision': '视觉安防:HUD 取景框(CV 角标检测框 + 扫描线)、滚动事件日志、仪表读数。', + 'saas-classic': '经典 SaaS:手绘产品窗口模型(看板 + 浮动通知)、月付/年付切换(年付显示原价删除线)、bento 功能格。', + 'saas-collab': '协作文档:块编辑器(待办可勾选)、多人光标漂移、斜杠菜单悬浮、数据库表格视图。', + 'saas-bi': '数据 BI:KPI 迷你趋势线、柱图悬停数值气泡、环图中心汇总、实时事件流滚动条。', + 'saas-crm': '客服 CRM:对话自动播放可重播、时间戳与已读回执、工单流转卡(已完成 ✓ 弹出)。', + 'saas-builder': '建站平台:点击组件库往画布加积木(可上移/下移/删除)、发布按钮状态、协作光标。', + 'saas-medlink': '医联体 SaaS 多页站:粒子背景(鼠标互动)、3D 倾斜驾驶舱、数字滚动、产品/复诊演示/文章/视频子页。', + 'furn-ming': '新中式家具:月洞门借景、水墨山水 SVG、竖排诗句、展品式产品页 + 可筛选出报价单的商品册子页。', + 'furn-wabi': '侘寂家具:亚麻底、木纹 SVG、标本卡式产品卡、滚动渐入的慢节奏。', + 'furn-milano': '意式轻奢:墨绿鎏金、大理石纹 SVG、杂志式排版、金光掠过 hover。', + 'furn-atelier': '收藏级画廊:超大无衬线、作品索引表、光标跟随的浮动预览(Teleport)。', + + /* ---- 实验室 ---- */ + 'motion-lab': '动效陈列馆:canvas 流光丝背景 + 漂移光晕、磁性/涟漪/果冻/流光描边按钮、6 款 loader、缓动曲线 SVG 图鉴(小球试跑 + 复制 CSS)、转场切换台。', + 'exploded-view': '滚动驱动拆解双模板(小米 YU7 真车模 GLB + 耳机 SVG):sticky 画布 + 滚动进度(smoothstep 分段)驱动部件散开/结尾合体;真车模用 three.js 质心比例爆炸(从中心均匀撑开不互穿 + 地面余量钳制)、外层先分离、相机随滚动环绕并后撤,相机/灯光随模型尺度自适应,three 按需动态 import。', + 'premium-showcase': '高质感样板:噪点覆层、鼠标视差(表盘 + 光斑反向移动)、逐字浮现标题、磁性按钮、斜体跑马灯。', + 'api-playground': 'Swagger 三栏文档 + localStorage 后端:CRUD 带 400/404 校验与模拟延迟,Try it out 返回真实状态码,可重置数据库。', + 'dev-docs': 'VitePress 风文档站:零依赖迷你 Markdown 渲染器、目录树/TOC/搜索,管理模式可增删改排序文档并持久化。', + 'typing-test': '打字测速:逐字符比对高亮(对/错/光标),实时字符每分与准确率,中/英/代码题库,成绩历史与最佳纪录存本地。', + 'pixel-painter': '像素画板:16×16 网格按住拖绘,画笔/橡皮/油漆桶(洪水填充)/取色器,撤销栈,canvas 导出 PNG,作品库存本地。', + 'im-oa': 'imOA 协同办公:深色侧栏 + 徽标脉冲,IM 聊天(气泡弹入/打字三点/已读回执/自动回复),涟漪圆钮打卡(对勾描边 + 按班次判定迟到早退 + 记录滑入)+ 排班日历(早/晚/休配色、出勤补卡圆点、翻月格子逐个弹入),请假/报销表单提交后审批流自动流转(节点点亮、连线注水、通过弹徽章),全部存本地。', + 'palette-lab': '配色实验室:HSL 和谐算法(邻近/互补/三角/单色)生成五色板,空格重生成、锁定保留、对比度标注、CSS 变量导出与收藏。', + 'car-3d': 'three.js 真 3D 拆解:GLTFLoader 加载 GLB(缺省回退内置低模车),网格拍平后按质心比例爆炸(从中心均匀撑开不互穿 + 地面钳制,滑杆 + 帧间 lerp),OrbitControls 阻尼环绕、自动旋转、阴影地台,支持拖拽 .glb 即载即拆。', +} + +/* 路径注册表(含企业子页归并到父风格) */ +const registry = new Map() +for (const s of styleList) registry.set(`/style/${s.id}`, { ...s, coll: '个人页面', collKey: 'personal' }) +for (const s of corpStyleList) registry.set(`/corp/${s.id}`, { ...s, coll: '企业官网', collKey: 'corp' }) +for (const s of labList) registry.set(`/lab/${s.id}`, { ...s, coll: '实验室', collKey: 'lab' }) + +export function findStyleByPath(path) { + if (registry.has(path)) return registry.get(path) + // 子页(如 /corp/furn-ming/products)归并到父风格 + const seg = path.split('/').filter(Boolean) + if (seg.length >= 2) { + const parent = `/${seg[0]}/${seg[1]}` + if (registry.has(parent)) return registry.get(parent) + } + return null +} + +function contentReq(e) { + if (e.collKey === 'personal') { + return '页面主角是虚构人物「年糕崽崽」:25 岁程序员,坐标杭州,座右铭"把代码写得像年糕一样,软糯又有韧性"。需包含自我介绍、技能(约 6 项带熟练度)、代表作品(4 个带星标数)与联系方式,全部使用虚构 mock 数据。' + } + if (e.collKey === 'corp') { + return `页面是一家虚构公司的官网(行业:${e.industryLabel || '综合'}),需包含主视觉、核心业务/产品展示、数据指标、客户声音与页脚,并在页脚声明"公司与数据均为虚构演示"。` + } + return '这是一个功能演示页:交互状态与数据存 localStorage,刷新后仍可恢复;页面需自带使用说明与重置入口。' +} + +export function buildPrompt(e) { + const extra = extras[e.id] ? `\n- 核心交互:${extras[e.id]}` : '' + return `你是一位资深前端工程师兼视觉设计师。请用 Vue 3( + + + + diff --git a/src/pages/CorpHome.vue b/src/pages/CorpHome.vue new file mode 100644 index 0000000..b30232e --- /dev/null +++ b/src/pages/CorpHome.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/src/pages/Home.vue b/src/pages/Home.vue new file mode 100644 index 0000000..edcd6b2 --- /dev/null +++ b/src/pages/Home.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/src/pages/KlPage.vue b/src/pages/KlPage.vue new file mode 100644 index 0000000..f49b0c8 --- /dev/null +++ b/src/pages/KlPage.vue @@ -0,0 +1,318 @@ + + + + + diff --git a/src/pages/LabHome.vue b/src/pages/LabHome.vue new file mode 100644 index 0000000..b71d6fd --- /dev/null +++ b/src/pages/LabHome.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/src/pages/corp/AiLlmPage.vue b/src/pages/corp/AiLlmPage.vue new file mode 100644 index 0000000..03f9e61 --- /dev/null +++ b/src/pages/corp/AiLlmPage.vue @@ -0,0 +1,782 @@ + + + + + diff --git a/src/pages/corp/AiPaintPage.vue b/src/pages/corp/AiPaintPage.vue new file mode 100644 index 0000000..7082097 --- /dev/null +++ b/src/pages/corp/AiPaintPage.vue @@ -0,0 +1,575 @@ + + + + + diff --git a/src/pages/corp/AiRobotPage.vue b/src/pages/corp/AiRobotPage.vue new file mode 100644 index 0000000..5db1b23 --- /dev/null +++ b/src/pages/corp/AiRobotPage.vue @@ -0,0 +1,721 @@ + + + + + diff --git a/src/pages/corp/AiVisionPage.vue b/src/pages/corp/AiVisionPage.vue new file mode 100644 index 0000000..87c1332 --- /dev/null +++ b/src/pages/corp/AiVisionPage.vue @@ -0,0 +1,702 @@ + + + + + diff --git a/src/pages/corp/AiVoicePage.vue b/src/pages/corp/AiVoicePage.vue new file mode 100644 index 0000000..26a8e0e --- /dev/null +++ b/src/pages/corp/AiVoicePage.vue @@ -0,0 +1,606 @@ + + + + + diff --git a/src/pages/corp/ArtAuctionPage.vue b/src/pages/corp/ArtAuctionPage.vue new file mode 100644 index 0000000..1c009f6 --- /dev/null +++ b/src/pages/corp/ArtAuctionPage.vue @@ -0,0 +1,710 @@ + + + + + diff --git a/src/pages/corp/ArtAvantgardePage.vue b/src/pages/corp/ArtAvantgardePage.vue new file mode 100644 index 0000000..8fd5446 --- /dev/null +++ b/src/pages/corp/ArtAvantgardePage.vue @@ -0,0 +1,548 @@ + + + + + diff --git a/src/pages/corp/ArtDigitalPage.vue b/src/pages/corp/ArtDigitalPage.vue new file mode 100644 index 0000000..7cb51c3 --- /dev/null +++ b/src/pages/corp/ArtDigitalPage.vue @@ -0,0 +1,583 @@ + + + + + diff --git a/src/pages/corp/ArtKidsPage.vue b/src/pages/corp/ArtKidsPage.vue new file mode 100644 index 0000000..45b55a7 --- /dev/null +++ b/src/pages/corp/ArtKidsPage.vue @@ -0,0 +1,499 @@ + + + + + diff --git a/src/pages/corp/ArtWhiteboxPage.vue b/src/pages/corp/ArtWhiteboxPage.vue new file mode 100644 index 0000000..feeb283 --- /dev/null +++ b/src/pages/corp/ArtWhiteboxPage.vue @@ -0,0 +1,595 @@ + + + + + diff --git a/src/pages/corp/EcomDutyFreePage.vue b/src/pages/corp/EcomDutyFreePage.vue new file mode 100644 index 0000000..7119c55 --- /dev/null +++ b/src/pages/corp/EcomDutyFreePage.vue @@ -0,0 +1,657 @@ + + + + + diff --git a/src/pages/corp/EcomFreshPage.vue b/src/pages/corp/EcomFreshPage.vue new file mode 100644 index 0000000..3b88c3b --- /dev/null +++ b/src/pages/corp/EcomFreshPage.vue @@ -0,0 +1,715 @@ + + + + + diff --git a/src/pages/corp/EcomPremiumPage.vue b/src/pages/corp/EcomPremiumPage.vue new file mode 100644 index 0000000..19c1909 --- /dev/null +++ b/src/pages/corp/EcomPremiumPage.vue @@ -0,0 +1,639 @@ + + + + + diff --git a/src/pages/corp/EcomSalePage.vue b/src/pages/corp/EcomSalePage.vue new file mode 100644 index 0000000..7296ce7 --- /dev/null +++ b/src/pages/corp/EcomSalePage.vue @@ -0,0 +1,843 @@ + + + + + diff --git a/src/pages/corp/EcomToyPage.vue b/src/pages/corp/EcomToyPage.vue new file mode 100644 index 0000000..a4297c9 --- /dev/null +++ b/src/pages/corp/EcomToyPage.vue @@ -0,0 +1,704 @@ + + + + + diff --git a/src/pages/corp/HomeBabyPage.vue b/src/pages/corp/HomeBabyPage.vue new file mode 100644 index 0000000..6ed9993 --- /dev/null +++ b/src/pages/corp/HomeBabyPage.vue @@ -0,0 +1,774 @@ + + + + + diff --git a/src/pages/corp/HomeButlerPage.vue b/src/pages/corp/HomeButlerPage.vue new file mode 100644 index 0000000..4db8943 --- /dev/null +++ b/src/pages/corp/HomeButlerPage.vue @@ -0,0 +1,770 @@ + + + + + diff --git a/src/pages/corp/HomeCleanPage.vue b/src/pages/corp/HomeCleanPage.vue new file mode 100644 index 0000000..64dc7cd --- /dev/null +++ b/src/pages/corp/HomeCleanPage.vue @@ -0,0 +1,785 @@ + + + + + diff --git a/src/pages/corp/HomeWarmPage.vue b/src/pages/corp/HomeWarmPage.vue new file mode 100644 index 0000000..706c35c --- /dev/null +++ b/src/pages/corp/HomeWarmPage.vue @@ -0,0 +1,859 @@ + + + + + diff --git a/src/pages/corp/MedClinicPage.vue b/src/pages/corp/MedClinicPage.vue new file mode 100644 index 0000000..f595737 --- /dev/null +++ b/src/pages/corp/MedClinicPage.vue @@ -0,0 +1,562 @@ + + + + + diff --git a/src/pages/corp/MedDentalPage.vue b/src/pages/corp/MedDentalPage.vue new file mode 100644 index 0000000..2b7ebfd --- /dev/null +++ b/src/pages/corp/MedDentalPage.vue @@ -0,0 +1,637 @@ + + + + + diff --git a/src/pages/corp/MedFamilyPage.vue b/src/pages/corp/MedFamilyPage.vue new file mode 100644 index 0000000..e5b490d --- /dev/null +++ b/src/pages/corp/MedFamilyPage.vue @@ -0,0 +1,581 @@ + + + + + diff --git a/src/pages/corp/MedHospitalPage.vue b/src/pages/corp/MedHospitalPage.vue new file mode 100644 index 0000000..3d0ee13 --- /dev/null +++ b/src/pages/corp/MedHospitalPage.vue @@ -0,0 +1,866 @@ + + + + + diff --git a/src/pages/corp/MedOnlinePage.vue b/src/pages/corp/MedOnlinePage.vue new file mode 100644 index 0000000..a6567dc --- /dev/null +++ b/src/pages/corp/MedOnlinePage.vue @@ -0,0 +1,935 @@ + + + + + diff --git a/src/pages/corp/PharmaBiotechPage.vue b/src/pages/corp/PharmaBiotechPage.vue new file mode 100644 index 0000000..e146790 --- /dev/null +++ b/src/pages/corp/PharmaBiotechPage.vue @@ -0,0 +1,681 @@ + + + + + diff --git a/src/pages/corp/PharmaModernPage.vue b/src/pages/corp/PharmaModernPage.vue new file mode 100644 index 0000000..62622be --- /dev/null +++ b/src/pages/corp/PharmaModernPage.vue @@ -0,0 +1,789 @@ + + + + + diff --git a/src/pages/corp/PharmaStorePage.vue b/src/pages/corp/PharmaStorePage.vue new file mode 100644 index 0000000..9d3acbc --- /dev/null +++ b/src/pages/corp/PharmaStorePage.vue @@ -0,0 +1,688 @@ + + + + + diff --git a/src/pages/corp/PharmaTcmPage.vue b/src/pages/corp/PharmaTcmPage.vue new file mode 100644 index 0000000..9d7ab1d --- /dev/null +++ b/src/pages/corp/PharmaTcmPage.vue @@ -0,0 +1,732 @@ + + + + + diff --git a/src/pages/corp/SaasBiPage.vue b/src/pages/corp/SaasBiPage.vue new file mode 100644 index 0000000..daecb22 --- /dev/null +++ b/src/pages/corp/SaasBiPage.vue @@ -0,0 +1,695 @@ + + + + + diff --git a/src/pages/corp/SaasBuilderPage.vue b/src/pages/corp/SaasBuilderPage.vue new file mode 100644 index 0000000..8fb8616 --- /dev/null +++ b/src/pages/corp/SaasBuilderPage.vue @@ -0,0 +1,766 @@ + + + + + diff --git a/src/pages/corp/SaasClassicPage.vue b/src/pages/corp/SaasClassicPage.vue new file mode 100644 index 0000000..f801265 --- /dev/null +++ b/src/pages/corp/SaasClassicPage.vue @@ -0,0 +1,988 @@ + + + + + diff --git a/src/pages/corp/SaasCollabPage.vue b/src/pages/corp/SaasCollabPage.vue new file mode 100644 index 0000000..674fd2f --- /dev/null +++ b/src/pages/corp/SaasCollabPage.vue @@ -0,0 +1,729 @@ + + + + + diff --git a/src/pages/corp/SaasCrmPage.vue b/src/pages/corp/SaasCrmPage.vue new file mode 100644 index 0000000..5cc682a --- /dev/null +++ b/src/pages/corp/SaasCrmPage.vue @@ -0,0 +1,669 @@ + + + + + diff --git a/src/pages/corp/TechChipPage.vue b/src/pages/corp/TechChipPage.vue new file mode 100644 index 0000000..2f04f30 --- /dev/null +++ b/src/pages/corp/TechChipPage.vue @@ -0,0 +1,683 @@ + + + + + diff --git a/src/pages/corp/TechEnterprisePage.vue b/src/pages/corp/TechEnterprisePage.vue new file mode 100644 index 0000000..1822b91 --- /dev/null +++ b/src/pages/corp/TechEnterprisePage.vue @@ -0,0 +1,713 @@ + + + + + diff --git a/src/pages/corp/TechHardwarePage.vue b/src/pages/corp/TechHardwarePage.vue new file mode 100644 index 0000000..1f51b4a --- /dev/null +++ b/src/pages/corp/TechHardwarePage.vue @@ -0,0 +1,554 @@ + + + + + diff --git a/src/pages/corp/TechOpensourcePage.vue b/src/pages/corp/TechOpensourcePage.vue new file mode 100644 index 0000000..9e0cf25 --- /dev/null +++ b/src/pages/corp/TechOpensourcePage.vue @@ -0,0 +1,607 @@ + + + + + diff --git a/src/pages/corp/TechSpacePage.vue b/src/pages/corp/TechSpacePage.vue new file mode 100644 index 0000000..74e6b1f --- /dev/null +++ b/src/pages/corp/TechSpacePage.vue @@ -0,0 +1,744 @@ + + + + + diff --git a/src/pages/corp/TravelInkPage.vue b/src/pages/corp/TravelInkPage.vue new file mode 100644 index 0000000..46828ed --- /dev/null +++ b/src/pages/corp/TravelInkPage.vue @@ -0,0 +1,753 @@ + + + + + diff --git a/src/pages/corp/TravelIslandPage.vue b/src/pages/corp/TravelIslandPage.vue new file mode 100644 index 0000000..8909532 --- /dev/null +++ b/src/pages/corp/TravelIslandPage.vue @@ -0,0 +1,691 @@ + + + + + diff --git a/src/pages/corp/TravelOldtownPage.vue b/src/pages/corp/TravelOldtownPage.vue new file mode 100644 index 0000000..a390945 --- /dev/null +++ b/src/pages/corp/TravelOldtownPage.vue @@ -0,0 +1,781 @@ + + + + + diff --git a/src/pages/corp/TravelParkPage.vue b/src/pages/corp/TravelParkPage.vue new file mode 100644 index 0000000..6831098 --- /dev/null +++ b/src/pages/corp/TravelParkPage.vue @@ -0,0 +1,823 @@ + + + + + diff --git a/src/pages/corp/TravelSkiPage.vue b/src/pages/corp/TravelSkiPage.vue new file mode 100644 index 0000000..a432c10 --- /dev/null +++ b/src/pages/corp/TravelSkiPage.vue @@ -0,0 +1,643 @@ + + + + + diff --git a/src/pages/corp/ecom/PremiumDetail.vue b/src/pages/corp/ecom/PremiumDetail.vue new file mode 100644 index 0000000..cda629d --- /dev/null +++ b/src/pages/corp/ecom/PremiumDetail.vue @@ -0,0 +1,649 @@ + + + + + diff --git a/src/pages/corp/furn/AtelierHome.vue b/src/pages/corp/furn/AtelierHome.vue new file mode 100644 index 0000000..d81a7c0 --- /dev/null +++ b/src/pages/corp/furn/AtelierHome.vue @@ -0,0 +1,646 @@ + + + + + diff --git a/src/pages/corp/furn/AtelierProducts.vue b/src/pages/corp/furn/AtelierProducts.vue new file mode 100644 index 0000000..6335709 --- /dev/null +++ b/src/pages/corp/furn/AtelierProducts.vue @@ -0,0 +1,576 @@ + + + + + diff --git a/src/pages/corp/furn/MilanoHome.vue b/src/pages/corp/furn/MilanoHome.vue new file mode 100644 index 0000000..5680b1c --- /dev/null +++ b/src/pages/corp/furn/MilanoHome.vue @@ -0,0 +1,720 @@ + + + + + diff --git a/src/pages/corp/furn/MilanoProducts.vue b/src/pages/corp/furn/MilanoProducts.vue new file mode 100644 index 0000000..9ab2422 --- /dev/null +++ b/src/pages/corp/furn/MilanoProducts.vue @@ -0,0 +1,456 @@ + + + + + diff --git a/src/pages/corp/furn/MingCatalog.vue b/src/pages/corp/furn/MingCatalog.vue new file mode 100644 index 0000000..6370065 --- /dev/null +++ b/src/pages/corp/furn/MingCatalog.vue @@ -0,0 +1,768 @@ + + + + + diff --git a/src/pages/corp/furn/MingHome.vue b/src/pages/corp/furn/MingHome.vue new file mode 100644 index 0000000..00110f9 --- /dev/null +++ b/src/pages/corp/furn/MingHome.vue @@ -0,0 +1,774 @@ + + + + + diff --git a/src/pages/corp/furn/MingProducts.vue b/src/pages/corp/furn/MingProducts.vue new file mode 100644 index 0000000..a58bd2c --- /dev/null +++ b/src/pages/corp/furn/MingProducts.vue @@ -0,0 +1,453 @@ + + + + + diff --git a/src/pages/corp/furn/WabiHome.vue b/src/pages/corp/furn/WabiHome.vue new file mode 100644 index 0000000..94bd9d3 --- /dev/null +++ b/src/pages/corp/furn/WabiHome.vue @@ -0,0 +1,730 @@ + + + + + diff --git a/src/pages/corp/furn/WabiProducts.vue b/src/pages/corp/furn/WabiProducts.vue new file mode 100644 index 0000000..f3ea9d9 --- /dev/null +++ b/src/pages/corp/furn/WabiProducts.vue @@ -0,0 +1,502 @@ + + + + + diff --git a/src/pages/corp/pharma/TcmFangshu.vue b/src/pages/corp/pharma/TcmFangshu.vue new file mode 100644 index 0000000..11f6a85 --- /dev/null +++ b/src/pages/corp/pharma/TcmFangshu.vue @@ -0,0 +1,667 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkArticles.vue b/src/pages/corp/saas/MedlinkArticles.vue new file mode 100644 index 0000000..079e2a7 --- /dev/null +++ b/src/pages/corp/saas/MedlinkArticles.vue @@ -0,0 +1,529 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkHome.vue b/src/pages/corp/saas/MedlinkHome.vue new file mode 100644 index 0000000..afb670f --- /dev/null +++ b/src/pages/corp/saas/MedlinkHome.vue @@ -0,0 +1,943 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkIcon.vue b/src/pages/corp/saas/MedlinkIcon.vue new file mode 100644 index 0000000..5081f24 --- /dev/null +++ b/src/pages/corp/saas/MedlinkIcon.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkNav.vue b/src/pages/corp/saas/MedlinkNav.vue new file mode 100644 index 0000000..e4e7b63 --- /dev/null +++ b/src/pages/corp/saas/MedlinkNav.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkParticles.vue b/src/pages/corp/saas/MedlinkParticles.vue new file mode 100644 index 0000000..473c4bd --- /dev/null +++ b/src/pages/corp/saas/MedlinkParticles.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkProduct.vue b/src/pages/corp/saas/MedlinkProduct.vue new file mode 100644 index 0000000..9838a89 --- /dev/null +++ b/src/pages/corp/saas/MedlinkProduct.vue @@ -0,0 +1,738 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkRevisit.vue b/src/pages/corp/saas/MedlinkRevisit.vue new file mode 100644 index 0000000..49c9013 --- /dev/null +++ b/src/pages/corp/saas/MedlinkRevisit.vue @@ -0,0 +1,1371 @@ + + + + + diff --git a/src/pages/corp/saas/MedlinkVideos.vue b/src/pages/corp/saas/MedlinkVideos.vue new file mode 100644 index 0000000..78bac13 --- /dev/null +++ b/src/pages/corp/saas/MedlinkVideos.vue @@ -0,0 +1,661 @@ + + + + + diff --git a/src/pages/corp/saas/medlinkFx.js b/src/pages/corp/saas/medlinkFx.js new file mode 100644 index 0000000..f34fe06 --- /dev/null +++ b/src/pages/corp/saas/medlinkFx.js @@ -0,0 +1,50 @@ +// 医联体站点共享交互:滚动渐入 / 卡片聚光灯 / 数字滚动 +import { onBeforeUnmount, onMounted } from 'vue' + +/** 监听 .mlk-rv 元素进入视口后渐入 */ +export function useReveal() { + let ob + onMounted(() => { + ob = new IntersectionObserver( + (entries) => { + for (const e of entries) { + if (e.isIntersecting) { + e.target.classList.add('mlk-rv-in') + ob.unobserve(e.target) + } + } + }, + { threshold: 0.12 }, + ) + document.querySelectorAll('.mlk-rv').forEach((el) => ob.observe(el)) + }) + onBeforeUnmount(() => ob?.disconnect()) +} + +/** 鼠标聚光灯:@mousemove="spot" 配合 CSS var(--mx)/var(--my) */ +export function spot(e) { + const r = e.currentTarget.getBoundingClientRect() + e.currentTarget.style.setProperty('--mx', `${e.clientX - r.left}px`) + e.currentTarget.style.setProperty('--my', `${e.clientY - r.top}px`) +} + +/** 数字滚动:el 内文本形如 "4,200+" "+37%" "96 万" */ +export function countUp(el, duration = 1400) { + const raw = el.dataset.v ?? el.textContent + el.dataset.v = raw + const m = raw.match(/([\d,.]+)/) + if (!m) return + const target = Number.parseFloat(m[1].replace(/,/g, '')) + const prefix = raw.slice(0, m.index) + const suffix = raw.slice(m.index + m[1].length) + const withComma = m[1].includes(',') + const t0 = performance.now() + const tick = (t) => { + const p = Math.min(1, (t - t0) / duration) + const eased = 1 - (1 - p) ** 3 + const val = Math.round(target * eased) + el.textContent = prefix + (withComma ? val.toLocaleString('en-US') : val) + suffix + if (p < 1) requestAnimationFrame(tick) + } + requestAnimationFrame(tick) +} diff --git a/src/pages/lab/ApiPlayground.vue b/src/pages/lab/ApiPlayground.vue new file mode 100644 index 0000000..7882e82 --- /dev/null +++ b/src/pages/lab/ApiPlayground.vue @@ -0,0 +1,1091 @@ + + + + + diff --git a/src/pages/lab/Car3dPage.vue b/src/pages/lab/Car3dPage.vue new file mode 100644 index 0000000..6154090 --- /dev/null +++ b/src/pages/lab/Car3dPage.vue @@ -0,0 +1,691 @@ + + + + + diff --git a/src/pages/lab/DevDocs.vue b/src/pages/lab/DevDocs.vue new file mode 100644 index 0000000..c0aa138 --- /dev/null +++ b/src/pages/lab/DevDocs.vue @@ -0,0 +1,1280 @@ + + + + + diff --git a/src/pages/lab/ExplodedView.vue b/src/pages/lab/ExplodedView.vue new file mode 100644 index 0000000..9fa07a7 --- /dev/null +++ b/src/pages/lab/ExplodedView.vue @@ -0,0 +1,1195 @@ + + + + + diff --git a/src/pages/lab/ImOaPage.vue b/src/pages/lab/ImOaPage.vue new file mode 100644 index 0000000..251f53e --- /dev/null +++ b/src/pages/lab/ImOaPage.vue @@ -0,0 +1,2015 @@ + + + + + diff --git a/src/pages/lab/MotionLab.vue b/src/pages/lab/MotionLab.vue new file mode 100644 index 0000000..79f7d9c --- /dev/null +++ b/src/pages/lab/MotionLab.vue @@ -0,0 +1,872 @@ + + + + + diff --git a/src/pages/lab/PaletteLab.vue b/src/pages/lab/PaletteLab.vue new file mode 100644 index 0000000..345c1c3 --- /dev/null +++ b/src/pages/lab/PaletteLab.vue @@ -0,0 +1,551 @@ + + + + + diff --git a/src/pages/lab/PixelPainter.vue b/src/pages/lab/PixelPainter.vue new file mode 100644 index 0000000..85ddfff --- /dev/null +++ b/src/pages/lab/PixelPainter.vue @@ -0,0 +1,538 @@ + + + + + diff --git a/src/pages/lab/PremiumShowcase.vue b/src/pages/lab/PremiumShowcase.vue new file mode 100644 index 0000000..2831240 --- /dev/null +++ b/src/pages/lab/PremiumShowcase.vue @@ -0,0 +1,484 @@ + + + + + diff --git a/src/pages/lab/TypingTest.vue b/src/pages/lab/TypingTest.vue new file mode 100644 index 0000000..501846d --- /dev/null +++ b/src/pages/lab/TypingTest.vue @@ -0,0 +1,505 @@ + + + + + diff --git a/src/pages/lab/useTheme.js b/src/pages/lab/useTheme.js new file mode 100644 index 0000000..b22344b --- /dev/null +++ b/src/pages/lab/useTheme.js @@ -0,0 +1,31 @@ +// 亮 / 暗 / 跟随系统 三态主题,持久化到 localStorage +import { onBeforeUnmount, onMounted, ref, watch } from 'vue' + +export function useTheme(storageKey) { + const saved = localStorage.getItem(storageKey) + const mode = ref(['light', 'dark', 'auto'].includes(saved) ? saved : 'auto') + const resolved = ref('dark') + const mq = window.matchMedia('(prefers-color-scheme: dark)') + + function resolve() { + resolved.value = mode.value === 'auto' ? (mq.matches ? 'dark' : 'light') : mode.value + } + function onSystemChange() { + if (mode.value === 'auto') resolve() + } + + watch(mode, (v) => { + try { + localStorage.setItem(storageKey, v) + } catch { + /* 忽略 */ + } + resolve() + }) + + resolve() + onMounted(() => mq.addEventListener('change', onSystemChange)) + onBeforeUnmount(() => mq.removeEventListener('change', onSystemChange)) + + return { mode, resolved } +} diff --git a/src/pages/styles/AeroPage.vue b/src/pages/styles/AeroPage.vue new file mode 100644 index 0000000..70e5815 --- /dev/null +++ b/src/pages/styles/AeroPage.vue @@ -0,0 +1,424 @@ + + + + + diff --git a/src/pages/styles/AuroraPage.vue b/src/pages/styles/AuroraPage.vue new file mode 100644 index 0000000..8b2efb2 --- /dev/null +++ b/src/pages/styles/AuroraPage.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/src/pages/styles/BauhausPage.vue b/src/pages/styles/BauhausPage.vue new file mode 100644 index 0000000..f881705 --- /dev/null +++ b/src/pages/styles/BauhausPage.vue @@ -0,0 +1,449 @@ + + + + + diff --git a/src/pages/styles/BentoPage.vue b/src/pages/styles/BentoPage.vue new file mode 100644 index 0000000..39468a0 --- /dev/null +++ b/src/pages/styles/BentoPage.vue @@ -0,0 +1,348 @@ + + + + + diff --git a/src/pages/styles/BlueprintPage.vue b/src/pages/styles/BlueprintPage.vue new file mode 100644 index 0000000..e788ea8 --- /dev/null +++ b/src/pages/styles/BlueprintPage.vue @@ -0,0 +1,349 @@ + + + + + diff --git a/src/pages/styles/BoardingPassPage.vue b/src/pages/styles/BoardingPassPage.vue new file mode 100644 index 0000000..b4f1a9a --- /dev/null +++ b/src/pages/styles/BoardingPassPage.vue @@ -0,0 +1,515 @@ + + + + + diff --git a/src/pages/styles/BrutalismPage.vue b/src/pages/styles/BrutalismPage.vue new file mode 100644 index 0000000..27e70ab --- /dev/null +++ b/src/pages/styles/BrutalismPage.vue @@ -0,0 +1,359 @@ + + + + + diff --git a/src/pages/styles/CandyPage.vue b/src/pages/styles/CandyPage.vue new file mode 100644 index 0000000..d1d3cf6 --- /dev/null +++ b/src/pages/styles/CandyPage.vue @@ -0,0 +1,385 @@ + + + + + diff --git a/src/pages/styles/CheckupPage.vue b/src/pages/styles/CheckupPage.vue new file mode 100644 index 0000000..ab4e9c9 --- /dev/null +++ b/src/pages/styles/CheckupPage.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/src/pages/styles/ClayPage.vue b/src/pages/styles/ClayPage.vue new file mode 100644 index 0000000..e0f5641 --- /dev/null +++ b/src/pages/styles/ClayPage.vue @@ -0,0 +1,366 @@ + + + + + diff --git a/src/pages/styles/CollagePage.vue b/src/pages/styles/CollagePage.vue new file mode 100644 index 0000000..9f2b36a --- /dev/null +++ b/src/pages/styles/CollagePage.vue @@ -0,0 +1,411 @@ + + + + + diff --git a/src/pages/styles/CreditsPage.vue b/src/pages/styles/CreditsPage.vue new file mode 100644 index 0000000..bb1dc50 --- /dev/null +++ b/src/pages/styles/CreditsPage.vue @@ -0,0 +1,259 @@ + + + + + diff --git a/src/pages/styles/CrtTvPage.vue b/src/pages/styles/CrtTvPage.vue new file mode 100644 index 0000000..e66de4b --- /dev/null +++ b/src/pages/styles/CrtTvPage.vue @@ -0,0 +1,512 @@ + + + + + diff --git a/src/pages/styles/CyberpunkPage.vue b/src/pages/styles/CyberpunkPage.vue new file mode 100644 index 0000000..ab6c688 --- /dev/null +++ b/src/pages/styles/CyberpunkPage.vue @@ -0,0 +1,307 @@ + + + + + diff --git a/src/pages/styles/DanmakuPage.vue b/src/pages/styles/DanmakuPage.vue new file mode 100644 index 0000000..bf6e1fb --- /dev/null +++ b/src/pages/styles/DanmakuPage.vue @@ -0,0 +1,496 @@ + + + + + diff --git a/src/pages/styles/DashboardPage.vue b/src/pages/styles/DashboardPage.vue new file mode 100644 index 0000000..565dcac --- /dev/null +++ b/src/pages/styles/DashboardPage.vue @@ -0,0 +1,491 @@ + + + + + diff --git a/src/pages/styles/DoodlePage.vue b/src/pages/styles/DoodlePage.vue new file mode 100644 index 0000000..e518fae --- /dev/null +++ b/src/pages/styles/DoodlePage.vue @@ -0,0 +1,334 @@ + + + + + diff --git a/src/pages/styles/GameboyPage.vue b/src/pages/styles/GameboyPage.vue new file mode 100644 index 0000000..ee758b6 --- /dev/null +++ b/src/pages/styles/GameboyPage.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/src/pages/styles/GlassPage.vue b/src/pages/styles/GlassPage.vue new file mode 100644 index 0000000..ff46f16 --- /dev/null +++ b/src/pages/styles/GlassPage.vue @@ -0,0 +1,319 @@ + + + + + diff --git a/src/pages/styles/GuofengPage.vue b/src/pages/styles/GuofengPage.vue new file mode 100644 index 0000000..c4ae381 --- /dev/null +++ b/src/pages/styles/GuofengPage.vue @@ -0,0 +1,420 @@ + + + + + diff --git a/src/pages/styles/IdePage.vue b/src/pages/styles/IdePage.vue new file mode 100644 index 0000000..6235057 --- /dev/null +++ b/src/pages/styles/IdePage.vue @@ -0,0 +1,513 @@ + + + + + diff --git a/src/pages/styles/IpodPage.vue b/src/pages/styles/IpodPage.vue new file mode 100644 index 0000000..459d2d3 --- /dev/null +++ b/src/pages/styles/IpodPage.vue @@ -0,0 +1,391 @@ + + + + + diff --git a/src/pages/styles/LockscreenPage.vue b/src/pages/styles/LockscreenPage.vue new file mode 100644 index 0000000..864f1d9 --- /dev/null +++ b/src/pages/styles/LockscreenPage.vue @@ -0,0 +1,413 @@ + + + + + diff --git a/src/pages/styles/LuxuryPage.vue b/src/pages/styles/LuxuryPage.vue new file mode 100644 index 0000000..6b5b3d9 --- /dev/null +++ b/src/pages/styles/LuxuryPage.vue @@ -0,0 +1,339 @@ + + + + + diff --git a/src/pages/styles/MacosPage.vue b/src/pages/styles/MacosPage.vue new file mode 100644 index 0000000..e336112 --- /dev/null +++ b/src/pages/styles/MacosPage.vue @@ -0,0 +1,960 @@ + + + + + diff --git a/src/pages/styles/MagazinePage.vue b/src/pages/styles/MagazinePage.vue new file mode 100644 index 0000000..2dd179f --- /dev/null +++ b/src/pages/styles/MagazinePage.vue @@ -0,0 +1,443 @@ + + + + + diff --git a/src/pages/styles/MedievalPage.vue b/src/pages/styles/MedievalPage.vue new file mode 100644 index 0000000..d49201b --- /dev/null +++ b/src/pages/styles/MedievalPage.vue @@ -0,0 +1,405 @@ + + + + + diff --git a/src/pages/styles/MemphisPage.vue b/src/pages/styles/MemphisPage.vue new file mode 100644 index 0000000..49792c1 --- /dev/null +++ b/src/pages/styles/MemphisPage.vue @@ -0,0 +1,373 @@ + + + + + diff --git a/src/pages/styles/MetroPage.vue b/src/pages/styles/MetroPage.vue new file mode 100644 index 0000000..35e4589 --- /dev/null +++ b/src/pages/styles/MetroPage.vue @@ -0,0 +1,389 @@ + + + + + diff --git a/src/pages/styles/MinimalPage.vue b/src/pages/styles/MinimalPage.vue new file mode 100644 index 0000000..86bbf0d --- /dev/null +++ b/src/pages/styles/MinimalPage.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/src/pages/styles/NeonSignPage.vue b/src/pages/styles/NeonSignPage.vue new file mode 100644 index 0000000..312f454 --- /dev/null +++ b/src/pages/styles/NeonSignPage.vue @@ -0,0 +1,414 @@ + + + + + diff --git a/src/pages/styles/NeumorphismPage.vue b/src/pages/styles/NeumorphismPage.vue new file mode 100644 index 0000000..961e211 --- /dev/null +++ b/src/pages/styles/NeumorphismPage.vue @@ -0,0 +1,293 @@ + + + + + diff --git a/src/pages/styles/NewspaperPage.vue b/src/pages/styles/NewspaperPage.vue new file mode 100644 index 0000000..9c35a06 --- /dev/null +++ b/src/pages/styles/NewspaperPage.vue @@ -0,0 +1,303 @@ + + + + + diff --git a/src/pages/styles/PagerPage.vue b/src/pages/styles/PagerPage.vue new file mode 100644 index 0000000..bb1f230 --- /dev/null +++ b/src/pages/styles/PagerPage.vue @@ -0,0 +1,273 @@ + + + + + diff --git a/src/pages/styles/PassportPage.vue b/src/pages/styles/PassportPage.vue new file mode 100644 index 0000000..4362637 --- /dev/null +++ b/src/pages/styles/PassportPage.vue @@ -0,0 +1,344 @@ + + + + + diff --git a/src/pages/styles/PixelPage.vue b/src/pages/styles/PixelPage.vue new file mode 100644 index 0000000..a9ac461 --- /dev/null +++ b/src/pages/styles/PixelPage.vue @@ -0,0 +1,337 @@ + + + + + diff --git a/src/pages/styles/PolaroidPage.vue b/src/pages/styles/PolaroidPage.vue new file mode 100644 index 0000000..d5bdb37 --- /dev/null +++ b/src/pages/styles/PolaroidPage.vue @@ -0,0 +1,431 @@ + + + + + diff --git a/src/pages/styles/PopArtPage.vue b/src/pages/styles/PopArtPage.vue new file mode 100644 index 0000000..7d4f70d --- /dev/null +++ b/src/pages/styles/PopArtPage.vue @@ -0,0 +1,407 @@ + + + + + diff --git a/src/pages/styles/ReceiptPage.vue b/src/pages/styles/ReceiptPage.vue new file mode 100644 index 0000000..803100c --- /dev/null +++ b/src/pages/styles/ReceiptPage.vue @@ -0,0 +1,312 @@ + + + + + diff --git a/src/pages/styles/RetroPrintPage.vue b/src/pages/styles/RetroPrintPage.vue new file mode 100644 index 0000000..a2c81db --- /dev/null +++ b/src/pages/styles/RetroPrintPage.vue @@ -0,0 +1,435 @@ + + + + + diff --git a/src/pages/styles/SpacePage.vue b/src/pages/styles/SpacePage.vue new file mode 100644 index 0000000..260c65d --- /dev/null +++ b/src/pages/styles/SpacePage.vue @@ -0,0 +1,481 @@ + + + + + diff --git a/src/pages/styles/SteamPage.vue b/src/pages/styles/SteamPage.vue new file mode 100644 index 0000000..5448ac7 --- /dev/null +++ b/src/pages/styles/SteamPage.vue @@ -0,0 +1,542 @@ + + + + + diff --git a/src/pages/styles/SwissPage.vue b/src/pages/styles/SwissPage.vue new file mode 100644 index 0000000..023136c --- /dev/null +++ b/src/pages/styles/SwissPage.vue @@ -0,0 +1,354 @@ + + + + + diff --git a/src/pages/styles/TamagotchiPage.vue b/src/pages/styles/TamagotchiPage.vue new file mode 100644 index 0000000..27d435b --- /dev/null +++ b/src/pages/styles/TamagotchiPage.vue @@ -0,0 +1,406 @@ + + + + + diff --git a/src/pages/styles/TelegramPage.vue b/src/pages/styles/TelegramPage.vue new file mode 100644 index 0000000..11d4230 --- /dev/null +++ b/src/pages/styles/TelegramPage.vue @@ -0,0 +1,447 @@ + + + + + diff --git a/src/pages/styles/TerminalPage.vue b/src/pages/styles/TerminalPage.vue new file mode 100644 index 0000000..b81e633 --- /dev/null +++ b/src/pages/styles/TerminalPage.vue @@ -0,0 +1,601 @@ + + + + + diff --git a/src/pages/styles/TypewriterPage.vue b/src/pages/styles/TypewriterPage.vue new file mode 100644 index 0000000..f86c4c8 --- /dev/null +++ b/src/pages/styles/TypewriterPage.vue @@ -0,0 +1,277 @@ + + + + + diff --git a/src/pages/styles/VaporwavePage.vue b/src/pages/styles/VaporwavePage.vue new file mode 100644 index 0000000..635d39d --- /dev/null +++ b/src/pages/styles/VaporwavePage.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/src/pages/styles/VinylPage.vue b/src/pages/styles/VinylPage.vue new file mode 100644 index 0000000..c49d157 --- /dev/null +++ b/src/pages/styles/VinylPage.vue @@ -0,0 +1,625 @@ + + + + + diff --git a/src/pages/styles/WatercolorPage.vue b/src/pages/styles/WatercolorPage.vue new file mode 100644 index 0000000..f3c7411 --- /dev/null +++ b/src/pages/styles/WatercolorPage.vue @@ -0,0 +1,402 @@ + + + + + diff --git a/src/pages/styles/WechatPage.vue b/src/pages/styles/WechatPage.vue new file mode 100644 index 0000000..97266f9 --- /dev/null +++ b/src/pages/styles/WechatPage.vue @@ -0,0 +1,397 @@ + + + + + diff --git a/src/pages/styles/WikiPage.vue b/src/pages/styles/WikiPage.vue new file mode 100644 index 0000000..5bcf641 --- /dev/null +++ b/src/pages/styles/WikiPage.vue @@ -0,0 +1,419 @@ + + + + + diff --git a/src/pages/styles/Win11Page.vue b/src/pages/styles/Win11Page.vue new file mode 100644 index 0000000..ee1d9f5 --- /dev/null +++ b/src/pages/styles/Win11Page.vue @@ -0,0 +1,1071 @@ + + + + + diff --git a/src/pages/styles/Win98Page.vue b/src/pages/styles/Win98Page.vue new file mode 100644 index 0000000..fe91177 --- /dev/null +++ b/src/pages/styles/Win98Page.vue @@ -0,0 +1,1022 @@ + + + + + diff --git a/src/pages/styles/WrappedPage.vue b/src/pages/styles/WrappedPage.vue new file mode 100644 index 0000000..1082c5c --- /dev/null +++ b/src/pages/styles/WrappedPage.vue @@ -0,0 +1,297 @@ + + + + + diff --git a/src/pages/styles/Y2kPage.vue b/src/pages/styles/Y2kPage.vue new file mode 100644 index 0000000..5dfcdd0 --- /dev/null +++ b/src/pages/styles/Y2kPage.vue @@ -0,0 +1,458 @@ + + + + + diff --git a/src/pages/styles/ZenPage.vue b/src/pages/styles/ZenPage.vue new file mode 100644 index 0000000..2816cd0 --- /dev/null +++ b/src/pages/styles/ZenPage.vue @@ -0,0 +1,327 @@ + + + + + diff --git a/src/router/index.js b/src/router/index.js index 796771d..c81eb96 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,38 +1,95 @@ import { createRouter, createWebHistory } from 'vue-router' -import { useUserStore } from '@/stores/user' -import MainLayout from '@/layouts/Header.vue' +import { styleList } from '../data/styles' +import { corpStyleList } from '../data/corpStyles' +import { labList } from '../data/labStyles' -// 在路由配置中添加个人中心路由 const routes = [ { path: '/', - component: MainLayout, - children: [ - { path: '', name: 'Home', component: () => import('@/views/index/index.vue') }, - ] + name: 'home', + component: () => import('../pages/Home.vue'), + meta: { list: true }, }, + ...styleList.map((s) => ({ + path: `/style/${s.id}`, + name: s.id, + component: s.component, + meta: { title: s.title }, + })), + { + path: '/corp', + name: 'corp-home', + component: () => import('../pages/CorpHome.vue'), + meta: { corp: true, list: true }, + }, + ...corpStyleList.flatMap((s) => [ + { + path: `/corp/${s.id}`, + name: `corp-${s.id}`, + component: s.component, + meta: { title: s.title, corp: true }, + }, + ...(s.subPages || []).map((p) => ({ + path: `/corp/${s.id}/${p.path}`, + name: `corp-${s.id}-${p.path}`, + component: p.component, + meta: { title: `${s.title} · ${p.title}`, corp: true }, + })), + ]), + { + path: '/lab', + name: 'lab-home', + component: () => import('../pages/LabHome.vue'), + meta: { lab: true, list: true }, + }, + ...labList.map((s) => ({ + path: `/lab/${s.id}`, + name: `lab-${s.id}`, + component: s.component, + meta: { title: s.title, lab: true }, + })), + { + path: '/compare', + name: 'compare', + component: () => import('../pages/ComparePage.vue'), + meta: { title: '风格对比' }, + }, + { + path: '/kl', + name: 'kl', + component: () => import('../pages/KlPage.vue'), + meta: { title: '创作者口令' }, + }, + { path: '/:pathMatch(.*)*', redirect: '/' }, ] const router = createRouter({ history: createWebHistory(), routes, - scrollBehavior(to, from, savedPosition) { - return savedPosition || { top: 0 } - } + // 列表页由 StyleGallery 自己恢复滚动位置,其余页面回到顶部 + scrollBehavior: (to) => (to.meta.list ? false : { top: 0 }), }) -router.beforeEach((to, from) => { - const userStore = useUserStore() - if (to.meta.requiresAuth && !userStore.user) { - return { name: 'Login', query: { redirect: to.fullPath } } +router.afterEach((to) => { + if (to.meta.lab) { + document.title = to.meta.title ? `${to.meta.title} · 实验室` : '实验室 · 年糕崽崽' + } else if (to.meta.corp) { + document.title = to.meta.title ? `${to.meta.title} · 企业官网合集` : '企业官网合集 · 年糕崽崽' + } else { + document.title = to.meta.title ? `${to.meta.title} · 年糕崽崽` : '年糕崽崽的个人页面合集' + } + + // 最近浏览:仅记录风格/实验详情页 + if (to.meta.title && to.name !== 'compare' && to.name !== 'kl') { + try { + const KEY = 'recent-visits' + const list = JSON.parse(localStorage.getItem(KEY) || '[]').filter((r) => r.path !== to.path) + list.unshift({ path: to.path, title: to.meta.title, t: Date.now() }) + localStorage.setItem(KEY, JSON.stringify(list.slice(0, 12))) + } catch { + /* 存储不可用时忽略 */ + } } }) export default router - -router.beforeEach((to, from) => { - const userStore = useUserStore() - if (to.meta.requiresAuth && !userStore.user) { - return { name: 'Login', query: { redirect: to.fullPath } } - } -}) diff --git a/src/style.css b/src/style.css index a461c50..24d4e20 100644 --- a/src/style.css +++ b/src/style.css @@ -1 +1,81 @@ -@import "tailwindcss"; \ No newline at end of file +@import 'tailwindcss'; + +:root { + --font-sans: 'PingFang SC', 'Microsoft YaHei', 'Segoe UI', system-ui, + -apple-system, sans-serif; + --font-serif: 'Noto Serif SC', 'Songti SC', SimSun, serif; + --font-mono: 'Cascadia Code', Consolas, 'JetBrains Mono', 'Courier New', + monospace; + --font-kai: 'Ma Shan Zheng', 'Kaiti SC', KaiTi, STKaiti, serif; +} + +html { + scroll-behavior: smooth; +} + +body { + margin: 0; + font-family: var(--font-sans); + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; +} + +img { + max-width: 100%; +} + +/* ---------- 全局滚动条美化 ---------- */ +/* Firefox */ +* { + scrollbar-width: thin; + scrollbar-color: rgba(128, 138, 156, 0.45) transparent; +} +/* WebKit(Chrome / Edge / Safari) */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background-color: rgba(128, 138, 156, 0.45); + border-radius: 99px; + border: 3px solid transparent; + background-clip: padding-box; + transition: background-color 0.2s ease; +} +::-webkit-scrollbar-thumb:hover { + background-color: rgba(140, 152, 172, 0.75); +} +::-webkit-scrollbar-thumb:active { + background-color: rgba(150, 162, 184, 0.9); +} +::-webkit-scrollbar-corner { + background: transparent; +} + +/* 医联体站点共享:滚动渐入 */ +.mlk-rv { + opacity: 0; + transform: translateY(28px); + transition: + opacity 0.75s ease, + transform 0.75s cubic-bezier(0.22, 1, 0.36, 1); + transition-delay: var(--rvd, 0s); + will-change: opacity, transform; +} +.mlk-rv-in { + opacity: 1; + transform: none; +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} diff --git a/vite.config.js b/vite.config.js index df31b24..2f35f14 100644 --- a/vite.config.js +++ b/vite.config.js @@ -14,6 +14,10 @@ export default defineConfig({ '@': path.resolve(__dirname, './src') } }, + build: { + // three.js 单页 chunk 较大,放宽警告阈值 + chunkSizeWarningLimit: 1024 + }, server: { port: 8888, proxy: {