/* 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; } /* ── 渲染开销:把 backdrop-filter 从「重复的卡片层」撤掉 ── 实测首页 37 个元素带模糊(24 张卡片 + 6 个分组容器 + 顶栏 + 悬浮件)。 模糊要对背景逐帧重新采样,而卡片又参与逐张淡入/悬停位移, 两者叠加就是肉眼可见的卡顿。这里保留分组容器的玻璃感与悬浮件, 卡片只留半透明底 + 边框 + 投影(视觉差异很小,开销差很多)。 */ html[data-theme] body a.item, html[data-theme] body .minimal-section-inner, html[data-theme] body div.item-wrapper { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; } /* 搜索栏是最常动的元素(宽/圆角/内边距都在变),它的模糊每帧都要重算 */ html[data-theme] body .navi-search-bar { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; } /* ── 底部搜索:左下角放大镜悬浮球 ── 收起态只显示一个放大镜图标;点它展开成输入框; 展开后输入框内左侧仍是同一个放大镜按钮,点它收起。 */ 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 { transition: opacity .2s ease, transform .2s cubic-bezier(.22, 1, .36, 1), visibility 0s linear 0s !important; 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; } /* 滚动行两端用 mask 渐变淡出:此前卡片在滚动行边缘(紧贴两侧 ‹ › 按钮) 被硬切,看起来像"被按钮截断"。用 :has() 关联翻页按钮的 disabled 状态, 已经在尽头的一侧就不淡出,避免"尽头还在渐隐"的错觉。 */ html[data-theme] .minimal-headings-row { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%); mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%); } /* 已到最左:左侧不淡出 */ html[data-theme] .minimal-headings-wrap:has(> .tab-scroll-btn:first-child[disabled]) .minimal-headings-row { -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%); mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%); } /* 已到最右:右侧不淡出 */ html[data-theme] .minimal-headings-wrap:has(> .tab-scroll-btn:last-child[disabled]) .minimal-headings-row { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 100%); mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 100%); } /* 两端都到尽头:完全不淡出 */ html[data-theme] .minimal-headings-wrap:has(> .tab-scroll-btn:first-child[disabled]):has(> .tab-scroll-btn:last-child[disabled]) .minimal-headings-row { -webkit-mask-image: none; mask-image: none; } 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) { /* 备案号在这里会换行成两行(实测 390px 高 39px、320px 高 66px), 而按钮固定在 bottom:76px → 实测两者只剩 1px。把按钮上移并收紧凑页脚, 保证仍有 ~20px 间隙。 */ html[data-theme] .navi-search-bar { bottom: calc(88px + env(safe-area-inset-bottom, 0px)) !important; } html[data-theme] .navi-dock { bottom: calc(88px + env(safe-area-inset-bottom, 0px)) !important; } html[data-theme] .navi-footer { gap: 6px !important; padding: 8px 16px !important; } 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 延迟到淡出结束再切,否则瞬间消失、看不到过渡 */ visibility: hidden !important; pointer-events: none !important; opacity: 0 !important; transform: translateY(10px) !important; transition: opacity .2s ease, transform .2s cubic-bezier(.22, 1, .36, 1), visibility 0s linear .2s !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, /* 触摸/点击展开:第一次交互只滑出,第二次才触发(见 navi.js 的 peek guard) */ html[data-navi-view="workspace"].navi-peek-open .navi-search-bar, html[data-navi-view="workspace"].navi-peek-open .navi-dock, html[data-navi-view="workspace"].navi-peek-open .navi-footer-host { 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; } /* ── 「不支持在工作区显示」弹层 ── 被拒内嵌时不能只是面板里一行字:用户点了必须有明确反馈。 z-index 低于 Dashy 自己的配置弹层(10000),避免挡住它。 */ html[data-theme] .navi-ws-modal { position: fixed !important; inset: 0 !important; z-index: 9990 !important; display: flex !important; align-items: center !important; justify-content: center !important; padding: 18px !important; background: rgba(15, 23, 42, .28) !important; backdrop-filter: blur(4px) !important; -webkit-backdrop-filter: blur(4px) !important; animation: navi-fade-in .18s ease both; } html[data-theme] .navi-ws-modal.closing { opacity: 0 !important; transition: opacity .16s ease !important; } html[data-theme] .navi-ws-modal.closing .navi-ws-modal-card { transform: translateY(8px) scale(.98) !important; transition: transform .16s ease !important; } html[data-theme] .navi-ws-modal-card { box-sizing: border-box !important; width: min(420px, 100%) !important; display: flex !important; flex-direction: column !important; align-items: center !important; gap: 8px !important; padding: 24px 22px 20px !important; text-align: center !important; background: rgba(255, 255, 255, .96) !important; border: 1px solid rgba(255, 255, 255, .9) !important; border-radius: 20px !important; box-shadow: 0 26px 60px rgba(15, 23, 42, .28), inset 0 1px 0 rgba(255, 255, 255, .95) !important; animation: navi-fade-up .22s cubic-bezier(.22, 1, .36, 1) both; } html[data-theme] .navi-ws-modal-title { color: #0f172a !important; font-size: 17px !important; font-weight: 650 !important; } html[data-theme] .navi-ws-modal-host { color: #0284c7 !important; font-size: 13px !important; word-break: break-all !important; } html[data-theme] .navi-ws-modal-text { color: #64748b !important; font-size: 13.5px !important; line-height: 1.5 !important; } html[data-theme] .navi-ws-modal-actions { display: flex !important; flex-wrap: wrap !important; gap: 10px !important; justify-content: center !important; margin-top: 10px !important; } html[data-theme] .navi-ws-modal-ok { padding: 9px 18px !important; color: #334155 !important; font-family: inherit !important; font-size: 13.5px !important; background: rgba(241, 245, 249, .95) !important; border: 1px solid rgba(203, 213, 225, .9) !important; border-radius: 999px !important; cursor: pointer; -webkit-tap-highlight-color: transparent !important; outline: none !important; } html[data-theme] .navi-ws-modal-ok:hover, html[data-theme] .navi-ws-modal-ok:focus { color: #0f172a !important; background: rgba(255, 255, 255, .98) !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-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; } }