diff --git a/SHA256SUMS b/SHA256SUMS
index c3209fd..37b1cc6 100644
--- a/SHA256SUMS
+++ b/SHA256SUMS
@@ -138,9 +138,9 @@ d7d55b06ead173b4c23a277fa39800cadfc18f1163c500e8617cfc1f4ee0dea9 pigway_frame_f
1f77efa9acfb40872593e3b7c475d972b960cb9f21e9afb936add03c3f2dd542 pigway_frame_flow/web/features.js
a07ea444ab4ac75ea11e1188a431b48195353b1e08f7e80f3b931e8097ea6221 pigway_frame_flow/web/i18n.js
25f975a560aab00b57c5527a674d52bc45bd6c4b42e6169f1db406f2040f2177 pigway_frame_flow/web/index.html
-bf169d39b82c3da7ed2a8a22d0bd202abc205040e257dc7a4c259c294f18d63d pigway_frame_flow/web/libraries.js
+6128df031931bea57c6fa6107c534872b5d866f24ce8f901fd2a870c82bda674 pigway_frame_flow/web/libraries.js
0fa494a3fbd456c754bbea3f7f050be139e32e3b42b09a1ed953094087437210 pigway_frame_flow/web/logo-symbol.svg
-33cd5850a556479ca9ef2a97614cac74032ac020108a54348223f36258057127 pigway_frame_flow/web/style.css
+86ecbf86eb41a7a46b4878cbac679f83dc3de0ee6687bcc7779140689f0b5ec3 pigway_frame_flow/web/style.css
cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 pigway_frame_flow/web/swagger-LICENSE
050bc415ee7048dcd881682678f720264e7da5e373f7461d7c58c755305255f7 pigway_frame_flow/web/swagger-ui-bundle.js
1ac324f7dcd27e4b9386b4bd6421271ec147e922a22c05ba24b11515e9aa6321 pigway_frame_flow/web/swagger-ui.css
diff --git a/pigway_frame_flow/web/libraries.js b/pigway_frame_flow/web/libraries.js
index bebf12a..f97a7df 100644
--- a/pigway_frame_flow/web/libraries.js
+++ b/pigway_frame_flow/web/libraries.js
@@ -33,10 +33,10 @@ async function sourceLibraryPage(epoch,sources,terminals){
if(epoch!==state.epoch)return;
if(libraryUI.plan&&!plans.some(p=>p.id===libraryUI.plan))libraryUI.plan=null;
const plan=plans.find(p=>p.id===libraryUI.plan),uses=terminals.filter(t=>t.binding?.source_id===sourceId&&(!plan||t.binding.plan_id===plan.id));
- panel.innerHTML=`${tr('源画面先保存到本地;同一张照片按不同方案生成版本,多个终端可共用一份版本。Photos 画面可能是源预览。','Source pixels are stored locally first. Plans create versions of the same photo; terminals may share one version. Photos may supply source previews.')}
${tr('源画面','Source pixels')} ${plans.map(p=>`${esc(p.name)}${p.archived?tr('(已归档)',' (archived)'):''} `).join('')}
${tr('新增生成方案','New generation plan')} ${plan&&!plan.archived?`${t('edit')} ${tr('删除方案','Delete plan')} `:''}
${tr('使用终端:','Used by: ')}${uses.map(terminalLabel).map(esc).join('、')||tr('尚未绑定','No terminals bound')}
${tr('上一页','Previous')} =page.total?'disabled':''}>${tr('下一页','Next')} ${tr('共','Total')} ${page.total} ${tr('张来源照片','source pictures')}
${page.items.map((picture,i)=>{
+ panel.innerHTML=`
${tr('源画面先保存到本地;同一张照片按不同方案生成版本,多个终端可共用一份版本。Photos 画面可能是源预览。','Source pixels are stored locally first. Plans create versions of the same photo; terminals may share one version. Photos may supply source previews.')}
${tr('使用终端:','Used by: ')}${uses.map(terminalLabel).map(esc).join('、')||tr('尚未绑定','No terminals bound')}
${page.items.map((picture,i)=>{
const version=plan?picture.versions.find(v=>v.plan_id===plan.id):picture;
return `
${version?` `:`${tr('此方案尚未生成','Not generated for this plan')}
`}${esc(picture.name)} ${plan?version?`${esc(version.plan.name)} · ${version.plan.width} × ${version.plan.height}`:tr('未生成','Not generated'):tr('无叠加的源画面','Source pixels without overlays')} ${esc(fmt(version?.created_at||picture.created_at))} ${version?.terminal_uses?.length?`${version.terminal_uses.map(u=>esc(terminalLabel(terminals.find(t=>t.id===u.terminal_id)||{id:u.terminal_id}))+' · '+esc(libraryStatus(u.status))).join(' / ')} `:''}${version?`${tr('预览','Preview')} ${tr('下载图片','Download image')} ${plan?`${tr('生成参数','Generation settings')} `:''}`:''}${!plan?.archived?`${plan?tr('按此方案生成','Generate this plan'):tr('生成各方案版本','Generate plan versions')} `:''}${!plan?`${t(picture.starred?'unstar':'star')} ${t(picture.excluded?'includePhoto':'excludePhoto')} `:''}${t('delete')}
`;
- }).join('')}
${page.items.length?'':`
${tr('尚未选入源画面。先从来源选入照片,再按方案生成。旧成品保留在“历史本地成品”。','No source pixels imported yet. Import a photo, then generate its versions. Older products remain under Legacy local images.')} `}`;
+ }).join('')}
${page.items.length?'':`${tr('尚未选入源画面。先从来源选入照片,再按方案生成。旧成品保留在“历史本地成品”。','No source pixels imported yet. Import a photo, then generate its versions. Older products remain under Legacy local images.')} `}`;
$('#library-source').onchange=()=>{libraryUI.source=$('#library-source').value;libraryUI.plan=null;libraryUI.offset=0;return navigate();};
document.querySelectorAll('[data-library-plan]').forEach(b=>b.onclick=()=>{libraryUI.plan=b.dataset.libraryPlan||null;return navigate();});
bind('library-import',()=>libraryImportDialog(sourceId));bind('library-source-settings',()=>navigate('photo-sources'));bind('library-legacy',()=>libraryLegacy('local'));
diff --git a/pigway_frame_flow/web/style.css b/pigway_frame_flow/web/style.css
index 578c661..aff097a 100644
--- a/pigway_frame_flow/web/style.css
+++ b/pigway_frame_flow/web/style.css
@@ -269,3 +269,8 @@ form#history-filters{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
.library-source-toolbar label{margin:0;white-space:nowrap}
.library-source-toolbar select{width:220px;max-width:100%;min-width:0}
@media(max-width:720px){.library-source-toolbar>.field{max-width:100%}.library-source-toolbar select{width:180px}}
+
+.library-plan-toolbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
+.library-plan-toolbar>.tabs{margin-bottom:0}
+.source-library-gallery{grid-template-columns:repeat(auto-fill,min(100%,500px));margin-top:20px}
+.library-pagination{margin-top:20px;margin-bottom:20px}