🔥 Sync 2026-05-23 20:23:16

This commit is contained in:
github-actions[bot] 2026-05-23 20:23:16 +08:00
parent 00106d0a89
commit 2eb3f7748b
49 changed files with 2005 additions and 1916 deletions

View File

@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=hysteria
PKG_VERSION:=2.9.1
PKG_RELEASE:=6
PKG_VERSION:=2.9.2
PKG_RELEASE:=7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/apernet/hysteria/tar.gz/app/v$(PKG_VERSION)?

View File

@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.5.20
PKG_RELEASE:=133
PKG_RELEASE:=134
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \

View File

@ -61,6 +61,7 @@ function index()
entry({"admin", "services", appname, "server_user"}, cbi(appname .. "/server/user")).leaf = true
--[[ API ]]
entry({"admin", "services", appname, "server_user_update"}, call("server_user_update")).leaf = true
entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true
entry({"admin", "services", appname, "server_user_log"}, call("server_user_log")).leaf = true
entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true
@ -807,6 +808,23 @@ function rollback_rules()
http_write_json_ok()
end
function server_user_update()
local id = http.formvalue("id") -- Node id
local data = http.formvalue("data") -- json new Data
if id and data then
local data_t = jsonParse(data) or {}
if next(data_t) then
for k, v in pairs(data_t) do
uci:set(appname .. "_server", id, k, v)
end
api.uci_save(uci, appname .. "_server")
http_write_json_ok()
return
end
end
http_write_json_error()
end
function server_user_status()
local e = {}
e.index = http.formvalue("index")

View File

@ -14,6 +14,7 @@ formvalue_key = "cbid." .. appname .. "." .. arg[1] .. "."
local header = Template(appname .. "/node_config/header")
header.api = api
header.config = m.config
header.section = arg[1]
m:append(header)
@ -117,6 +118,7 @@ end
local footer = Template(appname .. "/node_config/footer")
footer.api = api
footer.config = m.config
footer.section = arg[1]
m:append(footer)

View File

@ -1,7 +1,5 @@
local m, s = ...
local api = require "luci.passwall.api"
if not api.finded_com("hysteria") then
return
end
@ -10,21 +8,24 @@ local fs = api.fs
local type_name = "Hysteria2"
-- [[ Hysteria2 ]]
s.fields["type"]:value(type_name, "Hysteria2")
if s.val["type"] and s.val["type"] ~= type_name then
return
end
local option_prefix = "hysteria2_"
local function _n(name)
return option_prefix .. name
end
-- [[ Hysteria2 ]]
s.fields["type"]:value(type_name, "Hysteria2")
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o.rmempty = false
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("realms"), translate("Realms"))

View File

@ -1,15 +1,22 @@
local m, s = ...
local api = require "luci.passwall.api"
if not api.finded_com("xray") then
return
end
local fs = api.fs
local type_name = "Xray"
-- [[ Xray ]]
s.fields["type"]:value(type_name, "Xray")
if not s.fields["type"].default then
s.fields["type"].default = type_name
end
if s.val["type"] and s.val["type"] ~= type_name then
return
end
local option_prefix = "xray_"
local function _n(name)
@ -24,10 +31,6 @@ local header_type_list = {
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns"
}
-- [[ Xray ]]
s.fields["type"]:value(type_name, "Xray")
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(ListValue, _n("protocol"), translate("Protocol"))

View File

@ -1,34 +1,37 @@
local m, s = ...
local api = require "luci.passwall.api"
local singbox_bin = api.finded_com("sing-box")
if not singbox_bin then
return
end
local fs = api.fs
local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'")
local type_name = "sing-box"
-- [[ Sing-Box ]]
s.fields["type"]:value(type_name, "Sing-Box")
if not s.fields["type"].default then
s.fields["type"].default = type_name
end
if s.val["type"] and s.val["type"] ~= type_name then
return
end
local option_prefix = "singbox_"
local function _n(name)
return option_prefix .. name
end
local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'")
local ss_method_list = {
"none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
}
-- [[ Sing-Box ]]
s.fields["type"]:value(type_name, "Sing-Box")
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
@ -55,7 +58,6 @@ o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o.rmempty = false
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("auth"), translate("Auth"))

View File

@ -1,7 +1,5 @@
local m, s = ...
local api = require "luci.passwall.api"
if not api.is_finded("microsocks") then
return
end
@ -17,6 +15,13 @@ end
-- [[ microsocks ]]
s.fields["type"]:value(type_name, "Socks")
if not s.fields["type"].default then
s.fields["type"].default = type_name
end
if s.val["type"] and s.val["type"] ~= type_name then
return
end
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"

View File

@ -1,13 +1,19 @@
local m, s = ...
local api = require "luci.passwall.api"
if not api.is_finded("ssserver") then
return
end
local type_name = "SS-Rust"
-- [[ Shadowsocks Rust ]]
s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
if s.val["type"] and s.val["type"] ~= type_name then
return
end
local option_prefix = "ssrust_"
local function _n(name)
@ -20,10 +26,6 @@ local ssrust_encrypt_method_list = {
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
}
-- [[ Shadowsocks Rust ]]
s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))

View File

@ -1,13 +1,19 @@
local m, s = ...
local api = require "luci.passwall.api"
if not api.is_finded("ssr-server") then
return
end
local type_name = "SSR"
-- [[ ShadowsocksR ]]
s.fields["type"]:value(type_name, translate("ShadowsocksR"))
if s.val["type"] and s.val["type"] ~= type_name then
return
end
local option_prefix = "ssr_"
local function _n(name)
@ -33,10 +39,6 @@ local ssr_obfs_list = {
"tls1.0_session_auth", "tls1.2_ticket_auth"
}
-- [[ ShadowsocksR ]]
s.fields["type"]:value(type_name, translate("ShadowsocksR"))
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))

View File

@ -1,7 +1,6 @@
local api = require "luci.passwall.api"
local appname = api.appname
local fs = api.fs
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
api = require "luci.passwall.api"
appname = api.appname
fs = api.fs
m = Map("passwall_server", translate("Server Config"))
m.redirect = api.url("server")
@ -11,12 +10,21 @@ if not arg[1] or not m:get(arg[1]) then
luci.http.redirect(m.redirect)
end
local header = Template(appname .. "/server/config_header")
header.api = api
header.config = m.config
header.section = arg[1]
m:append(header)
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
s = m:section(NamedSection, arg[1], "user", "")
s.addremove = false
s.dynamic = false
local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/"
s.val = m:get(arg[1]) or {}
o = s:option(Flag, "enable", translate("Enable"))
o.default = "1"
o.rmempty = false
@ -32,9 +40,9 @@ for filename in fs.dir(types_dir) do
table.insert(type_table, filename)
end
table.sort(type_table, function(a, b)
if a == "socks.lua" then return true end
if b == "socks.lua" then return false end
return a < b
if a == "socks.lua" then return true end
if b == "socks.lua" then return false end
return a < b
end)
for index, value in ipairs(type_table) do
@ -42,4 +50,10 @@ for index, value in ipairs(type_table) do
setfenv(p_func, getfenv(1))(m, s)
end
local footer = Template(appname .. "/server/config_footer")
footer.api = api
footer.config = m.config
footer.section = arg[1]
m:append(footer)
return m

View File

@ -1293,6 +1293,11 @@ function to_check_self()
end
function luci_types(id, m, s, type_name, option_prefix)
local fv_type
local field_type = s.fields["type"]
if field_type then
fv_type = field_type:formvalue(id)
end
local rewrite_option_table = {}
for key, value in pairs(s.fields) do
if key:find(option_prefix) == 1 then
@ -1361,6 +1366,10 @@ function luci_types(id, m, s, type_name, option_prefix)
else
s.fields[key]:depends({ type = type_name })
end
if fv_type and fv_type ~= type_name then
s.fields[key].rmempty = true
end
end
end
end

View File

@ -4,7 +4,7 @@ local api = self.api
<script type="text/javascript">
//<![CDATA[
document.addEventListener("DOMContentLoaded", function () {
waitForElement('select[name*="<%=api.appname%>"][name*="type"]', function(el) {
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
let o_val = el.value;
el.addEventListener("change", () => {
el.blur();
@ -22,7 +22,7 @@ local api = self.api
}
});
});
waitForElement('select[name*="<%=api.appname%>"][name*="protocol"]', function(el) {
waitForElement('select[name*="<%=self.config%>"][name*="protocol"]', function(el) {
let o_val = el.value;
el.addEventListener("change", () => {
el.blur();

View File

@ -21,7 +21,7 @@ local api = self.api
function getOption(opt) {
var obj;
var id = 'cbid.<%=api.appname%>.' + node_id + '.' + opt;
var id = 'cbid.<%=self.config%>.' + node_id + '.' + opt;
obj = document.getElementsByName(id)[0] || document.getElementById(id);
if (obj) {
var combobox = document.getElementById('cbi.combobox.' + id);

View File

@ -0,0 +1,27 @@
<%
local api = self.api
-%>
<script type="text/javascript">
//<![CDATA[
document.addEventListener("DOMContentLoaded", function () {
waitForElement('select[name*="<%=self.config%>"][name*="type"]', function(el) {
let o_val = el.value;
el.addEventListener("change", () => {
el.blur();
if (o_val != el.value) {
let save = true;
if (save) {
//document.getElementsByClassName('cbi-button-save')[0].click();
update_node({
enable: getOption("enable").value,
remarks: getOption("remarks").value,
type: getOption("type").value,
protocol: ''
});
}
}
});
});
});
//]]>
</script>

View File

@ -0,0 +1,56 @@
<%
local api = self.api
-%>
<script type="text/javascript">
//<![CDATA[
let node_id = "<%=self.section%>";
let node_config_url = '<%=api.url("server_user")%>/' + node_id;
function waitForElement(selector, callback) {
const el = document.querySelector(selector);
if (el) return callback(el);
const observer = new MutationObserver(() => {
const el = document.querySelector(selector);
if (el) {
observer.disconnect();
callback(el);
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
function getOption(opt) {
var obj;
var id = 'cbid.<%=self.config%>.' + node_id + '.' + opt;
obj = document.getElementsByName(id)[0] || document.getElementById(id);
if (obj) {
var combobox = document.getElementById('cbi.combobox.' + id);
if (combobox) {
obj.combobox = combobox;
}
var div = document.getElementById(id);
if (div && div.getElementsByTagName("li").length > 0) {
obj = div;
}
return obj;
} else {
return null;
}
}
function update_node(data) {
XHR.get('<%=api.url("server_user_update")%>', {
id: node_id,
data: JSON.stringify(data)
},
function(x, data) {
if (x && x.status == 200 && data.code == 1) {
window.location.href = node_config_url;
}
else {
alert("<%:Error%>");
}
});
}
//]]>
</script>

View File

@ -0,0 +1,88 @@
*:not(html) {
@apply scrollbar-thumb-rounded-full scrollbar-thin scrollbar-track-transparent scrollbar-thumb-foreground/70;
}
html {
@apply scrollbar-thumb-rounded-full scrollbar-thin scrollbar-track-page-bg scrollbar-thumb-foreground/70;
@apply bg-background relative h-full font-sans;
body {
@apply text-foreground relative flex flex-col bg-transparent text-sm leading-relaxed font-normal transition-all duration-300;
&.modal-overlay-active {
@apply h-screen overflow-hidden;
}
}
}
h1,
h2,
h3,
h4,
h5,
h6 {
@apply text-foreground font-sans leading-tight font-semibold tracking-tight;
}
h1 {
@apply mb-4 pl-6 text-3xl max-md:pl-4 max-md:text-2xl;
}
h2 {
@apply mb-4 pl-5 text-2xl max-md:mb-2 max-md:pl-4 max-md:text-xl;
}
h3 {
@apply mb-4 text-xl font-semibold tracking-tight max-md:mb-2 max-md:text-lg;
}
h4 {
@apply mb-2 text-lg max-md:text-base;
}
h5 {
@apply mb-2 text-base max-md:text-sm;
}
h6 {
@apply mb-2 text-sm max-md:text-xs;
}
hr {
@apply border-0;
}
strong {
@apply font-semibold tracking-tight;
}
abbr {
@apply cursor-help;
}
p {
@apply text-default-foreground text-sm leading-relaxed;
}
pre {
@apply text-secondary-foreground border-secondary/60 bg-secondary/60 block rounded-xl border px-3 py-2 font-mono text-sm leading-relaxed wrap-break-word whitespace-pre-wrap;
}
code {
@apply text-secondary-foreground bg-secondary/80 rounded px-2 py-1 font-mono text-sm;
}
a {
@apply text-link no-underline hover:underline;
}
var {
@apply text-link font-mono;
}
small {
@apply text-default-foreground text-xs font-normal;
}
em {
@apply text-muted-foreground font-medium italic;
}

View File

@ -0,0 +1,237 @@
header {
@apply bg-header-bg sticky top-0 z-60 mb-2;
& .header-content {
@apply relative flex h-14 items-center justify-between px-6 py-3 max-md:px-4 max-md:py-2;
}
[data-nav-type="mega-menu"] & {
& .desktop-menu-container {
@apply bg-header-bg/40 dark:bg-header-bg/90 pointer-events-none absolute inset-x-0 top-0 z-30 h-0 w-full overflow-hidden opacity-0 backdrop-blur-xl transition-all duration-150 ease-in-out max-md:hidden;
&.active {
@apply pointer-events-auto h-(--mega-menu-height,0) opacity-100;
}
}
}
.brand {
@apply hover:text-primary text-foreground inline-block shrink-0 text-xl font-semibold tracking-tight no-underline transition-all duration-200 hover:-translate-y-0.5 max-md:order-1 max-md:flex-1 max-md:text-lg;
}
.nav {
@apply absolute left-1/2 z-60 m-0 flex -translate-x-1/2 transform list-none items-center gap-1 p-0 max-md:hidden;
& > li {
@apply relative;
.menu {
@apply text-foreground block rounded-xl px-3.5 py-1.5 font-medium no-underline transition-all duration-150;
&.menu-active {
@apply text-foreground;
[data-nav-type="mega-menu"] & {
@apply underline decoration-2 underline-offset-4;
}
[data-nav-type="boxed-dropdown"] & {
@apply bg-header-interactive;
}
}
}
& .desktop-nav {
@apply pointer-events-none left-0 z-40 px-0 pt-0 opacity-0 transition-all duration-150;
[data-nav-type="mega-menu"] & {
@apply fixed top-14 left-1/2 -translate-x-1/2 pb-6;
}
[data-nav-type="boxed-dropdown"] & {
@apply absolute top-full mt-2 min-w-48;
}
&.active {
@apply pointer-events-auto opacity-100;
}
& .desktop-nav-list {
[data-nav-type="mega-menu"] & {
@apply grid w-max grid-cols-4 gap-x-4 gap-y-2;
}
[data-nav-type="boxed-dropdown"] & {
@apply border-border bg-header-bg/90 flex flex-col gap-y-1 rounded-3xl border py-2 shadow-lg backdrop-blur-md backdrop-saturate-150 transition-all duration-200;
}
& > li {
@apply m-0 list-none;
& > a {
@apply text-foreground block px-4 whitespace-nowrap no-underline;
[data-nav-type="mega-menu"] & {
@apply py-3 hover:underline hover:decoration-2 hover:underline-offset-4;
}
[data-nav-type="boxed-dropdown"] & {
@apply hover:bg-header-interactive mx-2 rounded-xl py-2;
}
}
}
}
}
}
}
.mobile-controls {
@apply max-md:order-last max-md:flex max-md:shrink-0 max-md:items-center md:hidden;
& .mobile-menu-toggle {
@apply max-md:ml-5 max-md:cursor-pointer max-md:transition-all max-md:duration-200 max-md:hover:scale-105 max-md:active:scale-95;
& svg {
@apply max-md:text-foreground size-5 max-md:transition-transform max-md:duration-200;
}
&.active {
& svg {
@apply max-md:rotate-180;
}
}
}
}
#indicators {
@apply flex shrink-0 flex-row-reverse gap-5 max-md:order-2 max-md:shrink-0 md:gap-8;
& span[data-indicator] {
@apply before:text-foreground size-5 cursor-pointer text-[0px] before:absolute before:size-5 before:bg-current;
&[data-indicator="media_error"] {
@apply before:[mask:url('@assets/icons/error.svg')_center/cover_no-repeat];
}
&[data-indicator="poll-status"] {
&[data-style="active"] {
@apply before:[mask:url('@assets/icons/refresh.svg')_center/cover_no-repeat];
}
&[data-style="inactive"] {
@apply before:[mask:url('@assets/icons/refresh-off.svg')_center/cover_no-repeat];
}
}
&[data-indicator="uci-changes"] {
@apply relative before:[mask:url('@assets/icons/setting.svg')_center/cover_no-repeat];
&[data-count]:not([data-count="0"]) {
@apply after:bg-accent after:text-accent-foreground after:absolute after:-top-0.5 after:-right-0.5 after:z-10 after:flex after:min-h-3 after:min-w-3 after:items-center after:justify-center after:rounded-full after:px-0.5 after:text-[8px] after:leading-none after:font-bold after:shadow-sm after:content-[attr(data-count)];
}
}
}
}
}
#maincontent {
@apply max-w-max-width mx-auto min-h-[calc(100vh-4rem)] w-23/24 px-4 max-md:w-full max-md:px-3;
#view {
@apply animate-in fade-in-0 slide-in-from-top-2 fill-mode-both md:border-border/30 md:bg-page-bg md:hover:border-border/50 mx-0 w-full p-0 shadow-none transition-all duration-300 empty:hidden md:rounded-4xl md:border md:p-6 md:shadow-xl md:hover:shadow-2xl;
.cbi-title-section {
@apply mb-6 leading-relaxed max-md:mx-2 max-md:mb-3;
}
.controls {
@apply m-2 flex flex-wrap items-center gap-3 max-md:m-1 max-md:gap-2;
& label {
& input[type="radio"],
& input[type="checkbox"] {
@apply mr-1 align-middle;
}
}
}
#content_syslog {
@apply m-2 max-md:m-1;
& > div {
@apply flex flex-wrap items-baseline gap-x-2 max-md:gap-x-1.5;
& > .cbi-input-select,
& > .cbi-input-text {
@apply max-md:min-w-45;
}
}
}
& div[style] {
& > svg {
@apply dark:!bg-page-bg;
& line[style] {
@apply dark:!stroke-foreground;
}
}
}
}
.cbi-map-descr,
.cbi-section-descr {
@apply text-muted-foreground mb-6 text-sm leading-relaxed max-md:mx-2 max-md:mb-3 max-md:text-sm;
}
.cbi-page-actions {
@apply border-border/50 mt-6 flex flex-wrap items-center justify-end gap-3 border-t pt-4 max-md:mx-2 max-md:mt-4 max-md:gap-2 max-md:pt-3;
}
.zone-forwards {
@apply flex items-start gap-3 leading-relaxed;
& > span {
@apply text-muted-foreground mt-1.5;
}
.zone-dest {
@apply flex flex-col items-start gap-2;
}
}
#syslog,
#log_textarea {
@apply w-full text-xs leading-snug;
}
#syslog {
@apply bg-terminal-bg text-terminal-foreground rounded-3xl border p-6 shadow-lg max-md:p-3;
}
}
footer {
@apply text-secondary-foreground mt-2 flex min-h-16 flex-wrap items-center justify-between text-xs;
& a {
@apply text-primary;
}
& span {
@apply inline-block text-center;
}
& .breadcrumb {
@apply bg-page-bg/60 hover:bg-page-bg/80 flex items-center gap-1 rounded-full px-3 py-1.5 text-xs shadow-sm backdrop-blur-sm transition-all duration-200 hover:shadow-md;
& li {
@apply list-none;
&.active a {
@apply text-default-foreground;
}
}
}
}
.control-group {
@apply mt-1;
}
.control-group,
.cbi-page-actions > div,
.cbi-section-actions > div {
@apply flex flex-row flex-nowrap items-center gap-2 max-md:flex-wrap max-md:gap-1;
}

View File

@ -0,0 +1,62 @@
/*
PATCH LAYER (temporary)
- Purpose: Quick fixes and app-specific overrides that may be removed at any time.
- Scope: Keep selectors narrow and limited to known breakages only.
- Migration: Promote stable rules to appropriate layers (e.g., components/plugins) or delete once fixed upstream.
*/
/* admin-network-network */
[data-name="bridge-vlan"] > div {
@apply max-md:overflow-visible!;
}
/* luci-app-openclash */
[data-page="admin-services-openclash-config"] {
.sub_div {
img {
@apply h-5 w-5;
}
}
}
[data-page="admin-services-openclash-settings"] {
.cbi-value-field {
& .cbi-input-select {
@apply max-md:w-full!;
}
}
}
/* luci-mod-dashboard */
.Dashboard {
& > .section-content {
& .dashboard-bg {
&.tr {
@apply rounded-none;
}
@apply bg-panel-bg/95 not-[.tr]:border-border/40 not-[.tr]:hover:border-border/50 max-md:bg-panel-bg/98 not-[.tr]:max-md:border-border/30 not-[.tr]:border not-[.tr]:shadow-lg not-[.tr]:hover:shadow-xl not-[.tr]:max-md:border;
}
.title {
img {
&[src*=".svg"] {
@apply dark:invert;
}
}
h3 {
@apply text-foreground border-0 pb-4 max-md:mx-0 max-md:pb-2;
}
}
.router-status-wifi {
.wifi-info {
.devices-info {
.tr {
.td {
@apply nth-3:relative nth-3:top-0 nth-3:w-full nth-3:px-0 max-md:flex-[1_1_50%];
}
}
}
}
}
}
}

View File

@ -0,0 +1,20 @@
/* luci-app-openclash */
.diag-style {
@apply max-md:grid max-md:grid-cols-1 max-md:gap-4;
& > div {
@apply flex flex-col items-center gap-2 max-md:w-full! max-md:gap-1;
}
}
/* luci-app-filemanager */
#file-manager-container {
@apply overflow-auto;
#status-bar {
@apply bg-page-bg border-0;
}
}
/* luci-app-statistics */
[data-page="admin-statistics-graphs"] [data-plugin] img {
@apply dark:hue-rotate-150 dark:invert;
}

View File

@ -0,0 +1,56 @@
.left {
@apply md:text-left!;
&:not(td) {
@apply text-left!;
}
}
.right {
@apply md:text-right!;
&:not(td) {
@apply text-right!;
}
}
.top {
@apply md:align-top!;
&:not(td) {
@apply align-top!;
}
}
.bottom {
@apply md:align-bottom!;
&:not(td) {
@apply align-bottom!;
}
}
.center {
@apply md:text-center!;
&:not(td) {
@apply text-center!;
}
}
.middle {
@apply md:align-middle!;
&:not(td) {
@apply align-middle!;
}
}
.nowrap:not(span) {
@apply md:whitespace-nowrap;
&:not(td) {
@apply whitespace-nowrap;
}
}
.spinning {
@apply relative inline-block pl-8!;
@apply before:absolute before:top-1/2 before:left-[6px] before:size-5 before:-translate-y-1/2 before:animate-spin before:bg-current before:[mask:url('@assets/icons/spinning.svg')_center/cover_no-repeat];
#view > & {
@apply first:mx-auto first:grid first:min-h-48 first:w-fit first:place-items-center first:max-md:min-h-[calc(100dvh-4rem)];
}
}

View File

@ -0,0 +1,70 @@
.label {
@apply bg-default text-default-foreground rounded-full px-3 py-1 text-xs font-bold uppercase;
&.important {
@apply bg-info text-info-foreground;
}
&.warning {
@apply bg-error text-error-foreground;
}
&.success {
@apply bg-success text-success-foreground;
}
&.notice {
@apply bg-warning text-warning-foreground;
}
}
.zonebadge {
@apply border-secondary bg-secondary text-secondary-foreground inline-flex items-center gap-1.5 overflow-visible rounded-full border px-1 py-1.5 text-sm font-medium shadow-sm transition-all duration-200 hover:shadow-md max-md:gap-1 max-md:text-xs;
&[style*="--zone-color-rgb"] {
@apply bg-[rgb(var(--zone-color-rgb),.7)]!;
& em {
@apply text-default-foreground;
}
}
.cbi-dropdown & {
@apply rounded-xl px-1 py-0.5;
}
}
.ifacebadge {
@apply border-border bg-label-surface text-default-foreground hover:border-border hover:bg-label-surface inline-flex cursor-default flex-wrap items-center gap-2 rounded-2xl border px-3 py-2 text-sm font-normal shadow-sm transition-all duration-200 hover:shadow-md max-md:gap-1.5 max-md:px-2.5 max-md:py-1.5 max-md:text-xs;
.cbi-dropdown &,
.cbi-tooltip & {
@apply flex-nowrap;
}
.zonebadge > &,
.cbi-dropdown & {
@apply rounded-2xl px-1.5 py-0;
& img {
@apply mr-1 w-4;
}
}
& > img {
@apply w-5 shrink-0 self-center max-md:w-4;
}
& > span {
& > .nowrap {
@apply mb-1.5 inline-block text-sm max-md:text-xs;
}
}
&.ifacebadge-active {
@apply border-primary font-semibold;
}
&.large {
@apply min-w-[200px] flex-1 px-4 py-3 max-md:min-w-[180px] max-md:px-3 max-md:py-2.5;
}
}

View File

@ -0,0 +1,48 @@
button,
.btn,
.cbi-button {
@apply inline-flex cursor-pointer items-center justify-center gap-1.5 rounded-2xl border px-3 py-1.5 text-sm font-medium antialiased shadow-sm transition-all duration-200 max-md:text-base max-md:font-medium;
&[disabled] {
@apply cursor-not-allowed opacity-40 dark:opacity-30;
}
.td & {
@apply inline-flex w-auto flex-none whitespace-nowrap max-md:min-h-9 max-md:text-sm;
}
}
.btn,
.cbi-button,
.cbi-button-default,
.cbi-button-download,
.cbi-button-find,
.cbi-button-link,
.cbi-button-up,
.cbi-button-down {
@apply border-secondary bg-secondary text-secondary-foreground hover:bg-secondary/90;
}
.drag-handle {
@apply border-muted bg-muted text-muted-foreground hover:bg-muted/90;
}
.btn.primary,
.cbi-button-action,
.cbi-button-apply,
.cbi-button-reload,
.cbi-button-add,
.cbi-button-edit {
@apply border-primary bg-primary hover:bg-primary/90 text-primary-foreground;
}
.cbi-button-positive,
.cbi-button-fieldadd,
.cbi-button-save {
@apply border-primary/25 bg-primary/25 text-primary hover:bg-primary/30;
}
.cbi-button-negative,
.cbi-section-remove .cbi-button,
.cbi-button-reset,
.cbi-button-remove {
@apply border-destructive bg-destructive text-destructive-foreground hover:bg-destructive/90;
}

View File

@ -0,0 +1,159 @@
.cbi-section {
@apply mb-3 overflow-visible rounded-2xl p-5 max-md:p-3;
&[data-tab-title] {
@apply m-0 p-0;
}
&[data-tab-active="true"] {
@apply mb-3 p-5 max-md:p-3;
}
#maincontent & {
@apply border-border/30 bg-panel-bg hover:border-border/50 border shadow-lg hover:shadow-xl;
}
& > .cbi-title {
@apply flex items-start justify-between;
& > h3 {
@apply flex-1;
& .label[data-clickable] {
@apply text-foreground bg-label-surface;
@apply inline-flex size-7 cursor-pointer items-center justify-center p-0 before:size-4 before:bg-current before:transition-transform before:duration-300 hover:shadow-md active:scale-95 max-md:size-6;
}
& span[data-indicator="poll-status"] {
@apply relative size-5 cursor-pointer text-[0px] before:absolute before:size-5 before:bg-current before:transition-transform before:duration-300 before:ease-out hover:before:scale-110 active:before:scale-95;
&[data-style="active"] {
@apply before:rotate-0 before:[mask:url('@assets/icons/arrow-right.svg')_center/cover_no-repeat];
}
&[data-style="inactive"] {
@apply before:rotate-90 before:[mask:url('@assets/icons/arrow-right.svg')_center/cover_no-repeat];
}
}
}
}
legend {
@apply text-lg font-semibold;
}
& h3 {
@apply text-foreground border-border/50 border-b pb-4 max-md:mx-0 max-md:pb-2;
}
& div[style*="display:grid"] {
@apply max-md:grid-cols-2! max-md:gap-3;
}
& .network-status-table {
@apply mb-3 flex flex-wrap justify-around gap-4 max-md:flex-col;
}
& .cbi-section-create {
@apply mt-6 flex flex-wrap items-center gap-3 max-md:mx-0 max-md:mt-5 max-md:flex-col max-md:items-stretch max-md:gap-3;
& > div {
@apply flex-none max-md:w-full max-md:flex-1;
}
}
}
.ifacebox {
@apply border-border bg-panel-bg/95 hover:border-border max-md:border-border/70 max-md:bg-panel-bg/98 relative inline-flex min-w-40 flex-col items-stretch overflow-visible rounded-2xl border text-center text-base leading-5 shadow-md hover:shadow-lg max-md:min-w-30 max-md:flex-1 max-md:rounded-3xl max-md:shadow-sm;
td & {
@apply max-md:flex-row;
}
& .ifacebox-head {
@apply border-border bg-label-surface text-foreground max-md:border-border/80 w-full rounded-t-2xl border-b px-4 py-3 text-center font-semibold tracking-tight transition-all duration-200 max-md:rounded-t-3xl max-md:px-3 max-md:py-2.5 max-md:text-sm max-md:leading-5 max-md:font-medium;
&[style*="--zone-color-rgb"] {
@apply bg-[rgb(var(--zone-color-rgb),.75)]!;
}
td & {
@apply max-md:flex max-md:w-auto max-md:shrink-0 max-md:items-center max-md:justify-center max-md:rounded-l-3xl max-md:rounded-tr-none max-md:border-r max-md:border-b-0;
}
&.cbi-tooltip-container {
@apply static bg-transparent;
& .cbi-tooltip {
@apply bottom-0 left-0;
}
}
&.active {
@apply border-primary bg-primary text-primary-foreground;
}
}
& .ifacebox-body {
@apply text-default-foreground flex w-full flex-1 flex-col items-center justify-around gap-2 rounded-b-2xl p-4 text-center max-md:rounded-b-3xl;
td & {
@apply max-md:flex-row max-md:rounded-r-3xl max-md:rounded-bl-none max-md:py-2 max-md:pr-2 max-md:pl-4;
}
& > span {
@apply text-foreground space-y-1.5 max-md:space-y-1 max-md:text-sm max-md:leading-5;
.network-status-table & {
@apply w-full;
}
.cbi-tooltip-container + .cbi-tooltip-container {
@apply ml-2 max-md:ml-1.5;
}
.cbi-tooltip {
@apply delay-200;
}
& .nowrap {
@apply inline-block;
}
& > .nowrap {
@apply not-last:mb-4 not-last:max-md:mb-3;
}
& img {
@apply w-6 shrink-0 max-md:w-5;
}
}
& > div {
@apply flex w-full flex-wrap space-y-2.5 max-md:space-y-1.5;
td & {
@apply max-md:w-auto max-md:flex-1 max-md:space-y-1;
}
& .ifacebadge {
@apply flex-1;
}
}
& .cbi-tooltip-container {
@apply text-foreground static inline-flex cursor-help items-center justify-center;
& .cbi-tooltip {
@apply bottom-0 md:left-0;
& .nowrap {
@apply whitespace-nowrap;
}
}
}
& small {
@apply block text-xs leading-4;
td & {
@apply max-md:mt-0;
}
}
}
}

View File

@ -0,0 +1,136 @@
.cbi-dropdown {
@apply inline-flex h-fit max-w-full min-w-fit shrink-0 items-center p-0 whitespace-nowrap shadow-sm transition-all duration-200;
&[disabled] {
@apply pointer-events-none opacity-40 dark:opacity-30;
}
&:not(.btn):not(.cbi-button) {
@apply border-border/70 bg-page-bg rounded-2xl border;
& > ul > li {
&[placeholder] {
@apply hidden;
}
}
}
& > ul {
@apply m-0 flex flex-1 list-none flex-nowrap items-center gap-0.5 overflow-hidden max-md:flex-wrap;
& > li {
@apply m-0 hidden list-none items-center gap-1 overflow-hidden px-2 py-1.5;
&[display] {
@apply !flex;
}
& .hide-open {
@apply block;
}
& .hide-close {
@apply hidden;
}
& > form {
@apply pointer-events-none hidden;
}
& > label {
@apply flex items-center gap-2;
}
& img {
@apply h-5 w-5 flex-none align-middle;
}
& span {
@apply truncate;
}
}
&.dropdown {
@apply border-border/60 bg-page-bg/95 absolute left-0 z-60 w-fit min-w-full overflow-y-auto rounded-lg border shadow-xl backdrop-blur-sm;
& > li {
@apply text-muted-foreground hover:bg-primary/15 min-h-9 w-full cursor-pointer px-3 py-1.5 font-medium;
}
}
&.preview {
@apply hidden;
}
}
&[empty] {
& > ul {
@apply max-h-px max-w-px;
& > li {
@apply block;
}
}
}
&[optional][open] > ul.dropdown > li[placeholder] {
@apply block;
}
&[open] {
@apply border-primary ring-primary/20 relative ring-2;
& > ul.dropdown {
@apply block w-auto max-w-none;
& > li {
@apply flex;
&[selected] {
@apply bg-primary/20 text-primary;
}
&[unselectable] {
@apply opacity-40 dark:opacity-30;
}
& .hide-open {
@apply hidden;
}
& .hide-close {
@apply block;
}
}
}
& > ul.preview {
@apply flex;
}
}
&[multiple] {
&[more],
&[empty] {
& > .more {
@apply flex flex-none shrink-0 px-2.5 py-1.5;
}
}
&[open] {
& > ul.dropdown > li > form {
@apply flex items-center;
}
}
& > ul > li > label {
@apply flex;
}
}
& > .open {
@apply border-border/70 flex flex-none shrink-0 cursor-pointer items-center justify-center border-l px-2.5 py-0.5 text-sm text-current;
}
& > .more {
@apply hidden;
}
}

View File

@ -0,0 +1,48 @@
.floating-toolbar {
@apply fixed right-4 bottom-4 z-40 flex flex-col items-center max-md:right-3 max-md:bottom-3;
.toolbar-list {
@apply visible mb-2 grid origin-bottom grid-rows-[1fr] opacity-100 transition-all duration-400 ease-in-out max-md:mb-1.5;
.toolbar-list-inner {
@apply border-border/70 bg-page-bg/90 flex min-h-0 flex-col items-center gap-2 overflow-hidden rounded-full border p-1 shadow-sm max-md:gap-1.5 max-md:p-0.5;
}
}
.toolbar-btn {
@apply flex h-10 w-10 shrink-0 cursor-pointer items-center justify-center rounded-full p-2 transition-all duration-300 ease-in-out active:scale-95 max-md:h-9 max-md:w-9 max-md:p-1.5;
.icon {
@apply h-5 w-5 shrink-0 transition-all duration-300 ease-in-out max-md:h-4 max-md:w-4;
}
&:not(.toggle) {
@apply hover:bg-border/40 no-underline hover:scale-110;
.icon {
@apply object-contain dark:invert;
}
}
&.toggle {
@apply bg-page-bg border-0 shadow-sm;
.icon {
@apply transition-transform duration-400 ease-out;
}
}
}
&.collapsed {
.toolbar-list {
@apply pointer-events-none invisible mb-0 translate-y-2 scale-90 grid-rows-[0fr] opacity-0;
}
.toolbar-btn {
&:not(.toggle) {
@apply scale-50 opacity-0;
}
&.toggle .icon {
@apply rotate-45;
}
}
}
}

View File

@ -0,0 +1,78 @@
.cbi-input-invalid,
.cbi-value-error {
@apply !border-error/70 focus:!ring-error/40;
}
.cbi-value {
@apply flex flex-row flex-wrap gap-6 py-1.5 max-md:flex-col max-md:gap-1.5 max-md:py-1;
&.hidden {
@apply hidden;
}
& + & {
@apply mt-3 max-md:mt-2;
}
& > .cbi-value-title {
@apply pt-1 text-right font-medium max-md:w-auto max-md:text-left md:flex-[0_0_12rem];
}
& > .cbi-value-field {
@apply max-w-full flex-1;
&:has(> .cbi-dropdown[disabled]) {
@apply cursor-not-allowed;
}
& .cbi-value-description {
@apply text-muted-foreground relative mt-1 pl-4 leading-none wrap-break-word;
&:not(:empty) {
@apply before:bg-info-foreground before:absolute before:-left-0.5 before:inline-block before:size-4 before:[mask:url('@assets/icons/info.svg')_center/cover_no-repeat];
}
}
}
& > .cbi-section,
& > .cbi-tblsection {
@apply w-full;
}
}
.cbi-dynlist {
@apply inline-flex w-max max-w-120 flex-col items-start gap-3 max-md:max-w-full!;
& .item {
@apply border-border/40 bg-panel-bg pointer-events-auto relative inline-flex cursor-move flex-col items-start gap-2 self-stretch overflow-hidden rounded-2xl border py-3 pr-10 pl-4 break-all shadow-sm transition-all duration-200 select-text max-md:w-full max-md:py-2.5 max-md:pr-8 max-md:pl-3;
@apply after:bg-muted after:text-muted-foreground after:absolute after:top-2.5 after:right-2 after:inline-flex after:h-6 after:w-6 after:shrink-0 after:cursor-pointer after:items-center after:justify-center after:rounded-xl after:text-sm after:font-medium after:content-['\00D7'];
&.dragging {
@apply scale-95 cursor-grabbing opacity-50 shadow-2xl;
}
&.drag-over {
@apply border-primary/60 bg-primary/5 ring-primary/30 scale-105 shadow-lg ring-2;
}
& > span,
& > code {
@apply pointer-events-none w-full rounded-lg font-mono leading-relaxed;
}
}
& .placeholder {
@apply break-all;
}
& .add-item {
@apply border-border/70 hover:border-border hover:bg-page-bg/50 inline-flex items-center gap-1.5 self-stretch rounded-2xl border border-dashed bg-transparent px-1 py-1 transition-all duration-200;
& > input {
@apply min-w-61 flex-1;
}
& > .cbi-button {
@apply inline-flex min-h-6 min-w-6 shrink-0 cursor-pointer items-center justify-center rounded-xl px-2 py-0 text-sm font-medium shadow-none active:scale-95;
}
}
}

View File

@ -0,0 +1,39 @@
input {
@apply disabled:cursor-not-allowed disabled:opacity-40 disabled:dark:opacity-30;
}
input[type="text"],
input[type="password"],
.cbi-input-text,
.cbi-input {
@apply text-foreground border-border/70 bg-page-bg placeholder-muted-foreground/70 focus:border-primary focus:ring-primary/20 relative rounded-2xl border px-3 py-1.5 text-sm font-normal shadow-sm transition-all duration-200 focus:ring-2 focus:outline-none;
.table.cbi-section-table & {
@apply w-full;
}
}
.cbi-input-text {
@apply min-w-20 max-md:min-w-14;
}
#localtime {
@apply min-w-70;
}
input[type="radio"],
input[type="checkbox"] {
@apply focus:before:border-primary focus:before:ring-primary/20 checked:before:border-primary checked:before:bg-primary before:border-border/70 before:bg-page-bg after:bg-input-checked hover:before:border-border relative mr-3 inline-block h-4 w-4 cursor-pointer appearance-none before:absolute before:top-0 before:left-0 before:h-4 before:w-4 before:border before:transition-all before:duration-200 after:absolute after:top-0.5 after:left-0.5 after:h-3 after:w-3 after:opacity-0 after:transition-opacity after:duration-200 checked:after:opacity-100 focus:before:ring-2 focus:before:outline-none disabled:cursor-not-allowed;
}
input[type="radio"] {
@apply before:rounded-full after:[mask:url('@assets/icons/radio.svg')_center/cover_no-repeat];
}
input[type="checkbox"] {
@apply before:rounded after:[mask:url('@assets/icons/check.svg')_center/cover_no-repeat];
}
.cbi-checkbox {
@apply relative inline-flex items-center;
}

View File

@ -0,0 +1,78 @@
.login-screen {
@apply relative flex min-h-dvh items-center justify-center overflow-hidden px-5;
.login-shell {
@apply relative z-10 flex w-full max-w-md flex-col items-stretch gap-6;
.login-card {
@apply border-border bg-panel-bg relative overflow-hidden rounded-4xl border p-10 shadow-xl max-md:rounded-3xl max-md:p-6;
.login-brand {
@apply flex items-center gap-4;
.login-logo {
@apply bg-primary/15 ring-primary/20 flex h-12 w-12 items-center justify-center rounded-2xl ring-1;
& img {
@apply h-6 w-6;
}
}
.login-title {
@apply flex flex-col gap-1;
.login-hostname {
@apply text-foreground text-2xl font-semibold tracking-tight;
}
.login-subtitle {
@apply text-default-foreground text-sm;
}
}
}
.login-divider {
@apply via-border my-6 h-px w-full bg-linear-to-r from-transparent to-transparent md:my-8;
}
.login-form {
@apply flex flex-col gap-6 md:gap-4;
.login-fields {
@apply flex flex-col gap-4 md:gap-5;
.login-field {
@apply flex flex-col gap-2;
.login-label {
@apply text-default-foreground text-xs font-semibold uppercase;
}
.login-input {
@apply border-border bg-panel-bg text-foreground focus:border-primary focus:ring-0 focus:shadow-sm rounded-2xl border px-3 py-2.5 text-base shadow-sm transition-none;
}
}
}
.login-actions {
@apply md:pt-4;
.login-submit {
@apply w-full py-2.5 text-base;
}
}
}
}
.login-footer {
@apply text-muted-foreground fixed bottom-0 left-1/2 w-[calc(100%-1.25rem)] -translate-x-1/2 pb-4 text-center max-md:pb-3;
& p {
@apply text-xs whitespace-normal;
& a {
@apply text-primary hover:text-primary;
}
}
}
}
}

View File

@ -0,0 +1,54 @@
.alert-message {
@apply bg-default text-default-foreground border-default/30 sticky top-14 z-40 mb-4 rounded-4xl border p-6 max-md:mx-0 max-md:mb-3 max-md:rounded-3xl max-md:p-4;
&.modal {
@apply static top-auto;
}
.modal & {
@apply mb-0;
}
.login-shell & {
@apply mb-0 rounded-2xl px-2 py-2.5 text-center text-base max-md:px-0.5;
}
&.success {
@apply border-success/30 bg-success text-success-foreground;
}
&.info {
@apply border-info/30 bg-info text-info-foreground;
}
&.warning,
&.notice {
@apply border-warning/30 bg-warning text-warning-foreground;
}
&.error,
&.danger {
@apply border-error/30 bg-error text-error-foreground;
}
h4,
h5,
pre,
ul,
li,
p {
@apply border-0 bg-transparent text-inherit;
}
& h4 {
@apply mb-2 text-lg font-semibold max-md:mb-1.5 max-md:text-base;
}
& p {
@apply text-sm leading-relaxed max-md:text-sm;
}
& .right {
@apply mt-4 max-md:mt-3;
}
}

View File

@ -0,0 +1,128 @@
#modal_overlay {
@apply pointer-events-none fixed top-0 bottom-0 hidden overflow-auto bg-transparent;
.modal-overlay-active & {
@apply bg-overlay-base/70 pointer-events-auto inset-0 right-0 left-0 z-100 grid grid-cols-1 place-items-center backdrop-blur-sm;
}
& > .modal {
@apply border-border/70 bg-page-bg flex w-5xl flex-col gap-4 rounded-3xl border p-6 wrap-break-word whitespace-normal shadow-2xl backdrop-blur-lg backdrop-saturate-150 max-md:w-full max-md:gap-3 max-md:p-4;
& h4 {
@apply mb-0 text-center;
& em {
@apply text-primary font-semibold;
}
}
& h5 {
@apply text-foreground my-3;
}
& p {
@apply text-default-foreground text-sm leading-relaxed;
}
& > ul {
@apply border-border/60 bg-page-bg/60 overflow-auto rounded-2xl border p-3;
}
& label.btn {
@apply border-border/60 bg-page-bg/60 text-foreground hover:border-border border;
}
& pre {
@apply overflow-auto;
&.errors {
@apply border-error/60 bg-error/20 text-error-foreground;
}
}
pre + pre {
@apply mt-3;
}
& .button-row,
& div.left,
& div.right {
@apply border-border/40 flex shrink-0 gap-3 border-t p-4 max-md:gap-1.5 max-md:p-2.5;
}
& div.left {
@apply justify-start;
}
& .button-row,
& div.right {
@apply justify-end;
}
&.uci-dialog {
& ins,
& del,
& var {
@apply font-mono not-italic no-underline shadow-sm;
}
& ins {
@apply border-success bg-success/80 text-success-foreground border;
}
& del {
@apply border-error bg-error/80 text-error-foreground border;
}
& var {
@apply border-info bg-info/80 text-info-foreground border;
}
& .uci-change-legend {
@apply border-border/60 bg-page-bg/60 mt-4 grid grid-cols-2 gap-3 rounded-2xl border p-4 max-md:grid-cols-1 max-md:gap-2 max-md:p-3;
& .uci-change-legend-label {
@apply text-foreground flex items-center gap-2 text-sm font-medium;
& ins,
& del,
& var {
@apply flex h-6 min-w-6 items-center justify-center rounded-lg px-2 text-xs font-semibold;
}
& var {
& ins,
& del {
@apply ml-1 h-4 min-w-4 px-1;
}
}
}
}
& .uci-change-list {
@apply mt-4 space-y-3;
& h5 {
@apply bg-default text-default-foreground mt-6 mb-2 rounded-xl px-3 py-2 text-sm font-semibold first:mt-0;
}
& ins,
& del {
@apply block rounded-xl px-4 py-3 text-sm;
& strong {
@apply text-sm;
}
}
& var {
@apply inline-block rounded-lg px-2 py-1 text-sm;
& ins,
& del {
@apply ml-1 inline-block px-1.5 py-0.5 text-xs;
}
}
}
}
}
}

View File

@ -0,0 +1,62 @@
.mobile-menu-overlay {
@apply max-md:bg-overlay-base/60 max-md:invisible max-md:fixed max-md:inset-0 max-md:z-60 max-md:opacity-0 max-md:transition-all max-md:duration-300 md:hidden;
&.mobile-menu-open {
@apply max-md:visible max-md:opacity-100 max-md:backdrop-blur-md;
& .mobile-nav {
@apply max-md:translate-x-0;
}
}
.mobile-nav {
@apply max-md:bg-page-bg max-md:absolute max-md:top-0 max-md:right-0 max-md:flex max-md:h-full max-md:w-80 max-md:translate-x-full max-md:flex-col max-md:shadow-2xl max-md:backdrop-blur-xl max-md:backdrop-saturate-150 max-md:transition-transform max-md:duration-300;
& .mobile-nav-header {
@apply max-md:flex max-md:items-center max-md:justify-between max-md:p-6 max-md:pb-4;
& .mobile-nav-title {
@apply max-md:text-foreground max-md:m-0 max-md:text-lg max-md:font-semibold;
}
& .mobile-nav-close {
@apply max-md:cursor-pointer max-md:transition-all max-md:duration-200 max-md:hover:scale-105 max-md:active:scale-95;
& svg {
@apply max-md:text-foreground size-5 max-md:transition-transform max-md:duration-200;
}
}
}
& .mobile-nav-list {
@apply max-md:m-0 max-md:flex max-md:flex-1 max-md:list-none max-md:flex-col max-md:gap-0 max-md:overflow-y-auto max-md:p-0 max-md:px-6;
& .mobile-nav-item {
& .mobile-nav-link {
@apply max-md:text-default-foreground max-md:hover:text-foreground max-md:flex max-md:w-full max-md:items-center max-md:px-0 max-md:py-4 max-md:text-base max-md:font-medium max-md:no-underline max-md:transition-all max-md:duration-300 max-md:hover:translate-x-1;
}
& .mobile-nav-submenu {
@apply max-md:m-0 max-md:list-none max-md:overflow-hidden max-md:p-0 max-md:transition-all max-md:duration-300 max-md:ease-in-out;
& .mobile-nav-subitem {
@apply max-md:border-border/20 max-md:border-b max-md:last:border-b-0;
& .mobile-nav-sublink {
@apply max-md:text-default-foreground max-md:hover:text-foreground max-md:flex max-md:w-full max-md:items-center max-md:py-3 max-md:pr-0 max-md:pl-4 max-md:text-sm max-md:font-normal max-md:no-underline max-md:transition-all max-md:duration-300 max-md:hover:translate-x-1;
}
}
}
}
}
}
}
[data-nav-type="mega-menu"] {
& .desktop-menu-overlay {
@apply bg-overlay-base/35 pointer-events-none fixed inset-0 z-50 opacity-0 transition-all duration-300 max-md:hidden;
&.active {
@apply pointer-events-auto opacity-100 backdrop-blur-sm;
}
}
}

View File

@ -0,0 +1,10 @@
.cbi-progressbar {
@apply before:text-foreground bg-secondary relative h-3.5 w-full cursor-help overflow-hidden rounded-full before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:rounded-2xl before:text-xs before:whitespace-nowrap before:content-[attr(title)] max-md:h-4 max-md:rounded-2xl max-md:before:text-xs max-md:before:leading-normal;
[data-page="admin-system-package-manager"] & {
@apply max-sm:before:text-[10px];
}
& > div {
@apply from-progress-bar-start to-progress-bar-end h-full bg-linear-to-r transition-all duration-300;
}
}

View File

@ -0,0 +1,28 @@
.cbi-tabmenu {
@apply border-border/60 bg-label-surface mb-1 flex items-center gap-1 overflow-x-auto rounded-4xl border p-1;
& li {
@apply relative m-0 min-w-fit shrink-0 list-none;
&[data-errors] {
@apply after:bg-accent after:text-accent-foreground after:absolute after:-top-0.5 after:-right-1.5 after:z-20 after:inline-flex after:min-h-4 after:min-w-4 after:items-center after:justify-center after:rounded-full after:px-1.5 after:py-0.5 after:text-xs after:font-semibold after:content-[attr(data-errors)];
& > a {
@apply border-error/50 border;
}
}
& > a {
@apply text-muted-foreground hover:text-foreground block rounded-4xl px-4 py-2 text-center text-sm font-medium whitespace-nowrap no-underline;
}
&.cbi-tab a {
@apply bg-foreground text-page-bg font-semibold shadow-sm;
}
}
}
[data-tab-title] {
@apply invisible h-0 overflow-hidden;
}
[data-tab-active="true"] {
@apply visible h-auto overflow-visible;
}

View File

@ -0,0 +1,7 @@
select {
@apply text-foreground border-border/70 bg-page-bg focus:border-primary focus:ring-primary/20 appearance-none rounded-2xl border px-3 py-1.5 pr-10 text-sm font-normal shadow-sm transition-all duration-200 focus:ring-2 focus:outline-none;
@apply bg-[url('@assets/icons/arrow-down.svg')] bg-size-[16px] bg-position-[right_0.75rem_center] bg-no-repeat dark:bg-[url('@assets/icons/arrow-down-dark.svg')];
&[disabled] {
@apply cursor-not-allowed opacity-40 dark:opacity-30;
}
}

View File

@ -0,0 +1,65 @@
.theme-switcher {
@apply bg-page-bg relative inline-flex items-center gap-0 rounded-full shadow-sm backdrop-blur-sm transition-all duration-300 max-md:py-0.5;
@apply border-border/70 border;
@apply before:bg-border/50 before:ring-border/60 before:absolute before:top-1 before:left-1 before:z-0 before:h-[calc(100%-0.5rem)] before:w-[calc(33.333%-0.5rem)] before:rounded-full before:shadow-md before:ring-1 before:transition-all before:duration-300;
footer & {
@apply max-md:hidden;
}
& .theme-option {
@apply relative z-10 flex cursor-pointer items-center justify-center gap-1.5 rounded-full px-3 py-1.5 transition-all duration-300 hover:scale-105 active:scale-95;
& input[type="radio"] {
@apply sr-only;
}
& .theme-icon {
@apply text-muted-foreground flex items-center justify-center transition-all duration-300;
& svg {
@apply size-4 transition-transform duration-300;
}
}
& .theme-label {
@apply text-muted-foreground hidden text-xs font-medium transition-colors duration-300;
}
&.active {
& .theme-icon {
@apply text-foreground;
& svg {
@apply scale-110;
}
}
& .theme-label {
@apply text-foreground;
}
}
&:hover:not(.active) {
& .theme-icon {
@apply text-foreground;
}
& .theme-label {
@apply text-foreground;
}
}
}
&:has(.theme-option[data-theme="device"].active) {
@apply before:translate-x-0;
}
&:has(.theme-option[data-theme="light"].active) {
@apply before:translate-x-[calc(100%+0.5rem)];
}
&:has(.theme-option[data-theme="dark"].active) {
@apply before:translate-x-[calc(200%+1rem)];
}
}

View File

@ -0,0 +1,22 @@
#tabmenu {
@apply mb-8 w-full;
}
.tabs {
@apply border-border relative flex items-center gap-0 overflow-x-auto border-b;
& a {
@apply text-muted-foreground hover:text-foreground block px-8 py-4 text-center text-sm font-medium whitespace-nowrap transition-colors duration-200 hover:no-underline;
}
& > li.active {
@apply border-foreground border-b-2;
& > a {
@apply text-foreground font-semibold;
}
}
}
.cbi-section-node-tabbed {
@apply mt-6;
}

View File

@ -0,0 +1,231 @@
table.table,
.table {
@apply border-border max-md:bg-panel-bg/98 mb-3 w-full border-separate border-spacing-0 overflow-visible rounded-2xl border max-md:mx-0 max-md:block max-md:w-full max-md:overflow-visible max-md:border-0 max-md:shadow-none;
&[width="100%"] {
@apply w-full;
}
&[width="33%"] {
@apply w-1/3;
}
& .cbi-section-table-titles {
@apply font-bold;
}
& .cbi-section-table-titles.named,
& .cbi-section-table-descr.named,
& .cbi-section-table-row[data-title] {
@apply before:border-border before:table-cell before:px-3 before:py-3 before:align-middle before:text-base before:font-semibold before:content-[attr(data-title)] before:max-md:flex before:max-md:flex-[0_0_100%] before:max-md:px-3 before:max-md:py-2.5 before:max-md:text-sm before:md:border-b;
&:not([data-title]),
&:has(td.cbi-section-table-titles) {
@apply before:content-none;
}
}
& .cbi-section-table-titles.named {
@apply before:bg-label-surface before:max-md:bg-label-surface before:md:rounded-tl-2xl;
}
& tbody,
& .tbody {
@apply max-md:block;
}
& tr,
& .tr {
@apply hover:bg-label-surface max-md:border-border transition-colors duration-200 max-md:flex max-md:flex-wrap max-md:border-b max-md:px-2 max-md:py-2;
@apply has-[.cbi-progressbar]:max-md:flex has-[.cbi-progressbar]:max-md:items-center has-[.cbi-progressbar]:max-md:justify-center;
&:first-child {
&:not([data-title]) {
& .th,
& .td {
@apply first:md:rounded-tl-2xl;
}
}
& .th,
& .td {
@apply last:md:rounded-tr-2xl;
}
}
&:last-child {
@apply max-md:rounded-b-2xl;
&[data-title] {
@apply before:rounded-bl-2xl before:border-b-0;
}
.td {
@apply border-b-0 first:md:rounded-bl-2xl last:md:rounded-br-2xl;
}
}
&.table-titles,
&.cbi-section-table-titles,
&.cbi-section-table-descr {
@apply max-md:hidden;
}
&:first-child:not(
.table-titles,
.cbi-section-table-titles,
.cbi-section-table-descr
),
&.table-titles + .tr,
&.cbi-section-table-titles + .tr,
&.cbi-section-table-descr + .tr {
@apply max-md:rounded-t-2xl;
}
&.cbi-rowstyle-1 {
@apply bg-panel-bg;
}
&.cbi-rowstyle-2 {
@apply bg-label-surface/50;
}
& > .col-1 {
@apply max-md:flex-[1_1_2rem] md:w-20 md:max-w-28;
}
& > .col-2 {
@apply whitespace-normal max-md:flex-[2_2_4rem] md:w-32 md:max-w-40;
}
& > .col-3 {
@apply max-md:flex-[3_3_6rem] md:w-44 md:max-w-52;
}
& > .col-4 {
@apply max-md:flex-[4_4_8rem] md:w-56 md:max-w-64;
}
& > .col-5 {
@apply max-md:flex-[5_5_10rem] md:w-68 md:max-w-76;
}
& > .col-6 {
@apply max-md:flex-[6_6_12rem] md:w-80 md:max-w-88;
}
& > .col-7 {
@apply max-md:flex-[7_7_14rem] md:w-92 md:max-w-100;
}
& > .col-8 {
@apply max-md:flex-[8_8_16rem] md:w-104 md:max-w-112;
}
& > .col-9 {
@apply max-md:flex-[9_9_18rem] md:w-116 md:max-w-124;
}
& > .col-10 {
@apply max-md:max-w-[calc(100vw-40px)] max-md:flex-[0_0_100%] md:w-128 md:max-w-136;
}
}
& th,
& .th {
@apply border-border bg-label-surface border-b px-3 py-3 text-left text-base font-medium backdrop-blur-sm max-md:flex-[1_1_50%] max-md:border-0 max-md:text-sm;
#cbi-samba4 & {
@apply px-0.5 py-1.5;
}
&[width="100%"] {
@apply w-full max-md:flex-[0_0_100%];
}
&[width="33%"] {
@apply w-1/3 max-md:flex-[0_0_33.333%];
}
&[data-sortable-row="true"] {
@apply hover:bg-label-surface cursor-pointer select-none after:ml-0.5 after:text-xs;
&[data-sort-direction="asc"] {
@apply after:content-['\25B2'];
}
&[data-sort-direction="desc"] {
@apply after:content-['\25BC'];
}
}
}
&[id*="status_leases"] {
& .td {
@apply max-w-62 max-md:max-w-full;
}
}
& td,
& .td {
@apply border-border table-cell border-b px-3 py-3 align-middle text-base wrap-break-word whitespace-normal max-md:flex-[1_1_50%] max-md:border-0 max-md:px-1 max-md:py-1 max-md:text-sm;
@apply before:hidden before:content-[attr(data-title)] before:max-md:mb-1 before:max-md:block before:max-md:text-xs before:max-md:font-semibold before:max-md:tracking-wider;
#cbi-samba4 & {
@apply px-0.5 py-1.5;
}
[data-page="admin-system-mounts"] & {
@apply max-w-104 max-md:max-w-full;
}
#wifi_assoclist_table & {
@apply max-md:flex-[0_0_100%] max-md:px-3 max-md:py-2 before:max-md:mb-1.5;
}
& > input[type="text"],
& > input[type="password"],
& > select,
& > .cbi-dropdown:not(.btn):not(.cbi-button) {
@apply w-full;
}
&.cbi-value-field {
@apply break-all;
}
&.cbi-section-actions {
@apply max-md:flex-[0_0_100%];
& > div {
@apply max-md:w-full;
& > .cbi-button {
@apply max-md:flex-1;
}
}
}
& > .cbi-button {
@apply max-md:w-full;
}
&[width="100%"] {
@apply w-full max-md:flex-[0_0_100%];
}
&[width="33%"] {
@apply w-1/3 max-md:flex-[0_0_33.333%];
}
[data-page="admin-network-network"] & {
&[data-name="_ifacebox"],
&[data-name="_ifacestat"] {
@apply max-md:basis-[100%];
}
}
}
}
.cbi-section-table {
.cbi-section-table-titles {
.cbi-section-table-cell {
@apply !w-auto;
}
}
}

View File

@ -0,0 +1,6 @@
textarea {
@apply text-foreground border-border/70 bg-page-bg placeholder-muted-foreground/70 focus:border-primary focus:ring-primary/20 min-h-24 w-full resize-y rounded-2xl border px-3 py-2 text-sm font-normal shadow-sm transition-all duration-200 focus:ring-2 focus:outline-none;
&[disabled] {
@apply cursor-not-allowed opacity-40 dark:opacity-30;
}
}

View File

@ -0,0 +1,28 @@
.cbi-tooltip {
@apply bg-tooltip-bg text-foreground border-border/60 absolute z-110 max-w-xs scale-95 transform rounded-xl border px-3 py-2 text-xs break-normal whitespace-normal opacity-0 shadow-lg backdrop-blur-xl transition-all duration-300 ease-out;
&.error {
@apply border-error/40 bg-error text-error-foreground;
}
&.success {
@apply border-success/40 bg-success text-success-foreground;
}
&.info {
@apply border-info/40 bg-info text-info-foreground;
}
&.notice {
@apply border-warning/40 bg-warning text-warning-foreground;
}
}
.cbi-tooltip-container,
[data-tooltip] {
@apply relative inline-block cursor-help whitespace-nowrap underline decoration-current decoration-dotted underline-offset-2 transition-all duration-200;
& .cbi-tooltip {
@apply invisible scale-95 transform opacity-0 transition-all duration-300 ease-out;
}
&:hover .cbi-tooltip {
@apply visible scale-100 opacity-100;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=Aurora Theme (A modern browser theme built with Vite and Tailwind CSS)
LUCI_DEPENDS:=+luci-base
PKG_VERSION:=0.11.8
PKG_RELEASE:=10
PKG_VERSION:=0.11.9
PKG_RELEASE:=11
PKG_LICENSE:=Apache-2.0
LUCI_MINIFY_CSS:=

View File

@ -1,8 +1,7 @@
<h4 align="right"><strong>English</strong> | <a href="README_zh.md">简体中文</a></h4>
<p align="center">
<img src="https://raw.githubusercontent.com/eamonxg/assets/master/aurora/logo/logo-rounded.png" width="152"/>
<img src="https://raw.githubusercontent.com/eamonxg/assets/master/aurora/logo/logo-lockup.png" width="360" alt="Aurora Theme"/>
</p>
<h1 align="center">Aurora Theme</h1>
<p align="center"><strong>A modern OpenWrt LuCI theme built with Vite and Tailwind CSS.</strong></p>
<h4 align="center">🏔️ Pure | 🦢 Elegant | 📱 Responsive | 🌗 Dark/Light Mode | ⚙️ Settable </h4>
<div align="center">

View File

@ -1,8 +1,7 @@
<h4 align="right"><a href="README.md">English</a> | <strong>简体中文</strong></h4>
<p align="center">
<img src="https://raw.githubusercontent.com/eamonxg/assets/master/aurora/logo/logo-rounded.png" width="152"/>
<img src="https://raw.githubusercontent.com/eamonxg/assets/master/aurora/logo/logo-lockup.png" width="360" alt="Aurora Theme"/>
</p>
<h1 align="center">Aurora Theme</h1>
<p align="center"><strong>一款基于 Vite 和 Tailwind CSS 构建的现代 OpenWrt LuCI 主题。</strong></p>
<h4 align="center">🏔️ 纯净 | 🦢 优雅 | 📱 响应式 | 🌗 深色/浅色模式 | ⚙️ 可配置 </h4>
<div align="center">

File diff suppressed because one or more lines are too long

View File

@ -6,13 +6,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=caddy
PKG_VERSION:=2.11.3
PKG_RELEASE:=2
PKG_VERSION:=2.11.4
PKG_RELEASE:=3
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/caddyserver/caddy.git
PKG_SOURCE_DATE:=2026-03-31
PKG_SOURCE_VERSION:=4f504588669e28373f455b694539475ffe4d2926
PKG_SOURCE_DATE:=2026-05-23
PKG_SOURCE_VERSION:=44b667a79f48e6163570cd6b32fa806e12625516
PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL-3.0-or-later

View File

@ -1,6 +1,6 @@
diff -rNu a/cmd/caddy/main.go b/cmd/caddy/main.go
--- a/cmd/caddy/main.go 2026-03-31 13:46:32.000000000 +0800
+++ b/cmd/caddy/main.go 2026-04-01 13:25:45.106981103 +0800
--- a/cmd/caddy/main.go 2026-05-22 23:25:04.000000000 +0800
+++ b/cmd/caddy/main.go 2026-05-23 01:11:34.865671285 +0800
@@ -35,6 +35,8 @@
// plug in Caddy modules here
@ -11,34 +11,34 @@ diff -rNu a/cmd/caddy/main.go b/cmd/caddy/main.go
func main() {
diff -rNu a/go.mod b/go.mod
--- a/go.mod 2026-03-31 13:46:32.000000000 +0800
+++ b/go.mod 2026-04-01 13:27:36.037581120 +0800
--- a/go.mod 2026-05-22 23:25:04.000000000 +0800
+++ b/go.mod 2026-05-23 01:18:14.846072312 +0800
@@ -1,12 +1,13 @@
module github.com/caddyserver/caddy/v2
-go 1.25.0
+go 1.26.1
-go 1.25.1
+go 1.26.3
require (
github.com/BurntSushi/toml v1.6.0
github.com/DeRuina/timberjack v1.4.0
github.com/DeRuina/timberjack v1.4.2
github.com/KimMachineGun/automemlimit v0.7.5
github.com/Masterminds/sprig/v3 v3.3.0
+ github.com/aksdb/caddy-cgi/v2 v2.2.7
github.com/alecthomas/chroma/v2 v2.23.1
github.com/alecthomas/chroma/v2 v2.24.1
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
github.com/caddyserver/certmagic v0.25.2
github.com/caddyserver/certmagic v0.25.3
@@ -19,6 +20,7 @@
github.com/klauspost/compress v1.18.5
github.com/klauspost/compress v1.18.6
github.com/klauspost/cpuid/v2 v2.3.0
github.com/mholt/acmez/v3 v3.1.6
+ github.com/mholt/caddy-webdav v0.0.0-20260127042217-fa2f366b0d75
github.com/prometheus/client_golang v1.23.2
github.com/quic-go/quic-go v0.59.0
github.com/quic-go/quic-go v0.59.1
github.com/smallstep/certificates v0.30.2
diff -rNu a/go.sum b/go.sum
--- a/go.sum 2026-03-31 13:46:32.000000000 +0800
+++ b/go.sum 2026-04-01 13:27:36.036581120 +0800
--- a/go.sum 2026-05-22 23:25:04.000000000 +0800
+++ b/go.sum 2026-05-23 01:18:14.846072312 +0800
@@ -40,6 +40,8 @@
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=

View File

@ -9,7 +9,7 @@ PKG_NAME:=natmapt
PKG_UPSTREAM_VERSION:=20260214
PKG_UPSTREAM_GITHASH:=
PKG_VERSION:=$(PKG_UPSTREAM_VERSION)$(if $(PKG_UPSTREAM_GITHASH),~$(call version_abbrev,$(PKG_UPSTREAM_GITHASH)))
PKG_RELEASE:=4
PKG_RELEASE:=5
SCRIPTS_VERSION:=0.2026.01.24
PKG_SOURCE_SUBDIR:=$(PKG_UPSTREAM_NAME)-$(PKG_UPSTREAM_VERSION)
@ -23,7 +23,7 @@ PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.xz
else
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/heiher/natmap.git
PKG_SOURCE_VERSION:=e0975d64fbd22a34e30d573e51c44fc017b3ff8c
PKG_SOURCE_VERSION:=1853fc21aff07a1d5fdfb31c7e90af34fddf0296
PKG_MIRROR_HASH:=skip
PKG_SOURCE:=$(PKG_SOURCE_SUBDIR)-$(PKG_SOURCE_VERSION).tar.gz

View File

@ -23,7 +23,7 @@ start() {
-H "Referer: ${scheme}://${host}:${web_port}" \
-d "username=${username}&password=${password}" \
--url ${scheme}://${host}:${web_port}/api/v2/auth/login \
| grep -i set-cookie | sed -En 's|^.*(SID=\S+);.*|\1|p')"
| grep -i set-cookie | sed -En 's#^.*\b((SID|QBT_SID_'"${web_port}"')=[^;]+);.*#\1#p')"
$CURL $retry $self_signed -L -X POST \
-b "$cookie" \
-d "$payload" \