/* * Deni shell adapted from OpenVue Foundation Deni (MIT), commit * 72156473d5f73a26f97d35aa5fed3a96059779ef: * src/assets/styles/_layout.scss, _sidebar.scss, _topbar.scss. * Nuxt 路由插槽、维护横幅偏移测量及移动端无障碍焦点管理保留本地实现。 */ .deni-layout { min-height: 100dvh; padding-top: var(--console-banner-height, 0px); background: var(--deni-ground); } .deni-layout .layout-main { display: flex; flex-direction: column; min-width: 0; min-height: calc(100dvh - var(--console-banner-height, 0px)); margin-left: var(--deni-sidebar-width); } .deni-layout .layout-content { flex: 1 1 auto; width: 100%; min-width: 0; max-width: var(--deni-content-max); margin: 0 auto; padding: 24px 32px 48px; } .deni-layout .layout-content:focus { outline: none; } .deni-layout .maintenance-banner { position: fixed; inset: 0 0 auto; z-index: 1000; display: flex; align-items: flex-start; gap: 8px; min-height: 38px; max-height: 40dvh; padding: 8px 14px; overflow-y: auto; background: var(--p-yellow-100); color: var(--p-yellow-900); } .deni-layout .maintenance-message { min-width: 0; overflow-wrap: anywhere; } .deni-layout .maintenance-banner > .iconify { flex-shrink: 0; width: 18px; height: 18px; margin-top: 2px; } .app-dark .deni-layout .maintenance-banner { background: var(--p-yellow-950); color: var(--p-yellow-200); } .deni-layout .sidebar { --deni-menu-active-background: var(--p-primary-50); --deni-menu-active-color: var(--p-text-color); --deni-menu-active-accent: var(--p-primary-600); --deni-menu-sub-active-color: var(--p-primary-700); position: fixed; top: var(--console-banner-height, 0px); bottom: 0; left: 0; z-index: 950; display: flex; flex-direction: column; width: var(--deni-sidebar-width); background: var(--deni-panel); border-right: 1px solid var(--p-content-border-color); transition: transform var(--deni-transition); } .app-dark .deni-layout .sidebar { --deni-menu-active-background: color-mix( in srgb, var(--p-primary-color) 16%, transparent ); --deni-menu-active-color: var(--p-primary-300); --deni-menu-active-accent: var(--p-primary-300); --deni-menu-sub-active-color: var(--p-primary-300); } .deni-layout .sidebar-brand { display: flex; flex: 0 0 auto; align-items: center; gap: 10px; height: var(--deni-topbar-height); padding: 0 16px; border-bottom: 1px solid var(--p-content-border-color); } .deni-layout .brand, .deni-layout .mobile-brand { display: inline-flex; align-items: center; min-width: 0; } .deni-layout .brand-logo { display: block; width: 148px; height: auto; max-height: 32px; object-fit: contain; } .deni-layout .sidebar-nav { flex: 1 1 auto; min-height: 0; padding: 12px 10px 20px; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; } .deni-layout .sidebar-section + .sidebar-section { margin-top: 20px; } .deni-layout .sidebar-section-label { margin: 0; padding: 0 8px 6px; color: var(--p-text-muted-color); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; } .deni-layout .sidebar-list { display: flex; flex-direction: column; gap: 1px; } .deni-layout .nav-item { position: relative; display: flex; align-items: center; gap: 10px; width: 100%; min-height: 36px; padding: 7px 10px; border: 0; border-radius: 4px; background: transparent; color: var(--p-text-color); font: inherit; font-size: 13.5px; text-align: left; text-decoration: none; cursor: pointer; transition: background var(--deni-transition), color var(--deni-transition); } .deni-layout .nav-item:hover, .deni-layout .sub-item:hover { background: var(--deni-hover); text-decoration: none; } .deni-layout .nav-item:focus-visible { outline-offset: -2px; } .deni-layout .nav-item.active:not(button), .deni-layout .nav-item.router-link-exact-active { background: var(--deni-menu-active-background); color: var(--deni-menu-active-color); font-weight: 600; } .deni-layout .nav-item.active:not(button)::before { position: absolute; top: 6px; bottom: 6px; left: -10px; width: 2px; border-radius: 0 2px 2px 0; background: var(--p-primary-color); content: ""; } .deni-layout .nav-icon { flex: 0 0 18px; width: 18px; height: 18px; color: var(--p-text-muted-color); } .deni-layout .nav-item.active .nav-icon { color: var(--deni-menu-active-accent); } .deni-layout .nav-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .deni-layout .nav-unavailable { color: var(--p-text-muted-color); cursor: not-allowed; } .deni-layout .nav-arrow { flex-shrink: 0; width: 14px; height: 14px; margin-left: auto; transition: transform var(--deni-transition); } .deni-layout .nav-arrow.open { transform: rotate(90deg); } /* 已有后台递归菜单的 i 图标朝下,静态 Deni 菜单的 Lucide 图标朝右。 */ .deni-layout i.nav-arrow { transform: rotate(-90deg); } .deni-layout i.nav-arrow.open { transform: rotate(0); } .deni-layout .sub-nav { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--deni-transition); } .deni-layout .sub-nav.open { grid-template-rows: 1fr; } .deni-layout .sub-nav-clip { min-height: 0; overflow: hidden; } .deni-layout .sub-nav-items { display: flex; flex-direction: column; gap: 1px; margin: 1px 0 1px 19px; padding-left: 10px; border-left: 1px solid var(--p-content-border-color); } .deni-layout .sub-item { display: block; padding: 6px 10px; border-radius: 4px; color: var(--p-text-muted-color); font-size: 13px; text-decoration: none; transition: background var(--deni-transition), color var(--deni-transition); } .deni-layout .sub-item.active { color: var(--deni-menu-sub-active-color); font-weight: 600; } .deni-layout .sidebar-footer { flex: 0 0 auto; padding: 10px; border-top: 1px solid var(--p-content-border-color); } .deni-layout .sidebar-account { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px; border-radius: 4px; color: var(--p-text-color); text-align: left; text-decoration: none; } .deni-layout .sidebar-account:hover, .deni-layout .topbar-user:hover, .deni-layout .topbar-action:hover, .deni-layout .nav-close:hover { background: var(--deni-hover); } .deni-layout .sidebar-account-text { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; line-height: 1.3; } .deni-layout .sidebar-account-name { overflow: hidden; font-size: 13px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; } .deni-layout .sidebar-account-id { color: var(--p-text-muted-color); font-size: 12px; } .deni-layout .sidebar-account > .iconify { width: 16px; height: 16px; color: var(--p-text-muted-color); } .deni-layout .topbar { position: sticky; top: var(--console-banner-height, 0px); z-index: 800; display: flex; flex: 0 0 auto; align-items: center; gap: 12px; height: var(--deni-topbar-height); padding: 0 20px; border-bottom: 1px solid var(--p-content-border-color); background: var(--deni-panel); } .deni-layout .topbar-left, .deni-layout .topbar-right { display: flex; align-items: center; } .deni-layout .topbar-left { gap: 12px; min-width: 0; } .deni-layout .topbar-right { flex-shrink: 0; gap: 4px; margin-left: auto; } .deni-layout .topbar-action, .deni-layout .nav-close { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--p-text-muted-color); cursor: pointer; } .deni-layout .topbar-action > .iconify, .deni-layout .nav-close > .iconify { width: 20px; height: 20px; } .deni-layout .nav-close { margin-left: auto; } .deni-layout .nav-toggle, .deni-layout .mobile-brand, .deni-layout .nav-close { display: none; } .deni-layout .topbar-divider { width: 1px; height: 20px; margin: 0 6px; background: var(--p-content-border-color); } .deni-layout .topbar-user { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 4px 8px 4px 4px; border: 0; border-radius: 4px; background: transparent; color: var(--p-text-color); font: inherit; cursor: pointer; } .deni-layout .topbar-user-name { max-width: 160px; overflow: hidden; font-size: 13px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; } .deni-layout .topbar-user > .iconify { width: 14px; height: 14px; color: var(--p-text-muted-color); } .deni-layout .crumbs { display: flex; align-items: center; gap: 10px; min-width: 0; overflow: hidden; font-size: 13px; } .deni-layout .crumb-home { display: inline-flex; flex-shrink: 0; color: var(--p-text-muted-color); } .deni-layout .crumb-home > .iconify { width: 16px; height: 16px; } .deni-layout .crumb-sep { flex-shrink: 0; width: 12px; height: 12px; color: var(--p-text-muted-color); } .deni-layout .crumb { color: var(--p-text-muted-color); white-space: nowrap; } .deni-layout .crumb.current { overflow: hidden; color: var(--p-text-color); text-overflow: ellipsis; } .deni-layout .mail-btn { position: relative; } .deni-layout .mail-badge { position: absolute; top: 0; right: 0; min-width: 18px; height: 18px; font-size: 10px; line-height: 18px; pointer-events: none; } .deni-layout .layout-mask { position: fixed; inset: 0; z-index: 900; padding: 0; border: 0; background: var(--deni-mask); cursor: pointer; } .deni-layout .skip-link { position: fixed; top: 8px; left: 14px; z-index: 1100; padding: 12px 18px; border-radius: 4px; background: var(--p-primary-color); color: var(--p-primary-contrast-color); text-decoration: none; transform: translateY(-160%); } .deni-layout .skip-link:focus { transform: translateY(0); } /* Dialog 内容会 Teleport 到 body;这些规则不依赖布局祖先。 */ .mail-pop { width: 100%; } .mail-pop-list { display: flex; flex-direction: column; max-height: 360px; overflow: auto; } .mail-pop-item { display: flex; flex-direction: column; gap: 4px; width: 100%; padding: 14px; border: 0; border-bottom: 1px solid var(--p-content-border-color); background: transparent; color: var(--p-text-color); text-align: left; cursor: pointer; } .mail-pop-item:hover { background: var(--deni-hover); } .mail-pop-title { display: flex; align-items: center; gap: 7px; } .mail-pop-dot { flex-shrink: 0; width: 6px; height: 6px; border-radius: 50%; background: var(--p-primary-color); } .mail-pop-time { color: var(--p-text-muted-color); font-size: 12px; } .mail-pop-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; min-height: 280px; text-align: center; } .mail-pop-empty > .iconify { width: 28px; height: 28px; margin-bottom: 12px; color: var(--p-text-muted-color); } .mail-pop-empty strong { font-size: 16px; font-weight: 600; } .mail-pop-empty > span { color: var(--p-text-muted-color); font-size: 13px; } .mail-pop-foot { display: block; width: 100%; padding: 10px; border: 0; background: transparent; color: var(--p-primary-color); cursor: pointer; } @media (max-width: 1024px) { .deni-layout .layout-main { margin-left: 0; } .deni-layout .layout-content { padding: 20px 20px 40px; } .deni-layout .sidebar { max-width: calc(100vw - 32px); transform: translateX(-100%); } .deni-layout.layout-overlay-open .sidebar { transform: translateX(0); } .deni-layout .nav-toggle, .deni-layout .nav-close, .deni-layout .mobile-brand { display: inline-flex; } .deni-layout .crumbs { display: none; } } @media (max-width: 768px) { .deni-layout .topbar { padding: 0 12px; } .deni-layout .topbar-left { gap: 8px; } .deni-layout .mobile-brand .brand-logo { width: 120px; } .deni-layout .topbar-user { justify-content: center; width: 36px; height: 36px; padding: 0; } .deni-layout .topbar-user-name, .deni-layout .topbar-user > .iconify, .deni-layout .topbar-divider { display: none; } } @media (max-width: 360px) { .deni-layout .mobile-brand .brand-logo { width: 96px; } } @media print { .deni-layout { min-height: 0; padding-top: 0; background: white; } .deni-layout .sidebar, .deni-layout .topbar, .deni-layout .layout-mask, .deni-layout .maintenance-banner, .deni-layout .skip-link { display: none !important; } .deni-layout .layout-main { min-height: 0; margin-left: 0; } .deni-layout .layout-content { max-width: none; padding: 0; } }