Files
HomeDash/web/navi.css
HomeDash Bot 8ba5e5117b feat(web): 工作空间内嵌网页 + 控件收边 + 页脚去重 + 窄屏不再重叠
1) 工作空间真的在中间打开网页
   Dashy 的面板就是 iframe,但它的 launchApp() 只在 target 不是 newtab 时
   才把 URL 灌进 iframe;而且侧栏项目大多没有 per-item target,Dashy 走的是
   Vue 直接改 iframe.src 的路径 —— 根本不经过 window.open,导致判定逻辑被
   绕过(实测:Gitea 仍被内嵌、空白)。现在两条路径统一进 verifyAndShow():
   先探测再决定内嵌还是明确提示;被拒时还会清空 iframe 的 src。

2) 控件在工作空间收边
   中间嵌的是别人的应用,常驻控件会遮挡。搜索球收左边缘、右下角两个按钮
   组成 dock 整组收右边缘、备案号收下边缘,各露 14px(备案号 13px),
   鼠标移入或点击、聚焦时滑出展开。只在工作空间生效。

3) 修 iframe 撑高页面 77px
   Dashy 的 .web-content iframe 是 position:absolute,包含块是 #dashy 而非
   .web-content,外层 overflow:hidden 拦不住它,它按 #dashy 高度撑到 814px
   (164+814=977 正好等于页面 scrollHeight)。补 position:static 后归零。

4) 首页不再出现两个备案号
   Vue 异步挂载,navi.js 可能先补了一份页脚,之后 Dashy 的页脚才出现;
   原来的守卫只判断 .navi-footer 是否存在,不会回收自己早先注入的那份。
   新增 dashyFooterNode() 区分两者,发现 Dashy 的就把我们补的移除。

5) 窄屏展开搜索框不再压住右下按钮组
   手机端展开宽度是 calc(100% - 86px),而按钮组占最后 114px → 重叠 38px。
   改为按按钮组真实占位预留(≥600px: min(560px, 100% - 158px);
   ≤599px: calc(100% - 132px));≤380px 时输入框会窄到不可用,改为
   临时隐藏按钮组(用 visibility 而非 transform,因为 prefers-reduced-motion
   会强制 transform:none)。
2026-09-11 19:04:38 +08:00

1195 lines
37 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* HomeDash responsive presentation layer.
Loaded after Dashy's bundled styles; persistent wallpaper rules stay in conf.yml. */
html {
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
/* 禁用移动端/Chromium 对可点击元素注入的蓝色点击闪烁。 */
html[data-theme] *,
html[data-theme] *::before,
html[data-theme] *::after {
-webkit-tap-highlight-color: transparent !important;
}
html[data-theme] body {
/* border-box 让 padding 计入 min-height:否则 min-height:100vh 与
padding-bottom 相加,短页面(极简/工作空间)必然多出一屏滚动。 */
box-sizing: border-box !important;
min-width: 0;
overflow-x: hidden;
/* 列向 flex + 页脚 margin-top:auto,把备案号顶到页面底部而非浮在中间。 */
display: flex !important;
flex-direction: column !important;
min-height: 100vh !important;
/* 备案号占据真正的页面最底部;悬浮控件在它上方,不再用底部 padding
把页脚整体抬高。 */
padding-bottom: 0 !important;
}
html[data-theme] #app {
width: 100% !important;
}
/* Dashy 的 #dashy 默认 min-height:100vh,短页面叠加页脚后必出滚动;
交回内容自然撑高,视口高度由 body 兜住。 */
html[data-theme] #dashy {
min-height: auto !important;
}
/* Dashy's native filter/settings strip duplicates the portal search and breaks on phones.
原生设置入口(齿轮/铅笔/调色板)与我们的 /admin/ 重复,统一隐藏。 */
html[data-theme] .home > .settings-outer,
html[data-theme] .config-launcher,
html[data-theme] .options-trigger,
html[data-theme] .settings-outer,
html[data-theme] .minimal-home .title-and-search > form {
display: none !important;
}
html[data-theme] body:has(.modal-overlay) > .navi-search-bar,
html[data-theme] body:has(.modal-overlay) > .navi-footer-host {
visibility: hidden !important;
pointer-events: none !important;
}
/* Keep configuration dialogs above section tabs and cards without changing dialog layout. */
html[data-theme] .modal-overlay {
z-index: 10000 !important;
}
html[data-theme] dialog.dashy-modal {
z-index: 10001 !important;
}
/* Stable icon geometry: raster/SVG and font icons occupy the same visual box. */
html[data-theme] a.item .item-icon {
flex: 0 0 56px !important;
width: 56px !important;
min-width: 56px !important;
height: 56px !important;
min-height: 56px !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
overflow: hidden !important;
transform: none !important;
}
html[data-theme] a.item .item-icon .tile-icon,
html[data-theme] a.item .item-icon img,
html[data-theme] a.item .item-icon object {
box-sizing: border-box !important;
width: 48px !important;
min-width: 48px !important;
max-width: 48px !important;
height: 48px !important;
min-height: 48px !important;
max-height: 48px !important;
padding: 2px !important;
object-fit: contain !important;
object-position: center !important;
transform: none !important;
}
html[data-theme] a.item .item-icon i,
html[data-theme] a.item .item-icon svg:not(.tile-icon) {
width: 32px !important;
height: 32px !important;
font-size: 30px !important;
line-height: 32px !important;
}
html[data-theme] a.item .tile-title {
min-width: 0 !important;
overflow: hidden;
}
html[data-theme] a.item .tile-title .text,
html[data-theme] a.item .description,
html[data-theme] a.item .item-url {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ── 底部搜索:左下角放大镜悬浮球 ──
收起态只显示一个放大镜图标;点它展开成输入框;
展开后输入框内左侧仍是同一个放大镜按钮,点它收起。 */
html[data-theme] .navi-search-bar {
box-sizing: border-box !important;
position: fixed !important;
left: calc(16px + env(safe-area-inset-left, 0px)) !important;
bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important;
margin: 0 !important;
display: flex !important;
align-items: center !important;
gap: 8px !important;
z-index: 900 !important;
color: #475569 !important;
background: rgba(255, 255, 255, .72) !important;
border: 1px solid rgba(255, 255, 255, .9) !important;
box-shadow: 0 14px 38px rgba(15, 23, 42, .16), inset 0 1px 0 rgba(255, 255, 255, .95) !important;
backdrop-filter: blur(22px) saturate(180%) !important;
-webkit-backdrop-filter: blur(22px) saturate(180%) !important;
overflow: hidden !important;
}
html[data-theme] .navi-search-bar[data-state="collapsed"] {
width: 56px !important;
height: 56px !important;
padding: 0 !important;
border-radius: 50% !important;
}
html[data-theme] .navi-search-bar[data-state="open"] {
/* 必须给右下按钮组留位:按钮组 right:16px、宽 52+10+52=114px,
其左边缘在 innerW-130;搜索栏 left:16 → 上限 innerW-130-12-16 = 100%-158px。
否则展开后发送按钮会压在视图切换/管理入口上(窄屏尤其明显)。 */
width: min(560px, calc(100% - 158px)) !important;
min-height: 58px !important;
padding: 7px 8px !important;
border-radius: 20px !important;
}
html[data-theme] .navi-search-bar[data-state="collapsed"] input,
html[data-theme] .navi-search-bar[data-state="collapsed"] .navi-search-submit {
display: none !important;
}
html[data-theme] .navi-search-toggle {
flex: 0 0 42px !important;
width: 42px !important;
height: 42px !important;
display: grid !important;
place-items: center !important;
padding: 0 !important;
color: #0f172a !important;
background: transparent !important;
border: 0 !important;
border-radius: 50% !important;
cursor: pointer;
appearance: none !important;
-webkit-appearance: none !important;
-webkit-tap-highlight-color: transparent;
transition: transform .28s cubic-bezier(.22, 1, .36, 1) !important;
}
/* 点击与聚焦都不变蓝,只保留轻微缩放反馈。 */
html[data-theme] .navi-search-toggle:hover,
html[data-theme] .navi-search-toggle:focus,
html[data-theme] .navi-search-toggle:active {
color: #0f172a !important;
background: transparent !important;
outline: none !important;
}
@media (hover: hover) {
html[data-theme] .navi-search-toggle:hover {
transform: scale(1.05);
}
}
html[data-theme] .navi-search-toggle:active {
transform: scale(.96);
}
/* ── 右下角按钮组(视图切换 + 管理入口)────
两者放进同一个 fixed 容器,便于在工作空间作为一组收边,
避免各自位移后互相重叠。 */
html[data-theme] .navi-dock {
position: fixed !important;
right: calc(16px + env(safe-area-inset-right, 0px)) !important;
bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important;
display: flex !important;
align-items: center !important;
gap: 10px !important;
z-index: 900 !important;
}
html[data-theme] .navi-dock > .navi-admin-entry {
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
}
html[data-theme] .navi-dock > .navi-view-switch {
position: relative !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
}
/* 右侧管理入口:Dashy 页面本身没有去 /admin/ 的链接 */
html[data-theme] .navi-admin-entry {
box-sizing: border-box !important;
width: 52px !important;
height: 52px !important;
display: grid !important;
place-items: center !important;
z-index: 900 !important;
color: #334155 !important;
background: rgba(255, 255, 255, .72) !important;
border: 1px solid rgba(255, 255, 255, .9) !important;
border-radius: 50% !important;
box-shadow: 0 14px 38px rgba(15, 23, 42, .16), inset 0 1px 0 rgba(255, 255, 255, .95) !important;
backdrop-filter: blur(22px) saturate(180%) !important;
-webkit-backdrop-filter: blur(22px) saturate(180%) !important;
-webkit-tap-highlight-color: transparent !important;
transition: transform .22s cubic-bezier(.22, 1, .36, 1), background .2s ease !important;
}
html[data-theme] .navi-admin-entry:hover,
html[data-theme] .navi-admin-entry:focus,
html[data-theme] .navi-admin-entry:active {
color: #334155 !important;
background: rgba(255, 255, 255, .94) !important;
outline: none !important;
}
@media (hover: hover) {
html[data-theme] .navi-admin-entry:hover {
transform: translateY(-1px) scale(1.05);
}
}
html[data-theme] .navi-admin-entry:active {
transform: scale(.96);
}
html[data-theme] .navi-admin-entry svg {
width: 22px !important;
height: 22px !important;
}
html[data-theme] body:has(.modal-overlay) > .navi-dock,
html[data-theme] body:has(.modal-overlay) .navi-admin-entry {
visibility: hidden !important;
pointer-events: none !important;
}
/* ── 视图切换:圆形悬浮按钮,紧贴管理入口左侧 ──
原生 .switch-view-buttons 是侧栏底部的方形图标,这里一并隐藏。 */
html[data-theme] nav.side-bar .switch-view-buttons {
display: none !important;
}
html[data-theme] .navi-view-switch {
display: block !important;
}
html[data-theme] .navi-view-toggle {
box-sizing: border-box !important;
width: 52px !important;
height: 52px !important;
display: grid !important;
place-items: center !important;
padding: 0 !important;
color: #334155 !important;
background: rgba(255, 255, 255, .72) !important;
border: 1px solid rgba(255, 255, 255, .9) !important;
border-radius: 50% !important;
box-shadow: 0 14px 38px rgba(15, 23, 42, .16), inset 0 1px 0 rgba(255, 255, 255, .95) !important;
backdrop-filter: blur(22px) saturate(180%) !important;
-webkit-backdrop-filter: blur(22px) saturate(180%) !important;
-webkit-tap-highlight-color: transparent !important;
appearance: none !important;
-webkit-appearance: none !important;
outline: none !important;
cursor: pointer;
transition: transform .22s cubic-bezier(.22, 1, .36, 1), background .2s ease !important;
}
html[data-theme] .navi-view-toggle:hover,
html[data-theme] .navi-view-toggle:focus,
html[data-theme] .navi-view-toggle:active {
color: #334155 !important;
background: rgba(255, 255, 255, .94) !important;
}
@media (hover: hover) {
html[data-theme] .navi-view-toggle:hover {
transform: translateY(-1px) scale(1.05);
}
}
html[data-theme] .navi-view-toggle:active {
transform: scale(.96);
}
html[data-theme] .navi-view-toggle svg {
width: 22px !important;
height: 22px !important;
}
html[data-theme] .navi-view-menu {
position: absolute !important;
right: 0 !important;
bottom: 62px !important;
min-width: 134px !important;
display: flex !important;
flex-direction: column !important;
gap: 2px !important;
padding: 7px !important;
background: rgba(255, 255, 255, .92) !important;
border: 1px solid rgba(255, 255, 255, .95) !important;
border-radius: 16px !important;
box-shadow: 0 18px 40px rgba(15, 23, 42, .18), inset 0 1px 0 rgba(255, 255, 255, .95) !important;
backdrop-filter: blur(20px) saturate(180%) !important;
-webkit-backdrop-filter: blur(20px) saturate(180%) !important;
animation: navi-fade-up .22s cubic-bezier(.22, 1, .36, 1) both;
}
html[data-theme] .navi-view-menu[hidden] {
display: none !important;
}
html[data-theme] .navi-view-option {
padding: 9px 12px !important;
color: #334155 !important;
font-size: 13.5px !important;
text-decoration: none !important;
border-radius: 10px !important;
white-space: nowrap !important;
-webkit-tap-highlight-color: transparent !important;
}
html[data-theme] .navi-view-option:hover,
html[data-theme] .navi-view-option:focus,
html[data-theme] .navi-view-option:active {
color: #0f172a !important;
background: rgba(226, 232, 240, .7) !important;
outline: none !important;
}
html[data-theme] .navi-view-option.is-active {
color: #0f172a !important;
background: rgba(186, 230, 253, .55) !important;
font-weight: 600 !important;
}
html[data-theme] body:has(.modal-overlay) .navi-view-switch {
visibility: hidden !important;
pointer-events: none !important;
}
html[data-theme] .navi-search-bar input {
min-width: 0 !important;
height: 42px !important;
flex: 1 1 auto !important;
padding: 0 4px !important;
color: #0f172a !important;
background: transparent !important;
border: 0 !important;
outline: 0 !important;
box-shadow: none !important;
font: inherit !important;
font-size: 16px !important;
}
html[data-theme] .navi-search-bar input::placeholder {
color: #64748b !important;
opacity: 1;
}
html[data-theme] .navi-search-submit {
flex: 0 0 44px !important;
width: 44px !important;
height: 44px !important;
display: grid !important;
place-items: center !important;
padding: 0 !important;
color: #fff !important;
background: linear-gradient(135deg, #0ea5e9, #2563eb) !important;
border: 0 !important;
border-radius: 14px !important;
box-shadow: 0 8px 20px rgba(37, 99, 235, .28) !important;
cursor: pointer;
-webkit-tap-highlight-color: transparent !important;
outline: none !important;
}
html[data-theme] .navi-search-toggle svg,
html[data-theme] .navi-search-submit svg {
width: 20px;
height: 20px;
}
/* 放大镜与搜索框同步形变:圆环、手柄退场,向左收起箭头进入。 */
html[data-theme] .navi-search-toggle svg {
overflow: visible;
}
html[data-theme] .navi-magnifier-ring,
html[data-theme] .navi-magnifier-handle,
html[data-theme] .navi-collapse-arrow {
transform-box: fill-box;
transform-origin: center;
transition: opacity .22s ease, transform .28s cubic-bezier(.22, 1, .36, 1) !important;
}
html[data-theme] .navi-collapse-arrow {
opacity: 0;
transform: translateX(5px) scale(.62);
}
html[data-theme] .navi-search-bar[data-state="open"] .navi-magnifier-ring {
opacity: 0;
transform: translateX(-4px) scale(.28);
}
html[data-theme] .navi-search-bar[data-state="open"] .navi-magnifier-handle {
opacity: 0;
transform: translate(-4px, -4px) rotate(-35deg) scale(.45);
}
html[data-theme] .navi-search-bar[data-state="open"] .navi-collapse-arrow {
opacity: 1;
transform: translateX(0) scale(1);
}
/* Minimal view is the phone/tablet layout used by Dashy. */
html[data-theme] .minimal-home {
box-sizing: border-box !important;
width: min(100% - 24px, 920px) !important;
max-width: 920px !important;
min-height: auto !important;
margin: 0 auto !important;
padding: 28px 0 16px !important;
background: transparent !important;
}
html[data-theme] .minimal-home .title-and-search {
padding: 0 8px !important;
}
/* ── 顶部标题:三个视图统一(同字号/字重/字距/居中)──
此前 /minimal 是 48px 居中,而 / 与 /workspace 是顶栏里 40px 左对齐,
同一个站点的三个视图两套标题样式,很割裂。 */
html[data-theme] #dashy > header {
display: flex !important;
align-items: center !important;
justify-content: center !important;
padding: 10px 12px !important;
}
html[data-theme] #dashy > header .page-titles {
display: block !important;
width: auto !important;
max-width: 100% !important;
margin: 0 auto !important;
text-align: center !important;
}
html[data-theme] #dashy > header .page-titles .text {
display: block !important;
text-align: center !important;
}
html[data-theme] #dashy > header .page-titles .subtitle {
display: block !important;
margin: 6px 0 0 !important;
color: #64748b !important;
font-size: 13.5px !important;
font-weight: 400 !important;
letter-spacing: 0 !important;
text-align: center !important;
}
html[data-theme] #dashy > header .page-titles h1,
html[data-theme] .minimal-home .title-and-search h1 {
max-width: 100%;
margin: 0 !important;
color: #0f172a !important;
font-size: clamp(1.75rem, 4vw, 2.75rem) !important;
font-weight: 700 !important;
line-height: 1.08 !important;
letter-spacing: -.035em !important;
text-align: center !important;
overflow-wrap: anywhere;
}
html[data-theme] .minimal-home > .item-group-container {
box-sizing: border-box !important;
width: 100% !important;
margin: 32px auto 0 !important;
padding: 0 6px !important;
}
html[data-theme] .minimal-headings-wrap {
position: relative;
z-index: 2;
gap: 6px !important;
margin-bottom: 8px !important;
}
html[data-theme] .minimal-headings-row {
gap: 6px !important;
scroll-snap-type: x proximity;
}
html[data-theme] .minimal-headings-row .headings {
flex-basis: 132px !important;
min-height: 44px !important;
padding: 8px 12px !important;
border-radius: 14px !important;
scroll-snap-align: start;
}
html[data-theme] .minimal-headings-row .headings .section-title {
font-size: 15px !important;
line-height: 1.2 !important;
}
html[data-theme] .minimal-headings-wrap .tab-scroll-btn {
min-width: 34px !important;
padding: 0 8px !important;
border-radius: 12px !important;
}
html[data-theme] .minimal-section-inner {
padding: 8px !important;
background: rgba(255, 255, 255, .34) !important;
border: 1px solid rgba(255, 255, 255, .72) !important;
border-radius: 20px !important;
box-shadow: 0 16px 38px rgba(15, 23, 42, .10), inset 0 1px 0 rgba(255, 255, 255, .88) !important;
backdrop-filter: blur(20px) saturate(170%) !important;
-webkit-backdrop-filter: blur(20px) saturate(170%) !important;
}
/* 空分组(非选中分组 / 无条目)不能被渲染成空玻璃条。
Dashy 会把其余分组渲染成 16px 的空 .minimal-section-inner,
一旦给它加了边框和底色就会变成一排“莫名其妙的框”。 */
html[data-theme] .minimal-section-inner:not(:has(a.item)),
html[data-theme] .minimal-section-inner:empty {
display: none !important;
}
html[data-theme] .minimal-widget-wrap:empty {
display: none !important;
}
html[data-theme] .minimal-section-inner .section-items {
gap: 10px !important;
}
html[data-theme] .minimal-section-inner a.item {
box-sizing: border-box !important;
min-height: 82px !important;
margin: 0 !important;
padding: 12px 16px !important;
}
@media (max-width: 599px) {
html[data-theme] .minimal-home {
width: min(100% - 16px, 430px) !important;
padding-top: 22px !important;
}
html[data-theme] #dashy > header .page-titles h1,
html[data-theme] .minimal-home .title-and-search h1 {
font-size: clamp(1.6rem, 8vw, 2.2rem) !important;
}
html[data-theme] .minimal-home > .item-group-container {
margin-top: 26px !important;
padding: 0 !important;
}
html[data-theme] .minimal-headings-row .headings {
flex-basis: 116px !important;
padding: 8px 10px !important;
}
html[data-theme] .minimal-section-inner {
padding: 7px !important;
}
html[data-theme] .minimal-section-inner a.item {
min-height: 78px !important;
padding: 10px 12px !important;
border-radius: 16px !important;
}
html[data-theme] a.item .item-icon {
flex-basis: 52px !important;
width: 52px !important;
min-width: 52px !important;
height: 52px !important;
min-height: 52px !important;
}
html[data-theme] a.item .item-icon .tile-icon,
html[data-theme] a.item .item-icon img,
html[data-theme] a.item .item-icon object {
width: 44px !important;
min-width: 44px !important;
max-width: 44px !important;
height: 44px !important;
min-height: 44px !important;
max-height: 44px !important;
}
/* Keep the screen-level warning inside the phone viewport. */
html[data-theme] .modal-overlay .modal-body {
min-width: 0 !important;
max-width: 100vw !important;
overflow-x: hidden !important;
}
html[data-theme] .modal-overlay .config-tabs {
overflow-x: auto !important;
overscroll-behavior-x: contain;
scrollbar-width: none;
}
html[data-theme] .modal-overlay .config-tabs::-webkit-scrollbar {
display: none;
}
html[data-theme] .modal-overlay .config-tabs > * {
flex: 0 0 auto !important;
}
html[data-theme] .modal-overlay .config-buttons,
html[data-theme] .modal-overlay .config-buttons > * {
min-width: 0 !important;
max-width: 100% !important;
}
html[data-theme] .modal-overlay .config-buttons > p,
html[data-theme] .modal-overlay .config-buttons .warning,
html[data-theme] .modal-overlay .config-buttons .info {
white-space: normal !important;
overflow-wrap: anywhere !important;
}
html[data-theme] .navi-search-bar {
left: calc(10px + env(safe-area-inset-left, 0px)) !important;
bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important;
}
html[data-theme] .navi-search-bar[data-state="collapsed"] {
width: 52px !important;
height: 52px !important;
}
html[data-theme] .navi-search-bar[data-state="open"] {
/* 移动端按钮组 right:10px、宽 48+8+48=104px → 左边缘 innerW-114,
搜索栏 left:10 → 上限 100%-132px */
width: calc(100% - 132px) !important;
min-height: 56px !important;
border-radius: 18px !important;
}
html[data-theme] .navi-admin-entry {
width: 48px !important;
height: 48px !important;
}
html[data-theme] .navi-dock {
right: calc(10px + env(safe-area-inset-right, 0px)) !important;
bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important;
gap: 8px !important;
}
/* 移动端基准 right:10px,露出 14px → 位移 = 自身宽度 - 4px */
html[data-theme][data-navi-view="workspace"] .navi-dock {
transform: translateX(calc(100% - 4px)) !important;
}
html[data-theme] .navi-view-toggle {
width: 48px !important;
height: 48px !important;
}
html[data-theme] .navi-view-toggle svg {
width: 20px !important;
height: 20px !important;
}
html[data-theme] body {
padding-bottom: 0 !important;
}
}
/* 极窄屏(≤380px):输入框展开时右下按钮组整组让位。
预留式收窄在 320px 下只剩 68px 可输入,不可用;搜索是聚焦动作,
此时把两个按钮藏起来(visibility 不受 prefers-reduced-motion 影响,
比 transform 更可靠),搜索栏即可用满宽度。 */
@media (max-width: 380px) {
html[data-theme] .navi-search-bar[data-state="open"] {
width: calc(100% - 40px) !important;
}
html[data-theme] .navi-search-bar[data-state="open"] ~ .navi-dock {
visibility: hidden !important;
pointer-events: none !important;
opacity: 0 !important;
}
}
/* ── 页脚:备案号胶囊 ──
备案号在 /admin/ 里编辑,这里只负责呈现;同时清掉历史上塞在
内联样式里的 margin-bottom:80px(那是给旧的流式搜索栏让位的)。 */
html[data-theme] footer {
margin: 0 !important;
padding: 0 0 8px !important;
background: transparent !important;
}
html[data-theme] footer > div {
margin-bottom: 0 !important;
padding: 0 !important;
}
/* 极简/工作空间视图补的备案号页脚:留在文档流里,靠 body 的 flex
把它顶到页面底部(贴着悬浮搜索栏上方),而不是 fixed 浮在内容中间。 */
html[data-theme] .navi-footer-host {
margin-top: auto !important;
display: flex !important;
justify-content: center !important;
padding: 8px !important;
}
html[data-theme] .navi-footer {
display: flex !important;
flex-wrap: wrap !important;
align-items: center !important;
justify-content: center !important;
gap: 9px !important;
width: fit-content !important;
max-width: min(680px, calc(100% - 24px)) !important;
margin: 14px auto 0 !important;
padding: 9px 18px !important;
color: #64748b !important;
font-size: 12.5px !important;
line-height: 1.4 !important;
background: rgba(255, 255, 255, .55) !important;
border: 1px solid rgba(255, 255, 255, .78) !important;
border-radius: 999px !important;
box-shadow: 0 6px 18px rgba(15, 23, 42, .06), inset 0 1px 0 rgba(255, 255, 255, .92) !important;
backdrop-filter: blur(14px) saturate(170%) !important;
-webkit-backdrop-filter: blur(14px) saturate(170%) !important;
}
html[data-theme] .navi-footer a {
color: #64748b !important;
text-decoration: none !important;
border-bottom: 1px dashed rgba(100, 116, 139, .45) !important;
-webkit-tap-highlight-color: transparent !important;
}
html[data-theme] .navi-footer a:hover,
html[data-theme] .navi-footer a:focus,
html[data-theme] .navi-footer a:active {
color: #64748b !important;
border-bottom-color: rgba(100, 116, 139, .45) !important;
outline: none !important;
}
html[data-theme] .navi-footer-sep {
color: rgba(100, 116, 139, .45) !important;
}
/* ── 工作空间:悬浮控件与备案号收起到屏幕边缘 ──
工作空间中间嵌的是别人的应用,这些常驻控件会遮挡内容。
搜索球收左边缘、右下角按钮组整组收右边缘、备案号收下边缘,
各留 14px 露出;鼠标移入或点击、聚焦时滑出展开。 */
html[data-theme][data-navi-view="workspace"] .navi-search-bar,
html[data-theme][data-navi-view="workspace"] .navi-dock,
html[data-theme][data-navi-view="workspace"] .navi-footer-host {
opacity: .55 !important;
transition: transform .26s cubic-bezier(.22, 1, .36, 1), opacity .26s ease !important;
animation: none !important;
}
/* 基础 left 为 16px、宽 56px → 位移 58px 后恰好露出 14px */
html[data-theme][data-navi-view="workspace"] .navi-search-bar {
transform: translateX(-58px) !important;
}
/* 按钮组整组右移自身宽度减 14px,恰好露出 14px */
html[data-theme][data-navi-view="workspace"] .navi-dock {
/* 基准 right:16px,露出 14px → 位移 = 自身宽度 + 16px - 14px */
transform: translateX(calc(100% + 2px)) !important;
}
html[data-theme][data-navi-view="workspace"] .navi-footer-host {
position: fixed !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
z-index: 880 !important;
padding: 0 !important;
transform: translateY(calc(100% - 13px)) !important;
}
/* 展开:悬停 / 聚焦 / 按下 / 搜索已展开 */
html[data-theme][data-navi-view="workspace"] .navi-search-bar:hover,
html[data-theme][data-navi-view="workspace"] .navi-search-bar:focus-within,
html[data-theme][data-navi-view="workspace"] .navi-search-bar[data-state="open"],
html[data-theme][data-navi-view="workspace"] .navi-dock:hover,
html[data-theme][data-navi-view="workspace"] .navi-dock:focus-within,
html[data-theme][data-navi-view="workspace"] .navi-footer-host:hover,
html[data-theme][data-navi-view="workspace"] .navi-footer-host:focus-within {
opacity: 1 !important;
transform: translateX(0) translateY(0) !important;
}
/* ── 工作空间:点侧栏应用 → 在中间内嵌打开网页 ──
Dashy 的面板就是 iframe,我们只是让它在文档流里正常显示、并且只在
「可内嵌」时显示;被拒绝时改为明确提示,而不是一片空白。
用正常文档流(而不是 fixed 钉在视口中间),否则会把页面切成
「顶栏 / 大方块 / 底部」三段,看起来上下都被截断。 */
html[data-theme] .work-space {
height: auto !important;
min-height: 0 !important;
}
html[data-theme] .work-space .multi-taking-view,
html[data-theme] .work-space .workspace-widget-view {
display: none !important;
}
/* iframe 面板与提示卡共用同一块位置,切换状态时布局不跳动 */
html[data-theme] .work-space .web-content,
html[data-theme] .work-space .navi-ws-notice {
box-sizing: border-box !important;
position: static !important;
display: none !important;
width: auto !important;
height: min(72vh, 720px) !important;
min-height: 300px !important;
margin: 18px 18px 14px 72px !important;
border: 1px solid rgba(255, 255, 255, .85) !important;
border-radius: 20px !important;
box-shadow: 0 18px 44px rgba(15, 23, 42, .14), inset 0 1px 0 rgba(255, 255, 255, .92) !important;
overflow: hidden !important;
z-index: 1 !important;
}
html[data-theme] .work-space .web-content {
padding: 0 !important;
background: #fff !important;
}
html[data-theme] .work-space[data-navi-ws="frame"] .web-content {
display: block !important;
margin-top: 8px !important;
}
/* 面板工具条:常驻退路(刷新 / 在新标签页打开),只在内嵌态出现 */
html[data-theme] .navi-ws-bar {
display: none !important;
}
html[data-theme] .work-space[data-navi-ws="frame"] .navi-ws-bar {
box-sizing: border-box !important;
position: static !important;
display: flex !important;
align-items: center !important;
gap: 10px !important;
min-height: 40px !important;
margin: 18px 18px 0 72px !important;
padding: 5px 6px 5px 16px !important;
background: rgba(255, 255, 255, .55) !important;
border: 1px solid rgba(255, 255, 255, .82) !important;
border-radius: 999px !important;
box-shadow: 0 10px 26px rgba(15, 23, 42, .1), inset 0 1px 0 rgba(255, 255, 255, .92) !important;
backdrop-filter: blur(16px) saturate(180%) !important;
-webkit-backdrop-filter: blur(16px) saturate(180%) !important;
}
html[data-theme] .navi-ws-bar-host {
color: #0f172a !important;
font-size: 13.5px !important;
font-weight: 600 !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
html[data-theme] .navi-ws-bar-note {
color: #94a3b8 !important;
font-size: 12.5px !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
html[data-theme] .navi-ws-bar-spacer {
flex: 1 1 auto !important;
}
html[data-theme] .navi-ws-bar-btn {
flex: 0 0 auto !important;
padding: 6px 13px !important;
color: #334155 !important;
font-family: inherit !important;
font-size: 12.5px !important;
background: rgba(255, 255, 255, .72) !important;
border: 1px solid rgba(255, 255, 255, .9) !important;
border-radius: 999px !important;
cursor: pointer;
-webkit-tap-highlight-color: transparent !important;
outline: none !important;
}
html[data-theme] .navi-ws-bar-btn:hover,
html[data-theme] .navi-ws-bar-btn:focus,
html[data-theme] .navi-ws-bar-btn:active {
color: #0f172a !important;
background: rgba(255, 255, 255, .95) !important;
}
html[data-theme] .work-space .web-content iframe {
/* 必须是 static:Dashy 默认 absolute,包含块是 #dashy 而不是 .web-content,
于是 .web-content 的 overflow:hidden 拦不住它,iframe 会按 #dashy 的高度
撑高整页(实测多出 77px 纵向滚动)。 */
position: static !important;
display: block !important;
width: 100% !important;
height: 100% !important;
border: 0 !important;
background: #fff !important;
}
html[data-theme] .work-space[data-navi-ws="hint"] .navi-ws-notice,
html[data-theme] .work-space[data-navi-ws="loading"] .navi-ws-notice,
html[data-theme] .work-space[data-navi-ws="blocked"] .navi-ws-notice {
display: flex !important;
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
gap: 10px !important;
padding: 24px !important;
text-align: center !important;
background: rgba(255, 255, 255, .55) !important;
backdrop-filter: blur(18px) saturate(180%) !important;
-webkit-backdrop-filter: blur(18px) saturate(180%) !important;
}
html[data-theme] .navi-ws-notice-title {
color: #0f172a !important;
font-size: 16px !important;
font-weight: 650 !important;
}
html[data-theme] .navi-ws-notice-text {
color: #64748b !important;
font-size: 13.5px !important;
}
html[data-theme] .navi-ws-notice-url {
max-width: 80% !important;
color: #94a3b8 !important;
font-size: 12.5px !important;
word-break: break-all !important;
}
html[data-theme] .navi-ws-open {
margin-top: 6px !important;
padding: 9px 18px !important;
color: #fff !important;
font-family: inherit !important;
font-size: 13.5px !important;
background: linear-gradient(135deg, #0ea5e9, #2563eb) !important;
border: 0 !important;
border-radius: 999px !important;
box-shadow: 0 10px 24px rgba(37, 99, 235, .28) !important;
-webkit-tap-highlight-color: transparent !important;
outline: none !important;
cursor: pointer;
}
/* ── 工作空间:侧栏与内容区同样走玻璃圆角 ── */
html[data-theme] nav.side-bar {
background: rgba(255, 255, 255, .62) !important;
border-right: 1px solid rgba(255, 255, 255, .6) !important;
backdrop-filter: blur(18px) saturate(180%) !important;
-webkit-backdrop-filter: blur(18px) saturate(180%) !important;
}
html[data-theme] nav.side-bar .side-bar-section {
padding: 2px !important;
}
html[data-theme] nav.side-bar .side-bar-item {
border-radius: 12px !important;
transition: background .2s ease !important;
}
html[data-theme] nav.side-bar .side-bar-item:hover {
background: rgba(255, 255, 255, .92) !important;
}
/* ── 动效 ──
只动 transform / opacity,不触发布局;时长 180–380ms,
缓动统一 cubic-bezier(.22,1,.36,1)(快速起步、平稳收尾)。 */
@keyframes navi-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes navi-fade-up {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes navi-bar-in {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
html[data-theme] html,
html[data-theme] body {
scroll-behavior: smooth;
}
/* 视图切换:主内容与选中分组淡入 */
html[data-theme] #dashy > *,
html[data-theme] .minimal-section-inner.selected,
html[data-theme] .work-space {
animation: navi-fade-in .3s cubic-bezier(.22, 1, .36, 1) both;
}
/* 悬浮搜索栏:从下侧滑入 */
html[data-theme] .navi-search-bar {
animation: navi-bar-in .36s cubic-bezier(.22, 1, .36, 1) both;
transition: box-shadow .24s ease, border-color .24s ease, background .24s ease,
width .28s cubic-bezier(.22, 1, .36, 1), border-radius .28s ease !important;
}
html[data-theme] .navi-admin-entry {
animation: navi-fade-in .42s ease both;
}
html[data-theme] .navi-search-submit {
transition: transform .2s cubic-bezier(.22, 1, .36, 1), box-shadow .2s ease, filter .2s ease !important;
}
html[data-theme] .navi-search-submit:hover {
filter: brightness(1.06);
transform: translateY(-1px) scale(1.04);
box-shadow: 0 12px 26px rgba(37, 99, 235, .34) !important;
}
html[data-theme] .navi-search-submit:focus,
html[data-theme] .navi-search-submit:active {
outline: none !important;
}
html[data-theme] .navi-search-submit:active {
transform: translateY(0) scale(.96);
}
html[data-theme] .navi-footer-host {
animation: navi-fade-in .42s ease both;
}
/* 卡片逐个淡入:只作用在内容层,避免和 masonry 布局的位移冲突 */
html[data-theme] div.collapsible-content .item-wrapper,
html[data-theme] .minimal-section-inner .item-wrapper {
animation: navi-fade-up .34s cubic-bezier(.22, 1, .36, 1) both;
}
html[data-theme] .item-wrapper:nth-child(1) { animation-delay: 0ms; }
html[data-theme] .item-wrapper:nth-child(2) { animation-delay: 30ms; }
html[data-theme] .item-wrapper:nth-child(3) { animation-delay: 60ms; }
html[data-theme] .item-wrapper:nth-child(4) { animation-delay: 90ms; }
html[data-theme] .item-wrapper:nth-child(5) { animation-delay: 120ms; }
html[data-theme] .item-wrapper:nth-child(6) { animation-delay: 150ms; }
html[data-theme] .item-wrapper:nth-child(n+7) { animation-delay: 180ms; }
/* 分组容器:悬停轻微上浮 */
html[data-theme] div.collapsable {
transition: box-shadow .26s ease, border-color .26s ease, transform .26s cubic-bezier(.22, 1, .36, 1) !important;
}
html[data-theme] div.collapsable:hover {
transform: translateY(-2px);
border-color: rgba(147, 197, 253, .6) !important;
box-shadow: 0 18px 40px rgba(15, 23, 42, .12), inset 0 1px 0 rgba(255, 255, 255, .9) !important;
}
html[data-theme] div.collapsable h2,
html[data-theme] .minimal-headings-row .headings {
transition: background .22s ease, color .22s ease, transform .22s cubic-bezier(.22, 1, .36, 1), border-color .22s ease !important;
}
html[data-theme] .minimal-headings-row .headings:hover {
transform: translateY(-1px);
border-color: rgba(147, 197, 253, .75) !important;
}
html[data-theme] .minimal-headings-row .headings:active {
transform: scale(.975);
}
html[data-theme] .minimal-headings-wrap .tab-scroll-btn {
transition: background .2s ease, color .2s ease, transform .2s cubic-bezier(.22, 1, .36, 1) !important;
}
html[data-theme] .minimal-headings-wrap .tab-scroll-btn:hover:not([disabled]) {
transform: scale(1.06);
}
html[data-theme] a.item:active {
transform: translateY(-1px) scale(.99) !important;
}
html[data-theme] a.item .item-icon img,
html[data-theme] a.item .item-icon svg {
transition: transform .26s cubic-bezier(.22, 1, .36, 1) !important;
}
html[data-theme] nav.side-bar .side-bar-item {
transition: background .2s ease, transform .2s cubic-bezier(.22, 1, .36, 1) !important;
}
html[data-theme] nav.side-bar .side-bar-item:hover {
transform: scale(1.06);
}
html[data-theme] .navi-footer a {
transition: color .2s ease, border-color .2s ease !important;
}
@media (prefers-reduced-motion: reduce) {
html[data-theme] html,
html[data-theme] body {
scroll-behavior: auto !important;
}
html[data-theme] #dashy > *,
html[data-theme] .minimal-section-inner.selected,
html[data-theme] .work-space,
html[data-theme] .navi-search-bar,
html[data-theme] .navi-dock,
html[data-theme] .navi-admin-entry,
html[data-theme] .navi-footer-host,
html[data-theme] div.collapsible-content .item-wrapper,
html[data-theme] .minimal-section-inner .item-wrapper {
animation: none !important;
opacity: 1 !important;
transform: none !important;
}
html[data-theme] a.item,
html[data-theme] a.item .tile-icon {
transition: none !important;
}
html[data-theme] a.item:hover,
html[data-theme] div.collapsable:hover,
html[data-theme] nav.side-bar .side-bar-item:hover,
html[data-theme] .minimal-headings-row .headings:hover {
transform: none !important;
}
}