```json
{
"summary": "彻底重构曲库卡片为专辑封面风格:①卡片改为正方形(aspect-ratio:1),上方72%为全幅封面图+从右侧探出1/3的黑胶唱片半圆(模拟唱片从封套抽出的经典设计),下方28%为渐变遮罩叠加曲库名与曲目数;②每张卡片分配不同的资产图片作为封面;③子曲谱视图上栏同步更新为相同风格(左侧封面+黑胶,右侧曲库信息);④管理模式下删除按钮与拖拽手柄叠加在封面层上方;⑤保持所有既有交互功能不变。",
"widget": {
"type": "full-html",
"html": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, viewport-fit=cover\">\n <title>VintageSheet | 复古曲谱阅读器</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.c…\">\n <link href=\"https://fonts.googleapis.com/css2?family=Playfair+Display+SC:wght@400;7…\" rel=\"stylesheet\">\n <style>\n :root {\n --bg-dark: #2f2f2f;\n --bg-cream: #e9e7e0;\n --red-primary: #e33b0d;\n --red-deep: #b32a08;\n --red-accent: #f0481a;\n --text-on-dark: #e5ded5;\n --text-on-dark-secondary: #b0a89e;\n --text-primary: #1a1214;\n --text-muted: #8b7670;\n }\n *{margin:0;padding:0;box-sizing:border-box}\n html,body{width:100%;height:100%;overflow:hidden;background:#1a1a1a;font-family:'Josefin Sans',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none}\n .app-root{width:100%;height:100dvh;height:100vh;display:flex;flex-direction:column;background:var(--bg-dark);position:relative;overflow:hidden}\n .nav-top{background:rgba(47,47,47,0.88);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;z-index:30;box-shadow:0 4px 20px rgba(0,0,0,0.35),inset 0 1px 0 rgba(255,255,255,0.04);border-bottom:0.5px solid rgba(255,255,255,0.05)}\n .bottom-nav-container{background:rgba(47,47,47,0.85);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);position:relative;z-index:30;box-shadow:0 -4px 20px rgba(0,0,0,0.35),inset 0 -0.5px 0 rgba(255,255,255,0.03);border-top:0.5px solid rgba(255,255,255,0.05)}\n .staff-lines-bg{position:relative;background-color:var(--bg-cream)}\n .staff-lines-bg::before{content:'';position:absolute;inset:0;pointer-events:none;z-index:0;opacity:.22;background:repeating-linear-gradient(0deg,transparent 0px,transparent 3px,rgba(227,59,13,0.25) 3px,rgba(227,59,13,0.25) 3.5px,transparent 3.5px,transparent 9px,rgba(227,59,13,0.25) 9px,rgba(227,59,13,0.25) 9.5px,transparent 9.5px,transparent 15px,rgba(227,59,13,0.25) 15px,rgba(227,59,13,0.25) 15.5px,transparent 15.5px,transparent 21px,rgba(227,59,13,0.25) 21px,rgba(227,59,13,0.25) 21.5px,transparent 21.5px,transparent 27px,rgba(227,59,13,0.25) 27px,rgba(227,59,13,0.25) 27.5px,transparent 27.5px,transparent 55px)}\n .staff-lines-bg::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:1;opacity:.06;background:radial-gradient(ellipse at 25% 30%,rgba(227,59,13,0.18) 0%,transparent 60%),radial-gradient(ellipse at 75% 70%,rgba(227,59,13,0.10) 0%,transparent 55%)}\n\n /* ===== 黑胶唱片(缩小版用于卡片) ===== */\n .vinyl-mini{width:100%;height:100%;border-radius:50%;position:relative;background:radial-gradient(circle at 50% 50%,#2a2a2a 0%,#222 1%,#1e1e1e 8%,#2a2a2a 10%,#202020 12%,#2a2a2a 14%,#1e1e1e 16%,#2a2a2a 18%,#202020 20%,#2a2a2a 22%,#1e1e1e 24%,#2a2a2a 26%,#202020 28%,#282828 32%,#1e1e1e 36%,#282828 40%,#202020 44%,#282828 48%,#1e1e1e 52%,#2a2a2a 56%,#202020 60%,#2a2a2a 64%,#1e1e1e 68%,#2a2a2a 72%,#202020 74%,#2a2a2a 76%,#1e1e1e 78%,#2a2a2a 80%,#202020 81%,#2a2a2a 82%,#1e1e1e 83%,#2a2a2a 84%,var(--red-deep) 84.5%,#8a1f06 86%,var(--red-deep) 87%,var(--red-primary) 89%,var(--red-deep) 91%,#4a1506 93%,#8a1f06 95%,#3a1003 97%,#1e1e1e 98%,#1a1a1a 100%);box-shadow:inset 0 0 1px rgba(255,255,255,0.012),0 3px 10px rgba(0,0,0,0.30),0 0 0 1px rgba(80,30,15,0.30)}\n .vinyl-mini::before{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:6px;height:6px;border-radius:50%;background:#2a2a2a;z-index:2;box-shadow:inset 0 0 1px rgba(255,255,255,0.02)}\n .vinyl-mini .vinyl-shine{position:absolute;inset:0;border-radius:50%;pointer-events:none;z-index:1;background:linear-gradient(135deg,rgba(255,255,255,0.04) 0%,transparent 35%,transparent 55%,rgba(255,255,255,0.015) 70%,transparent 100%)}\n\n /* ===== 曲库卡片 — 专辑封面风格 ===== */\n .lib-card{\n aspect-ratio:1;\n border-radius:8px;overflow:hidden;cursor:pointer;position:relative;\n background:var(--bg-cream);\n box-shadow:0 6px 20px rgba(0,0,0,0.15),0 1px 3px rgba(0,0,0,0.08);\n transition:transform .2s ease,box-shadow .2s ease;\n }\n .lib-card:active{transform:scale(.965);box-shadow:0 3px 10px rgba(0,0,0,0.18)}\n .lib-card.dragging{opacity:.45;z-index:25;transform:scale(1.04);box-shadow:0 16px 40px rgba(0,0,0,0.35)}\n\n /* 封面图区域 */\n .lib-card .card-cover{position:absolute;inset:0 0 28% 0;overflow:hidden}\n .lib-card .card-cover img{width:100%;height:100%;object-fit:cover;display:block}\n .lib-card .card-cover .cover-placeholder{width:100%;height:100%;background:linear-gradient(160deg,#3a3532 0%,#2f2b28 50%,#1f1c1a 100%);display:flex;align-items:center;justify-content:center}\n\n /* 黑胶唱片从右侧探出 */\n .lib-card .vinyl-peek{position:absolute;right:-22%;top:8%;width:60%;aspect-ratio:1;z-index:2;pointer-events:none;transition:transform .4s cubic-bezier(.25,.46,.45,.94)}\n .lib-card:active .vinyl-peek{transform:translateX(-6%)}\n\n /* 底部信息栏 */\n .lib-card .card-info{position:absolute;inset:72% 0 0 0;background:linear-gradient(to bottom,rgba(30,26,24,0.92),rgba(20,17,15,0.96));display:flex;flex-direction:column;justify-content:center;padding:0 10px;z-index:3}\n .lib-card .card-info .card-name{font-family:'Josefin Sans',sans-serif;font-size:11px;font-weight:600;letter-spacing:.04em;color:#e5ded5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n .lib-card .card-info .card-count{font-size:9px;color:#b0a89e;letter-spacing:.05em;margin-top:2px}\n\n /* 锁定标记 */\n .lib-card .card-locked-badge{position:absolute;top:8px;left:8px;z-index:4;font-size:9px;color:rgba(255,255,255,0.6);text-shadow:0 1px 2px rgba(0,0,0,0.5)}\n\n /* 删除按钮 */\n .lib-card .del-btn{position:absolute;top:6px;right:6px;width:22px;height:22px;border-radius:50%;background:var(--red-primary);color:#fff;display:none;align-items:center;justify-content:center;font-size:9px;z-index:8;box-shadow:0 2px 6px rgba(227,59,13,0.45);cursor:pointer;transition:all .2s ease}\n .lib-card .del-btn.show-del{display:flex;animation:popIn .25s cubic-bezier(.34,1.56,.64,1)}\n @keyframes popIn{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}\n .lib-card .del-btn:active{transform:scale(.85)}\n\n /* 拖拽手柄 */\n .lib-card .drag-handle{position:absolute;top:6px;left:6px;z-index:8;color:rgba(255,255,255,0.7);font-size:13px;cursor:grab;letter-spacing:-2px;line-height:1;opacity:0;padding:2px 5px;border-radius:3px;transition:all .2s ease;pointer-events:none;text-shadow:0 1px 3px rgba(0,0,0,0.6)}\n .lib-card .drag-handle.show-handle{opacity:.85;pointer-events:auto}\n .lib-card .drag-handle:active{cursor:grabbing;background:rgba(255,255,255,0.10)}\n\n /* 换封面遮罩 */\n .lib-card .cover-overlay-card{position:absolute;inset:0 0 28% 0;z-index:5;background:rgba(0,0,0,0.40);display:none;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}\n .lib-card .cover-overlay-card.show-cover{display:flex;animation:fadeIn .2s ease}\n @keyframes fadeIn{from{opacity:0}to{opacity:1}}\n .lib-card .cover-overlay-card i{color:#fff;font-size:20px;text-shadow:0 1px 3px rgba(0,0,0,0.5)}\n\n /* ===== 子曲谱视图 ===== */\n .sub-view{position:absolute;inset:0;z-index:20;background:var(--bg-cream);transition:transform .35s cubic-bezier(.25,.46,.45,.94);display:flex;flex-direction:column}\n .sub-view.hidden-sub{transform:translateX(105%);pointer-events:none}\n .sub-view.visible-sub{transform:translateX(0);pointer-events:auto}\n .sub-header{display:flex;align-items:center;gap:14px;padding:12px 16px 10px 16px;flex-shrink:0}\n .sub-cover-wrap{width:85px;height:85px;border-radius:8px;flex-shrink:0;overflow:hidden;position:relative;box-shadow:0 4px 14px rgba(0,0,0,0.18)}\n .sub-cover-wrap img{width:100%;height:100%;object-fit:cover;display:block}\n .sub-cover-wrap .vinyl-peek-sub{position:absolute;right:-24%;top:5%;width:62%;aspect-ratio:1;z-index:2;pointer-events:none}\n .sub-info{flex:1;min-width:0}\n .sub-info .lib-name{font-family:'Josefin Sans',sans-serif;font-size:15px;font-weight:600;letter-spacing:.05em;color:var(--text-primary)}\n .sub-info .lib-author{font-size:11px;color:var(--text-muted);letter-spacing:.04em;margin-top:2px}\n .sub-info .lib-meta{font-size:10px;color:var(--red-primary);letter-spacing:.05em;margin-top:4px}\n .sub-song-list{flex:1;overflow-y:auto;padding:4px 16px 12px 16px}\n .sub-song-list.no-scrollbar::-webkit-scrollbar{display:none}\n .sub-song-list.no-scrollbar{scrollbar-width:none;-ms-overflow-style:none}\n .song-row{display:flex;align-items:center;gap:10px;padding:12px 8px;border-bottom:1px solid rgba(227,59,13,0.10);cursor:pointer;transition:all .2s ease;position:relative}\n .song-row:active{background:rgba(227,59,13,0.04)}\n .song-row .song-index{width:22px;text-align:right;font-size:10px;color:var(--text-muted);font-family:'Josefin Sans',sans-serif;flex-shrink:0}\n .song-row .song-body{flex:1;min-width:0}\n .song-row .song-title{font-size:16px;color:var(--text-primary);font-family:'Liu Jian Mao Cao','Ma Shan Zheng',cursive;line-height:1.3}\n .song-row .song-artist{font-size:10px;color:var(--text-muted);font-family:'Josefin Sans',sans-serif;letter-spacing:.04em;margin-top:1px}\n .song-more-btn{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-muted);transition:all .2s ease;flex-shrink:0;font-size:14px;letter-spacing:-1px;font-weight:bold}\n .song-more-btn:active{background:rgba(227,59,13,0.08);color:var(--red-primary)}\n .song-action-popup{position:absolute;right:8px;top:100%;z-index:30;background:#f5f2ec;border-radius:8px;box-shadow:0 8px 28px rgba(0,0,0,0.18);min-width:150px;overflow:hidden;animation:slideUp .2s cubic-bezier(.34,1.56,.64,1);border:1px solid rgba(0,0,0,0.06)}\n @keyframes slideUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\n .song-action-popup .action-item{display:flex;align-items:center;gap:10px;padding:11px 16px;font-size:12px;color:var(--text-primary);cursor:pointer;transition:all .15s ease;letter-spacing:.04em}\n .song-action-popup .action-item:active{background:rgba(227,59,13,0.06);color:var(--red-primary)}\n .song-action-popup .action-item i{width:16px;text-align:center;font-size:12px}\n .song-action-popup .action-item.danger{color:var(--red-primary)}\n\n /* ===== 推荐页 ===== */\n .stack-card-wrap{position:relative;height:170px;cursor:pointer}\n .stack-card-wrap:active{transform:scale(.97)}\n .stack-card-back{position:absolute;top:7px;left:12px;right:0;bottom:0;border-radius:8px;overflow:hidden;opacity:.30;filter:blur(2.5px);transform:rotate(1.5deg)}\n .stack-card-back img{width:100%;height:100%;object-fit:cover}\n .stack-card-front{position:absolute;top:0;left:0;right:12px;bottom:7px;border-radius:8px;overflow:hidden;box-shadow:0 6px 24px rgba(0,0,0,0.25),0 2px 6px rgba(0,0,0,0.15)}\n .stack-card-front img{width:100%;height:100%;object-fit:cover}\n .stack-label{position:absolute;bottom:8px;left:8px;z-index:3;background:rgba(15,10,8,0.80);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);color:#e5ded5;font-size:11px;padding:4px 10px;border-radius:3px;letter-spacing:.06em;font-family:'Josefin Sans',sans-serif}\n .rec-mini-card{flex-shrink:0;width:130px;border-radius:8px;overflow:hidden;cursor:pointer;transition:transform .2s ease;position:relative;background:rgba(233,231,224,0.65);border:1px solid rgba(255,255,255,0.40);box-shadow:0 3px 12px rgba(0,0,0,0.06)}\n .rec-mini-card:active{transform:scale(.95)}\n .rec-mini-card img{width:100%;height:80px;object-fit:cover;display:block}\n .rec-mini-card .rec-mini-label{padding:8px 10px;font-size:10px;letter-spacing:.04em;color:var(--text-primary);font-family:'Josefin Sans',sans-serif}\n\n /* ===== 搜索等 ===== */\n .search-bar{background:rgba(233,231,224,0.68);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);border:1px solid rgba(255,255,255,0.42);border-radius:8px;display:flex;align-items:center;gap:8px;padding:10px 14px;cursor:pointer;transition:all .25s ease;box-shadow:inset 0 1px 0 rgba(255,255,255,0.40);flex:1}\n .search-bar i{color:var(--text-muted);font-size:13px}\n .search-bar span{color:var(--text-muted);font-size:12px;letter-spacing:.04em;flex:1}\n .search-bar.focused{border-color:rgba(227,59,13,0.30);box-shadow:inset 0 1px 0 rgba(255,255,255,0.40),0 0 0 2px rgba(227,59,13,0.08)}\n .search-history-dropdown{position:absolute;top:100%;left:0;right:0;z-index:60;background:#f0ede8;border-radius:8px;margin-top:4px;box-shadow:0 8px 28px rgba(0,0,0,0.18);overflow:hidden;transition:all .3s ease;max-height:260px;overflow-y:auto}\n .search-history-dropdown.no-scrollbar::-webkit-scrollbar{display:none}\n .search-history-dropdown.no-scrollbar{scrollbar-width:none;-ms-overflow-style:none}\n .search-history-dropdown.hidden-dropdown{max-height:0;opacity:0;pointer-events:none;margin-top:0}\n .history-item{padding:11px 16px;display:flex;align-items:center;gap:10px;cursor:pointer;transition:all .15s ease;border-bottom:1px solid rgba(0,0,0,0.04);font-size:12px;color:var(--text-primary)}\n .history-item:active{background:rgba(227,59,13,0.06)}\n .history-item i{color:var(--text-muted);font-size:10px}\n .clear-history-btn{display:flex;align-items:center;justify-content:center;gap:6px;padding:12px;cursor:pointer;font-size:11px;color:var(--red-primary);letter-spacing:.05em;transition:all .15s ease;border-top:1px solid rgba(0,0,0,0.06)}\n .clear-history-btn:active{background:rgba(227,59,13,0.06)}\n .clear-history-btn i{font-size:10px}\n\n .btn-manage{width:34px;height:34px;border-radius:50%;border:1px solid rgba(227,59,13,0.28);background:transparent;color:var(--text-muted);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease;flex-shrink:0}\n .btn-manage:active{background:rgba(227,59,13,0.10);color:var(--red-primary)}\n .btn-manage.active-manage{background:rgba(227,59,13,0.14);border-color:rgba(227,59,13,0.45);color:var(--red-accent)}\n .btn-manage i{font-size:14px}\n\n .drag-ghost{position:fixed;pointer-events:none;z-index:99;opacity:.85;transform:scale(1.05);box-shadow:0 14px 36px rgba(0,0,0,0.35);border-radius:8px;overflow:hidden;background:rgba(233,231,224,0.92);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(227,59,13,0.30)}\n\n .btn-back{width:32px;height:32px;border-radius:50%;border:1px solid rgba(255,255,255,0.40);background:rgba(233,231,224,0.55);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);color:var(--text-muted);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .25s ease;box-shadow:inset 0 1px 0 rgba(255,255,255,0.40)}\n .btn-back:active{background:rgba(227,59,13,0.10);color:var(--red-primary)}\n\n .nav-item{cursor:pointer;transition:all .3s ease;color:var(--text-on-dark-secondary);font-family:'Josefin Sans',sans-serif;font-weight:300;letter-spacing:.06em;font-size:12px;display:flex;align-items:center;gap:8px;padding:6px 14px;border-radius:20px;background:transparent;border:1px solid transparent}\n .nav-item.active{color:var(--red-accent);font-weight:400;background:rgba(227,59,13,0.10);border:1px solid rgba(255,255,255,0.10);box-shadow:inset 0 1px 0 rgba(255,255,255,0.06)}\n .nav-item i{font-size:14px}\n\n .btn-account{width:36px;height:36px;border-radius:50%;border:1px solid rgba(255,255,255,0.18);background:rgba(47,47,47,0.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:var(--text-on-dark-secondary);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .25s ease;position:relative;overflow:visible;box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),0 2px 8px rgba(0,0,0,0.25)}\n .btn-account:active{background:rgba(227,59,13,0.20);color:var(--text-on-dark)}\n .btn-account .note-icon{position:relative;z-index:2;font-size:12px;color:var(--red-primary)}\n .btn-account::after{content:'';position:absolute;inset:-3px;border-radius:50%;border:1px dashed rgba(227,59,13,0.20);pointer-events:none;animation:gearRotate 12s linear infinite}\n @keyframes gearRotate{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\n\n .sidebar-overlay{position:absolute;inset:0;z-index:45;background:rgba(0,0,0,0.40);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);transition:opacity .35s ease;pointer-events:auto}\n .sidebar-overlay.hidden-overlay{opacity:0;pointer-events:none}\n .sidebar-panel{position:absolute;top:0;right:0;bottom:0;width:75%;z-index:46;background:rgba(35,33,31,0.78);backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);box-shadow:-8px 0 35px rgba(0,0,0,0.50),inset -1px 0 0 rgba(255,255,255,0.06);border-left:0.5px solid rgba(255,255,255,0.08);transition:transform .35s cubic-bezier(.25,.46,.45,.94);display:flex;flex-direction:column;overflow-y:auto}\n .sidebar-panel.hidden-sidebar{transform:translateX(105%)}\n .sidebar-panel.visible-sidebar{transform:translateX(0)}\n .sidebar-section{border-bottom:0.5px solid rgba(255,255,255,0.05);padding:14px 18px}\n .sidebar-item{display:flex;align-items:center;gap:12px;cursor:pointer;transition:all .2s ease;color:var(--text-on-dark-secondary);font-size:13px;letter-spacing:.04em;border-radius:8px;padding:10px 10px;margin:2px -6px}\n .sidebar-item:active{color:var(--red-accent);background:rgba(255,255,255,0.04)}\n .sidebar-item i{width:20px;text-align:center;font-size:13px}\n .avatar-ring{border:2px solid rgba(255,255,255,0.20);box-shadow:0 0 20px rgba(227,59,13,0.15),inset 0 0 8px rgba(255,255,255,0.04)}\n\n .app-logo{width:32px;height:32px;position:relative;display:flex;align-items:center;justify-content:center}\n .app-logo .logo-diamond{width:20px;height:20px;border:1.2px solid var(--red-primary);transform:rotate(45deg);position:absolute;opacity:.85}\n .app-logo .logo-diamond-inner{width:10px;height:10px;border:0.8px solid rgba(227,59,13,0.45);transform:rotate(45deg);position:absolute}\n .app-logo .logo-staff{position:absolute;display:flex;flex-direction:column;gap:2.5px;align-items:center;z-index:1}\n .app-logo .logo-staff span{display:block;height:.6px;background:var(--red-primary);border-radius:1px}\n .app-logo .logo-dot{width:3px;height:3px;background:var(--red-accent);border-radius:50%;position:absolute;bottom:4px;z-index:2}\n .font-calligraphy{font-family:'Liu Jian Mao Cao','Ma Shan Zheng',cursive;font-weight:400}\n\n .btn-add-lib{display:flex;align-items:center;justify-content:center;gap:6px;padding:10px;border-radius:8px;border:1.5px dashed rgba(227,59,13,0.30);color:var(--red-primary);font-size:12px;letter-spacing:.05em;cursor:pointer;transition:all .2s ease;background:rgba(233,231,224,0.35)}\n .btn-add-lib:active{background:rgba(227,59,13,0.08);border-color:rgba(227,59,13,0.50)}\n\n .tab-panel{transition:opacity .4s ease,transform .4s ease}\n .tab-panel.hidden-panel{opacity:0;pointer-events:none;position:absolute;transform:translateY(6px)}\n .tab-panel.visible-panel{opacity:1;pointer-events:auto;position:relative;transform:translateY(0)}\n\n .no-scrollbar::-webkit-scrollbar{display:none}\n .no-scrollbar{scrollbar-width:none;-ms-overflow-style:none}\n\n .sub-cover-placeholder{width:100%;height:100%;background:linear-gradient(160deg,#3a3532 0%,#2f2b28 50%,#1f1c1a 100%);display:flex;align-items:center;justify-content:center}\n </style>\n</head>\n<body>\n <div class=\"app-root\">\n\n <div class=\"w-full flex items-center justify-between px-6 shrink-0 relative z-30\" style=\"height:34px;background:#1f1e1c\">\n <span class=\"text-[11px] text-[#b0a89e] font-['Josefin_Sans'] tracking-wide\">15:00</span>\n <div class=\"flex items-center gap-1.5\">\n <div class=\"w-3 h-3 rounded-full border border-[#5e5850] flex items-center justify-center\"><div class=\"w-[6px] h-[6px] rounded-full bg-[#8a8278]\"></div></div>\n <span class=\"text-[10px] text-[#b0a89e]\">88%</span>\n </div>\n </div>\n\n <div class=\"w-full shrink-0 nav-top\">\n <div class=\"flex items-center justify-between px-5 py-2.5\">\n <div class=\"app-logo\" aria-label=\"曲谱应用\"><div class=\"logo-diamond\"></div><div class=\"logo-diamond-inner\"></div><div class=\"logo-staff\"><span style=\"width:11px;\"></span><span style=\"width:9px;\"></span><span style=\"width:11px;\"></span></div><div class=\"logo-dot\"></div></div>\n <button class=\"btn-account\" aria-label=\"账号\" onclick=\"openSidebar()\"><i class=\"fa-solid fa-music note-icon\"></i></button>\n </div>\n </div>\n\n <div class=\"relative flex-1 overflow-hidden\" style=\"min-height:0;z-index:15\">\n\n <!-- TAB 0: 推荐 -->\n <div id=\"tab-panel-0\" class=\"tab-panel visible-panel h-full w-full flex flex-col\" style=\"background:#e9e7e0\">\n <div class=\"relative px-5 pt-4 pb-1 z-10 shrink-0\"><div class=\"flex items-center gap-2 mb-0.5\"><div class=\"w-5 h-[1px] bg-[#e33b0d] opacity-35\"></div><span class=\"text-[9px] tracking-[0.15em] text-[#8b7670] font-['Josefin_Sans'] font-light uppercase\">Commendatio</span><div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-18\"></div></div></div>\n <div class=\"flex-1 overflow-y-auto no-scrollbar z-10 relative px-4 pb-2\">\n <div class=\"stack-card-wrap mb-4\" onclick=\"openSubCollection('古典精选','周杰伦')\"><div class=\"stack-card-back\"><img src=\"/assets/images/16-9/business-04.jpg\" alt=\"\" loading=\"lazy\"></div><div class=\"stack-card-front\"><img src=\"/assets/images/business/business-25.jpg\" alt=\"\" loading=\"lazy\"></div><span class=\"stack-label\">古典精选 · 经典永恒</span></div>\n <div class=\"flex items-center gap-2 mb-3\"><div class=\"w-4 h-[1px] bg-[#e33b0d] opacity-40\"></div><span class=\"text-[11px] tracking-[0.10em] text-[#5c4046] font-['Josefin_Sans'] font-semibold uppercase\">热门精选</span><div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-15\"></div></div>\n <div class=\"grid grid-cols-2 gap-3 mb-4\">\n <div class=\"rec-mini-card\" style=\"width:auto\" onclick=\"openSubCollection('肖邦夜曲','陈奕迅')\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">肖邦夜曲全集 · 浪漫经典</div></div>\n <div class=\"rec-mini-card\" style=\"width:auto\" onclick=\"openSubCollection('巴赫平均律','周杰伦')\"><img src=\"/assets/images/education/education-1.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">巴赫平均律 · 键盘圣经</div></div>\n </div>\n <div class=\"flex items-center gap-2 mb-3\"><div class=\"w-4 h-[1px] bg-[#e33b0d] opacity-40\"></div><span class=\"text-[11px] tracking-[0.10em] text-[#5c4046] font-['Josefin_Sans'] font-semibold uppercase\">编辑推荐</span><div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-15\"></div></div>\n <div class=\"flex gap-3 overflow-x-auto no-scrollbar pb-2\">\n <div class=\"rec-mini-card\" onclick=\"openSubCollection('德彪西意象集','林俊杰')\"><img src=\"/assets/images/cases/porto2.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">德彪西意象集</div></div>\n <div class=\"rec-mini-card\" onclick=\"openSubCollection('拉赫玛尼诺夫','邓紫棋')\"><img src=\"/assets/images/16-9/business-03.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">拉赫玛尼诺夫</div></div>\n <div class=\"rec-mini-card\" onclick=\"openSubCollection('舒伯特艺术歌曲','五月天')\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-4.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">舒伯特艺术歌曲</div></div>\n </div>\n </div>\n <div class=\"px-5 pb-2 relative z-10 shrink-0\"><div class=\"flex items-center gap-2\"><div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-12\"></div><div class=\"flex gap-1\"><div class=\"w-1 h-1 bg-[#e33b0d] opacity-35\"></div><div class=\"w-2 h-1 bg-[#e33b0d] opacity-25\"></div><div class=\"w-1 h-1 bg-[#e33b0d] opacity-35\"></div></div><div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-12\"></div></div></div>\n </div>\n\n <!-- TAB 1: 曲库 -->\n <div id=\"tab-panel-1\" class=\"tab-panel hidden-panel h-full w-full flex flex-col\" style=\"background:#e9e7e0\">\n <div class=\"shrink-0 px-4 pt-3 pb-2 relative\" style=\"z-index:28\">\n <div class=\"relative flex items-center gap-2\" id=\"search-wrapper\">\n <div class=\"search-bar\" id=\"search-bar\" onclick=\"toggleSearchHistory()\"><i class=\"fa-solid fa-magnifying-glass\"></i><span id=\"search-placeholder\">搜索曲谱…</span></div>\n <div class=\"search-history-dropdown no-scrollbar hidden-dropdown\" id=\"search-dropdown\">\n <div id=\"history-list\">\n <div class=\"history-item\" onclick=\"selectHistory('贝多芬月光奏鸣曲')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>贝多芬月光奏鸣曲</span></div>\n <div class=\"history-item\" onclick=\"selectHistory('莫扎特钢琴协奏曲')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>莫扎特钢琴协奏曲</span></div>\n <div class=\"history-item\" onclick=\"selectHistory('肖邦夜曲全集')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>肖邦夜曲全集</span></div>\n <div class=\"history-item\" onclick=\"selectHistory('巴赫平均律曲集')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>巴赫平均律曲集</span></div>\n </div>\n <div class=\"clear-history-btn\" onclick=\"clearSearchHistory()\"><i class=\"fa-solid fa-trash-can\"></i><span>清除搜索历史</span></div>\n </div>\n <button class=\"btn-manage\" id=\"btn-manage\" onclick=\"toggleManageMode()\" aria-label=\"管理曲库\"><i class=\"fa-solid fa-pen-to-square\"></i></button>\n </div>\n </div>\n\n <div class=\"px-4 shrink-0 relative\" style=\"z-index:10\"><div class=\"h-[1px]\" style=\"background:linear-gradient(90deg,transparent,rgba(227,59,13,0.20),transparent)\"></div></div>\n\n <!-- 曲库网格 — 专辑封面风格 -->\n <div class=\"flex-1 px-4 overflow-y-auto no-scrollbar relative pt-2 pb-1\" style=\"z-index:5\" id=\"lib-scroll-area\">\n <div class=\"grid grid-cols-2 gap-3\" id=\"lib-grid\">\n <!-- 我的曲库 -->\n <div class=\"lib-card\" id=\"lib-mine\" data-lib=\"我的曲库\" data-locked=\"true\" data-cover=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" onclick=\"handleLibClick('我的曲库','周杰伦')\">\n <div class=\"card-cover\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\" loading=\"lazy\"></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">我的曲库</div><div class=\"card-count\">7 首曲目</div></div>\n </div>\n <!-- 古典奏鸣曲集 -->\n <div class=\"lib-card\" id=\"lib-1\" data-lib=\"古典奏鸣曲集\" data-locked=\"false\" data-cover=\"/assets/images/business/business-25.jpg\" onclick=\"handleLibClick('古典奏鸣曲集','周杰伦')\">\n <div class=\"drag-handle\">⠿</div>\n <div class=\"del-btn\" id=\"del-1\" onclick=\"event.stopPropagation();deleteLib('lib-1')\"><i class=\"fa-solid fa-xmark\"></i></div>\n <div class=\"cover-overlay-card\" id=\"cover-overlay-1\" onclick=\"event.stopPropagation();changeCover('1')\"><i class=\"fa-solid fa-camera\"></i></div>\n <div class=\"card-cover\"><img src=\"/assets/images/business/business-25.jpg\" alt=\"\" loading=\"lazy\" id=\"cover-img-1\"></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">古典奏鸣曲集</div><div class=\"card-count\">12 首曲目</div></div>\n </div>\n <!-- 浪漫钢琴选 -->\n <div class=\"lib-card\" id=\"lib-2\" data-lib=\"浪漫钢琴选\" data-locked=\"false\" data-cover=\"/assets/images/fashion-lifestyle/fashion-lifestyle-4.jpg\" onclick=\"handleLibClick('浪漫钢琴选','陈奕迅')\">\n <div class=\"drag-handle\">⠿</div>\n <div class=\"del-btn\" id=\"del-2\" onclick=\"event.stopPropagation();deleteLib('lib-2')\"><i class=\"fa-solid fa-xmark\"></i></div>\n <div class=\"cover-overlay-card\" id=\"cover-overlay-2\" onclick=\"event.stopPropagation();changeCover('2')\"><i class=\"fa-solid fa-camera\"></i></div>\n <div class=\"card-cover\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-4.jpg\" alt=\"\" loading=\"lazy\" id=\"cover-img-2\"></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">浪漫钢琴选</div><div class=\"card-count\">8 首曲目</div></div>\n </div>\n <!-- 交响乐珍藏 -->\n <div class=\"lib-card\" id=\"lib-3\" data-lib=\"交响乐珍藏\" data-locked=\"false\" data-cover=\"/assets/images/cases/porto2.jpg\" onclick=\"handleLibClick('交响乐珍藏','林俊杰')\">\n <div class=\"drag-handle\">⠿</div>\n <div class=\"del-btn\" id=\"del-3\" onclick=\"event.stopPropagation();deleteLib('lib-3')\"><i class=\"fa-solid fa-xmark\"></i></div>\n <div class=\"cover-overlay-card\" id=\"cover-overlay-3\" onclick=\"event.stopPropagation();changeCover('3')\"><i class=\"fa-solid fa-camera\"></i></div>\n <div class=\"card-cover\"><img src=\"/assets/images/cases/porto2.jpg\" alt=\"\" loading=\"lazy\" id=\"cover-img-3\"></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">交响乐珍藏</div><div class=\"card-count\">15 首曲目</div></div>\n </div>\n <!-- 巴洛克精选 -->\n <div class=\"lib-card\" id=\"lib-4\" data-lib=\"巴洛克精选\" data-locked=\"false\" data-cover=\"/assets/images/16-9/business-03.jpg\" onclick=\"handleLibClick('巴洛克精选','邓紫棋')\">\n <div class=\"drag-handle\">⠿</div>\n <div class=\"del-btn\" id=\"del-4\" onclick=\"event.stopPropagation();deleteLib('lib-4')\"><i class=\"fa-solid fa-xmark\"></i></div>\n <div class=\"cover-overlay-card\" id=\"cover-overlay-4\" onclick=\"event.stopPropagation();changeCover('4')\"><i class=\"fa-solid fa-camera\"></i></div>\n <div class=\"card-cover\"><img src=\"/assets/images/16-9/business-03.jpg\" alt=\"\" loading=\"lazy\" id=\"cover-img-4\"></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">巴洛克精选</div><div class=\"card-count\">5 首曲目</div></div>\n </div>\n <!-- 现代作品集 -->\n <div class=\"lib-card\" id=\"lib-5\" data-lib=\"现代作品集\" data-locked=\"false\" data-cover=\"/assets/images/education/education-1.jpg\" onclick=\"handleLibClick('现代作品集','五月天')\">\n <div class=\"drag-handle\">⠿</div>\n <div class=\"del-btn\" id=\"del-5\" onclick=\"event.stopPropagation();deleteLib('lib-5')\"><i class=\"fa-solid fa-xmark\"></i></div>\n <div class=\"cover-overlay-card\" id=\"cover-overlay-5\" onclick=\"event.stopPropagation();changeCover('5')\"><i class=\"fa-solid fa-camera\"></i></div>\n <div class=\"card-cover\"><img src=\"/assets/images/education/education-1.jpg\" alt=\"\" loading=\"lazy\" id=\"cover-img-5\"></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">现代作品集</div><div class=\"card-count\">9 首曲目</div></div>\n </div>\n </div>\n <div class=\"btn-add-lib mt-3 mb-2\" onclick=\"addNewLib()\"><i class=\"fa-solid fa-plus text-[11px]\"></i><span>新增曲库</span></div>\n </div>\n </div>\n\n <!-- 子曲谱视图 -->\n <div id=\"sub-collection-view\" class=\"sub-view hidden-sub\">\n <div class=\"flex items-center gap-2 px-4 pt-3 pb-1 z-10\">\n <button class=\"btn-back\" onclick=\"closeSubCollection()\" aria-label=\"返回\"><i class=\"fa-solid fa-arrow-left text-[11px]\"></i></button>\n <div class=\"w-5 h-[1px] bg-[#e33b0d] opacity-35\"></div>\n <span class=\"text-[9px] tracking-[0.12em] text-[#8b7670] font-['Josefin_Sans'] font-light uppercase\">shorthand of emotion</span>\n <div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-18\"></div>\n </div>\n <div class=\"sub-header\">\n <div class=\"sub-cover-wrap\" id=\"sub-cover-wrap\">\n <img id=\"sub-cover-img\" src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\" loading=\"lazy\">\n <div class=\"vinyl-peek-sub\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n </div>\n <div class=\"sub-info\">\n <div class=\"lib-name\" id=\"sub-lib-name\">我的曲库</div>\n <div class=\"lib-author\" id=\"sub-lib-author\">周杰伦</div>\n <div class=\"lib-meta\" id=\"sub-lib-meta\">共 5 首曲目</div>\n </div>\n </div>\n <div class=\"px-4\"><div class=\"h-[1px]\" style=\"background:linear-gradient(90deg,transparent,rgba(227,59,13,0.20),transparent)\"></div></div>\n <div class=\"sub-song-list no-scrollbar\" id=\"sub-song-list\">\n <div class=\"song-row\" onclick=\"closeAllPopups()\"><span class=\"song-index\">I</span><div class=\"song-body\"><div class=\"song-title\">晴天</div><div class=\"song-artist\">周杰伦</div></div><div class=\"song-more-btn\" onclick=\"event.stopPropagation();toggleSongPopup(event)\">···</div></div>\n <div class=\"song-row\" onclick=\"closeAllPopups()\"><span class=\"song-index\">II</span><div class=\"song-body\"><div class=\"song-title\">十年</div><div class=\"song-artist\">陈奕迅</div></div><div class=\"song-more-btn\" onclick=\"event.stopPropagation();toggleSongPopup(event)\">···</div></div>\n <div class=\"song-row\" onclick=\"closeAllPopups()\"><span class=\"song-index\">III</span><div class=\"song-body\"><div class=\"song-title\">修炼爱情</div><div class=\"song-artist\">林俊杰</div></div><div class=\"song-more-btn\" onclick=\"event.stopPropagation();toggleSongPopup(event)\">···</div></div>\n <div class=\"song-row\" onclick=\"closeAllPopups()\"><span class=\"song-index\">IV</span><div class=\"song-body\"><div class=\"song-title\">光年之外</div><div class=\"song-artist\">邓紫棋</div></div><div class=\"song-more-btn\" onclick=\"event.stopPropagation();toggleSongPopup(event)\">···</div></div>\n <div class=\"song-row\" onclick=\"closeAllPopups()\"><span class=\"song-index\">V</span><div class=\"song-body\"><div class=\"song-title\">突然好想你</div><div class=\"song-artist\">五月天</div></div><div class=\"song-more-btn\" onclick=\"event.stopPropagation();toggleSongPopup(event)\">···</div></div>\n </div>\n </div>\n </div>\n\n <div class=\"w-full shrink-0 bottom-nav-container\">\n <div class=\"flex items-center justify-center gap-20 relative\" style=\"height:42px\">\n <button class=\"nav-item active\" id=\"nav-recommend\" onclick=\"switchTab(0)\"><i class=\"fa-solid fa-comment-dots\"></i><span>推荐</span></button>\n <button class=\"nav-item\" id=\"nav-library\" onclick=\"switchTab(1)\"><i class=\"fa-solid fa-compact-disc\"></i><span>曲库</span></button>\n </div>\n </div>\n\n <div id=\"sidebar-overlay\" class=\"sidebar-overlay hidden-overlay\" onclick=\"closeSidebar()\"></div>\n <div id=\"sidebar-panel\" class=\"sidebar-panel hidden-sidebar\">\n <div class=\"sidebar-section flex flex-col items-center pt-6 pb-4 gap-3\">\n <div class=\"w-16 h-16 rounded-full avatar-ring flex items-center justify-center\" style=\"background:rgba(37,35,33,0.60)\"><i class=\"fa-solid fa-user-astronaut text-2xl\" style=\"color:var(--red-primary)\"></i></div>\n <p class=\"text-[15px] font-['Josefin_Sans'] font-semibold tracking-wider\" style=\"color:var(--text-on-dark)\">Vintage Musician</p>\n <span class=\"text-[10px] tracking-[0.1em] px-3 py-0.5 rounded-full\" style=\"background:rgba(227,59,13,0.14);color:var(--red-accent);border:1px solid rgba(227,59,13,0.22)\">PRO 会员</span>\n </div>\n <div class=\"sidebar-section\">\n <div class=\"flex items-center justify-between mb-2\"><span class=\"text-[11px] tracking-wider\" style=\"color:var(--text-on-dark-secondary)\">云端存储</span><span class=\"text-[11px]\" style=\"color:var(--red-accent)\">2.1 / 5.0 GB</span></div>\n <div class=\"w-full h-2 rounded-full\" style=\"background:rgba(0,0,0,0.35)\"><div class=\"h-full rounded-full\" style=\"width:42%;background:var(--red-primary)\"></div></div>\n </div>\n <div class=\"sidebar-section\" style=\"border-bottom:none\">\n <div class=\"sidebar-item\"><i class=\"fa-solid fa-palette\"></i><span>外观设置</span><i class=\"fa-solid fa-chevron-right text-[9px] ml-auto opacity-30\"></i></div>\n <div class=\"sidebar-item\"><i class=\"fa-solid fa-bell\"></i><span>通知偏好</span><i class=\"fa-solid fa-chevron-right text-[9px] ml-auto opacity-30\"></i></div>\n <div class=\"sidebar-item\"><i class=\"fa-solid fa-cloud-arrow-up\"></i><span>数据同步</span><i class=\"fa-solid fa-chevron-right text-[9px] ml-auto opacity-30\"></i></div>\n <div class=\"sidebar-item\"><i class=\"fa-solid fa-circle-info\"></i><span>关于应用</span><i class=\"fa-solid fa-chevron-right text-[9px] ml-auto opacity-30\"></i></div>\n </div>\n <div class=\"sidebar-section\" style=\"border-bottom:none;margin-top:auto;padding-bottom:20px\">\n <div class=\"sidebar-item\" style=\"color:var(--red-primary)\"><i class=\"fa-solid fa-arrow-right-from-bracket\"></i><span>退出登录</span></div>\n </div>\n </div>\n </div>\n\n <script>\n let manageMode = false;\n let dragCard = null, dragGhost = null;\n let dragStartX = 0, dragStartY = 0, dragOrigRect = null;\n\n function switchTab(i){\n const p=[document.getElementById('tab-panel-0'),document.getElementById('tab-panel-1')];\n const n=[document.getElementById('nav-recommend'),document.getElementById('nav-library')];\n p.forEach((e,x)=>{if(x===i){e.classList.remove('hidden-panel');e.classList.add('visible-panel')}else{e.classList.remove('visible-panel');e.classList.add('hidden-panel')}});\n n.forEach((e,x)=>{if(e){if(x===i)e.classList.add('active');else e.classList.remove('active')}});\n closeSubCollection();exitManageMode();closeSearchHistory();\n }\n\n function openSubCollection(title,composer){\n if(manageMode) return;\n document.getElementById('sub-lib-name').textContent = title;\n document.getElementById('sub-lib-author').textContent = composer;\n const sv = document.getElementById('sub-collection-view');\n sv.classList.remove('hidden-sub');sv.classList.add('visible-sub');\n }\n function closeSubCollection(){\n const sv = document.getElementById('sub-collection-view');\n sv.classList.remove('visible-sub');sv.classList.add('hidden-sub');\n closeAllPopups();\n }\n\n function handleLibClick(title,composer){if(manageMode) return;openSubCollection(title, composer);}\n\n function toggleManageMode(){\n manageMode = !manageMode;\n const btn = document.getElementById('btn-manage');\n if(manageMode){\n btn.classList.add('active-manage');\n document.querySelectorAll('.lib-card[data-locked=\"false\"] .del-btn').forEach(b=>b.classList.add('show-del'));\n document.querySelectorAll('.lib-card[data-locked=\"false\"] .drag-handle').forEach(b=>b.classList.add('show-handle'));\n document.querySelectorAll('.lib-card[data-locked=\"false\"] .cover-overlay-card').forEach(b=>b.classList.add('show-cover'));\n }else{exitManageMode();}\n }\n function exitManageMode(){\n manageMode = false;\n document.getElementById('btn-manage').classList.remove('active-manage');\n document.querySelectorAll('.del-btn').forEach(b=>b.classList.remove('show-del'));\n document.querySelectorAll('.drag-handle').forEach(b=>b.classList.remove('show-handle'));\n document.querySelectorAll('.cover-overlay-card').forEach(b=>b.classList.remove('show-cover'));\n cleanupDrag();\n }\n\n function deleteLib(id){const c=document.getElementById(id);if(c){c.style.transition='all .3s ease';c.style.opacity='0';c.style.transform='scale(0.8)';setTimeout(()=>c.remove(),300);}}\n\n function changeCover(libId){\n const url = prompt('请输入封面图片URL(留空恢复默认):');\n const img = document.getElementById('cover-img-'+libId);\n if(!img) return;\n if(url && url.trim()){img.src=url.trim();}else{const def=document.getElementById('lib-'+libId)?.getAttribute('data-cover');img.src=def||'';}\n }\n\n function addNewLib(){\n const name = prompt('请输入新曲库名称:');\n if(name && name.trim()){\n const grid = document.getElementById('lib-grid');\n const newId = 'lib-' + Date.now();\n const div = document.createElement('div');\n div.className='lib-card';div.id=newId;\n div.setAttribute('data-lib',name.trim());div.setAttribute('data-locked','false');div.setAttribute('data-cover','');\n div.setAttribute('onclick',`handleLibClick('${name.trim().replace(/'/g,\"\\\\'\")}','自建曲库')`);\n div.innerHTML=`\n <div class=\"drag-handle\">⠿</div>\n <div class=\"del-btn\" id=\"del-${newId}\" onclick=\"event.stopPropagation();deleteLib('${newId}')\"><i class=\"fa-solid fa-xmark\"></i></div>\n <div class=\"cover-overlay-card\" id=\"cover-overlay-${newId}\" onclick=\"event.stopPropagation();changeCover('${newId}')\"><i class=\"fa-solid fa-camera\"></i></div>\n <div class=\"card-cover\"><div class=\"cover-placeholder\"></div></div>\n <div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div>\n <div class=\"card-info\"><div class=\"card-name\">${name.trim()}</div><div class=\"card-count\">0 首曲目</div></div>\n `;\n grid.appendChild(div);\n bindDragEvents(div);\n if(manageMode){div.querySelector('.del-btn').classList.add('show-del');div.querySelector('.drag-handle').classList.add('show-handle');div.querySelector('.cover-overlay-card').classList.add('show-cover');}\n }\n }\n\n function bindDragEvents(card){const h=card.querySelector('.drag-handle');if(!h)return;h.addEventListener('touchstart',onDragStart,{passive:false});h.addEventListener('mousedown',onDragStart);}\n\n function hideAllDelButtons(){document.querySelectorAll('.del-btn.show-del').forEach(b=>b.classList.remove('show-del'));}\n function restoreAllDelButtons(){if(!manageMode)return;document.querySelectorAll('.lib-card[data-locked=\"false\"] .del-btn').forEach(b=>b.classList.add('show-del'));}\n\n function onDragStart(e){\n if(!manageMode)return;e.preventDefault();\n const h=e.target.closest('.drag-handle');\n if(!h||!h.classList.contains('show-handle'))return;\n dragCard=h.closest('.lib-card');\n if(!dragCard||dragCard.getAttribute('data-locked')==='true'){dragCard=null;return;}\n hideAllDelButtons();\n const t=e.touches?e.touches[0]:e;\n dragStartX=t.clientX;dragStartY=t.clientY;\n dragOrigRect=dragCard.getBoundingClientRect();\n dragGhost=dragCard.cloneNode(true);\n const gd=dragGhost.querySelector('.del-btn');if(gd)gd.classList.remove('show-del');\n const gh=dragGhost.querySelector('.drag-handle');if(gh)gh.classList.remove('show-handle');\n const gc=dragGhost.querySelector('.cover-overlay-card');if(gc)gc.classList.remove('show-cover');\n dragGhost.classList.add('drag-ghost');\n dragGhost.style.width=dragOrigRect.width+'px';dragGhost.style.height=dragOrigRect.height+'px';\n dragGhost.style.left=dragOrigRect.left+'px';dragGhost.style.top=dragOrigRect.top+'px';\n document.body.appendChild(dragGhost);\n dragCard.classList.add('dragging');\n document.addEventListener('touchmove',onDragMove,{passive:false});\n document.addEventListener('touchend',onDragEnd);document.addEventListener('mousemove',onDragMove);document.addEventListener('mouseup',onDragEnd);\n }\n function onDragMove(e){if(!dragCard||!dragGhost)return;e.preventDefault();const t=e.touches?e.touches[0]:e;dragGhost.style.left=(dragOrigRect.left+(t.clientX-dragStartX))+'px';dragGhost.style.top=(dragOrigRect.top+(t.clientY-dragStartY))+'px';}\n function onDragEnd(e){\n document.removeEventListener('touchmove',onDragMove);document.removeEventListener('touchend',onDragEnd);document.removeEventListener('mousemove',onDragMove);document.removeEventListener('mouseup',onDragEnd);\n if(!dragCard||!dragGhost){cleanupDrag();return;}\n const gr=dragGhost.getBoundingClientRect();const gcx=gr.left+gr.width/2,gcy=gr.top+gr.height/2;\n const grid=document.getElementById('lib-grid');const cards=Array.from(grid.querySelectorAll('.lib-card')).filter(c=>c!==dragCard);\n let target=null,min=Infinity;\n cards.forEach(c=>{const r=c.getBoundingClientRect();const d=Math.hypot(gcx-(r.left+r.width/2),gcy-(r.top+r.height/2));if(d<min){min=d;target=c;}});\n if(target&&min<130){const all=Array.from(grid.children);const iD=all.indexOf(dragCard),iT=all.indexOf(target);if(iD<iT)grid.insertBefore(dragCard,target.nextSibling);else grid.insertBefore(dragCard,target);}\n cleanupDrag();\n }\n function cleanupDrag(){restoreAllDelButtons();if(dragCard)dragCard.classList.remove('dragging');if(dragGhost){dragGhost.remove();dragGhost=null;}dragCard=null;dragOrigRect=null;}\n\n function toggleSearchHistory(){if(manageMode)return;const dd=document.getElementById('search-dropdown'),sb=document.getElementById('search-bar');if(dd.classList.contains('hidden-dropdown')){dd.classList.remove('hidden-dropdown');sb.classList.add('focused');}else{closeSearchHistory();}}\n function closeSearchHistory(){document.getElementById('search-dropdown').classList.add('hidden-dropdown');document.getElementById('search-bar').classList.remove('focused');}\n function selectHistory(t){document.getElementById('search-placeholder').textContent=t;closeSearchHistory();}\n function clearSearchHistory(){document.getElementById('history-list').innerHTML='';closeSearchHistory();}\n\n function toggleSongPopup(e){\n const btn=e.target.closest('.song-more-btn');if(!btn)return;\n const ex=document.querySelector('.song-action-popup');if(ex&&ex.parentElement===btn.parentElement){ex.remove();return;}\n closeAllPopups();\n const popup=document.createElement('div');popup.className='song-action-popup';\n popup.innerHTML=`<div class=\"action-item\" onclick=\"event.stopPropagation();closeAllPopups();\"><i class=\"fa-regular fa-comment\"></i><span>评论</span></div><div class=\"action-item\" onclick=\"event.stopPropagation();closeAllPopups();\"><i class=\"fa-regular fa-heart\"></i><span>点赞 · <span style=\"color:var(--red-primary)\">328</span></span></div><div class=\"action-item danger\" onclick=\"event.stopPropagation();closeAllPopups();\"><i class=\"fa-regular fa-trash-can\"></i><span>删除</span></div><div class=\"action-item\" onclick=\"event.stopPropagation();closeAllPopups();\"><i class=\"fa-solid fa-share-nodes\"></i><span>分享</span></div>`;\n btn.parentElement.appendChild(popup);\n setTimeout(()=>document.addEventListener('click',closeAllPopupsOnce,{once:true}),10);\n }\n function closeAllPopups(){document.querySelectorAll('.song-action-popup').forEach(p=>p.remove());}\n function closeAllPopupsOnce(){closeAllPopups();}\n\n function openSidebar(){document.getElementById('sidebar-overlay').classList.remove('hidden-overlay');document.getElementById('sidebar-panel').classList.remove('hidden-sidebar');document.getElementById('sidebar-panel').classList.add('visible-sidebar');}\n function closeSidebar(){document.getElementById('sidebar-overlay').classList.add('hidden-overlay');document.getElementById('sidebar-panel').classList.remove('visible-sidebar');document.getElementById('sidebar-panel').classList.add('hidden-sidebar');}\n\n document.addEventListener('DOMContentLoaded',()=>{\n document.querySelectorAll('.lib-card[data-locked=\"false\"]').forEach(bindDragEvents);\n document.getElementById('tab-panel-1').addEventListener('click',function(e){if(!e.target.closest('#search-wrapper'))closeSearchHistory();});\n });\n </script>\n</body>\n</html>"
},
"next": [
"封面更换支持图片预览",
"黑胶探出动画更自然",
"搜索框支持键盘实时输入",
"推荐卡片增加更多内容",
"装饰艺术细节深化"
],
"breakpoint": "xs"
}
```
推理
让我们重新设计曲库卡片。用户希望曲库卡片占满方形区域、有封面、带黑胶唱片元素,参照歌手专辑设计。
我需要在曲库页面的网格中重构 lib-card:
- 卡片占满方形区域(正方形卡片)
- 上半部分是大封面图片(或黑胶唱片),下半部分是曲库名称和曲目数
- 融入黑胶唱片元素——可以在封面区域叠加半截黑胶唱片(从一侧插入),类似一些专辑封面设计
- 类似 Apple Music 或 Spotify 的专辑卡片风格
同时需要更新子曲谱视图中的上栏封面。
用户之前也提到过曲库点开后的界面需要调整,我已经在上一次做了。现在重点是曲库卡片本身。
设计方向:
- 正方形卡片,类似专辑封面的布局
- 上半部分约70%区域:封面图片(可以用黑胶唱片代替,或封面+黑胶唱片叠加)
- 黑胶唱片从右侧部分滑入覆盖在封面上——这是经典设计:封面+半张黑胶从右侧探出
- 下半部分约30%:曲库名称+曲目数量
- 保持红黑米白配色
让我重新设计 lib-card:
1. 卡片为正方形(aspect-ratio: 1)
2. 背景为封面图片(如果有的话),否则显示黑胶唱片
3. 黑胶唱片元素可以是一个从右下角探出的半圆,模拟黑胶唱片从封套中抽出一半的效果
4. 底部有渐变遮罩+文字
对于没有自定义封面的卡片,可以使用默认黑胶唱片样式。
让我也考虑通过 get_assets 获取一些合适的图片资源。
实际上我应该专注于设计 HTML/CSS,获取一些合适的资产图片来作为默认封面。
让我先设计卡片结构:
- 正方形卡片,带圆角
- 上半部分:封面区域,使用 asset 图片或黑胶唱片
- 黑胶唱片可以是一个从右侧探出的圆形元素,覆盖在封面上
- 底部文字区域
对于黑胶唱片元素,我可以使用之前定义的 vinyl-record CSS,但做成半截从侧面滑出的效果——使用 overflow: hidden 遮住一半。
让我来实现这个设计。我会:
1. 将 lib-grid 改为 aspect-ratio: 1 的正方形卡片
2. 卡片顶部为封面图(占满),底部为渐变遮罩+文字
3. 黑胶唱片从右侧探出(position: absolute, right: -30%,用圆形 overflow hidden 遮一半)
4. 或者更简单:封面为圆形黑胶唱片在中央,周围是卡片底色
实际上更好的设计可能是像 Apple Music 那样的专辑卡片——方形封面图占大部分,底部是文字。我可以在此基础上加入黑胶唱片的元素。
让我把黑胶唱片放在封面图片的一个角落,像是从封套中滑出。
具体设计:
- 卡片 aspect-ratio: 1
- 内部上方约75%为封面区域(可以是图片或默认黑胶唱片)
- 在封面区域的右下角,有一个黑胶唱片半圆从下方探出(overflow: hidden 在卡片上)
- 下方25%为曲库名称和曲目数
对于黑胶唱片的探出效果,我可以在封面区域下方放置一个大的黑胶唱片圆形,让它一半在卡片内一半在卡片外(通过卡片的 overflow: hidden 来裁剪)。
让我编码实现。同时更新子曲谱视图的上栏封面也使用类似风格。
先获取一些适合作为专辑封面的图片资源。搜索结果不太理想,没有找到音乐相关的封面图片。让我尝试其他搜索词。Let me use the existing assets we already have in the page - fashion-lifestyle-15.jpg, education-1.jpg, cases/porto2.jpg, 16-9/business-03.jpg, fashion-lifestyle-4.jpg, etc. These are already in the recommendation cards.
For the library cards, I'll redesign them as square album-cover style cards with:
1. Full square card (aspect-ratio: 1)
2. Top ~70% is a cover image area, with a vinyl record peeking out from the right side (like a record sleeve with vinyl partially pulled out)
3. Bottom ~30% is the library name + track count
4. Each card has its own colored background
For the vinyl peeking effect: I'll put a vinyl record circle positioned so that only the left half is visible inside the card (using overflow: hidden on the card), creating the effect of a record being pulled out of its sleeve.
Let me also add some individual character to each card by giving them different accent colors or subtle variations.
I'll also update the sub-collection view header to match this style.
For cover images, I'll use the existing asset paths in the design - specifically the ones already in use. Each library card can use one of these images.
Let me now write the complete updated HTML. I need to be careful to keep all existing functionality intact while redesigning the library cards.Good. Now I have a clear idea. Let me redesign the library cards as square album-cover style cards. I'll write the complete HTML now with:
1. Square cards (aspect-ratio: 1)
2. Cover image filling most of the card
3. A vinyl record peeking from the right side (half-visible, like being pulled out of a sleeve)
4. Bottom text overlay with library name + track count
5. Each card uses one of the available asset images
6. Updated sub-collection view with the same cover style
Key design elements:
- Card: rounded corners, glass-like border, shadow
- Cover image fills top ~72% of card
- Vinyl record circle positioned so ~40% is visible from right edge (overflow hidden on card)
- Bottom section: dark gradient overlay with name and count
- Delete button & drag handle still work in manage mode
Let me also update the sub-collection view's header to use the same style - cover image on the left with vinyl peeking out.
For the card images, I'll assign:
- 我的曲库: fashion-lifestyle-15.jpg
- 古典奏鸣曲集: business/business-25.jpg
- 浪漫钢琴选: fashion-lifestyle/fashion-lifestyle-4.jpg
- 交响乐珍藏: cases/porto2.jpg
- 巴洛克精选: 16-9/business-03.jpg
- 现代作品集: education/education-1.jpg
Let me write the complete HTML now.
我需要在曲库页面的网格中重构 lib-card:
- 卡片占满方形区域(正方形卡片)
- 上半部分是大封面图片(或黑胶唱片),下半部分是曲库名称和曲目数
- 融入黑胶唱片元素——可以在封面区域叠加半截黑胶唱片(从一侧插入),类似一些专辑封面设计
- 类似 Apple Music 或 Spotify 的专辑卡片风格
同时需要更新子曲谱视图中的上栏封面。
用户之前也提到过曲库点开后的界面需要调整,我已经在上一次做了。现在重点是曲库卡片本身。
设计方向:
- 正方形卡片,类似专辑封面的布局
- 上半部分约70%区域:封面图片(可以用黑胶唱片代替,或封面+黑胶唱片叠加)
- 黑胶唱片从右侧部分滑入覆盖在封面上——这是经典设计:封面+半张黑胶从右侧探出
- 下半部分约30%:曲库名称+曲目数量
- 保持红黑米白配色
让我重新设计 lib-card:
1. 卡片为正方形(aspect-ratio: 1)
2. 背景为封面图片(如果有的话),否则显示黑胶唱片
3. 黑胶唱片元素可以是一个从右下角探出的半圆,模拟黑胶唱片从封套中抽出一半的效果
4. 底部有渐变遮罩+文字
对于没有自定义封面的卡片,可以使用默认黑胶唱片样式。
让我也考虑通过 get_assets 获取一些合适的图片资源。
实际上我应该专注于设计 HTML/CSS,获取一些合适的资产图片来作为默认封面。
让我先设计卡片结构:
- 正方形卡片,带圆角
- 上半部分:封面区域,使用 asset 图片或黑胶唱片
- 黑胶唱片可以是一个从右侧探出的圆形元素,覆盖在封面上
- 底部文字区域
对于黑胶唱片元素,我可以使用之前定义的 vinyl-record CSS,但做成半截从侧面滑出的效果——使用 overflow: hidden 遮住一半。
让我来实现这个设计。我会:
1. 将 lib-grid 改为 aspect-ratio: 1 的正方形卡片
2. 卡片顶部为封面图(占满),底部为渐变遮罩+文字
3. 黑胶唱片从右侧探出(position: absolute, right: -30%,用圆形 overflow hidden 遮一半)
4. 或者更简单:封面为圆形黑胶唱片在中央,周围是卡片底色
实际上更好的设计可能是像 Apple Music 那样的专辑卡片——方形封面图占大部分,底部是文字。我可以在此基础上加入黑胶唱片的元素。
让我把黑胶唱片放在封面图片的一个角落,像是从封套中滑出。
具体设计:
- 卡片 aspect-ratio: 1
- 内部上方约75%为封面区域(可以是图片或默认黑胶唱片)
- 在封面区域的右下角,有一个黑胶唱片半圆从下方探出(overflow: hidden 在卡片上)
- 下方25%为曲库名称和曲目数
对于黑胶唱片的探出效果,我可以在封面区域下方放置一个大的黑胶唱片圆形,让它一半在卡片内一半在卡片外(通过卡片的 overflow: hidden 来裁剪)。
让我编码实现。同时更新子曲谱视图的上栏封面也使用类似风格。
先获取一些适合作为专辑封面的图片资源。搜索结果不太理想,没有找到音乐相关的封面图片。让我尝试其他搜索词。Let me use the existing assets we already have in the page - fashion-lifestyle-15.jpg, education-1.jpg, cases/porto2.jpg, 16-9/business-03.jpg, fashion-lifestyle-4.jpg, etc. These are already in the recommendation cards.
For the library cards, I'll redesign them as square album-cover style cards with:
1. Full square card (aspect-ratio: 1)
2. Top ~70% is a cover image area, with a vinyl record peeking out from the right side (like a record sleeve with vinyl partially pulled out)
3. Bottom ~30% is the library name + track count
4. Each card has its own colored background
For the vinyl peeking effect: I'll put a vinyl record circle positioned so that only the left half is visible inside the card (using overflow: hidden on the card), creating the effect of a record being pulled out of its sleeve.
Let me also add some individual character to each card by giving them different accent colors or subtle variations.
I'll also update the sub-collection view header to match this style.
For cover images, I'll use the existing asset paths in the design - specifically the ones already in use. Each library card can use one of these images.
Let me now write the complete updated HTML. I need to be careful to keep all existing functionality intact while redesigning the library cards.Good. Now I have a clear idea. Let me redesign the library cards as square album-cover style cards. I'll write the complete HTML now with:
1. Square cards (aspect-ratio: 1)
2. Cover image filling most of the card
3. A vinyl record peeking from the right side (half-visible, like being pulled out of a sleeve)
4. Bottom text overlay with library name + track count
5. Each card uses one of the available asset images
6. Updated sub-collection view with the same cover style
Key design elements:
- Card: rounded corners, glass-like border, shadow
- Cover image fills top ~72% of card
- Vinyl record circle positioned so ~40% is visible from right edge (overflow hidden on card)
- Bottom section: dark gradient overlay with name and count
- Delete button & drag handle still work in manage mode
Let me also update the sub-collection view's header to use the same style - cover image on the left with vinyl peeking out.
For the card images, I'll assign:
- 我的曲库: fashion-lifestyle-15.jpg
- 古典奏鸣曲集: business/business-25.jpg
- 浪漫钢琴选: fashion-lifestyle/fashion-lifestyle-4.jpg
- 交响乐珍藏: cases/porto2.jpg
- 巴洛克精选: 16-9/business-03.jpg
- 现代作品集: education/education-1.jpg
Let me write the complete HTML now.
角色
assistant
content
total_tokens
430221
summary
彻底重构曲库卡片为专辑封面风格:①卡片改为正方形(aspect-ratio:1),上方72%为全幅封面图+从右侧探出1/3的黑胶唱片半圆(模拟唱片从封套抽出的经典设计),下方28%为渐变遮罩叠加曲库名与曲目数;②每张卡片分配不同的资产图片作为封面;③子曲谱视图上栏同步更新为相同风格(左侧封面+黑胶,右侧曲库信息);④管理模式下删除按钮与拖拽手柄叠加在封面层上方;⑤保持所有既有交互功能不变。
uiParsing
关闭