diff --git a/admin.php b/admin.php index 3793e79..9bc6c0b 100644 --- a/admin.php +++ b/admin.php @@ -802,7 +802,7 @@ fb_layout_head('管理后台', ['robots' => 'noindex,nofollow']); $dSw = !empty($t['software_id']) ? fb_software((int)$t['software_id']) : null; $dCat = !empty($t['category_id']) ? fb_category((int)$t['category_id']) : null; ?> - + @@ -1451,7 +1451,7 @@ function fb_admin_pending_row(array $t) {
- + diff --git a/assets/app.js b/assets/app.js index 8fca85d..7a1a530 100644 --- a/assets/app.js +++ b/assets/app.js @@ -808,15 +808,20 @@ function bindSoftwarePanel() { var btn = document.getElementById('swToggle'); var panel = document.getElementById('swPanel'); + var mask = document.getElementById('swMask'); if (!btn || !panel) { return; } function open() { panel.hidden = false; + if (mask) { mask.hidden = false; } btn.setAttribute('aria-expanded', 'true'); + document.body.style.overflow = 'hidden'; // 抽屉开着时锁住背景滚动 } function close() { panel.hidden = true; + if (mask) { mask.hidden = true; } btn.setAttribute('aria-expanded', 'false'); + document.body.style.overflow = ''; } function toggle() { if (panel.hidden) { open(); } else { close(); } @@ -827,7 +832,15 @@ toggle(); }); - // 点面板内部不算「点外部」 + // 点遮罩关闭(遮罩就是「下面的内容」,点了就是点外部) + if (mask) { + mask.addEventListener('click', function (e) { + e.stopPropagation(); + close(); + }); + } + + // 点面板内部不算点外部 panel.addEventListener('click', function (e) { e.stopPropagation(); }); document.addEventListener('click', function () { @@ -837,6 +850,11 @@ document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !panel.hidden) { close(); btn.focus(); } }); + + // 转到别的页面时把滚动锁解掉,避免返回后页面不能滚 + window.addEventListener('pagehide', function () { + document.body.style.overflow = ''; + }); } /* ---------- 邮件测试发送(后台设置页) ---------- */ diff --git a/assets/style.css b/assets/style.css index b2b0c87..fc31624 100644 --- a/assets/style.css +++ b/assets/style.css @@ -31,6 +31,7 @@ p{margin:8px 0} backdrop-filter:saturate(180%) blur(14px); -webkit-backdrop-filter:saturate(180%) blur(14px); border-bottom:1px solid var(--line); + /* 软件抽屉是 absolute + top:100%,需要它来做定位参照,否则会跑到页面最上面 */ } .topbar .wrap{display:flex; align-items:center; gap:14px; height:66px} .topbar .brand-mini{display:flex; align-items:center; gap:10px; font-weight:700; font-size:17px; color:var(--fg); min-width:0} @@ -64,34 +65,46 @@ p{margin:8px 0} .sw-toggle[aria-expanded="true"] span:nth-child(2){opacity:0} .sw-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)} +/* ---------- 软件抽屉:一律竖排浮层,覆盖在正文之上 ---------- + * 用户 2026-11-03:「都保持统一,点了之后下拉出来一个条一个条竖着排列, + * 把下面的内容全部盖住」。 + * 早期实现是宽屏横排、窄屏竖排两套,结果手机上会跟正文撞在一起; + * 现在只有一种形态:绝对定位的浮卡,overlay 盖住页面内容。 */ .sw-panel{ - border-top:1px solid var(--line); + position:absolute; left:0; right:0; top:100%; + z-index:60; background:var(--card); - box-shadow:0 8px 20px -12px rgba(20,30,50,.18); + border-top:1px solid var(--line); + border-bottom:1px solid var(--line); + box-shadow:0 18px 40px -12px rgba(20,30,50,.28); + max-height:calc(100vh - 66px); + overflow:auto; } -.sw-panel .wrap{padding-top:14px; padding-bottom:16px} +.sw-panel .wrap{padding-top:14px; padding-bottom:14px} .sw-panel-hd{ - font-size:13.5px; font-weight:600; color:var(--muted); - margin-bottom:10px; letter-spacing:.2px; + font-size:13px; font-weight:600; color:var(--muted); + margin-bottom:8px; letter-spacing:.2px; } +/* 永远竖排:一条一行,不再有宽屏横排分支 */ .sw-panel-list{display:flex; flex-direction:column; gap:2px} .sw-item{ display:flex; align-items:center; gap:10px; - padding:9px 10px; border-radius:10px; color:var(--fg); + padding:10px 12px; border-radius:10px; color:var(--fg); + border:1px solid transparent; } .sw-item:hover{background:var(--bg, #f6f8fb); text-decoration:none; color:var(--fg)} -.sw-item.on{background:var(--brand-soft)} -.sw-item.on .sw-badge-nm{color:var(--brand); font-weight:700} +.sw-item.on{background:var(--brand-soft); border-color:var(--brand-soft)} +.sw-item.on .sw-badge-nm{font-weight:700} .sw-item-cur{ margin-left:auto; font-size:11.5px; font-weight:600; color:var(--brand); background:var(--card); border:1px solid var(--brand); padding:1px 8px; border-radius:99px; } -@media (min-width:561px){ - .sw-panel-list{flex-direction:row; flex-wrap:wrap; gap:8px} - .sw-item{padding:7px 12px; border:1px solid var(--line)} - .sw-item.on{border-color:var(--brand)} - .sw-item-cur{margin-left:4px} + +/* 抽屉打开时给正文加一层遮罩,点它也能关 —— 视觉上更明确「盖住了」 */ +.sw-mask{ + position:fixed; inset:0; z-index:55; + background:rgba(15,23,35,.18); } .topbar .brand-text{overflow:hidden; text-overflow:ellipsis; white-space:nowrap} .topbar .logo-mark{ @@ -191,10 +204,12 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} .sw-badge-sm .sw-badge-nm{font-size:14px} .sw-badge-md .sw-badge-nm{font-size:16px; font-weight:600} /* 内容区:只是软件标识,字号刻意小于顶栏标题(17px), - * 避免「上面的字比下面的小」这种主次颠倒。 */ -.sw-badge-lg .sw-badge-nm{font-size:15px; font-weight:600} -/* 顶栏主标题:比「选择软件」标签(13.5px)大两号 = 17px,且大于内容区的 15px */ -.sw-badge-brand .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px} + * 避免「上面的字比下面的小」这种主次颠倒。颜色同样跟随软件主题色。 */ +.sw-badge-lg .sw-badge-nm{font-size:15px; font-weight:600; color:var(--swc, var(--fg))} +/* 顶栏主标题:比「选择软件」标签(13.5px)大两号 = 17px,且大于内容区的 15px。 + * 颜色跟随软件主题色(--swc 由 PHP 内联写到 .brand-mini 上), + * 让「同步日历」「密码生成器」这些标题一眼可辨。 */ +.sw-badge-brand .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px; color:var(--swc, var(--fg))} /* 页头副行:图标 + 软件名 */ .page-sw-id{margin:0; display:flex; align-items:center} /* 提交页顶部的软件上下文条:同样无背景色,只留一行轻分隔 */ @@ -422,7 +437,20 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh} .badge.st-closed{background:#f1f3f5; color:#8a929c} .badge.official{background:var(--brand); color:#fff} /* 软件徽章:比分类更"重",一眼看出属于哪个软件 */ -.badge.sw{background:#eef2f8; color:#2b4a74; border:1px solid #cfdcee; font-weight:600} +/* 软件徽标:每个软件用自己的主题色 + 图标,方便一眼区分是哪个软件。 + * 颜色由 PHP 内联写入(--swc / --swc-soft),这里只管形态。 */ +.badge.sw{ + display:inline-flex; align-items:center; gap:5px; + background:var(--swc-soft, #eef2f8); color:var(--swc, #2b4a74); + border:1px solid var(--swc-line, #cfdcee); font-weight:600; + padding:1px 9px 1px 6px; +} +.badge.sw .badge-sw-ic{ + display:inline-flex; align-items:center; justify-content:center; + width:15px; height:15px; flex:none; line-height:1; +} +.badge.sw .badge-sw-ic img{width:15px; height:15px; display:block; object-fit:contain} +.badge.sw .badge-sw-nm{white-space:nowrap} .badge.st-wontfix{background:#f6eef0; color:#a13c53} /* ---------- 分页 ---------- */ diff --git a/index.php b/index.php index 21e3c20..51c610c 100644 --- a/index.php +++ b/index.php @@ -87,17 +87,23 @@ fb_layout_head($sw ? fb_software_site_title($sw) : $headTitle, ['software' => $s
-
+ +

全部问题

-

我要反馈 diff --git a/lib/layout.php b/lib/layout.php index 991f93f..988c45e 100644 --- a/lib/layout.php +++ b/lib/layout.php @@ -64,7 +64,16 @@ function fb_layout_head($title, array $opt = []) { $swList = fb_softwares(true); ?> - + + @@ -91,6 +100,9 @@ function fb_layout_head($title, array $opt = []) {
1): ?> + +