```json
{
"summary": "四项精确修改:①「新增曲库」改为底部50%高度面板,含封面URL(留空默认灰色)+曲库名称输入+确认按钮;②曲库工具栏新增多选切换按钮,激活后每行左侧出现圆形复选框,底部浮现红色「删除已选(N)」浮动条,点选计数实时更新;③曲目操作弹窗删除项移至最底部(分享之上);④曲目搜索支持标题+作者双字段匹配,placeholder改为「搜索标题/作者…」。",
"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{--bg-dark:#2f2f2f;--bg-cream:#e9e7e0;--red-primary:#e33b0d;--red-deep:#b32a08;--red-accent:#f0481a;--red-darker:#8a1f06;--text-on-dark:#e5ded5;--text-on-dark-secondary:#b0a89e;--text-primary:#1a1214;--text-muted:#8b7670}\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);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);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 .vinyl-mini{width:100%;height:100%;border-radius:50%;position:relative;overflow:hidden;background:repeating-radial-gradient(circle at 50% 50%,transparent 0px,transparent 2.8px,rgba(0,0,0,0.07) 2.8px,rgba(0,0,0,0.07) 3px),repeating-radial-gradient(circle at 50% 50%,transparent 0px,transparent 5.6px,rgba(0,0,0,0.05) 5.6px,rgba(0,0,0,0.05) 5.9px),repeating-radial-gradient(circle at 50% 50%,transparent 0px,transparent 9.5px,rgba(0,0,0,0.04) 9.5px,rgba(0,0,0,0.04) 9.8px),repeating-radial-gradient(circle at 50% 50%,transparent 0px,transparent 14px,rgba(0,0,0,0.035) 14px,rgba(0,0,0,0.035) 14.4px),repeating-radial-gradient(circle at 50% 50%,transparent 0px,transparent 21px,rgba(0,0,0,0.03) 21px,rgba(0,0,0,0.03) 21.5px),radial-gradient(circle at 50% 50%,#1a1a1a 0%,#1e1e1e 100%);box-shadow:inset 0 0 1px rgba(255,255,255,0.012),0 3px 12px rgba(0,0,0,0.32),0 0 0 1px rgba(60,28,15,0.35)}\n .vinyl-mini::before{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:34%;height:34%;border-radius:50%;background:radial-gradient(circle at 50% 50%,var(--red-primary) 0%,var(--red-deep) 55%,var(--red-darker) 88%,#3a1003 100%);z-index:3;box-shadow:inset 0 1px 0 rgba(255,255,255,0.12),inset 0 -1px 2px rgba(0,0,0,0.35),0 0 0 0.6px rgba(255,255,255,0.06)}\n .vinyl-mini::after{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:7px;height:7px;border-radius:50%;background:#0a0a0a;z-index:4;box-shadow:inset 0 0 1px rgba(255,255,255,0.03),0 0 0 1px rgba(0,0,0,0.3)}\n .vinyl-mini .vinyl-shine{position:absolute;inset:0;border-radius:50%;pointer-events:none;z-index:2;background:linear-gradient(135deg,rgba(255,255,255,0.05) 0%,transparent 30%,transparent 55%,rgba(255,255,255,0.02) 70%,transparent 100%)}\n .lib-card{aspect-ratio:1;border-radius:10px;overflow:hidden;cursor:pointer;position:relative;background:var(--bg-cream);box-shadow:0 6px 22px rgba(0,0,0,0.16),0 1px 3px rgba(0,0,0,0.08);transition:transform .2s ease,box-shadow .2s ease}\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 .lib-card .card-cover{position:absolute;inset:0;overflow:hidden}.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 .lib-card .vinyl-peek{position:absolute;right:-24%;top:5%;width:62%;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 .lib-card .card-info{position:absolute;inset:auto 0 0 0;z-index:3;background:linear-gradient(to bottom,transparent 0%,rgba(20,17,15,0.55) 30%,rgba(16,13,11,0.88) 100%);padding:18px 10px 10px 10px;display:flex;flex-direction:column;border-top:0.5px solid rgba(227,59,13,0.22)}\n .lib-card .card-info .card-name{font-family:'Josefin Sans',sans-serif;font-size:11px;font-weight:600;letter-spacing:.05em;color:#f0e8e0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 1px 2px rgba(0,0,0,0.35)}\n .lib-card .card-info .card-count{font-size:9px;color:rgba(200,188,178,0.75);letter-spacing:.06em;margin-top:2px;text-shadow:0 1px 1px rgba(0,0,0,0.25)}\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)}@keyframes popIn{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}\n .lib-card .del-btn:active{transform:scale(.85)}\n .lib-card .drag-handle{position:absolute;top:6px;left:6px;z-index:8;color:rgba(255,255,255,0.75);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}.lib-card .drag-handle:active{cursor:grabbing;background:rgba(255,255,255,0.10)}\n .lib-card .cover-overlay-card{position:absolute;inset: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:fadeIn2 .2s ease}@keyframes fadeIn2{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 .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}.sub-view.visible-sub{transform:translateX(0);pointer-events:auto}\n .sub-header{display:flex;align-items:flex-start;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);cursor:pointer}\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;display:flex;flex-direction:column;gap:6px}\n .sub-info .lib-name{font-family:'Josefin Sans',sans-serif;font-size:15px;font-weight:600;letter-spacing:.05em;color:var(--text-primary);cursor:text;display:inline-block;outline:none;border-bottom:1px dashed transparent;transition:border-color .2s ease;padding:1px 2px;margin:-1px -2px;border-radius:3px;align-self:flex-start}\n .sub-info .lib-name:focus{background:rgba(227,59,13,0.04);border-bottom-color:rgba(227,59,13,0.30)}\n .sub-info .lib-name.locked-name{cursor:default;border-bottom:none;color:var(--text-primary);opacity:.85}\n .sub-info .lib-name.locked-name:focus{background:transparent;border-bottom-color:transparent}\n .btn-import-inline{display:inline-flex;align-items:center;gap:4px;padding:5px 10px;border-radius:5px;border:1px solid rgba(227,59,13,0.30);background:rgba(227,59,13,0.05);color:var(--red-primary);font-size:10px;letter-spacing:.04em;cursor:pointer;transition:all .2s ease;align-self:flex-start}\n .btn-import-inline:active{background:rgba(227,59,13,0.14)}\n .sub-info .lib-meta{font-size:10px;color:var(--red-primary);letter-spacing:.05em}\n .toolbar-row{display:flex;align-items:center;justify-content:space-between;padding:6px 16px 4px;flex-shrink:0;z-index:22;gap:8px}\n .search-inline-wrap{display:flex;align-items:center;gap:0;flex:1;min-width:0}\n .btn-search-toggle{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-muted);border:1px solid rgba(0,0,0,0.06);background:rgba(233,231,224,0.50);transition:all .2s ease;flex-shrink:0}\n .btn-search-toggle:active{background:rgba(227,59,13,0.08);color:var(--red-primary)}\n .search-input-inline{flex:1;min-width:0;height:30px;border-radius:16px;border:1px solid rgba(227,59,13,0.22);background:rgba(233,231,224,0.60);padding:0 10px;font-size:11px;font-family:'Josefin Sans',sans-serif;color:var(--text-primary);outline:none;transition:all .25s ease;display:none}\n .search-input-inline.show-input{display:block}.search-input-inline:focus{border-color:rgba(227,59,13,0.40)}\n .sort-dropdown-wrap{position:relative;flex-shrink:0}\n .sort-toggle{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:16px;font-size:11px;letter-spacing:.04em;color:var(--text-muted);background:rgba(233,231,224,0.55);border:1px solid rgba(0,0,0,0.06);cursor:pointer;transition:all .2s ease}\n .sort-toggle:active{background:rgba(227,59,13,0.06);color:var(--red-primary)}.sort-toggle i{font-size:10px}\n .sort-dropdown{position:absolute;top:100%;right:0;z-index:25;background:#f5f2ec;border-radius:8px;box-shadow:0 6px 22px rgba(0,0,0,0.14);min-width:155px;overflow:hidden;animation:slideUp2 .2s cubic-bezier(.34,1.56,.64,1);border:1px solid rgba(0,0,0,0.05);margin-top:4px}\n @keyframes slideUp2{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}\n .sort-dropdown .sort-opt{padding:10px 16px;font-size:11px;color:var(--text-primary);cursor:pointer;transition:all .15s ease;letter-spacing:.04em;display:flex;align-items:center;gap:8px}\n .sort-dropdown .sort-opt:active{background:rgba(227,59,13,0.06);color:var(--red-primary)}.sort-dropdown .sort-opt i{font-size:10px;width:16px;text-align:center}\n .btn-multiselect{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-muted);border:1px solid rgba(0,0,0,0.06);background:rgba(233,231,224,0.50);transition:all .2s ease;flex-shrink:0}\n .btn-multiselect:active{background:rgba(227,59,13,0.08);color:var(--red-primary)}\n .btn-multiselect.active-multi{background:rgba(227,59,13,0.14);color:var(--red-accent);border-color:rgba(227,59,13,0.30)}\n\n .song-checkbox{width:20px;height:20px;border-radius:50%;border:1.5px solid rgba(227,59,13,0.30);flex-shrink:0;display:none;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease;background:transparent}\n .song-checkbox.show-check{display:flex}.song-checkbox.checked{background:var(--red-primary);border-color:var(--red-primary)}\n .song-checkbox.checked::after{content:'';width:6px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg);margin-top:-2px}\n\n .sub-song-list{flex:1;overflow-y:auto;padding:4px 16px 12px 16px}\n .sub-song-list.no-scrollbar::-webkit-scrollbar{display:none}.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)}.song-row.hidden-row{display:none}\n .song-row .song-index{width:22px;text-align:right;font-size:9px;color:var(--text-muted);font-family:'Josefin Sans',sans-serif;flex-shrink:0;font-weight:400}\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:slideUp3 .2s cubic-bezier(.34,1.56,.64,1);border:1px solid rgba(0,0,0,0.06)}\n @keyframes slideUp3{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}.song-action-popup .action-item.danger{color:var(--red-primary)}\n\n .batch-delete-bar{position:absolute;bottom:0;left:0;right:0;z-index:25;background:#f5f1eb;padding:12px 16px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 -4px 16px rgba(0,0,0,0.12);transform:translateY(100%);transition:transform .3s cubic-bezier(.25,.46,.45,.94)}\n .batch-delete-bar.show-bar{transform:translateY(0)}\n .batch-delete-bar .batch-count{font-size:12px;color:var(--text-primary);letter-spacing:.04em}\n .batch-delete-bar .batch-count span{color:var(--red-primary);font-weight:600}\n .batch-delete-bar .btn-batch-del{padding:8px 18px;border-radius:20px;background:var(--red-primary);color:#fff;font-size:12px;letter-spacing:.05em;cursor:pointer;border:none;font-family:'Josefin Sans',sans-serif;transition:all .2s ease}\n .batch-delete-bar .btn-batch-del:active{transform:scale(.95);opacity:.85}\n\n .cover-modal-overlay{position:absolute;inset:0;z-index:55;background:rgba(0,0,0,0.60);display:flex;align-items:center;justify-content:center;transition:opacity .3s ease;pointer-events:auto}.cover-modal-overlay.hidden-modal{opacity:0;pointer-events:none}\n .cover-modal{background:#f5f1eb;border-radius:14px;padding:20px 18px;width:80%;max-width:320px;box-shadow:0 16px 48px rgba(0,0,0,0.35)}\n .cover-modal .modal-title{font-size:14px;font-weight:600;letter-spacing:.05em;color:var(--text-primary);margin-bottom:12px}\n .cover-modal .cover-preview{width:100%;aspect-ratio:1;border-radius:8px;overflow:hidden;margin-bottom:12px;background:#e0dbd2;border:1px solid rgba(0,0,0,0.08)}\n .cover-modal .cover-preview img{width:100%;height:100%;object-fit:cover;display:block}\n .cover-modal input{width:100%;padding:10px 12px;border-radius:8px;border:1px solid rgba(0,0,0,0.12);font-size:11px;font-family:'Josefin Sans',sans-serif;margin-bottom:10px;outline:none;background:#fff}.cover-modal input:focus{border-color:rgba(227,59,13,0.35)}\n .cover-modal .modal-actions{display:flex;gap:8px}.cover-modal .modal-btn{flex:1;padding:10px;border-radius:8px;font-size:12px;letter-spacing:.04em;cursor:pointer;text-align:center;font-family:'Josefin Sans',sans-serif;transition:all .2s ease}\n .modal-btn-cancel{background:#e0dbd2;color:var(--text-primary);border:none}.modal-btn-confirm{background:var(--red-primary);color:#fff;border:none}.modal-btn:active{transform:scale(.96);opacity:.85}\n\n .bottom-panel-overlay{position:absolute;inset:0;z-index:58;background:rgba(0,0,0,0.50);transition:opacity .3s ease;pointer-events:auto}.bottom-panel-overlay.hidden-modal{opacity:0;pointer-events:none}\n .bottom-panel{position:absolute;bottom:0;left:0;right:0;height:50%;z-index:59;background:#f5f1eb;border-radius:16px 16px 0 0;box-shadow:0 -8px 36px rgba(0,0,0,0.30);transition:transform .35s cubic-bezier(.25,.46,.45,.94);display:flex;flex-direction:column;padding:16px 16px 10px;overflow-y:auto}\n .bottom-panel.hidden-panel{transform:translateY(105%)}.bottom-panel.visible-panel{transform:translateY(0)}\n .bottom-panel .panel-handle{width:36px;height:4px;border-radius:2px;background:rgba(0,0,0,0.15);align-self:center;margin-bottom:12px}\n .bottom-panel .panel-title{font-family:'Josefin Sans',sans-serif;font-size:14px;font-weight:600;letter-spacing:.05em;color:var(--text-primary);margin-bottom:10px}\n .bottom-panel .field-label{font-size:9px;letter-spacing:.06em;color:var(--text-muted);margin-bottom:3px;text-transform:uppercase}\n .bottom-panel input{width:100%;padding:9px 10px;border-radius:7px;border:1px solid rgba(0,0,0,0.10);font-size:11px;font-family:'Josefin Sans',sans-serif;margin-bottom:10px;outline:none;background:#fff}.bottom-panel input:focus{border-color:rgba(227,59,13,0.35)}\n .bottom-panel .btn-file{display:flex;align-items:center;gap:8px;padding:9px 12px;border-radius:7px;border:1.5px dashed rgba(227,59,13,0.30);background:rgba(227,59,13,0.03);color:var(--red-primary);font-size:10px;cursor:pointer;margin-bottom:10px;transition:all .2s ease}.bottom-panel .btn-file:active{background:rgba(227,59,13,0.10)}\n .bottom-panel .btn-submit{padding:10px;border-radius:8px;background:var(--red-primary);color:#fff;text-align:center;font-size:12px;letter-spacing:.05em;cursor:pointer;font-family:'Josefin Sans',sans-serif;border:none}.bottom-panel .btn-submit:active{transform:scale(.97);opacity:.85}\n\n .stack-card-wrap{position:relative;height:170px;cursor:pointer}.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)}.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)}.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);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)}.rec-mini-card:active{transform:scale(.95)}\n .rec-mini-card img{width:100%;height:80px;object-fit:cover;display:block}.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 .search-bar{background:rgba(233,231,224,0.68);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}.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}.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)}.history-item:active{background:rgba(227,59,13,0.06)}\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)}.clear-history-btn:active{background:rgba(227,59,13,0.06)}\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)}.btn-manage.active-manage{background:rgba(227,59,13,0.14);border-color:rgba(227,59,13,0.45);color:var(--red-accent)}\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:10px;overflow:hidden;background:rgba(233,231,224,0.92);backdrop-filter:blur(8px);border:1px solid rgba(227,59,13,0.30)}\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);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)}.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 .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);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)}.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}@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);transition:opacity .35s ease;pointer-events:auto}.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);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%)}.sidebar-panel.visible-sidebar{transform:translateX(0)}\n .sidebar-section{border-bottom:0.5px solid rgba(255,255,255,0.05);padding:14px 18px}.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}.sidebar-item:active{color:var(--red-accent);background:rgba(255,255,255,0.04)}\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 .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}.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 .tab-panel{transition:opacity .4s ease,transform .4s ease}.tab-panel.hidden-panel{opacity:0;pointer-events:none;position:absolute;transform:translateY(6px)}.tab-panel.visible-panel{opacity:1;pointer-events:auto;position:relative;transform:translateY(0)}\n .no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{scrollbar-width:none;-ms-overflow-style:none}\n </style>\n</head>\n<body>\n <div class=\"app-root\">\n <div class=\"w-full flex items-center justify-between px-6 shrink-0 relative z-30\" style=\"height:34px;background:#1f1e1c\"><span class=\"text-[11px] text-[#b0a89e] font-['Josefin_Sans'] tracking-wide\">15:00</span><div class=\"flex items-center gap-1.5\"><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><span class=\"text-[10px] text-[#b0a89e]\">88%</span></div></div>\n <div class=\"w-full shrink-0 nav-top\"><div class=\"flex items-center justify-between px-5 py-2.5\"><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><button class=\"btn-account\" aria-label=\"账号\" onclick=\"openSidebar()\"><i class=\"fa-solid fa-music note-icon\"></i></button></div></div>\n\n <div class=\"relative flex-1 overflow-hidden\" style=\"min-height:0;z-index:15\">\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\"><div class=\"rec-mini-card\" onclick=\"openSubCollection('肖邦夜曲','陈奕迅')\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">肖邦夜曲全集</div></div><div class=\"rec-mini-card\" onclick=\"openSubCollection('巴赫平均律','周杰伦')\"><img src=\"/assets/images/education/education-1.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">巴赫平均律</div></div></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\"><div class=\"rec-mini-card\" onclick=\"openSubCollection('德彪西意象集','林俊杰')\"><img src=\"/assets/images/cases/porto2.jpg\" alt=\"\" loading=\"lazy\"><div class=\"rec-mini-label\">德彪西意象集</div></div><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><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></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 <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\"><div class=\"relative flex items-center gap-2\" id=\"search-wrapper\"><div class=\"search-bar\" id=\"search-bar\" onclick=\"toggleSearchHistory()\"><i class=\"fa-solid fa-magnifying-glass\"></i><span id=\"search-placeholder\">搜索曲谱…</span></div><div class=\"search-history-dropdown no-scrollbar hidden-dropdown\" id=\"search-dropdown\"><div id=\"history-list\"><div class=\"history-item\" onclick=\"selectHistory('贝多芬月光奏鸣曲')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>贝多芬月光奏鸣曲</span></div><div class=\"history-item\" onclick=\"selectHistory('莫扎特钢琴协奏曲')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>莫扎特钢琴协奏曲</span></div><div class=\"history-item\" onclick=\"selectHistory('肖邦夜曲全集')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>肖邦夜曲全集</span></div><div class=\"history-item\" onclick=\"selectHistory('巴赫平均律曲集')\"><i class=\"fa-solid fa-clock-rotate-left\"></i><span>巴赫平均律曲集</span></div></div><div class=\"clear-history-btn\" onclick=\"clearSearchHistory()\"><i class=\"fa-solid fa-trash-can\"></i><span>清除搜索历史</span></div></div><button class=\"btn-manage\" id=\"btn-manage\" onclick=\"toggleManageMode()\" aria-label=\"管理曲库\"><i class=\"fa-solid fa-pen-to-square\"></i></button></div></div>\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 <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 <div class=\"lib-card\" id=\"lib-mine\" data-lib=\"我的曲库\" data-locked=\"true\" data-cover=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" onclick=\"handleLibCardClick(this)\"><div class=\"card-cover\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\"></div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">我的曲库</div><div class=\"card-count\">5 首曲目</div></div></div>\n <div class=\"lib-card\" id=\"lib-1\" data-lib=\"古典奏鸣曲集\" data-locked=\"false\" data-cover=\"/assets/images/business/business-25.jpg\" onclick=\"handleLibCardClick(this)\"><div class=\"drag-handle\">⠿</div><div class=\"del-btn\" id=\"del-1\" onclick=\"event.stopPropagation();deleteLib('lib-1')\"><i class=\"fa-solid fa-xmark\"></i></div><div class=\"cover-overlay-card\" id=\"cover-overlay-1\" onclick=\"event.stopPropagation();changeCover('1')\"><i class=\"fa-solid fa-camera\"></i></div><div class=\"card-cover\"><img src=\"/assets/images/business/business-25.jpg\" alt=\"\" id=\"cover-img-1\"></div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">古典奏鸣曲集</div><div class=\"card-count\">0 首曲目</div></div></div>\n <div class=\"lib-card\" id=\"lib-2\" data-lib=\"浪漫钢琴选\" data-locked=\"false\" data-cover=\"/assets/images/fashion-lifestyle/fashion-lifestyle-4.jpg\" onclick=\"handleLibCardClick(this)\"><div class=\"drag-handle\">⠿</div><div class=\"del-btn\" id=\"del-2\" onclick=\"event.stopPropagation();deleteLib('lib-2')\"><i class=\"fa-solid fa-xmark\"></i></div><div class=\"cover-overlay-card\" id=\"cover-overlay-2\" onclick=\"event.stopPropagation();changeCover('2')\"><i class=\"fa-solid fa-camera\"></i></div><div class=\"card-cover\"><img src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-4.jpg\" alt=\"\" id=\"cover-img-2\"></div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">浪漫钢琴选</div><div class=\"card-count\">0 首曲目</div></div></div>\n <div class=\"lib-card\" id=\"lib-3\" data-lib=\"交响乐珍藏\" data-locked=\"false\" data-cover=\"/assets/images/cases/porto2.jpg\" onclick=\"handleLibCardClick(this)\"><div class=\"drag-handle\">⠿</div><div class=\"del-btn\" id=\"del-3\" onclick=\"event.stopPropagation();deleteLib('lib-3')\"><i class=\"fa-solid fa-xmark\"></i></div><div class=\"cover-overlay-card\" id=\"cover-overlay-3\" onclick=\"event.stopPropagation();changeCover('3')\"><i class=\"fa-solid fa-camera\"></i></div><div class=\"card-cover\"><img src=\"/assets/images/cases/porto2.jpg\" alt=\"\" id=\"cover-img-3\"></div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">交响乐珍藏</div><div class=\"card-count\">0 首曲目</div></div></div>\n <div class=\"lib-card\" id=\"lib-4\" data-lib=\"巴洛克精选\" data-locked=\"false\" data-cover=\"/assets/images/16-9/business-03.jpg\" onclick=\"handleLibCardClick(this)\"><div class=\"drag-handle\">⠿</div><div class=\"del-btn\" id=\"del-4\" onclick=\"event.stopPropagation();deleteLib('lib-4')\"><i class=\"fa-solid fa-xmark\"></i></div><div class=\"cover-overlay-card\" id=\"cover-overlay-4\" onclick=\"event.stopPropagation();changeCover('4')\"><i class=\"fa-solid fa-camera\"></i></div><div class=\"card-cover\"><img src=\"/assets/images/16-9/business-03.jpg\" alt=\"\" id=\"cover-img-4\"></div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">巴洛克精选</div><div class=\"card-count\">0 首曲目</div></div></div>\n <div class=\"lib-card\" id=\"lib-5\" data-lib=\"现代作品集\" data-locked=\"false\" data-cover=\"/assets/images/education/education-1.jpg\" onclick=\"handleLibCardClick(this)\"><div class=\"drag-handle\">⠿</div><div class=\"del-btn\" id=\"del-5\" onclick=\"event.stopPropagation();deleteLib('lib-5')\"><i class=\"fa-solid fa-xmark\"></i></div><div class=\"cover-overlay-card\" id=\"cover-overlay-5\" onclick=\"event.stopPropagation();changeCover('5')\"><i class=\"fa-solid fa-camera\"></i></div><div class=\"card-cover\"><img src=\"/assets/images/education/education-1.jpg\" alt=\"\" id=\"cover-img-5\"></div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">现代作品集</div><div class=\"card-count\">0 首曲目</div></div></div>\n </div>\n <div class=\"btn-add-lib mt-3 mb-2\" onclick=\"openCreateLibPanel()\"><i class=\"fa-solid fa-plus text-[11px]\"></i><span>新增曲库</span></div>\n </div>\n </div>\n\n <div id=\"sub-collection-view\" class=\"sub-view hidden-sub\" style=\"position:relative\">\n <div class=\"flex items-center gap-2 px-4 pt-3 pb-1 z-10\"><button class=\"btn-back\" onclick=\"closeSubCollection()\" aria-label=\"返回\"><i class=\"fa-solid fa-arrow-left text-[11px]\"></i></button><div class=\"w-5 h-[1px] bg-[#e33b0d] opacity-35\"></div><span class=\"text-[9px] tracking-[0.12em] text-[#8b7670] font-['Josefin_Sans'] font-light uppercase\">shorthand of emotion</span><div class=\"flex-1 h-[1px] bg-[#e33b0d] opacity-18\"></div></div>\n <div class=\"sub-header\"><div class=\"sub-cover-wrap\" onclick=\"event.stopPropagation();openCoverModal()\"><img id=\"sub-cover-img\" src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\"><div class=\"vinyl-peek-sub\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div></div><div class=\"sub-info\"><div class=\"lib-name\" id=\"sub-lib-name\" contenteditable=\"true\" onfocus=\"this._prev=this.textContent\" onblur=\"saveLibName(this)\" onkeydown=\"if(event.key==='Enter'){this.blur();event.preventDefault()}\">我的曲库</div><button class=\"btn-import-inline\" onclick=\"event.stopPropagation();openImportPanel()\"><i class=\"fa-solid fa-plus text-[9px]\"></i> 导入曲谱</button><div class=\"lib-meta\" id=\"sub-lib-meta\">共 5 首曲目</div></div></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=\"toolbar-row\">\n <div class=\"search-inline-wrap\"><button class=\"btn-search-toggle\" id=\"btn-search-toggle\" onclick=\"toggleInlineSearch()\"><i class=\"fa-solid fa-magnifying-glass\" style=\"font-size:11px\"></i></button><input class=\"search-input-inline\" id=\"search-input-inline\" type=\"text\" placeholder=\"搜索标题/作者…\" oninput=\"filterSongRows()\"></div>\n <button class=\"btn-multiselect\" id=\"btn-multiselect\" onclick=\"toggleMultiSelect()\" aria-label=\"多选\"><i class=\"fa-solid fa-check-double\" style=\"font-size:12px\"></i></button>\n <div class=\"sort-dropdown-wrap\"><div class=\"sort-toggle\" id=\"sort-toggle\" onclick=\"event.stopPropagation();toggleSortDropdown()\"><i class=\"fa-solid fa-arrow-down-wide-short\"></i><span id=\"sort-label\">名称正序</span><i class=\"fa-solid fa-chevron-down\" style=\"font-size:8px\"></i></div></div>\n </div>\n <div class=\"sub-song-list no-scrollbar\" id=\"sub-song-list\"></div>\n <div class=\"batch-delete-bar\" id=\"batch-delete-bar\"><div class=\"batch-count\">已选 <span id=\"batch-count-num\">0</span> 首曲目</div><button class=\"btn-batch-del\" onclick=\"batchDelete()\">删除已选</button></div>\n </div>\n\n <div id=\"cover-modal\" class=\"cover-modal-overlay hidden-modal\" onclick=\"closeCoverModal(event)\"><div class=\"cover-modal\" onclick=\"event.stopPropagation()\"><div class=\"modal-title\">更换封面图片</div><div class=\"cover-preview\"><img id=\"cover-preview-img\" src=\"/assets/images/fashion-lifestyle/fashion-lifestyle-15.jpg\" alt=\"\"></div><input type=\"text\" id=\"cover-url-input\" placeholder=\"输入图片URL地址…\"><div class=\"modal-actions\"><button class=\"modal-btn modal-btn-cancel\" onclick=\"closeCoverModal()\">取消</button><button class=\"modal-btn modal-btn-confirm\" onclick=\"confirmCoverChange()\">确认更换</button></div></div></div>\n\n <div id=\"import-panel-overlay\" class=\"bottom-panel-overlay hidden-modal\" onclick=\"closeImportPanel()\"></div>\n <div id=\"import-panel\" class=\"bottom-panel hidden-panel\"><div class=\"panel-handle\"></div><div class=\"panel-title\">导入曲谱</div><span class=\"field-label\">曲谱名称</span><input type=\"text\" id=\"import-name\" placeholder=\"请输入曲谱名称\"><span class=\"field-label\">作者</span><input type=\"text\" id=\"import-author\" placeholder=\"未知\" value=\"未知\"><div class=\"btn-file\" onclick=\"alert('选择文件(模拟)')\"><i class=\"fa-regular fa-file-lines\"></i> 选择曲谱文件</div><button class=\"btn-submit\" onclick=\"confirmImport()\">确认导入</button></div>\n\n <div id=\"create-lib-overlay\" class=\"bottom-panel-overlay hidden-modal\" onclick=\"closeCreateLibPanel()\"></div>\n <div id=\"create-lib-panel\" class=\"bottom-panel hidden-panel\"><div class=\"panel-handle\"></div><div class=\"panel-title\">新增曲库</div><span class=\"field-label\">曲库名称</span><input type=\"text\" id=\"create-lib-name\" placeholder=\"请输入曲库名称\"><span class=\"field-label\">封面图片(留空使用默认)</span><input type=\"text\" id=\"create-lib-cover\" placeholder=\"输入图片URL或留空…\"><button class=\"btn-submit\" onclick=\"confirmCreateLib()\">确认新增</button></div>\n </div>\n\n <div class=\"w-full shrink-0 bottom-nav-container\"><div class=\"flex items-center justify-center gap-20 relative\" style=\"height:42px\"><button class=\"nav-item active\" id=\"nav-home\" onclick=\"switchTab(0)\"><i class=\"fa-solid fa-house\"></i><span>首页</span></button><button class=\"nav-item\" id=\"nav-library\" onclick=\"switchTab(1)\"><i class=\"fa-solid fa-compact-disc\"></i><span>曲库</span></button></div></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\"><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><p class=\"text-[15px] font-['Josefin_Sans'] font-semibold tracking-wider\" style=\"color:var(--text-on-dark)\">Vintage Musician</p><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></div>\n <div class=\"sidebar-section\"><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><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></div>\n <div class=\"sidebar-section\" style=\"border-bottom:none\"><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><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><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><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></div>\n <div class=\"sidebar-section\" style=\"border-bottom:none;margin-top:auto;padding-bottom:20px\"><div class=\"sidebar-item\" style=\"color:var(--red-primary)\"><i class=\"fa-solid fa-arrow-right-from-bracket\"></i><span>退出登录</span></div></div>\n </div>\n </div>\n\n <script>\n const libDataMap = new Map();\n function initLibData(){libDataMap.set('lib-mine',[{title:'晴天',artist:'周杰伦'},{title:'十年',artist:'陈奕迅'},{title:'修炼爱情',artist:'林俊杰'},{title:'光年之外',artist:'邓紫棋'},{title:'突然好想你',artist:'五月天'}]);['lib-1','lib-2','lib-3','lib-4','lib-5'].forEach(id=>{libDataMap.set(id,[])});}\n function getLibData(libId){if(!libDataMap.has(libId))libDataMap.set(libId,[]);return libDataMap.get(libId)}\n initLibData();\n\n let manageMode=false;let dragCard=null,dragGhost=null,dragStartX=0,dragStartY=0,dragOrigRect=null;\n let currentOpenLibId=null;let multiSelectMode=false;\n\n function switchTab(i){const p=[document.getElementById('tab-panel-0'),document.getElementById('tab-panel-1')],n=[document.getElementById('nav-home'),document.getElementById('nav-library')];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.forEach((e,x)=>{if(e){if(x===i)e.classList.add('active');else e.classList.remove('active')}});closeSubCollection();exitManageMode();closeSearchHistory()}\n\n function handleLibCardClick(cardEl){if(manageMode)return;const name=cardEl.getAttribute('data-lib')||'曲库';const cover=cardEl.getAttribute('data-cover')||'';const coverImg=cardEl.querySelector('.card-cover img');const coverSrc=coverImg?coverImg.src:cover;openSubCollection(name,coverSrc,cardEl)}\n function openSubCollection(title,coverSrc,cardEl){if(manageMode&&cardEl)return;const sv=document.getElementById('sub-collection-view');const nameEl=document.getElementById('sub-lib-name');const coverImg=document.getElementById('sub-cover-img');nameEl.textContent=title||'曲库';if(coverSrc){coverImg.src=coverSrc};hideInlineSearch();exitMultiSelect();if(cardEl){currentOpenLibId=cardEl.id;nameEl.setAttribute('contenteditable',cardEl.getAttribute('data-locked')==='true'?'false':'true');if(cardEl.getAttribute('data-locked')==='true'){nameEl.classList.add('locked-name')}else{nameEl.classList.remove('locked-name')}}else{currentOpenLibId=null;nameEl.setAttribute('contenteditable','true');nameEl.classList.remove('locked-name')};sv.classList.remove('hidden-sub');sv.classList.add('visible-sub');if(cardEl){syncCardToSub(cardEl)};renderSongList()}\n function syncCardToSub(cardEl){const coverImg=document.getElementById('sub-cover-img');const cardCover=cardEl.querySelector('.card-cover img');if(cardCover){coverImg.src=cardCover.src};document.getElementById('sub-lib-name').textContent=cardEl.getAttribute('data-lib')||'曲库'}\n function syncSubToCard(){if(!currentOpenLibId)return;const card=document.getElementById(currentOpenLibId);if(!card)return;const name=document.getElementById('sub-lib-name').textContent.trim();const cover=document.getElementById('sub-cover-img').src;card.setAttribute('data-lib',name);card.setAttribute('data-cover',cover);const cn=card.querySelector('.card-name');if(cn)cn.textContent=name;const cc=card.querySelector('.card-cover img');if(cc)cc.src=cover;const list=getLibData(currentOpenLibId);const ccount=card.querySelector('.card-count');if(ccount)ccount.textContent=list.length+' 首曲目'}\n\n function renderSongList(){\n const listEl=document.getElementById('sub-song-list');listEl.innerHTML='';\n if(!currentOpenLibId){updateTrackCount();return}\n const list=getLibData(currentOpenLibId);\n list.forEach((item,i)=>{const row=document.createElement('div');row.className='song-row';row.setAttribute('data-title',item.title);row.setAttribute('data-time',String(i+1));row.innerHTML=`<div class=\"song-checkbox\" onclick=\"event.stopPropagation();toggleCheck(this)\"></div><span class=\"song-index\">${i+1}</span><div class=\"song-body\"><div class=\"song-title\">${item.title}</div><div class=\"song-artist\">${item.artist}</div></div><div class=\"song-more-btn\" onclick=\"event.stopPropagation();toggleSongPopup(event)\">···</div>`;listEl.appendChild(row)});\n if(multiSelectMode){document.querySelectorAll('#sub-song-list .song-checkbox').forEach(cb=>cb.classList.add('show-check'));updateBatchBar()}\n updateTrackCount()\n }\n\n function closeSubCollection(){const sv=document.getElementById('sub-collection-view');sv.classList.remove('visible-sub');sv.classList.add('hidden-sub');closeAllPopups();closeSortDropdown();hideInlineSearch();closeCoverModal();closeImportPanel();closeCreateLibPanel();exitMultiSelect();currentOpenLibId=null}\n\n function toggleManageMode(){manageMode=!manageMode;const btn=document.getElementById('btn-manage');if(manageMode){btn.classList.add('active-manage');document.querySelectorAll('.lib-card[data-locked=\"false\"] .del-btn').forEach(b=>b.classList.add('show-del'));document.querySelectorAll('.lib-card[data-locked=\"false\"] .drag-handle').forEach(b=>b.classList.add('show-handle'));document.querySelectorAll('.lib-card[data-locked=\"false\"] .cover-overlay-card').forEach(b=>b.classList.add('show-cover'))}else{exitManageMode()}}\n function exitManageMode(){manageMode=false;document.getElementById('btn-manage').classList.remove('active-manage');document.querySelectorAll('.del-btn').forEach(b=>b.classList.remove('show-del'));document.querySelectorAll('.drag-handle').forEach(b=>b.classList.remove('show-handle'));document.querySelectorAll('.cover-overlay-card').forEach(b=>b.classList.remove('show-cover'));cleanupDrag()}\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);libDataMap.delete(id)}}\n function changeCover(libId){const url=prompt('请输入封面图片URL(留空恢复默认):');const img=document.getElementById('cover-img-'+libId);if(!img)return;if(url&&url.trim()){img.src=url.trim()}else{const def=document.getElementById('lib-'+libId)?.getAttribute('data-cover');img.src=def||''}}\n\n function openCreateLibPanel(){document.getElementById('create-lib-overlay').classList.remove('hidden-modal');document.getElementById('create-lib-panel').classList.remove('hidden-panel');document.getElementById('create-lib-panel').classList.add('visible-panel');document.getElementById('create-lib-name').value='';document.getElementById('create-lib-cover').value='';setTimeout(()=>document.getElementById('create-lib-name').focus(),400)}\n function closeCreateLibPanel(){document.getElementById('create-lib-overlay').classList.add('hidden-modal');document.getElementById('create-lib-panel').classList.add('hidden-panel');document.getElementById('create-lib-panel').classList.remove('visible-panel')}\n function confirmCreateLib(){const name=document.getElementById('create-lib-name').value.trim();if(!name){alert('请输入曲库名称');return};const cover=document.getElementById('create-lib-cover').value.trim();const grid=document.getElementById('lib-grid');const newId='lib-'+Date.now();libDataMap.set(newId,[]);const div=document.createElement('div');div.className='lib-card';div.id=newId;div.setAttribute('data-lib',name);div.setAttribute('data-locked','false');div.setAttribute('data-cover',cover);div.setAttribute('onclick','handleLibCardClick(this)');const coverHTML=cover?`<img src=\"${cover}\" alt=\"\">`:'<div class=\"cover-placeholder\"></div>';div.innerHTML=`<div class=\"drag-handle\">⠿</div><div class=\"del-btn\" id=\"del-${newId}\" onclick=\"event.stopPropagation();deleteLib('${newId}')\"><i class=\"fa-solid fa-xmark\"></i></div><div class=\"cover-overlay-card\" id=\"cover-overlay-${newId}\" onclick=\"event.stopPropagation();changeCover('${newId}')\"><i class=\"fa-solid fa-camera\"></i></div><div class=\"card-cover\">${coverHTML}</div><div class=\"vinyl-peek\"><div class=\"vinyl-mini\"><div class=\"vinyl-shine\"></div></div></div><div class=\"card-info\"><div class=\"card-name\">${name}</div><div class=\"card-count\">0 首曲目</div></div>`;grid.appendChild(div);bindDragEvents(div);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')};closeCreateLibPanel()}\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 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 function onDragStart(e){if(!manageMode)return;e.preventDefault();const h=e.target.closest('.drag-handle');if(!h||!h.classList.contains('show-handle'))return;dragCard=h.closest('.lib-card');if(!dragCard||dragCard.getAttribute('data-locked')==='true'){dragCard=null;return};hideAllDelButtons();const t=e.touches?e.touches[0]:e;dragStartX=t.clientX;dragStartY=t.clientY;dragOrigRect=dragCard.getBoundingClientRect();dragGhost=dragCard.cloneNode(true);const gd=dragGhost.querySelector('.del-btn');if(gd)gd.classList.remove('show-del');const gh=dragGhost.querySelector('.drag-handle');if(gh)gh.classList.remove('show-handle');const gc=dragGhost.querySelector('.cover-overlay-card');if(gc)gc.classList.remove('show-cover');dragGhost.classList.add('drag-ghost');dragGhost.style.width=dragOrigRect.width+'px';dragGhost.style.height=dragOrigRect.height+'px';dragGhost.style.left=dragOrigRect.left+'px';dragGhost.style.top=dragOrigRect.top+'px';document.body.appendChild(dragGhost);dragCard.classList.add('dragging');document.addEventListener('touchmove',onDragMove,{passive:false});document.addEventListener('touchend',onDragEnd);document.addEventListener('mousemove',onDragMove);document.addEventListener('mouseup',onDragEnd)}\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){document.removeEventListener('touchmove',onDragMove);document.removeEventListener('touchend',onDragEnd);document.removeEventListener('mousemove',onDragMove);document.removeEventListener('mouseup',onDragEnd);if(!dragCard||!dragGhost){cleanupDrag();return};const gr=dragGhost.getBoundingClientRect();const gcx=gr.left+gr.width/2,gcy=gr.top+gr.height/2;const grid=document.getElementById('lib-grid');const cards=Array.from(grid.querySelectorAll('.lib-card')).filter(c=>c!==dragCard);let target=null,min=Infinity;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}});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)};cleanupDrag()}\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 openCoverModal(){document.getElementById('cover-modal').classList.remove('hidden-modal');document.getElementById('cover-url-input').value='';const img=document.getElementById('sub-cover-img');document.getElementById('cover-preview-img').src=img?.src||''}\n function closeCoverModal(e){if(e&&e.target!==document.getElementById('cover-modal'))return;document.getElementById('cover-modal').classList.add('hidden-modal')}\n function confirmCoverChange(){const url=document.getElementById('cover-url-input').value.trim();const img=document.getElementById('sub-cover-img');const preview=document.getElementById('cover-preview-img');if(url){img.src=url;preview.src=url};closeCoverModal();syncSubToCard()}\n\n function openImportPanel(){document.getElementById('import-panel-overlay').classList.remove('hidden-modal');document.getElementById('import-panel').classList.remove('hidden-panel');document.getElementById('import-panel').classList.add('visible-panel')}\n function closeImportPanel(){document.getElementById('import-panel-overlay').classList.add('hidden-modal');document.getElementById('import-panel').classList.add('hidden-panel');document.getElementById('import-panel').classList.remove('visible-panel')}\n function confirmImport(){if(!currentOpenLibId)return;const name=document.getElementById('import-name').value.trim();if(!name){alert('请输入曲谱名称');return};const author=document.getElementById('import-author').value.trim()||'未知';const list=getLibData(currentOpenLibId);list.push({title:name,artist:author});renderSongList();closeImportPanel();syncSubToCard();document.getElementById('import-name').value='';document.getElementById('import-author').value='未知'}\n\n function saveLibName(el){const v=el.textContent.trim();if(!v){el.textContent=el._prev||'未命名曲库'};if(currentOpenLibId&&el.getAttribute('contenteditable')!=='false'){syncSubToCard()}el.scrollLeft=0}\n\n function updateTrackCount(){const listEl=document.getElementById('sub-song-list');const n=listEl.querySelectorAll('.song-row').length;document.getElementById('sub-lib-meta').textContent='共 '+n+' 首曲目';if(currentOpenLibId){const card=document.getElementById(currentOpenLibId);if(card){const cn=card.querySelector('.card-count');if(cn)cn.textContent=n+' 首曲目'}}}\n function renumberSongs(){const listEl=document.getElementById('sub-song-list');const rows=listEl.querySelectorAll('.song-row');rows.forEach((r,i)=>{const idx=r.querySelector('.song-index');if(idx)idx.textContent=i+1;r.setAttribute('data-time',String(i+1))});if(currentOpenLibId){const list=getLibData(currentOpenLibId);const newList=[];rows.forEach(r=>{newList.push({title:r.getAttribute('data-title'),artist:r.querySelector('.song-artist')?.textContent||'未知'})});libDataMap.set(currentOpenLibId,newList)}}\n\n function pinTrack(row){const listEl=document.getElementById('sub-song-list');listEl.insertBefore(row,listEl.firstChild);renumberSongs();updateTrackCount()}\n function deleteTrack(row){row.style.opacity='0';row.style.transform='translateX(20px)';row.style.transition='all .25s ease';setTimeout(()=>{row.remove();renumberSongs();updateTrackCount()},250)}\n function shareTrack(){alert('分享功能(模拟)')}\n\n function toggleMultiSelect(){multiSelectMode=!multiSelectMode;const btn=document.getElementById('btn-multiselect');const cbs=document.querySelectorAll('#sub-song-list .song-checkbox');if(multiSelectMode){btn.classList.add('active-multi');cbs.forEach(cb=>{cb.classList.add('show-check');cb.classList.remove('checked')});updateBatchBar()}else{btn.classList.remove('active-multi');cbs.forEach(cb=>{cb.classList.remove('show-check','checked')});document.getElementById('batch-delete-bar').classList.remove('show-bar')}}\n function exitMultiSelect(){multiSelectMode=false;const btn=document.getElementById('btn-multiselect');if(btn)btn.classList.remove('active-multi');document.querySelectorAll('#sub-song-list .song-checkbox').forEach(cb=>cb.classList.remove('show-check','checked'));const bar=document.getElementById('batch-delete-bar');if(bar)bar.classList.remove('show-bar')}\n function toggleCheck(cb){if(!multiSelectMode)return;cb.classList.toggle('checked');updateBatchBar()}\n function updateBatchBar(){const checked=document.querySelectorAll('#sub-song-list .song-checkbox.checked').length;document.getElementById('batch-count-num').textContent=checked;const bar=document.getElementById('batch-delete-bar');if(checked>0){bar.classList.add('show-bar')}else{bar.classList.remove('show-bar')}}\n function batchDelete(){const checked=document.querySelectorAll('#sub-song-list .song-checkbox.checked');const rows=[];checked.forEach(cb=>{const row=cb.closest('.song-row');if(row)rows.push(row)});rows.forEach(r=>{r.style.opacity='0';r.style.transform='translateX(20px)';r.style.transition='all .25s ease'});setTimeout(()=>{rows.forEach(r=>r.remove());renumberSongs();updateTrackCount();exitMultiSelect()},250)}\n\n function toggleSortDropdown(){const existing=document.querySelector('.sort-dropdown');if(existing){existing.remove();return}closeAllPopups();const wrap=document.querySelector('.sort-dropdown-wrap');const dd=document.createElement('div');dd.className='sort-dropdown';dd.innerHTML=`<div class=\"sort-opt\" onclick=\"applySort('名称正序','title','asc')\"><i class=\"fa-solid fa-arrow-up-a-z\"></i>名称正序</div><div class=\"sort-opt\" onclick=\"applySort('名称倒序','title','desc')\"><i class=\"fa-solid fa-arrow-down-z-a\"></i>名称倒序</div><div class=\"sort-opt\" onclick=\"applySort('时间正序','time','asc')\"><i class=\"fa-regular fa-clock\"></i>时间正序</div><div class=\"sort-opt\" onclick=\"applySort('时间倒序','time','desc')\"><i class=\"fa-regular fa-clock\"></i>时间倒序</div>`;wrap.appendChild(dd);setTimeout(()=>document.addEventListener('click',function f(e){if(!e.target.closest('.sort-dropdown-wrap')){dd.remove();document.removeEventListener('click',f)}},{once:false}),10)}\n function closeSortDropdown(){const d=document.querySelector('.sort-dropdown');if(d)d.remove()}\n function applySort(label,key,dir){document.getElementById('sort-label').textContent=label;if(!currentOpenLibId)return;const list=getLibData(currentOpenLibId);list.sort((a,b)=>{const va=(a[key]||'').toLowerCase();const vb=(b[key]||'').toLowerCase();if(key==='time'){return dir==='asc'?parseInt(va)-parseInt(vb):parseInt(vb)-parseInt(va)}return dir==='asc'?va.localeCompare(vb,'zh'):vb.localeCompare(va,'zh')});renderSongList();closeSortDropdown()}\n\n function toggleInlineSearch(){const inp=document.getElementById('search-input-inline');const btn=document.getElementById('btn-search-toggle');if(inp.classList.contains('show-input')){hideInlineSearch()}else{inp.classList.add('show-input');inp.focus();btn.style.background='rgba(227,59,13,0.10)';btn.style.color='var(--red-primary)'}}\n function hideInlineSearch(){const inp=document.getElementById('search-input-inline');const btn=document.getElementById('btn-search-toggle');inp.classList.remove('show-input');inp.value='';btn.style.background='';btn.style.color='';filterSongRows()}\n function filterSongRows(){const q=document.getElementById('search-input-inline').value.trim().toLowerCase();document.querySelectorAll('#sub-song-list .song-row').forEach(r=>{const title=(r.querySelector('.song-title')?.textContent||'').toLowerCase();const artist=(r.querySelector('.song-artist')?.textContent||'').toLowerCase();if(!q||title.includes(q)||artist.includes(q)){r.classList.remove('hidden-row')}else{r.classList.add('hidden-row')}})}\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();closeSortDropdown();const row=btn.closest('.song-row');\n const popup=document.createElement('div');popup.className='song-action-popup';\n popup.innerHTML=`<div class=\"action-item\" onclick=\"event.stopPropagation();pinTrack(this.closest('.song-row'));closeAllPopups();\"><i class=\"fa-solid fa-thumbtack\"></i><span>置顶</span></div><div class=\"action-item\" onclick=\"event.stopPropagation();shareTrack();closeAllPopups();\"><i class=\"fa-solid fa-share-nodes\"></i><span>分享</span></div><div class=\"action-item danger\" onclick=\"event.stopPropagation();deleteTrack(this.closest('.song-row'));closeAllPopups();\"><i class=\"fa-regular fa-trash-can\"></i><span>删除</span></div>`;\n btn.parentElement.appendChild(popup);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',()=>{document.querySelectorAll('.lib-card[data-locked=\"false\"]').forEach(bindDragEvents);document.getElementById('tab-panel-1').addEventListener('click',function(e){if(!e.target.closest('#search-wrapper'))closeSearchHistory()})});\n </script>\n</body>\n</html>"
},
"next": [
"多选全选按钮",
"拖拽排序与多选并存",
"曲库重复名称校验",
"封面URL实时预览",
"装饰艺术细节深化"
],
"breakpoint": "xs"
}
```
推理
The user wants several specific changes:
1. **"新增曲库" button opens a bottom panel** (like the import panel) with fields for cover image URL and library name. Default image if none provided.
2. **Multi-select button in the library** - a toggle button that enables batch delete mode. When active, checkboxes appear next to each track row, and a "delete selected" button appears somewhere (probably in toolbar).
3. **Delete option moved to the bottom** of the song action popup (below share).
4. **Search supports author name** - the inline search should filter by both title and artist.
5. **Search placeholder hint** - add hint text mentioning it searches title and author.
Let me implement these changes carefully.
For the "新增曲库" panel, I'll reuse the import panel pattern but with different fields (cover URL + name).
For multi-select: I'll add a toggle button in the toolbar row (next to search and sort). When active:
- Each song-row shows a checkbox on the left
- A "delete selected" bar appears at the bottom
- The action popup on individual rows still works
Let me build this step by step.
1. **"新增曲库" button opens a bottom panel** (like the import panel) with fields for cover image URL and library name. Default image if none provided.
2. **Multi-select button in the library** - a toggle button that enables batch delete mode. When active, checkboxes appear next to each track row, and a "delete selected" button appears somewhere (probably in toolbar).
3. **Delete option moved to the bottom** of the song action popup (below share).
4. **Search supports author name** - the inline search should filter by both title and artist.
5. **Search placeholder hint** - add hint text mentioning it searches title and author.
Let me implement these changes carefully.
For the "新增曲库" panel, I'll reuse the import panel pattern but with different fields (cover URL + name).
For multi-select: I'll add a toggle button in the toolbar row (next to search and sort). When active:
- Each song-row shows a checkbox on the left
- A "delete selected" bar appears at the bottom
- The action popup on individual rows still works
Let me build this step by step.
角色
assistant
content
total_tokens
598549
summary
四项精确修改:①「新增曲库」改为底部50%高度面板,含封面URL(留空默认灰色)+曲库名称输入+确认按钮;②曲库工具栏新增多选切换按钮,激活后每行左侧出现圆形复选框,底部浮现红色「删除已选(N)」浮动条,点选计数实时更新;③曲目操作弹窗删除项移至最底部(分享之上);④曲目搜索支持标题+作者双字段匹配,placeholder改为「搜索标题/作者…」。
uiParsing
关闭