mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-30 05:05:13 +08:00
🎄 Sync 2026-05-06 19:35:12
This commit is contained in:
1 parent
b3aea13cdd
commit
f58b6dd3a1
50 files changed
+1787
-626
No files matched your search
@@ -3,7 +3,8 @@ A Material Design 3 theme for OpenWrt Luci.
|
||||
|
||||
This is a personal project based on the LuCI Bootstrap theme, imitating the Material Design 3 style.
|
||||
|
||||
**Nice to initiate an issue or PR!**
|
||||
**Nice to initiate an issue or PR, and star! ⭐**
|
||||
|
||||
## ✨ Preview
|
||||
<table>
|
||||
<tr>
|
||||
@@ -19,37 +20,61 @@ This is a personal project based on the LuCI Bootstrap theme, imitating the Mate
|
||||
### 🎨 All color schemes
|
||||
<table>
|
||||
<tr>
|
||||
<th>Baseline Purple</th>
|
||||
<th>Trust Blue</th>
|
||||
<th>Growth Green</th>
|
||||
<th width="33.33%" align="center">Baseline Purple</th>
|
||||
<th width="33.33%" align="center">Trust Blue</th>
|
||||
<th width="33.33%" align="center">Growth Green</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/baseline.jpg" /></td>
|
||||
<td><img src="imgs/blue.jpg" /></td>
|
||||
<td><img src="imgs/green.jpg" /></td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/baseline.jpg" width="100%" />
|
||||
</td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/blue.jpg" width="100%" />
|
||||
</td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/green.jpg" width="100%" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Calm Teal</th>
|
||||
<th>Warm Orange</th>
|
||||
<th>Vivid Orange</th>
|
||||
<th width="33.33%" align="center">Calm Teal</th>
|
||||
<th width="33.33%" align="center">Warm Orange</th>
|
||||
<th width="33.33%" align="center">Vivid Orange</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/teal.jpg" /></td>
|
||||
<td><img src="imgs/orange.jpg" /></td>
|
||||
<td><img src="imgs/vivid-orange.jpg" /></td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/teal.jpg" width="100%" />
|
||||
</td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/orange.jpg" width="100%" />
|
||||
</td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/vivid-orange.jpg" width="100%" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sakura Red</th>
|
||||
<th>Expressive Rose</th>
|
||||
<th>Monochrome Gray</th>
|
||||
<th width="33.33%" align="center">Sakura Red</th>
|
||||
<th width="33.33%" align="center">Expressive Rose</th>
|
||||
<th width="33.33%" align="center">Monochrome Gray</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/sakura.jpg" /></td>
|
||||
<td><img src="imgs/rose.jpg" /></td>
|
||||
<td><img src="imgs/gray.jpg" /></td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/sakura.jpg" width="100%" />
|
||||
</td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/rose.jpg" width="100%" />
|
||||
</td>
|
||||
<td width="33.33%" align="center">
|
||||
<img src="imgs/gray.jpg" width="100%" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 📦 Release
|
||||
Download prebuilt packages from [GitHub Releases](https://github.com/KawaiiHachimi/luci-theme-material3/releases).
|
||||
|
||||
- `luci-theme-material3-*.apk` -> OpenWrt LuCI 25.12+
|
||||
- `luci-theme-material3_*.ipk` -> OpenWrt LuCI 23.05~24.10
|
||||
|
||||
## 🙏 Credits
|
||||
- [OpenWrt Luci](https://github.com/openwrt/luci)
|
||||
- [Cursor](https://www.cursor.com/)
|
||||
@@ -57,4 +82,4 @@ This is a personal project based on the LuCI Bootstrap theme, imitating the Mate
|
||||
- [MDUI](https://www.mdui.org/zh-cn/)
|
||||
- [Fluent UI System Icons](https://github.com/microsoft/fluentui-system-icons)
|
||||
- [Material Design 3](https://m3.material.io/)
|
||||
- [Reddit - LuCI theme bootstrap: Some modifications using userstyle](https://www.reddit.com/r/openwrt/comments/qmtmpf/lucithemebootstrap_some_modifications_using/)
|
||||
- [Reddit - LuCI theme bootstrap: Some modifications using userstyle](https://www.reddit.com/r/openwrt/comments/qmtmpf/lucithemebootstrap_some_modifications_using/)
|
||||
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* LuCI Bootstrap Theme
|
||||
* Material3 Mod
|
||||
* Material3 Mod by KawaiiHachimi <bilibili@att.net>
|
||||
* Copyright 2012 Nut & Bolt
|
||||
* By David Menting <david@nut-bolt.nl>
|
||||
* Based on Bootstrap v1.4.0
|
||||
@@ -131,7 +131,8 @@
|
||||
--material3-shell-background: var(--surface);
|
||||
--material3-shell-foreground: var(--on-surface);
|
||||
--material3-shell-state: var(--surface-container);
|
||||
--material3-header-background: color-mix(in srgb, var(--material3-shell-background) 88%, transparent);
|
||||
--material3-header-background: color-mix(in srgb, var(--material3-shell-background) 72%, transparent);
|
||||
--material3-header-scrolled-background: color-mix(in srgb, var(--material3-card-background) 72%, transparent);
|
||||
--material3-header-foreground: var(--material3-shell-foreground);
|
||||
--material3-header-state: var(--material3-shell-state);
|
||||
--material3-indicator-hover-background: var(--primary-container);
|
||||
@@ -1512,7 +1513,8 @@ select {
|
||||
.cbi-value {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 18px;
|
||||
margin: 0;
|
||||
padding: 9px 0;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
@@ -2079,12 +2081,17 @@ header p {
|
||||
header {
|
||||
background: var(--material3-header-background);
|
||||
box-shadow: none;
|
||||
transition: box-shadow .3s;
|
||||
transition: background-color .3s, box-shadow .3s;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
header.with-shadow {
|
||||
box-shadow: none;
|
||||
background: var(--material3-header-scrolled-background);
|
||||
box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%);
|
||||
}
|
||||
|
||||
body.sidebar-open header {
|
||||
background: var(--material3-shell-background);
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
@@ -2166,7 +2173,7 @@ header.with-shadow {
|
||||
top: var(--material3-header-height);
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 760;
|
||||
z-index: 820;
|
||||
box-sizing: border-box;
|
||||
width: var(--material3-sidebar-width);
|
||||
padding: 0;
|
||||
@@ -2246,6 +2253,17 @@ header.with-shadow {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open],
|
||||
.cbi-dropdown[open]>ul.dropdown {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open]>ul.dropdown {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.nav {
|
||||
@@ -2282,6 +2300,22 @@ header.with-shadow {
|
||||
transition: .3s;
|
||||
}
|
||||
|
||||
.nav-menu-title {
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
-webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
|
||||
mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
|
||||
}
|
||||
|
||||
.nav a:hover>.nav-menu-title,
|
||||
.nav a:focus>.nav-menu-title {
|
||||
-webkit-mask-image: none;
|
||||
mask-image: none;
|
||||
}
|
||||
|
||||
.nav>li>a::before {
|
||||
content: '';
|
||||
width: 1.5rem;
|
||||
@@ -2412,7 +2446,6 @@ header {
|
||||
border: none;
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
box-shadow: none;
|
||||
background: var(--md-sys-color-surface-translucent);
|
||||
}
|
||||
|
||||
@@ -2443,7 +2476,8 @@ header {
|
||||
transition: .3s;
|
||||
padding: 1rem 1.5rem;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 2rem;
|
||||
overflow: hidden;
|
||||
text-shadow: none;
|
||||
@@ -2786,6 +2820,7 @@ footer ul.breadcrumb {
|
||||
white-space: pre-wrap;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
border-radius: var(--material3-card-radius);
|
||||
}
|
||||
|
||||
.modal>.button-row {
|
||||
@@ -2822,8 +2857,16 @@ body.modal-overlay-active #modal_overlay {
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
background:
|
||||
radial-gradient(circle at top left, color-mix(in srgb, var(--primary-container) 64%, transparent), transparent 34rem),
|
||||
radial-gradient(circle at top right, color-mix(in srgb, var(--tertiary-container) 58%, transparent), transparent 30rem),
|
||||
radial-gradient(circle at 18% 8%,
|
||||
color-mix(in srgb, var(--primary-container) 38%, transparent),
|
||||
transparent 28rem),
|
||||
linear-gradient(135deg,
|
||||
color-mix(in srgb, var(--background) 78%, var(--primary-container)) 0%,
|
||||
color-mix(in srgb, var(--background) 92%, var(--primary-container)) 46%,
|
||||
color-mix(in srgb, var(--surface-container-low) 88%, var(--primary)) 100%),
|
||||
linear-gradient(180deg,
|
||||
color-mix(in srgb, var(--surface-container-low) 48%, transparent) 0%,
|
||||
transparent 52%),
|
||||
var(--background);
|
||||
}
|
||||
|
||||
@@ -2833,10 +2876,14 @@ body.modal-overlay-active #modal_overlay {
|
||||
max-width: 420px;
|
||||
margin: 0;
|
||||
padding: 32px;
|
||||
border: 0;
|
||||
border: 1px solid color-mix(in srgb, var(--outline-variant) 52%, transparent);
|
||||
border-radius: 28px;
|
||||
background: var(--material3-card-background);
|
||||
box-shadow: var(--material3-card-shadow);
|
||||
background: color-mix(in srgb, var(--material3-card-background) 78%, transparent);
|
||||
backdrop-filter: blur(24px) saturate(1.12);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(1.12);
|
||||
box-shadow:
|
||||
0 12px 36px color-mix(in srgb, var(--outline) 18%, transparent),
|
||||
0 1px 1px color-mix(in srgb, var(--outline) 10%, transparent);
|
||||
color: var(--on-surface);
|
||||
}
|
||||
|
||||
@@ -2954,8 +3001,8 @@ body.modal-overlay-active #modal_overlay {
|
||||
}
|
||||
|
||||
.modal.login .material3-login-header img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.modal.login .material3-login-header h2 {
|
||||
@@ -3434,16 +3481,18 @@ body.modal-overlay-active #modal_overlay {
|
||||
}
|
||||
|
||||
.cbi-progressbar {
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
min-width: 170px;
|
||||
height: 4px;
|
||||
margin: 1.4em 0 4px 0;
|
||||
background: var(--background-color-medium);
|
||||
background: var(--surface-container-high);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.cbi-progressbar>div {
|
||||
background: var(--primary-color-medium);
|
||||
background: var(--primary);
|
||||
height: 100%;
|
||||
transition: width .25s ease-in;
|
||||
width: 0%;
|
||||
@@ -3605,7 +3654,7 @@ header [data-indicator] {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
color: color-mix(in srgb, var(--material3-header-foreground) 80%, var(--material3-header-background));
|
||||
color: color-mix(in srgb, var(--material3-header-foreground) 60%, var(--material3-header-background));
|
||||
background: transparent;
|
||||
transition: background-color .2s ease, color .2s ease;
|
||||
}
|
||||
@@ -3966,7 +4015,7 @@ th[data-sort-direction="desc"]::after {
|
||||
background: var(--default-btn-background, var(--background-color-high));
|
||||
color: var(--on-color, var(--text-color-high));
|
||||
text-shadow: none;
|
||||
border-radius: 16px;
|
||||
border-radius: 12px;
|
||||
box-shadow: none;
|
||||
cursor: default;
|
||||
line-height: 1.2em;
|
||||
@@ -4413,8 +4462,9 @@ div.cbi-value var.cbi-tooltip-container,
|
||||
|
||||
.cbi-section-node,
|
||||
.table {
|
||||
margin: 0 1px 10px 1px;
|
||||
width: calc(100% - 2px);
|
||||
box-sizing: border-box;
|
||||
margin: 0 0 10px;
|
||||
width: 100%;
|
||||
border-radius: var(--material3-card-radius);
|
||||
background: var(--material3-card-background);
|
||||
box-shadow: var(--material3-card-shadow);
|
||||
@@ -4432,44 +4482,33 @@ div.cbi-value var.cbi-tooltip-container,
|
||||
stroke: var(--text-color-highest) !important;
|
||||
}
|
||||
|
||||
/* Status overview */
|
||||
body[data-page="admin-status-overview"] .cbi-section {
|
||||
/* Status overview and dashboard */
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-section,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .cbi-section,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"]) .cbi-section-node {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-section {
|
||||
margin: 0 0 18px;
|
||||
padding: 0;
|
||||
width: auto;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title h3 {
|
||||
color: var(--on-surface);
|
||||
font-size: 18px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-section>.cbi-title+div {
|
||||
margin: 1px;
|
||||
width: calc(100% - 2px);
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-section-descr,
|
||||
body[data-page="admin-status-overview"] .cbi-map-descr,
|
||||
body[data-page="admin-status-overview"] .cbi-section p,
|
||||
body[data-page="admin-status-overview"] .cbi-section li,
|
||||
body[data-page="admin-status-overview"] .table .td,
|
||||
body[data-page="admin-status-overview"] .table .th {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) :is(.cbi-section-descr,
|
||||
.cbi-map-descr,
|
||||
.cbi-section p,
|
||||
.cbi-section li) {
|
||||
color: var(--on-surface-variant);
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title .label {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -4489,7 +4528,7 @@ body[data-page="admin-status-overview"] .cbi-title .label {
|
||||
transition: background-color .2s ease, color .2s ease, opacity .2s ease;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title .label::before {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label::before {
|
||||
content: '';
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
@@ -4498,70 +4537,65 @@ body[data-page="admin-status-overview"] .cbi-title .label::before {
|
||||
mask: url("icons/eye-off.svg") center/contain no-repeat;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title .label:hover {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label:hover,
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label.notice:hover {
|
||||
background: var(--material3-menu-hover-background);
|
||||
color: var(--on-surface);
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title .label.notice {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label.notice {
|
||||
background: transparent;
|
||||
color: color-mix(in srgb, var(--on-surface-variant) 72%, transparent);
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title .label.notice::before {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label.notice::before {
|
||||
-webkit-mask-image: url("icons/eye.svg");
|
||||
mask-image: url("icons/eye.svg");
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-title .label.notice:hover {
|
||||
background: var(--material3-menu-hover-background);
|
||||
color: var(--on-surface);
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .network-status-table {
|
||||
gap: 10px;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .network-status-table {
|
||||
width: calc(100% + 16px);
|
||||
margin: 0 -8px 8px;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .network-status-table .ifacebox {
|
||||
margin: 8px;
|
||||
width: calc(100% - 16px);
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .network-status-table .ifacebox {
|
||||
flex: 1 1 260px;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
border: 0;
|
||||
border-radius: var(--material3-card-radius);
|
||||
background: var(--material3-card-background);
|
||||
box-shadow: var(--material3-card-shadow);
|
||||
text-align: left;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .ifacebox .ifacebox-head {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .ifacebox .ifacebox-head {
|
||||
padding: 2px 0 8px;
|
||||
border: 0;
|
||||
border-radius: 16px 16px 0 0;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
background: transparent !important;
|
||||
color: var(--on-surface-variant);
|
||||
font-weight: 400;
|
||||
opacity: .9;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .ifacebox .ifacebox-head strong {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .ifacebox .ifacebox-head strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .ifacebox .ifacebox-head.active {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .ifacebox .ifacebox-head.active {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
background: transparent !important;
|
||||
color: var(--on-surface);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .ifacebox .ifacebox-body {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .ifacebox .ifacebox-body {
|
||||
padding: 0;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .ifacebadge,
|
||||
body[data-page="admin-status-overview"] .ifacebadge.large,
|
||||
body[data-page="admin-status-overview"] .network-status-table .ifacebox-body .ifacebadge {
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .ifacebadge,
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .ifacebadge.large,
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .network-status-table .ifacebox-body .ifacebadge {
|
||||
padding: 8px;
|
||||
border: 1px solid color-mix(in srgb, var(--outline) 48%, transparent);
|
||||
border-radius: 16px;
|
||||
@@ -4570,55 +4604,19 @@ body[data-page="admin-status-overview"] .network-status-table .ifacebox-body .if
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .table {
|
||||
margin: 1px;
|
||||
width: calc(100% - 2px);
|
||||
border-radius: var(--material3-card-radius);
|
||||
background: var(--material3-card-background);
|
||||
box-shadow: var(--material3-card-shadow);
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-progressbar {
|
||||
border: 0;
|
||||
background: var(--surface-container-high);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .cbi-progressbar>div {
|
||||
background: var(--primary);
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .table .td,
|
||||
body[data-page="admin-status-overview"] .table .th,
|
||||
body[data-page="admin-status-overview"] .tr.cbi-section-table-titles,
|
||||
body[data-page="admin-status-overview"] .cbi-section-table-titles.named::before,
|
||||
body[data-page="admin-status-overview"] .cbi-section-table-descr.named::before,
|
||||
body[data-page="admin-status-overview"] .cbi-section-table-row[data-title]::before {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
body[data-page="admin-status-overview"] .tr.cbi-section-table-titles {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Dashboard cards */
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .cbi-section,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .cbi-section-node {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .dashboard-bg.box-s1 {
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .dashboard-bg.box-s1,
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .network-status-table .ifacebox {
|
||||
border: 0;
|
||||
border-radius: var(--material3-card-radius);
|
||||
background: var(--material3-card-background);
|
||||
box-shadow: var(--material3-card-shadow);
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .thead.dashboard-bg,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .tr.dashboard-bg,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .tfoot.dashboard-bg {
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard :is(.thead.dashboard-bg,
|
||||
.tr.dashboard-bg,
|
||||
.tfoot.dashboard-bg,
|
||||
.table) {
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
@@ -4627,34 +4625,28 @@ body[data-page="admin-status-overview"] .tr.cbi-section-table-titles {
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .table {
|
||||
margin: 0;
|
||||
width: auto;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard hr,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .table .td,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .table .th {
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .router-status-wifi .assoclist.devices-info .tr> :nth-child(3) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .router-status-wifi .assoclist.devices-info .tr> :nth-child(4) {
|
||||
width: 20%;
|
||||
min-width: 85px;
|
||||
white-space: normal;
|
||||
word-break: keep-all;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard hr {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard h3,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .settings-info,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .table .td,
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .table .th {
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard :is(h3, .settings-info) {
|
||||
color: var(--on-surface-variant);
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .cbi-progressbar {
|
||||
border: 0;
|
||||
background: var(--surface-container-high);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard .cbi-progressbar>div {
|
||||
background: var(--primary);
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-status-iptables"], body[data-page="admin-status-nftables-iptables"]) .cbi-tabmenu {
|
||||
margin-top: 28px;
|
||||
}
|
||||
@@ -4662,4 +4654,4 @@ body[data-page="admin-status-overview"] .tr.cbi-section-table-titles {
|
||||
[data-darkmode="true"] :is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard img.svgmonotone,
|
||||
[data-mode="dark"] :is(body[data-page="admin-dashboard"], body[data-page="admin"], body[data-page=""]) .Dashboard img.svgmonotone {
|
||||
filter: invert(1) brightness(1.65) contrast(.82) opacity(.86);
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,15 @@ header h3 a {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
footer {
|
||||
width: 100%;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label {
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
font-size: 0 !important;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
:is(body[data-page="admin-status-overview"], body[data-page=""]) .cbi-title .label::before {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
@media screen and (max-device-width: 600px) {
|
||||
@@ -143,6 +148,7 @@ footer {
|
||||
}
|
||||
|
||||
.tr.table-titles,
|
||||
.tr.dashboard-table-titles,
|
||||
.cbi-section-table-titles,
|
||||
.cbi-section-table-descr {
|
||||
display: none;
|
||||
@@ -189,6 +195,7 @@ footer {
|
||||
max-width: 100%;
|
||||
padding: 3px 2px;
|
||||
flex-basis: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.hide-sm,
|
||||
@@ -301,25 +308,41 @@ footer {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
[data-page="admin-status-overview"] .td[width="33%"] {
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .td[width="33%"] {
|
||||
flex-basis: 33%;
|
||||
}
|
||||
|
||||
[data-page="admin-status-overview"] .table {
|
||||
margin: 4px;
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
|
||||
[data-page="admin-status-overview"] .table,
|
||||
[data-page="admin-status-overview"] .tr,
|
||||
[data-page="admin-status-overview"] .td,
|
||||
[data-page="admin-status-overview"] .th,
|
||||
[data-page="admin-status-overview"] .tr[data-title]::before,
|
||||
[data-page="admin-status-overview"] .td[data-title]::before {
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .table,
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .tr,
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .td,
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .th,
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .tr[data-title]::before,
|
||||
:is([data-page="admin-status-overview"], [data-page=""]) .td[data-title]::before {
|
||||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
:is([data-page="admin-dashboard"], [data-page="admin"], [data-page=""]) :is(.Dashboard, .dashboard-bg.box-s1) .td[data-title]::before {
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
:is([data-page="admin-dashboard"], [data-page="admin"], [data-page=""]) .Dashboard .devices-list .devices-info .tr .td {
|
||||
padding: 3px !important;
|
||||
}
|
||||
|
||||
:is([data-page="admin-dashboard"], [data-page="admin"], [data-page=""]) .Dashboard .router-status-wifi.dashboard-bg.box-s1 .assoclist.devices-info.table>.tr:not(.dashboard-table-titles)>.td {
|
||||
display: block;
|
||||
flex: 0 0 50% !important;
|
||||
width: 50% !important;
|
||||
max-width: 50%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:is([data-page="admin-dashboard"], [data-page="admin"], [data-page=""]) .Dashboard .router-status-wifi.dashboard-bg.box-s1 .assoclist.devices-info .cbi-progressbar {
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
header .pull-right .label {
|
||||
white-space: normal;
|
||||
display: inline-block;
|
||||
@@ -530,4 +553,4 @@ footer {
|
||||
.ifacebox .ifacebox-body>* {
|
||||
margin: .125em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ return baseclass.extend({
|
||||
__init__() {
|
||||
ui.menu.load().then((tree) => this.render(tree));
|
||||
this.initNavigationShell();
|
||||
this.initDashboardTables();
|
||||
},
|
||||
|
||||
createRipple(ev, target) {
|
||||
@@ -64,11 +65,16 @@ return baseclass.extend({
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const overlay = document.querySelector('.sidebar-overlay');
|
||||
const header = document.querySelector('header');
|
||||
const collapsedQuery = window.matchMedia('(max-width: 854px), (max-device-width: 854px)');
|
||||
|
||||
if (header) {
|
||||
window.addEventListener('scroll', () => {
|
||||
header.classList.toggle('with-shadow', window.scrollY > 8);
|
||||
});
|
||||
const updateHeaderShadow = () => {
|
||||
header.classList.toggle('with-shadow', collapsedQuery.matches && window.scrollY > 8);
|
||||
};
|
||||
|
||||
updateHeaderShadow();
|
||||
window.addEventListener('scroll', updateHeaderShadow, { passive: true });
|
||||
collapsedQuery.addEventListener('change', updateHeaderShadow);
|
||||
}
|
||||
|
||||
if (!button || !sidebar || !overlay)
|
||||
@@ -78,6 +84,7 @@ return baseclass.extend({
|
||||
sidebar.classList.remove('active');
|
||||
overlay.classList.remove('active');
|
||||
button.classList.remove('active');
|
||||
document.body.classList.remove('sidebar-open');
|
||||
document.body.style.overflow = '';
|
||||
button.setAttribute('aria-expanded', 'false');
|
||||
};
|
||||
@@ -88,6 +95,7 @@ return baseclass.extend({
|
||||
const isOpen = sidebar.classList.contains('active');
|
||||
|
||||
button.classList.toggle('active', isOpen);
|
||||
document.body.classList.toggle('sidebar-open', isOpen);
|
||||
document.body.style.overflow = isOpen ? 'hidden' : '';
|
||||
button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
||||
});
|
||||
@@ -117,7 +125,87 @@ return baseclass.extend({
|
||||
if (target)
|
||||
this.createRipple(ev, target);
|
||||
});
|
||||
},
|
||||
|
||||
sidebar.addEventListener('mouseover', ev => {
|
||||
const link = ev.target.closest('.nav a');
|
||||
const title = link ? link.querySelector('.nav-menu-title') : null;
|
||||
|
||||
if (title && title.scrollWidth > title.clientWidth)
|
||||
title.scrollTo({ left: title.scrollWidth - title.clientWidth, behavior: 'smooth' });
|
||||
});
|
||||
|
||||
sidebar.addEventListener('mouseout', ev => {
|
||||
const link = ev.target.closest('.nav a');
|
||||
const title = link ? link.querySelector('.nav-menu-title') : null;
|
||||
|
||||
if (title && !link.contains(ev.relatedTarget))
|
||||
title.scrollTo({ left: 0, behavior: 'smooth' });
|
||||
});
|
||||
},
|
||||
|
||||
isDashboardPage() {
|
||||
const path = (L.env.requestpath || []).join('/');
|
||||
|
||||
return path == '' || path == 'admin' || path == 'admin/dashboard';
|
||||
},
|
||||
|
||||
initDashboardTables() {
|
||||
if (!this.isDashboardPage())
|
||||
return;
|
||||
|
||||
const sync = () => this.updateDashboardTables();
|
||||
|
||||
if (document.readyState == 'loading')
|
||||
document.addEventListener('DOMContentLoaded', sync, { once: true });
|
||||
else
|
||||
sync();
|
||||
|
||||
const target = document.querySelector('#maincontent') || document.body;
|
||||
let queued = false;
|
||||
const observer = new MutationObserver(() => {
|
||||
if (queued)
|
||||
return;
|
||||
|
||||
queued = true;
|
||||
window.setTimeout(() => {
|
||||
queued = false;
|
||||
sync();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
if (target)
|
||||
observer.observe(target, { childList: true, subtree: true });
|
||||
},
|
||||
|
||||
updateDashboardTables() {
|
||||
document.querySelectorAll('.Dashboard, .dashboard-bg.box-s1').forEach(scope => {
|
||||
scope.querySelectorAll('.table').forEach(table => {
|
||||
const rows = Array.prototype.filter.call(table.children, child => child.classList && child.classList.contains('tr'));
|
||||
const headerRow = rows.find(row => row.querySelector('.th'));
|
||||
|
||||
if (!headerRow)
|
||||
return;
|
||||
|
||||
const titles = Array.prototype.map.call(headerRow.children, cell =>
|
||||
cell.classList && cell.classList.contains('th') ? cell.textContent.trim() : '');
|
||||
|
||||
headerRow.classList.add('dashboard-table-titles');
|
||||
|
||||
rows.forEach(row => {
|
||||
if (row === headerRow)
|
||||
return;
|
||||
|
||||
Array.prototype.forEach.call(row.children, (cell, index) => {
|
||||
if (!cell.classList || !cell.classList.contains('td') || !titles[index])
|
||||
return;
|
||||
|
||||
if (!cell.getAttribute('data-title'))
|
||||
cell.setAttribute('data-title', titles[index]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render(tree) {
|
||||
let node = tree;
|
||||
@@ -148,7 +236,7 @@ return baseclass.extend({
|
||||
const className = 'tabmenu-item-%s %s'.format(child.name, activeClass);
|
||||
|
||||
ul.appendChild(E('li', { 'class': className }, [
|
||||
E('a', { 'href': L.url(url, child.name) }, [ _(child.title) ] )]));
|
||||
E('a', { 'href': L.url(url, child.name) }, [_(child.title)])]));
|
||||
|
||||
if (isActive)
|
||||
activeNode = child;
|
||||
@@ -204,7 +292,7 @@ return baseclass.extend({
|
||||
|
||||
const li = E('li', attrs, [
|
||||
E('a', linkAttrs, [
|
||||
_(child.title),
|
||||
E('span', { 'class': 'nav-menu-title' }, [_(child.title)]),
|
||||
]),
|
||||
submenu
|
||||
]);
|
||||
@@ -230,7 +318,7 @@ return baseclass.extend({
|
||||
: index === 0;
|
||||
|
||||
ul.appendChild(E('li', { 'class': isActive ? 'active' : '' }, [
|
||||
E('a', { 'href': L.url(child.name) }, [ _(child.title) ])
|
||||
E('a', { 'href': L.url(child.name) }, [_(child.title)])
|
||||
]));
|
||||
|
||||
if (isActive)
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
/
|
||||
<a href="{{ entityencode(version.disturl ?? '#', true) }}" target="_blank" rel="noreferrer">
|
||||
{{ version.distname }} {{ version.distversion }} ({{ version.distrevision }})</a>
|
||||
/
|
||||
<a href="https://github.com/KawaiiHachimi/luci-theme-material3" target="_blank" rel="noreferrer">
|
||||
luci-theme-material3</a>
|
||||
{% if (lua_active): %}
|
||||
/ {{ _('Lua compatibility mode active') }}
|
||||
{% endif %}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<meta name="darkreader-lock">
|
||||
<link rel="stylesheet" href="{{ media }}/cascade.css">
|
||||
<link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="{{ media }}/mobile.css" />
|
||||
<link rel="icon" href="{{ media }}/logo.svg" sizes="any">
|
||||
<link rel="icon" href="{{ media }}/logo.svg" sizes="any">
|
||||
{% if (node?.css): %}
|
||||
<link rel="stylesheet" href="{{ resource }}/{{ node.css }}">
|
||||
{% endif %}
|
||||
|
||||
Reference in new issue
Block a user