diff --git a/assets/style.css b/assets/style.css index 9a693ec..7a85f9f 100644 --- a/assets/style.css +++ b/assets/style.css @@ -54,7 +54,7 @@ --transition-normal: 0.3s ease; --transition-slow: 0.5s ease; --transition-bounce: cubic-bezier(0.4, 0, 0.2, 1); - + /* RGB Values for opacity manipulation */ --card-bg-rgb: 47, 48, 53; } @@ -92,8 +92,10 @@ body.light-theme { /* 预加载主题 - 在JS完全加载前显示正确的主题 */ html.theme-preload body { - background-color: #e0e0d8; /* 明亮主题背景色 */ - color: #333333; /* 明亮主题文本色 */ + background-color: #e0e0d8; + /* 明亮主题背景色 */ + color: #333333; + /* 明亮主题文本色 */ } /* 预加载侧边栏状态 - 在JS完全加载前显示正确的侧边栏宽度 */ @@ -169,13 +171,16 @@ html.preload * { /* 通用滚动条样式 */ .custom-scrollbar { - scrollbar-width: thin; /* Firefox */ - scrollbar-color: var(--scrollbar-color) transparent; /* Firefox */ + scrollbar-width: thin; + /* Firefox */ + scrollbar-color: var(--scrollbar-color) transparent; + /* Firefox */ } /* Webkit滚动条样式(Chrome, Safari, Edge等) */ .custom-scrollbar::-webkit-scrollbar { - width: 7px; /* 统一滚动条宽度 */ + width: 7px; + /* 统一滚动条宽度 */ } .custom-scrollbar::-webkit-scrollbar-track { @@ -183,18 +188,22 @@ html.preload * { } .custom-scrollbar::-webkit-scrollbar-thumb { - background-color: var(--scrollbar-color); /* 使用变量 */ + background-color: var(--scrollbar-color); + /* 使用变量 */ border-radius: 4px; } .custom-scrollbar::-webkit-scrollbar-thumb:hover { - background-color: var(--scrollbar-hover-color); /* 使用变量 */ + background-color: var(--scrollbar-hover-color); + /* 使用变量 */ } /* 防止滚动条导致的布局偏移 */ html { - overflow-y: hidden; /* 改为hidden,移除强制显示的滚动条 */ - scrollbar-width: thin; /* Firefox */ + overflow-y: hidden; + /* 改为hidden,移除强制显示的滚动条 */ + scrollbar-width: thin; + /* Firefox */ /* 明确 rem 基准字号:便于用 rem 统一管理字号(1rem = 16px) */ font-size: 16px; } @@ -216,8 +225,10 @@ body { background-color: var(--bg-color); color: var(--text-color); min-height: var(--app-height, 100vh); - overflow: hidden; /* 防止body滚动 */ - padding-right: 0 !important; /* 防止滚动条导致的布局偏移 */ + overflow: hidden; + /* 防止body滚动 */ + padding-right: 0 !important; + /* 防止滚动条导致的布局偏移 */ transition: background-color 0.3s ease, color 0.3s ease; } @@ -227,7 +238,8 @@ body { min-height: var(--app-height, 100vh); position: relative; z-index: 1; - overflow: hidden; /* 防止layout滚动 */ + overflow: hidden; + /* 防止layout滚动 */ opacity: 0; transition: opacity 0.3s ease; } @@ -291,7 +303,8 @@ body.loaded .layout { opacity: 0; visibility: hidden; transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); - z-index: 950; /* 调整遮罩层z-index,处于按钮与弹出面板之间 */ + z-index: 950; + /* 调整遮罩层z-index,处于按钮与弹出面板之间 */ } .overlay.active { @@ -315,7 +328,7 @@ body.loaded .layout { height: var(--app-height, 100vh); display: grid; grid-template-rows: auto 1fr auto auto; - grid-template-areas: + grid-template-areas: "header" "content" "social" @@ -338,14 +351,17 @@ body.loaded .layout { justify-content: center; display: flex; align-items: center; - height: 3.75rem; /* 确保与展开状态高度一致 */ - margin-bottom: 0.8rem; /* 收起态同样拉开与按钮的间距 */ + height: 3.75rem; + /* 确保与展开状态高度一致 */ + margin-bottom: 0.8rem; + /* 收起态同样拉开与按钮的间距 */ } /* 折叠状态下的侧边栏内容区域调整 */ .sidebar.collapsed .sidebar-content { padding: 0; - scrollbar-width: none; /* 隐藏滚动条 */ + scrollbar-width: none; + /* 隐藏滚动条 */ } /* 调整折叠侧边栏的部分元素间距 */ @@ -364,20 +380,27 @@ body.loaded .layout { } .sidebar.collapsed .sidebar-content::-webkit-scrollbar { - display: none; /* 隐藏WebKit浏览器的滚动条 */ + display: none; + /* 隐藏WebKit浏览器的滚动条 */ } /* 侧边栏头部区域 */ .sidebar .logo { grid-area: header; - padding: 1.2rem 1.2rem 0.6rem; /* 调整上下padding更紧凑 */ + padding: 1.2rem 1.2rem 0.6rem; + /* 调整上下padding更紧凑 */ display: flex; align-items: center; - overflow: hidden; /* 防止内容溢出 */ - position: relative; /* 添加相对定位,作为按钮的参考 */ - height: 3.75rem; /* 固定高度 60px */ - margin-bottom: 0.8rem; /* 与下方按钮区域拉开间距 */ - transition: padding 0.3s ease; /* 添加padding过渡,避免突变 */ + overflow: hidden; + /* 防止内容溢出 */ + position: relative; + /* 添加相对定位,作为按钮的参考 */ + height: 3.75rem; + /* 固定高度 60px */ + margin-bottom: 0.8rem; + /* 与下方按钮区域拉开间距 */ + transition: padding 0.3s ease; + /* 添加padding过渡,避免突变 */ } .logo-brand { @@ -386,7 +409,8 @@ body.loaded .layout { gap: 0.6rem; min-width: 0; flex: 1; - padding-right: 2.2rem; /* 预留右侧折叠按钮空间 */ + padding-right: 2.2rem; + /* 预留右侧折叠按钮空间 */ } .logo-brand h1 { @@ -428,13 +452,18 @@ body.loaded .layout { align-items: center; justify-content: center; cursor: pointer; - transition: background 0.3s ease; /* 只过渡背景色,移除all避免位置过渡 */ + transition: background 0.3s ease; + /* 只过渡背景色,移除all避免位置过渡 */ padding: 0; - flex-shrink: 0; /* 防止按钮被压缩 */ - position: absolute; /* 在两种状态下都使用绝对定位 */ - right: 1.2rem; /* 展开状态下固定在右侧 */ + flex-shrink: 0; + /* 防止按钮被压缩 */ + position: absolute; + /* 在两种状态下都使用绝对定位 */ + right: 1.2rem; + /* 展开状态下固定在右侧 */ top: 60%; - transform: translateY(-50%); /* 垂直居中 */ + transform: translateY(-50%); + /* 垂直居中 */ } .sidebar-toggle .toggle-icon { @@ -457,9 +486,12 @@ body.loaded .layout { /* 收起状态下按钮居中 */ .sidebar.collapsed .sidebar-toggle { - left: 50%; /* 水平居中 */ - right: auto; /* 移除右侧定位 */ - transform: translate(-50%, -50%); /* 同时水平和垂直居中 */ + left: 50%; + /* 水平居中 */ + right: auto; + /* 移除右侧定位 */ + transform: translate(-50%, -50%); + /* 同时水平和垂直居中 */ } .sidebar.collapsed .sidebar-toggle:hover { @@ -478,28 +510,35 @@ body.loaded .layout { /* 侧边栏内容区域 - 可滚动 */ .sidebar-content { grid-area: content; - min-height: 0; /* 允许在 CSS Grid 内正确收缩与滚动,避免把 footer 挤出可视区域 */ - overflow-y: auto; /* 只有内容区域可滚动 */ + min-height: 0; + /* 允许在 CSS Grid 内正确收缩与滚动,避免把 footer 挤出可视区域 */ + overflow-y: auto; + /* 只有内容区域可滚动 */ padding: 0 1.2rem; display: flex; flex-direction: column; - gap: 0.6rem; /* 从1rem减小到0.6rem */ + gap: 0.6rem; + /* 从1rem减小到0.6rem */ /* 隐藏滚动条但保持滚动功能 */ - scrollbar-width: none; /* Firefox */ + scrollbar-width: none; + /* Firefox */ } .sidebar-content::-webkit-scrollbar { - display: none; /* Webkit browsers */ + display: none; + /* Webkit browsers */ } /* 折叠状态下的内容区域调整 */ .sidebar.collapsed .sidebar-content { padding: 0 0.5rem; - scrollbar-width: none; /* 隐藏滚动条 */ + scrollbar-width: none; + /* 隐藏滚动条 */ } .sidebar.collapsed .sidebar-content::-webkit-scrollbar { - display: none; /* 隐藏WebKit浏览器的滚动条 */ + display: none; + /* 隐藏WebKit浏览器的滚动条 */ } /* 折叠状态下的Logo文本 */ @@ -507,22 +546,27 @@ body.loaded .layout { opacity: 0; transform: translateX(-20px); width: 0; - visibility: hidden; /* 确保完全隐藏,防止干扰布局 */ - pointer-events: none; /* 禁用交互,避免影响布局 */ + visibility: hidden; + /* 确保完全隐藏,防止干扰布局 */ + pointer-events: none; + /* 禁用交互,避免影响布局 */ } /* 导航区域样式 */ .nav-section { display: flex; flex-direction: column; - gap: 0.4rem; /* 增大按钮间距 */ + gap: 0.4rem; + /* 增大按钮间距 */ } .section-title { font-size: 1rem; color: var(--accent-color); - padding: 0.4rem 0.5rem; /* 减小上下padding */ - margin-bottom: 0.2rem; /* 增大与下方按钮组的间距 */ + padding: 0.4rem 0.5rem; + /* 减小上下padding */ + margin-bottom: 0.2rem; + /* 增大与下方按钮组的间距 */ display: flex; align-items: center; gap: 0.5rem; @@ -537,9 +581,10 @@ body.loaded .layout { .sidebar.collapsed .section-title { justify-content: center; /* 统一与展开态的垂直间距 */ - padding: 0.4rem 0; + padding: 0.4rem 0; text-align: center; - margin-bottom: 0.2rem; /* 与展开态保持一致且更大 */ + margin-bottom: 0.2rem; + /* 与展开态保持一致且更大 */ } .sidebar.collapsed .section-title i { @@ -556,12 +601,15 @@ body.loaded .layout { .sidebar.collapsed .nav-item { padding: 0; justify-content: center; - width: 2.75rem; /* 增大按钮方块尺寸 44px */ - height: 2.75rem; /* 增大按钮方块尺寸 44px */ + width: 2.75rem; + /* 增大按钮方块尺寸 44px */ + height: 2.75rem; + /* 增大按钮方块尺寸 44px */ text-align: center; margin-left: auto; margin-right: auto; - border-radius: var(--radius-md); /* 略增圆角 */ + border-radius: var(--radius-md); + /* 略增圆角 */ display: flex; align-items: center; box-sizing: border-box; @@ -589,7 +637,8 @@ body.loaded .layout { opacity: 0; transform: translateX(-10px); width: 0; - display: none; /* 完全移除,防止干扰布局 */ + display: none; + /* 完全移除,防止干扰布局 */ visibility: hidden; } @@ -659,22 +708,26 @@ body.loaded .layout { .content { flex: 1; margin-left: var(--sidebar-width); - padding: 2rem 1.5rem; + padding: 2rem 1.5rem; background-color: var(--bg-color); position: relative; - height: var(--app-height, 100vh); /* 固定高度(移动端避免 100vh 问题) */ - overflow-y: auto; /* 使用auto替代scroll,只在需要时显示滚动条 */ + height: var(--app-height, 100vh); + /* 固定高度(移动端避免 100vh 问题) */ + overflow-y: auto; + /* 使用auto替代scroll,只在需要时显示滚动条 */ overflow-x: hidden; width: calc(100vw - var(--sidebar-width)); display: flex; flex-direction: column; align-items: center; /* 隐藏滚动条但保持滚动功能 */ - scrollbar-width: none; /* Firefox */ + scrollbar-width: none; + /* Firefox */ } .content::-webkit-scrollbar { - display: none; /* Webkit browsers */ + display: none; + /* Webkit browsers */ } /* 优化内容区域在侧边栏折叠状态下的边距 */ @@ -989,8 +1042,8 @@ body .content.expanded { flex-direction: column; align-items: center; padding-top: 2rem; - padding-left: 0.5rem; - padding-right: 0.5rem; + padding-left: 0.5rem; + padding-right: 0.5rem; } .page.active { @@ -1097,12 +1150,11 @@ body .content.expanded { @keyframes glow { from { - filter: drop-shadow(0 0 2px rgba(118, 148, 185, 0.2)) - drop-shadow(0 0 4px rgba(168, 85, 247, 0.2)); + filter: drop-shadow(0 0 2px rgba(118, 148, 185, 0.2)) drop-shadow(0 0 4px rgba(168, 85, 247, 0.2)); } + to { - filter: drop-shadow(0 0 4px rgba(118, 148, 185, 0.4)) - drop-shadow(0 0 8px rgba(168, 85, 247, 0.4)); + filter: drop-shadow(0 0 4px rgba(118, 148, 185, 0.4)) drop-shadow(0 0 8px rgba(168, 85, 247, 0.4)); } } @@ -1131,8 +1183,8 @@ body .content.expanded { } /* 标题前图标固定宽度:避免不同图标宽度导致标题文本不对齐 */ -.category-header [data-editable="category-name"] > i, -.group-header [data-editable="group-name"] > i { +.category-header [data-editable="category-name"]>i, +.group-header [data-editable="group-name"]>i { width: 1.25em; min-width: 1.25em; text-align: center; @@ -1181,13 +1233,13 @@ body .content.expanded { transition: color 0.3s ease; } -.category h2 > i { +.category h2>i { color: var(--accent-color); font-size: 1.3rem; transition: all 0.3s ease; } -.category-header[data-toggle="category"]:hover h2 > i { +.category-header[data-toggle="category"]:hover h2>i { transform: scale(1.1); color: var(--accent-hover); } @@ -1233,14 +1285,15 @@ body .content.expanded { gap: 0.8rem; } -.category-level-2 .category-header h3 > i { +.category-level-2 .category-header h3>i { color: var(--accent-color); font-size: 1.2rem; opacity: 0.9; } /* 层级3: 分组 */ -.group-level-3, .category-level-3 { +.group-level-3, +.category-level-3 { margin-top: 0; margin-bottom: 0; padding-left: 0.5rem; @@ -1271,24 +1324,25 @@ body .content.expanded { } /* 层级4: 子分组 */ -.group-level-4, .category-level-4 { +.group-level-4, +.category-level-4 { margin-top: 0; margin-bottom: 0; padding-left: 0.5rem; } /* 嵌套层级间距:仅在同级相邻时增加间距,避免首项被额外下推 */ -.subcategories-container > .category-level-2 + .category-level-2 { +.subcategories-container>.category-level-2+.category-level-2 { margin-top: 1rem; } -.groups-container > .group-level-3 + .group-level-3, -.groups-container > .category-level-3 + .category-level-3 { +.groups-container>.group-level-3+.group-level-3, +.groups-container>.category-level-3+.category-level-3 { margin-top: 0.8rem; } -.subgroups-container > .group-level-4 + .group-level-4, -.subcategories-container > .category-level-4 + .category-level-4 { +.subgroups-container>.group-level-4+.group-level-4, +.subcategories-container>.category-level-4+.category-level-4 { margin-top: 0.6rem; } @@ -1317,7 +1371,7 @@ body .content.expanded { } /* 移除悬停时的缩放效果,保持简洁 */ -.category-level-2 .category-header:hover h3 > i, +.category-level-2 .category-header:hover h3>i, .group-level-3 .group-header:hover h4 i, .category-level-3 .category-header:hover h4 i, .group-level-4 .group-header:hover h5 i, @@ -1345,8 +1399,8 @@ body .content.expanded { } /* 展开态:图标旋转 180°(类似参考样式1) */ -.category:not(.collapsed) > .category-header .toggle-icon i, -.group:not(.collapsed) > .group-header .toggle-icon i { +.category:not(.collapsed)>.category-header .toggle-icon i, +.group:not(.collapsed)>.group-header .toggle-icon i { transform: rotate(180deg); color: var(--text-bright); } @@ -1358,6 +1412,7 @@ body .content.expanded { /* 分类/分组折叠图标:桌面端默认隐藏,悬停/收起时显示,避免按钮过多 */ @media (hover: hover) and (pointer: fine) { + .category-header .toggle-icon, .group-header .toggle-icon { opacity: 0; @@ -1365,18 +1420,19 @@ body .content.expanded { } .category-header[data-toggle="category"]:hover .toggle-icon, - .category.collapsed > .category-header .toggle-icon, + .category.collapsed>.category-header .toggle-icon, .group-header[data-toggle="group"]:hover .toggle-icon, - .group.collapsed > .group-header .toggle-icon { + .group.collapsed>.group-header .toggle-icon { opacity: 1; } } /* 展开/折叠动画 */ -.category-content, .group-content { +.category-content, +.group-content { overflow: visible; transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), - opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1); + opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1); max-height: 5000px; opacity: 1; } @@ -1390,22 +1446,22 @@ body .content.expanded { } /* 收起状态下调整header的下边距 */ -.category.collapsed > .category-header { +.category.collapsed>.category-header { margin-bottom: -0.5rem; } -.category-level-2.collapsed > .category-header { +.category-level-2.collapsed>.category-header { margin-bottom: 0; border-bottom: none; } -.group-level-3.collapsed > .group-header, -.category-level-3.collapsed > .category-header { +.group-level-3.collapsed>.group-header, +.category-level-3.collapsed>.category-header { margin-bottom: 0; } -.group-level-4.collapsed > .group-header, -.category-level-4.collapsed > .category-header { +.group-level-4.collapsed>.group-header, +.category-level-4.collapsed>.category-header { margin-bottom: 0; } @@ -1427,14 +1483,14 @@ body .content.expanded { } /* 当分类同时包含子分类和站点时的样式优化 */ -.category-content .subcategories-container + .sites-grid { +.category-content .subcategories-container+.sites-grid { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid var(--border-color); } /* 当分类同时包含分组和站点时的样式优化 */ -.category-content .groups-container + .sites-grid { +.category-content .groups-container+.sites-grid { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid var(--border-color); @@ -1463,29 +1519,31 @@ body .content.expanded { .category-level-2 { padding-left: 0; } - - .group-level-3, .category-level-3 { - padding-left: 0; - } - - .group-level-4, .category-level-4 { + + .group-level-3, + .category-level-3 { padding-left: 0; } - .subcategories-container > .category-level-2 + .category-level-2 { + .group-level-4, + .category-level-4 { + padding-left: 0; + } + + .subcategories-container>.category-level-2+.category-level-2 { margin-top: 0.8rem; } - .groups-container > .group-level-3 + .group-level-3, - .groups-container > .category-level-3 + .category-level-3 { + .groups-container>.group-level-3+.group-level-3, + .groups-container>.category-level-3+.category-level-3 { margin-top: 0.7rem; } - .subgroups-container > .group-level-4 + .group-level-4, - .subcategories-container > .category-level-4 + .category-level-4 { + .subgroups-container>.group-level-4+.group-level-4, + .subcategories-container>.category-level-4+.category-level-4 { margin-top: 0.55rem; } - + .category-level-2 .sites-grid, .group-level-3 .sites-grid, .category-level-3 .sites-grid, @@ -1502,19 +1560,22 @@ body .content.expanded { margin-right: 0.5rem; padding: 1rem; } - - .category-level-2, .group-level-3, .category-level-3 { + + .category-level-2, + .group-level-3, + .category-level-3 { margin-left: 0; padding-left: 0; width: 100%; } - - .group-level-4, .category-level-4 { + + .group-level-4, + .category-level-4 { margin-left: 0; padding-left: 0; width: 100%; } - + .category-level-2 .sites-grid, .group-level-3 .sites-grid, .category-level-3 .sites-grid, @@ -1611,6 +1672,8 @@ body .content.expanded { -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; + position: relative; + /* Ensure tooltip positioning context */ } .site-card.site-card-repo .repo-stats { @@ -1928,6 +1991,43 @@ body .content.expanded { overflow: hidden; text-overflow: ellipsis; width: 100%; + position: relative; + /* Ensure tooltip positioning context */ +} + +/* Tooltip styles */ +/* Tooltip styles */ +.site-card p[data-tooltip], +.site-card .repo-desc[data-tooltip] { + cursor: default; + /* Indicate interactivity */ +} + +.custom-tooltip { + position: fixed; + background: rgba(47, 48, 53, 0.95); + /* Fallback dark */ + background: rgba(var(--card-bg-rgb), 0.95); + color: var(--text-bright); + padding: 0.5rem 0.8rem; + border-radius: var(--radius-md); + box-shadow: 0 4px 12px var(--shadow-color); + border: 1px solid var(--border-color); + font-size: 0.85rem; + white-space: normal; + line-height: 1.4; + z-index: 9999; + pointer-events: none; + opacity: 0; + transition: opacity 0.2s ease-out; + backdrop-filter: blur(4px); + -webkit-backdrop-filter: blur(4px); + max-width: 300px; + word-break: break-word; +} + +.custom-tooltip.visible { + opacity: 1; } /* 添加编辑按钮 */ @@ -1945,7 +2045,8 @@ body .content.expanded { opacity: 1; } -.edit-btn, .delete-btn { +.edit-btn, +.delete-btn { background: none; border: none; color: var(--text-muted); @@ -1955,7 +2056,8 @@ body .content.expanded { transition: all 0.3s ease; } -.edit-btn:hover, .delete-btn:hover { +.edit-btn:hover, +.delete-btn:hover { color: var(--text-bright); background-color: var(--secondary-bg); } @@ -2080,7 +2182,8 @@ body .content.expanded { transition: color 0.3s ease; } -.form-group input, .form-group select { +.form-group input, +.form-group select { background-color: var(--secondary-bg); border: 1px solid transparent; border-radius: var(--radius-md); @@ -2091,7 +2194,8 @@ body .content.expanded { box-shadow: 0 2px 6px var(--shadow-color); } -.form-group input:focus, .form-group select:focus { +.form-group input:focus, +.form-group select:focus { outline: none; background-color: var(--secondary-bg); border-color: var(--accent-color); @@ -2151,7 +2255,7 @@ body .content.expanded { padding: 0 var(--spacing-lg); margin-bottom: 2rem; } - + .category { max-width: 1100px; margin: 0 auto 2.5rem auto; @@ -2162,73 +2266,74 @@ body .content.expanded { .mobile-buttons { display: flex; } - + .content { margin-left: 0; width: 100vw; max-width: 100vw; padding-top: 5rem; } - + .sidebar { transform: translateX(-100%); box-shadow: none; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); } - + .sidebar .logo { padding-top: 1.5rem; display: flex; align-items: center; height: 60px; } - + /* 移动端下隐藏侧边栏折叠按钮 */ .sidebar-toggle { display: none; } - + .sidebar.active { transform: translateX(0); box-shadow: 2px 0 10px var(--shadow-color); - z-index: 1000; /* 增加侧边栏激活时的z-index,确保显示在按钮之上 */ + z-index: 1000; + /* 增加侧边栏激活时的z-index,确保显示在按钮之上 */ } - + /* 重置移动端下的侧边栏展开状态 */ .sidebar.collapsed { width: var(--sidebar-width); } - - .sidebar.collapsed .logo h1, - .sidebar.collapsed .nav-item .nav-text, - .sidebar.collapsed .nav-item .external-icon { - opacity: 1; - transform: none; - width: auto; - } - .sidebar.collapsed .sidebar-footer { - height: auto; - padding: 1rem 1.2rem; - visibility: visible; - pointer-events: auto; - border-top: 1px solid var(--border-color); - } + .sidebar.collapsed .logo h1, + .sidebar.collapsed .nav-item .nav-text, + .sidebar.collapsed .nav-item .external-icon { + opacity: 1; + transform: none; + width: auto; + } + + .sidebar.collapsed .sidebar-footer { + height: auto; + padding: 1rem 1.2rem; + visibility: visible; + pointer-events: auto; + border-top: 1px solid var(--border-color); + } + + .sidebar.collapsed .sidebar-social { + padding: 0.2rem 1.2rem 0.8rem; + flex-direction: row; + } - .sidebar.collapsed .sidebar-social { - padding: 0.2rem 1.2rem 0.8rem; - flex-direction: row; - } - .sidebar.collapsed .nav-item { padding: 0.6rem 0.8rem; justify-content: flex-start; } - + .sidebar.collapsed .nav-item .icon-container { margin-right: 1rem; } - + .search-container { position: fixed; top: 0; @@ -2240,20 +2345,21 @@ body .content.expanded { z-index: 95; box-shadow: 0 2px 10px var(--shadow-color); } - + .search-container.active { transform: translateY(0); - z-index: 1000; /* 增加搜索容器激活时的z-index,确保显示在按钮之上 */ + z-index: 1000; + /* 增加搜索容器激活时的z-index,确保显示在按钮之上 */ } - + .search-box { max-width: 100%; } - + .search-container.active .search-box { margin-bottom: 0; } - + .search-box input { padding: 0.8rem 3rem 0.8rem 1rem; font-size: 0.95rem; @@ -2274,7 +2380,7 @@ body .content.expanded { flex: 0 0 104px; padding: 0 0.6rem; } - + .sidebar .logo h1, .sidebar .nav-item span { opacity: 1; @@ -2284,7 +2390,8 @@ body .content.expanded { /* 欢迎区域样式 */ .welcome-section { padding: 0 1rem; - margin-top: 1rem; /* 增加顶部间距 */ + margin-top: 1rem; + /* 增加顶部间距 */ } .page { @@ -2317,11 +2424,11 @@ body .content.expanded { width: 100%; } - .sites-grid { - gap: var(--spacing-sm); - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - + .sites-grid { + gap: var(--spacing-sm); + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .site-card { flex-direction: column; align-items: center; @@ -2358,23 +2465,23 @@ body .content.expanded { text-align: center; } - .site-card h3 { - font-size: 1rem; - margin-bottom: 0.4rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 100%; - } - - .site-card p { - font-size: 0.9rem; - line-height: 1.3; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - + .site-card h3 { + font-size: 1rem; + margin-bottom: 0.4rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + } + + .site-card p { + font-size: 0.9rem; + line-height: 1.3; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + /* 在移动端的主题切换按钮 */ .theme-toggle { bottom: 1rem; @@ -2383,17 +2490,18 @@ body .content.expanded { /* 移动端滚动进度条调整 */ .scroll-progress { - height: var(--radius-sm); /* 移动端略粗一些 */ + height: var(--radius-sm); + /* 移动端略粗一些 */ } .sidebar .submenu { margin-left: 1rem; } - + .sidebar.active .submenu-item { padding: 0.5rem 0.6rem; } - + /* 确保移动设备上子菜单不会出现漏出问题 */ .sidebar.collapsed .submenu { display: none; @@ -2416,23 +2524,23 @@ body .content.expanded { .search-container { padding: 0 1rem; } - + .page { padding-top: 1rem; padding-left: 0.1rem; padding-right: 0.1rem; } - - .sites-grid { - gap: 0.5rem; - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - + + .sites-grid { + gap: 0.5rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .site-card { padding: 0.75rem 0.5rem; gap: 0.5rem; } - + .site-card-icon { width: 2rem; height: 2rem; @@ -2456,22 +2564,22 @@ body .content.expanded { font-size: 1.2rem; } - .site-card h3 { - font-size: 1rem; - margin-bottom: 0.3rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 100%; - } + .site-card h3 { + font-size: 1rem; + margin-bottom: 0.3rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + } - .site-card p { - font-size: 0.9rem; - line-height: 1.2; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } + .site-card p { + font-size: 0.9rem; + line-height: 1.2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } } @media (max-width: 400px) { @@ -2480,17 +2588,17 @@ body .content.expanded { margin: 0 0.05rem 1.2rem 0.05rem; width: calc(100% - 0.1rem); } - + .sites-grid { gap: 0.4rem; grid-template-columns: repeat(3, minmax(0, 1fr)); } - + .site-card { padding: 0.6rem 0.4rem; gap: 0.45rem; } - + .site-card-icon { width: 1.9rem; height: 1.9rem; @@ -2513,23 +2621,23 @@ body .content.expanded { line-height: 1.25rem; font-size: 1.1rem; } - - .site-card h3 { - font-size: 1rem; - margin-bottom: 0.25rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 100%; - } - - .site-card p { - font-size: 0.9rem; - line-height: 1.15; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } + + .site-card h3 { + font-size: 1rem; + margin-bottom: 0.25rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + } + + .site-card p { + font-size: 0.9rem; + line-height: 1.15; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } } /* 动画效果 */ @@ -2538,6 +2646,7 @@ body .content.expanded { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); @@ -2552,8 +2661,10 @@ body .content.expanded { flex-direction: column; align-items: center; z-index: 15; - transform: none !important; /* 确保没有变换 */ - min-height: 400px; /* 确保最小高度,防止内容过少时的布局跳动 */ + transform: none !important; + /* 确保没有变换 */ + min-height: 400px; + /* 确保最小高度,防止内容过少时的布局跳动 */ } #search-results.active { @@ -2620,6 +2731,7 @@ body .content.expanded { from { opacity: 0; } + to { opacity: 1; } @@ -2630,6 +2742,7 @@ body .content.expanded { opacity: 0; transform: scale(0.9); } + to { opacity: 1; transform: scale(1); @@ -2689,7 +2802,8 @@ body .content.expanded { color: var(--text-muted); font-size: 0.85rem; border-top: 1px solid var(--border-color); - background-color: var(--sidebar-bg); /* 使用变量 */ + background-color: var(--sidebar-bg); + /* 使用变量 */ transition: background-color 0.3s ease, color 0.3s ease, opacity 0.3s ease; } @@ -2747,11 +2861,14 @@ body .content.expanded { /* 子菜单展开状态 */ .nav-item-wrapper.expanded .submenu { - max-height: 300px; /* 设置合理的最大高度 */ - overflow-y: scroll; /* 改为scroll确保始终能滚动 */ + max-height: 300px; + /* 设置合理的最大高度 */ + overflow-y: scroll; + /* 改为scroll确保始终能滚动 */ opacity: 1; visibility: visible; - scrollbar-width: none; /* Firefox隐藏滚动条 */ + scrollbar-width: none; + /* Firefox隐藏滚动条 */ } /* 为WebKit浏览器隐藏滚动条 */ @@ -2800,7 +2917,8 @@ body .content.expanded { 使用display: none确保完全隐藏,避免任何可能的视觉问题 */ .sidebar.collapsed .submenu { position: absolute; - left: var(--sidebar-collapsed-width); /* 使用变量确保与侧边栏宽度一致 */ + left: var(--sidebar-collapsed-width); + /* 使用变量确保与侧边栏宽度一致 */ top: 0; background-color: var(--sidebar-bg); border-radius: 0 8px 8px 0; @@ -2814,7 +2932,8 @@ body .content.expanded { z-index: 200; pointer-events: none; transition: all 0.3s ease; - display: none; /* 添加 display: none 确保完全隐藏 */ + display: none; + /* 添加 display: none 确保完全隐藏 */ } /* 确保子菜单项在悬停时不会漏出 @@ -2831,7 +2950,8 @@ body .content.expanded { 使用static定位是为了让子菜单相对于侧边栏定位,而不是相对于nav-item-wrapper, 这样可以避免子菜单在折叠状态下漏出的问题 */ .sidebar.collapsed .nav-item-wrapper { - position: static; /* 改为static,防止子菜单定位问题 */ + position: static; + /* 改为static,防止子菜单定位问题 */ } /* 修改子菜单在悬停时的显示位置 @@ -2845,9 +2965,12 @@ body .content.expanded { scrollbar-width: none; pointer-events: auto; display: block; - left: var(--sidebar-collapsed-width); /* 确保与侧边栏宽度一致 */ - top: 0; /* 确保从顶部开始 */ - position: absolute; /* 使用绝对定位,更符合文档流 */ + left: var(--sidebar-collapsed-width); + /* 确保与侧边栏宽度一致 */ + top: 0; + /* 确保从顶部开始 */ + position: absolute; + /* 使用绝对定位,更符合文档流 */ } /* 为WebKit浏览器隐藏滚动条 */ @@ -2864,11 +2987,11 @@ body .content.expanded { .sidebar .submenu { margin-left: 1rem; } - + .sidebar.active .submenu-item { padding: 0.5rem 0.6rem; } - + /* 确保移动设备上子菜单不会出现漏出问题 */ .sidebar.collapsed .submenu { display: none; @@ -2885,4 +3008,4 @@ body .content.expanded { background-color: var(--accent-color); z-index: 1000; transition: width 0.1s ease-out; -} +} \ No newline at end of file diff --git a/src/script.js b/src/script.js index 535f4ea..7ee8059 100644 --- a/src/script.js +++ b/src/script.js @@ -274,6 +274,7 @@ window.MeNav = { newSite.href = siteUrl; newSite.title = siteName + (siteDescription ? ' - ' + siteDescription : ''); + newSite.setAttribute('data-tooltip', siteName + (siteDescription ? ' - ' + siteDescription : '')); // 添加自定义 tooltip if (/^https?:\/\//i.test(siteUrl)) { newSite.target = '_blank'; newSite.rel = 'noopener'; @@ -1909,3 +1910,73 @@ document.addEventListener('DOMContentLoaded', () => { } }); }); + +// Tooltip functionality for truncated text +document.addEventListener('DOMContentLoaded', () => { + // Create tooltip element + const tooltip = document.createElement('div'); + tooltip.className = 'custom-tooltip'; + document.body.appendChild(tooltip); + + let activeElement = null; + + // Show tooltip on hover + document.addEventListener('mouseover', (e) => { + const target = e.target.closest('[data-tooltip]'); + if (target) { + const tooltipText = target.getAttribute('data-tooltip'); + if (tooltipText) { + activeElement = target; + tooltip.textContent = tooltipText; + tooltip.classList.add('visible'); + updateTooltipPosition(e); + } + } + }); + + // Move tooltip with cursor + document.addEventListener('mousemove', (e) => { + if (activeElement) { + updateTooltipPosition(e); + } + }); + + // Hide tooltip on mouse out + document.addEventListener('mouseout', (e) => { + const target = e.target.closest('[data-tooltip]'); + if (target && target === activeElement) { + // Check if we really left the element (not just went to a child) + if (!target.contains(e.relatedTarget)) { + activeElement = null; + tooltip.classList.remove('visible'); + } + } + }); + + function updateTooltipPosition(e) { + // Position tooltip 15px below/right of cursor + const x = e.clientX + 15; + const y = e.clientY + 15; + + // Boundary checks to keep inside viewport + const rect = tooltip.getBoundingClientRect(); + const winWidth = window.innerWidth; + const winHeight = window.innerHeight; + + let finalX = x; + let finalY = y; + + // If tooltip goes off right edge + if (x + rect.width > winWidth) { + finalX = e.clientX - rect.width - 10; + } + + // If tooltip goes off bottom edge + if (y + rect.height > winHeight) { + finalY = e.clientY - rect.height - 10; + } + + tooltip.style.left = finalX + 'px'; + tooltip.style.top = finalY + 'px'; + } +}); diff --git a/templates/components/site-card.hbs b/templates/components/site-card.hbs index 10931ae..e4619c7 100644 --- a/templates/components/site-card.hbs +++ b/templates/components/site-card.hbs @@ -1,203 +1,173 @@ {{#if url}} - - {{!-- articles:首行图标+标题;下方“时间/来源 + 简介”全宽对齐,不被图标列缩进 --}} - {{#ifEquals type "article"}} -
- -
-

{{#if name}}{{name}}{{else}}未命名站点{{/if}}

-
-
+
+ {{!-- articles:首行图标+标题;下方“时间/来源 + 简介”全宽对齐,不被图标列缩进 --}} + {{#ifEquals type "article"}} +
+ +
+

{{#if name}}{{name}}{{else}}未命名站点{{/if}}

+
+
-
- {{#ifCond publishedAt '||' source}} -
- {{#if publishedAt}} - {{formatDate publishedAt "YYYY-MM-DD"}} - {{/if}} - {{#ifCond publishedAt '&&' source}} - · - {{/ifCond}} - {{#if source}} - {{source}} - {{/if}} -
- {{/ifCond}} -

{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}

-
- {{else}} - {{!-- projects:代码仓库风格卡片(保留 data-* 结构,便于扩展识别与写回) --}} - {{#ifEquals style "repo"}} -
- -
{{#if name}}{{name}}{{else}}未命名项目{{/if}}
-
+
+ {{#ifCond publishedAt '||' source}} +
+ {{#if publishedAt}} + {{formatDate publishedAt "YYYY-MM-DD"}} + {{/if}} + {{#ifCond publishedAt '&&' source}} + · + {{/ifCond}} + {{#if source}} + {{source}} + {{/if}} +
+ {{/ifCond}} +

{{#if + description}}{{description}}{{else}}{{extractDomain url}}{{/if}}

+
+ {{else}} + {{!-- projects:代码仓库风格卡片(保留 data-* 结构,便于扩展识别与写回) --}} + {{#ifEquals style "repo"}} +
+ +
{{#if name}}{{name}}{{else}}未命名项目{{/if}}
+
-
{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}
+
{{#if + description}}{{description}}{{else}}{{extractDomain url}}{{/if}}
- {{#ifCond language '||' stars}} -
- {{#if language}} -
- - {{language}} -
- {{/if}} - {{#if stars}} -
- {{stars}} -
- {{/if}} - {{#if forks}} -
- {{forks}} -
- {{/if}} - {{#if issues}} -
- {{issues}} -
- {{/if}} -
- {{/ifCond}} - {{else}} - + {{#ifCond language '||' stars}} +
+ {{#if language}} +
+ + {{language}} +
+ {{/if}} + {{#if stars}} +
+ {{stars}} +
+ {{/if}} + {{#if forks}} +
+ {{forks}} +
+ {{/if}} + {{#if issues}} +
+ {{issues}} +
+ {{/if}} +
+ {{/ifCond}} + {{else}} + -
-

{{#if name}}{{name}}{{else}}未命名站点{{/if}}

-

{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}

-
- {{/ifEquals}} - {{/ifEquals}} +
+

{{#if name}}{{name}}{{else}}未命名站点{{/if}}

+

{{#if + description}}{{description}}{{else}}{{extractDomain url}}{{/if}}

+
+ {{/ifEquals}} + {{/ifEquals}}
-{{/if}} +{{/if}} \ No newline at end of file