🎁 Sync 2026-06-13 20:38:31

This commit is contained in:
github-actions[bot] committed 2026-06-13 20:38:31 +08:00
1 parent a2112fa32e
commit 6ad9333ace
41 files changed
+567 -501

No files matched your search

+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-daede
PKG_VERSION:=1.10.3
PKG_RELEASE:=4
PKG_VERSION:=1.10.4
PKG_RELEASE:=5
PKG_MAINTAINER:=kenzok8
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@@ -219,6 +219,11 @@ return view.extend({
btn.textContent = _('Unavailable');
} else if (sameVersion) {
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('up to date');
btn.disabled = true;
} else if (!entry.r.latest) {
// latest unknown (registry unreachable) - nothing to upgrade to
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('latest version unknown');
btn.disabled = true;
} else if (updatable) {
meta = _('installed') + ': ' + entry.r.installed + ' → ' + _('latest') + ': ' + entry.r.latest;
} else {
@@ -263,6 +268,12 @@ return view.extend({
if (ctx.backend.useNetns && ns && ns.exists) {
const btn = E('button', { 'class': 'dd-up-btn' }, _('Clean'));
btn.addEventListener('click', function() {
const daedRunning = !!(running && running[ctx.name]);
const msg = daedRunning
? _('%s is running. Deleting the daens netns now will break its networking until you restart it. Continue?').format(ctx.name)
: _('Delete the daens netns?');
if (!confirm(msg))
return;
btn.disabled = true;
fs.exec('/sbin/ip', ['netns', 'del', 'daens']).finally(function() { btn.disabled = false; });
});
@@ -26,7 +26,11 @@ function toggleService(be, turnOn, running) {
const enabled = turnOn ? '1' : '0';
const action = turnOn ? 'start' : 'stop';
return rejectIfOtherRunning(be, running)
// Only guard on start: two backends share the eBPF/cgroup attachment, so
// starting one while the other runs is unsafe. Stopping is always allowed.
const guard = turnOn ? rejectIfOtherRunning(be, running) : Promise.resolve();
return guard
.then(function() { return fs.exec('/sbin/uci', ['set', be.uci + '.config.enabled=' + enabled]); })
.then(function() { return fs.exec('/sbin/uci', ['commit', be.uci]); })
.then(function() {
@@ -1,14 +1,8 @@
#!/bin/sh
# Patch the daed package's /etc/init.d/daed to clean up /run/netns/daens on
# stop_service(). Without this, restarting daed fails with:
# fatal: failed to create netns: open /run/netns/daens: file exists
#
# This script lives under /etc/uci-defaults/ which OpenWrt runs once on
# every package install/upgrade and then removes - so each time luci-app-daede
# is (re-)installed we re-patch the daed init.d even if it was overwritten
# by a daed package upgrade in between.
#
# The patch is idempotent: a marker comment guards against double-injection.
# Run once on every (re-)install/upgrade of luci-app-daede: migrate legacy
# config, drop stale files from the old luci-app-daed package, and seed the
# default dae form sections. The netns cleanup that used to be patched into
# daed's init from here now lives directly in daed's own stop_service().
set -e
@@ -126,26 +120,6 @@ if [ -f /etc/config/dae ]; then
uci -q commit dae
fi
INIT="/etc/init.d/daed"
MARKER="# luci-app-daede: netns-cleanup"
[ -f "$INIT" ] || exit 0
grep -q "$MARKER" "$INIT" && exit 0
# Inject `ip netns del daens 2>/dev/null || true` right after `rm -f "$LOG"`
# inside stop_service(). awk is more reliable than sed for multiline contexts.
awk -v marker="$MARKER" '
BEGIN { in_stop = 0; injected = 0 }
/^stop_service\(\)/ { in_stop = 1 }
in_stop && /^}/ { in_stop = 0 }
{ print }
in_stop && !injected && /rm -f "\$LOG"/ {
print "\tip netns del daens 2>/dev/null || true " marker
injected = 1
}
' "$INIT" > "${INIT}.new" && mv "${INIT}.new" "$INIT"
chmod +x "$INIT"
exit 0
reload_service() {
+1 -1
View File
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-xray
PKG_VERSION:=3.7.1
PKG_RELEASE:=4
PKG_RELEASE:=5
PKG_LICENSE:=MPLv2
PKG_LICENSE_FILES:=LICENSE
@@ -64,7 +64,7 @@ export function fake_dns_conf(proxy) {
"poolSize": int(proxy.pool_v4_size) || 65535
},
{
"ipPool": proxy.pool_v6 || "fc00::/18",
"ipPool": proxy.pool_v6 || "2001:2::/48",
"poolSize": int(proxy.pool_v6_size) || 65535
}
];
@@ -360,8 +360,8 @@
{% if (length(fakedns) > 0): %}
ip protocol tcp ip daddr {{ general.pool_v4 || "198.18.0.0/15" }} {{ counter }} tproxy ip to :{{ general.tproxy_port_tcp_f4 || 1086 }} accept
ip protocol udp ip daddr {{ general.pool_v4 || "198.18.0.0/15" }} {{ counter }} tproxy ip to :{{ general.tproxy_port_udp_f4 || 1088 }} accept
ip6 nexthdr tcp ip6 daddr {{ general.pool_v6 || "fc00::/18" }} {{ counter }} tproxy ip6 to :{{ general.tproxy_port_tcp_f6 || 1087 }} accept
ip6 nexthdr udp ip6 daddr {{ general.pool_v6 || "fc00::/18" }} {{ counter }} tproxy ip6 to :{{ general.tproxy_port_udp_f6 || 1089 }} accept
ip6 nexthdr tcp ip6 daddr {{ general.pool_v6 || "2001:2::/48" }} {{ counter }} tproxy ip6 to :{{ general.tproxy_port_tcp_f6 || 1087 }} accept
ip6 nexthdr udp ip6 daddr {{ general.pool_v6 || "2001:2::/48" }} {{ counter }} tproxy ip6 to :{{ general.tproxy_port_udp_f6 || 1089 }} accept
{% endif %}
{% if (length(manual_tproxy_source_ips) > 0): %}
ip protocol tcp ip daddr @tp_spec_dv4_mt {{ counter }} tproxy ip to :{{ general.tproxy_port_tcp_v4 || 1082 }} accept
@@ -522,8 +522,8 @@
{% if (length(fakedns) > 0): %}
ip protocol tcp ip daddr {{ general.pool_v4 || "198.18.0.0/15" }} {{ counter }} goto tp_spec_lan_fw comment "Xray FakeDNS IPv4 Pool TCP"
ip protocol udp ip daddr {{ general.pool_v4 || "198.18.0.0/15" }} {{ counter }} goto tp_spec_lan_fw comment "Xray FakeDNS IPv4 Pool UDP"
ip6 nexthdr tcp ip6 daddr {{ general.pool_v6 || "fc00::/18" }} {{ counter }} goto tp_spec_lan_fw comment "Xray FakeDNS IPv6 Pool TCP"
ip6 nexthdr udp ip6 daddr {{ general.pool_v6 || "fc00::/18" }} {{ counter }} goto tp_spec_lan_fw comment "Xray FakeDNS IPv6 Pool UDP"
ip6 nexthdr tcp ip6 daddr {{ general.pool_v6 || "2001:2::/48" }} {{ counter }} goto tp_spec_lan_fw comment "Xray FakeDNS IPv6 Pool TCP"
ip6 nexthdr udp ip6 daddr {{ general.pool_v6 || "2001:2::/48" }} {{ counter }} goto tp_spec_lan_fw comment "Xray FakeDNS IPv6 Pool UDP"
{% endif %}
{% if (length(manual_tproxy_source_ips) > 0): %}
ip protocol tcp ip daddr @tp_spec_dv4_mt {{ counter }} goto tp_spec_lan_fw comment "Xray manual transparent proxy TCP"
@@ -622,7 +622,7 @@
chain xray_fakedns_ping_prerouting {
type nat hook prerouting priority dstnat {{ firewall_priority }}; policy accept;
ip daddr {{ general.pool_v4 || "198.18.0.0/15" }} icmp type echo-request {{ counter }} redirect comment "Xray FakeDNS IPv4 Pool ICMP"
ip6 daddr {{ general.pool_v6 || "fc00::/18" }} icmpv6 type echo-request {{ counter }} redirect comment "Xray FakeDNS IPv6 Pool ICMPv6"
ip6 daddr {{ general.pool_v6 || "2001:2::/48" }} icmpv6 type echo-request {{ counter }} redirect comment "Xray FakeDNS IPv6 Pool ICMPv6"
}
{% endif %}
@@ -630,7 +630,7 @@
chain xray_fakedns_ping_output {
type nat hook output priority dstnat {{ firewall_priority }}; policy accept;
ip daddr {{ general.pool_v4 || "198.18.0.0/15" }} icmp type echo-request {{ counter }} redirect comment "Xray FakeDNS IPv4 Pool ICMP"
ip6 daddr {{ general.pool_v6 || "fc00::/18" }} icmpv6 type echo-request {{ counter }} redirect comment "Xray FakeDNS IPv6 Pool ICMPv6"
ip6 daddr {{ general.pool_v6 || "2001:2::/48" }} icmpv6 type echo-request {{ counter }} redirect comment "Xray FakeDNS IPv6 Pool ICMPv6"
}
{% endif %}
{% endif %}
@@ -490,7 +490,7 @@ return view.extend({
let pool_v6 = s.taboption('fake_dns', form.Value, 'pool_v6', _('Address Pool (IPv6)'));
pool_v6.datatype = 'ip6addr';
pool_v6.placeholder = "fc00::/18";
pool_v6.placeholder = "2001:2::/48";
let pool_v6_size = s.taboption('fake_dns', form.Value, 'pool_v6_size', _('Address Pool Size (IPv6)'));
pool_v6_size.datatype = 'integer';
@@ -86,8 +86,8 @@ return view.extend({
s.tab('dynamic_direct', _('Dynamic Direct'));
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_tcp4', _('Enable for IPv4 TCP'), _("This should improve performance with large number of connections."));
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_tcp6', _('Enable for IPv4 UDP'), _("This may cause problems but worth a try."));
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_udp4', _('Enable for IPv6 TCP'), _("This may not be very useful but it should be good enough for a try."));
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_udp4', _('Enable for IPv4 UDP'), _("This may cause problems but worth a try."));
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_tcp6', _('Enable for IPv6 TCP'), _("This may not be very useful but it should be good enough for a try."));
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_udp6', _('Enable for IPv6 UDP'), _("This may cause problems and is not very useful at the same time. Not recommended."));
let dynamic_direct_timeout = s.taboption('dynamic_direct', form.Value, 'dynamic_direct_timeout', _('Dynamic Direct Timeout'), _("Larger value consumes more memory and performs generally better. Unit in seconds."));
+10 -10
View File
@@ -1,13 +1,13 @@
*:not(html) {
@apply scrollbar-thumb-rounded-full scrollbar-thin scrollbar-track-transparent scrollbar-thumb-foreground/70;
@apply scrollbar-thumb-rounded-full scrollbar-thin scrollbar-track-transparent scrollbar-thumb-content-muted;
}
html {
@apply scrollbar-thumb-rounded-full scrollbar-thin scrollbar-track-page-bg scrollbar-thumb-foreground/70;
@apply bg-background relative h-full font-sans;
@apply scrollbar-thumb-rounded-full scrollbar-thin scrollbar-track-surface scrollbar-thumb-content-muted;
@apply bg-canvas relative h-full font-sans;
body {
@apply text-foreground relative flex flex-col bg-transparent text-sm leading-relaxed font-normal;
@apply text-content relative flex flex-col bg-transparent text-sm leading-relaxed font-normal;
&.modal-overlay-active {
@apply h-screen overflow-hidden;
}
@@ -20,7 +20,7 @@ h3,
h4,
h5,
h6 {
@apply text-foreground font-sans leading-tight font-semibold tracking-tight;
@apply text-content font-sans leading-tight font-semibold tracking-tight;
}
h1 {
@@ -60,15 +60,15 @@ abbr {
}
p {
@apply text-default-foreground text-sm leading-relaxed;
@apply text-content 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;
@apply text-content-muted border-border-subtle bg-surface-muted 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;
@apply text-content-muted bg-surface-muted rounded px-2 py-1 font-mono text-sm;
}
a {
@@ -80,9 +80,9 @@ var {
}
small {
@apply text-default-foreground text-xs font-normal;
@apply text-content text-xs font-normal;
}
em {
@apply text-muted-foreground font-medium italic;
@apply text-content-muted font-medium italic;
}
+41 -34
View File
@@ -7,7 +7,7 @@ header {
[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-(--mega-menu-height,0) w-full overflow-hidden opacity-0 backdrop-blur-xl transition-[clip-path,opacity] duration-200 ease-out [will-change:clip-path,opacity] [clip-path:inset(0_0_100%_0)] max-md:hidden;
@apply bg-header-glass-bg pointer-events-none absolute inset-x-0 top-0 z-30 h-(--mega-menu-height,0) w-full overflow-hidden opacity-0 backdrop-blur-xl transition-[clip-path,opacity] duration-200 ease-out [will-change:clip-path,opacity] [clip-path:inset(0_0_100%_0)] max-md:hidden;
&.active {
@apply pointer-events-auto opacity-100 [clip-path:inset(0)];
@@ -32,7 +32,7 @@ header {
@apply absolute top-7 left-[calc(50%-30rem)] w-56 max-lg:hidden;
& .desktop-nav-title {
@apply text-foreground text-2xl font-semibold tracking-tight;
@apply text-content text-2xl font-semibold tracking-tight;
}
}
@@ -48,7 +48,7 @@ header {
@apply m-0 list-none;
& > a {
@apply text-foreground block w-fit py-2.5 text-sm whitespace-nowrap no-underline hover:underline hover:decoration-2 hover:underline-offset-4;
@apply text-content block w-fit py-2.5 text-sm whitespace-nowrap no-underline hover:underline hover:decoration-2 hover:underline-offset-4;
}
}
}
@@ -64,7 +64,7 @@ header {
@apply absolute top-34 left-[calc(50%-30rem)] flex w-56 flex-col gap-2 max-lg:hidden;
& .board-line {
@apply text-muted-foreground/80 flex max-w-full items-center gap-2.5 text-xs;
@apply text-content-muted flex max-w-full items-center gap-2.5 text-xs;
&::before {
@apply size-4 shrink-0 bg-current content-[''];
@@ -95,7 +95,7 @@ header {
}
.brand {
@apply hover:text-primary text-foreground inline-block shrink-0 text-xl font-semibold tracking-tight no-underline transition-[color,transform] duration-200 hover:-translate-y-0.5 max-md:flex-1 max-md:text-lg;
@apply hover:text-brand text-content inline-block shrink-0 text-xl font-semibold tracking-tight no-underline transition-[color,transform] duration-200 hover:-translate-y-0.5 max-md:flex-1 max-md:text-lg;
}
.nav {
@@ -105,15 +105,15 @@ header {
@apply relative;
.menu {
@apply text-foreground block rounded-xl px-3.5 py-1.5 font-medium no-underline transition-colors duration-150;
@apply text-content block rounded-xl px-3.5 py-1.5 font-medium no-underline transition-colors duration-150;
&.menu-active {
@apply text-foreground;
@apply text-content;
[data-nav-type="mega-menu"] & {
@apply underline decoration-2 underline-offset-4;
}
[data-nav-type="boxed-dropdown"] & {
@apply bg-header-interactive;
@apply bg-header-interactive-bg;
}
}
}
@@ -131,16 +131,16 @@ header {
& .desktop-nav-list {
[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;
@apply border-border-subtle bg-header-glass-bg flex flex-col gap-y-1 rounded-3xl border py-2 shadow-lg backdrop-blur-md backdrop-saturate-150;
}
& > li {
@apply m-0 list-none;
& > a {
@apply text-foreground block whitespace-nowrap no-underline;
@apply text-content block whitespace-nowrap no-underline;
[data-nav-type="boxed-dropdown"] & {
@apply hover:bg-header-interactive mx-2 rounded-xl px-4 py-2;
@apply hover:bg-header-interactive-bg mx-2 rounded-xl px-4 py-2;
}
}
}
@@ -157,10 +157,10 @@ header {
}
& .navigation-toggle {
@apply cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95;
@apply cursor-pointer rounded-none border-0 bg-transparent p-0 shadow-none transition-transform duration-200 hover:scale-105 active:scale-95;
& svg {
@apply text-foreground size-5;
@apply text-content size-5;
}
& .navigation-toggle-line {
@@ -189,7 +189,7 @@ header {
@apply flex shrink-0 flex-row-reverse gap-5 md:gap-8;
& span[data-indicator] {
@apply before:text-foreground size-5 cursor-pointer text-[0px] before:absolute before:size-5 before:bg-current;
@apply before:text-content 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];
@@ -209,7 +209,7 @@ header {
@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)];
@apply after:bg-danger after:text-on-brand 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)];
}
}
}
@@ -230,7 +230,7 @@ body[data-nav-type="sidebar"] {
}
& > header {
@apply md:border-border/60 md:col-span-full md:row-start-1 md:mb-0 md:border-b;
@apply md:border-border-subtle md:col-span-full md:row-start-1 md:mb-0 md:border-b;
}
& > .sidebar-panel {
@@ -242,7 +242,7 @@ body[data-nav-type="sidebar"] {
}
& .header-crumb {
@apply text-muted-foreground my-0 mr-auto ml-6 hidden min-w-0 list-none items-center gap-2 overflow-hidden p-0 text-sm md:flex;
@apply text-content-muted my-0 mr-auto ml-6 hidden min-w-0 list-none items-center gap-2 overflow-hidden p-0 text-sm md:flex;
& li {
@apply m-0 list-none whitespace-nowrap;
@@ -253,12 +253,12 @@ body[data-nav-type="sidebar"] {
}
& .current {
@apply text-foreground min-w-0 truncate font-medium;
@apply text-content min-w-0 truncate font-medium;
}
}
& .sidebar-panel {
@apply border-border/60 sticky top-14 hidden h-[calc(100vh-3.5rem)] w-full overflow-hidden rounded-none border-r transition-[visibility] duration-300 md:block;
@apply border-border-subtle sticky top-14 hidden h-[calc(100vh-3.5rem)] w-full overflow-hidden rounded-none border-r transition-[visibility] duration-300 md:block;
}
/* Visibility flips at the end of the slide so collapsed controls leave the
@@ -287,6 +287,13 @@ body[data-nav-type="sidebar"] {
@apply truncate text-lg;
}
/* Selected-pill background for top-level leaf links. The shared
.nav-link-active carries only brand text, so the sidebar owns its pill
here (submenu links get theirs below). */
& .sidebar-list > li > .nav-link-active {
@apply bg-brand-faint hover:bg-brand-faint;
}
& .sidebar-section {
@apply grid grid-rows-[0fr] opacity-0 transition-[grid-template-rows,opacity] duration-200 ease-out;
}
@@ -302,20 +309,20 @@ body[data-nav-type="sidebar"] {
}
& .sidebar-submenu .nav-link {
@apply text-muted-foreground hover:text-foreground rounded-lg px-3 py-1.5 text-sm;
@apply text-content-muted hover:text-content rounded-lg px-3 py-1.5 text-sm;
}
& .sidebar-submenu .nav-link-active {
@apply bg-primary/10 text-primary hover:text-primary;
@apply bg-brand-faint text-brand hover:text-brand;
}
& .sidebar-footer {
@apply border-border/60 shrink-0 border-t p-3;
@apply border-border-subtle shrink-0 border-t p-3;
/* Logout: muted at rest; on hover the base .nav-link pill background
plus error-colored text is the intended compound state (matches v1). */
& .nav-link {
@apply text-muted-foreground hover:text-error-foreground;
@apply text-content-muted hover:text-danger-content;
}
}
}
@@ -324,7 +331,7 @@ body[data-nav-type="sidebar"] {
@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 mx-0 w-full p-0 shadow-none empty:hidden md:rounded-4xl md:border md:p-6 md:shadow-xl;
@apply animate-in fade-in-0 slide-in-from-top-2 fill-mode-both md:border-border-faint md:bg-surface mx-0 w-full p-0 shadow-none empty:hidden md:rounded-4xl md:border md:p-6 md:shadow-xl;
.cbi-title-section {
@apply mb-6 leading-relaxed max-md:mx-2 max-md:mb-3;
@@ -355,10 +362,10 @@ body[data-nav-type="sidebar"] {
& div[style] {
& > svg {
@apply dark:!bg-page-bg;
@apply dark:!bg-surface;
& line[style] {
@apply dark:!stroke-foreground;
@apply dark:!stroke-content;
}
}
}
@@ -366,18 +373,18 @@ body[data-nav-type="sidebar"] {
.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;
@apply text-content-muted 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;
@apply border-border-subtle 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;
@apply text-content-muted mt-1.5;
}
.zone-dest {
@@ -391,15 +398,15 @@ body[data-nav-type="sidebar"] {
}
#syslog {
@apply bg-terminal-bg text-terminal-foreground rounded-3xl border p-6 shadow-lg max-md:p-3;
@apply bg-terminal-bg text-terminal-content 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;
@apply text-content-muted mt-2 flex min-h-16 flex-wrap items-center justify-between text-xs;
& a {
@apply text-primary;
@apply text-brand;
}
& span {
@@ -407,13 +414,13 @@ footer {
}
& .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-colors duration-200;
@apply bg-glass-surface hover:bg-surface flex items-center gap-1 rounded-full px-3 py-1.5 text-xs shadow-sm backdrop-blur-sm transition-colors duration-200;
& li {
@apply list-none;
&.active a {
@apply text-default-foreground;
@apply text-content;
}
}
}
@@ -14,7 +14,7 @@
#file-manager-container {
@apply overflow-auto;
#status-bar {
@apply bg-page-bg border-0;
@apply bg-surface border-0;
}
}
@@ -52,17 +52,17 @@
&.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;
@apply bg-glass-raised not-[.tr]:border-border-faint not-[.tr]:hover:border-border-subtle max-md:bg-glass-raised not-[.tr]:max-md:border-border-faint not-[.tr]:border not-[.tr]:shadow-lg not-[.tr]:hover:shadow-xl not-[.tr]:max-md:border;
/* Dark mode: override custom.css hardcoded light-mode colors on all text nodes */
& span {
@apply dark:text-foreground!;
@apply dark:text-content!;
}
& td {
@apply dark:text-foreground!;
@apply dark:text-content!;
}
& th {
@apply dark:text-foreground!;
@apply dark:text-content!;
}
img[src*=".svg"] {
@@ -94,7 +94,7 @@
.title {
h3 {
@apply text-foreground border-0 pb-4 max-md:mx-0 max-md:pb-2;
@apply text-content border-0 pb-4 max-md:mx-0 max-md:pb-2;
}
}
+208 -179
View File
@@ -4,222 +4,251 @@
* Licensed to the public under the Apache License 2.0.
*
* Shared between main.css and login.css.
* aurora-config writes UCI overrides that target the same --* variable
* names, so customizations apply automatically to both stylesheets.
*
* Layer 1 contains broad theme inputs. Layer 2 names semantic and component
* responsibilities. Components consume named roles and never apply numeric
* color opacity modifiers.
*
* ORDER MATTERS: [data-darkmode="true"] ties with :root on specificity, so
* the dark block must remain after :root.
*/
:root {
--background: oklch(0.968 0.007 247.896);
--foreground: oklch(0.208 0.042 265.755);
--primary: oklch(0.68 0.11 233);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.929 0.013 255.508);
--secondary-foreground: oklch(0.372 0.044 257.287);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.446 0.043 257.281);
--destructive: oklch(0.94 0.05 25);
--destructive-foreground: oklch(0.35 0.12 25);
--accent: oklch(0.62 0.22 25);
--accent-foreground: oklch(0.97 0.02 25);
--default: oklch(0.97 0 0);
--default-foreground: oklch(0.205 0 0);
--info: oklch(0.94 0.05 230);
--info-foreground: oklch(0.35 0.08 240);
--warning: oklch(0.95 0.05 90);
--warning-foreground: oklch(0.35 0.08 60);
--success: oklch(0.94 0.05 160);
--success-foreground: oklch(0.32 0.09 165);
--error: oklch(0.94 0.05 25);
--error-foreground: oklch(0.35 0.12 25);
--border: oklch(0.92 0 0);
/* Layer 1: theme inputs */
--canvas: oklch(0.968 0.007 247.896);
--surface: oklch(1 0 0);
--surface-raised: oklch(1 0 0);
--content: oklch(0.208 0.042 265.755);
--brand: oklch(0.68 0.11 233);
--on-brand: oklch(1 0 0);
--link: oklch(0.74 0.238 322.16);
--info: oklch(0.35 0.08 240);
--warning: oklch(0.35 0.08 60);
--success: oklch(0.32 0.09 165);
--danger: oklch(0.35 0.12 25);
--input-checked: oklch(1 0 0);
/* Layer 2: semantic surface and content roles */
--surface-subtle: oklch(from var(--surface-raised) calc(l - 0.02) c h);
--surface-muted: oklch(from var(--surface-raised) calc(l - 0.05) c h);
--content-muted: oklch(0.446 0.043 257.281);
--content-subtle: color-mix(in oklab, var(--content) 52%, var(--surface-raised));
--label-surface: oklch(from var(--panel-bg) calc(l - 0.02) c h);
/* Layer 2: semantic brand roles */
--brand-faint: color-mix(in oklab, var(--brand) 8%, var(--surface-raised));
--brand-soft: color-mix(in oklab, var(--brand) 15%, var(--surface-raised));
--brand-emphasis: color-mix(in oklab, var(--brand) 25%, var(--surface-raised));
--brand-emphasis-hover: color-mix(
in oklab,
var(--brand) 30%,
var(--surface-raised)
);
--brand-hover: color-mix(in oklab, var(--brand) 90%, var(--surface-raised));
--focus-ring: var(--brand-emphasis);
--login-aurora-1: oklch(0.70 0.26 148);
--login-aurora-2: oklch(0.65 0.22 190);
--login-aurora-3: oklch(0.58 0.24 268);
--login-aurora-4: oklch(0.62 0.26 312);
/* Layer 2: semantic border and material roles */
--border-faint: color-mix(in oklab, var(--content) 8%, transparent);
--border-subtle: color-mix(in oklab, var(--content) 12%, transparent);
--border-strong: color-mix(in oklab, var(--content) 28%, transparent);
--glass-surface: color-mix(in oklab, var(--surface) 92%, transparent);
--glass-raised: color-mix(in oklab, var(--surface-raised) 96%, transparent);
--scrim: oklch(0 0 0 / 0.5);
/* Layer 2: semantic status families */
--info-surface: oklch(from var(--info) 0.94 0.05 h);
--info-content: var(--info);
--info-border: color-mix(in oklab, var(--info) 28%, var(--surface-raised));
--warning-surface: oklch(from var(--warning) 0.95 0.05 h);
--warning-content: var(--warning);
--warning-border: color-mix(in oklab, var(--warning) 28%, var(--surface-raised));
--success-surface: oklch(from var(--success) 0.94 0.05 h);
--success-content: var(--success);
--success-border: color-mix(in oklab, var(--success) 28%, var(--surface-raised));
--danger-surface: oklch(from var(--danger) 0.94 0.05 h);
--danger-content: var(--danger);
--danger-border: color-mix(in oklab, var(--danger) 28%, var(--surface-raised));
/* Layer 2: shell and navigation */
--header-bg: var(--canvas);
--header-interactive-bg: oklch(from var(--header-bg) calc(l - 0.12) c h);
--header-glass-bg: color-mix(in oklab, var(--header-bg) 40%, transparent);
/* Layer 2: focused component responsibilities */
--tooltip-bg: oklch(from var(--surface) calc(l - 0.015) c h);
--terminal-bg: oklch(0.24 0.02 260);
--terminal-foreground: oklch(1 0 0);
--terminal-content: oklch(1 0 0);
--progress-track-bg: oklch(0.929 0.013 255.508);
--progress-start: var(--brand);
--progress-end: oklch(from var(--brand) calc(l + 0.07) c calc(h - 35));
--input-bg: var(--surface);
--input-checked-content: oklch(1 0 0);
--overlay-base: oklch(0 0 0);
/* Layer 2: buttons and neutral status */
--button-secondary-bg: oklch(0.929 0.013 255.508);
--button-secondary-hover-bg: color-mix(
in oklab,
var(--button-secondary-bg) 90%,
var(--surface-raised)
);
--button-secondary-content: oklch(0.372 0.044 257.287);
--button-secondary-border: var(--button-secondary-bg);
--button-muted-bg: var(--surface-muted);
--button-muted-hover-bg: color-mix(
in oklab,
var(--button-muted-bg) 90%,
var(--surface-raised)
);
--button-muted-content: var(--content-muted);
--button-muted-border: var(--button-muted-bg);
--neutral-status-surface: oklch(0.97 0 0);
--neutral-status-content: oklch(0.205 0 0);
--neutral-status-border: var(--border-faint);
--progress-bar-start: oklch(0.68 0.11 233);
--progress-bar-end: oklch(0.7535 0.1034 198.37);
--header-bg: oklch(from var(--background) l c h);
--header-interactive: oklch(from var(--header-bg) calc(l - 0.12) c h);
--page-bg: oklch(1 0 0);
--panel-bg: oklch(1 0 0);
--tooltip-bg: oklch(from var(--page-bg) calc(l - 0.015) c h);
/* Layer 2: responsibilities formerly shared by label-surface */
--card-action-bg: var(--surface-subtle);
--interface-badge-bg: var(--surface-subtle);
--segmented-control-bg: var(--surface-subtle);
--ifacebox-header-bg: var(--surface-subtle);
--table-header-bg: var(--surface-subtle);
--table-row-hover-bg: var(--surface-subtle);
--table-row-alternate-bg: color-mix(
in oklab,
var(--table-row-hover-bg) 50%,
var(--surface-raised)
);
/* Structure */
--font-sans: "Lato", ui-sans-serif, system-ui, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--spacing: 0.25rem;
--container-max-width: 80rem;
--radius-base: 0.5rem;
}
[data-darkmode="true"] {
--background: oklch(0.32 0.059 188.42);
--foreground: oklch(0.968 0.007 247.896);
--primary: oklch(0.6 0.13 188.745);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.372 0.044 257.287);
--secondary-foreground: oklch(0.928 0.006 264.531);
--muted: oklch(0.373 0.026 259.733);
--muted-foreground: oklch(0.704 0.04 256.788);
--destructive: oklch(0.258 0.092 26.042);
--destructive-foreground: oklch(0.88 0.14 26.042);
--accent: oklch(0.35 0.12 25);
--accent-foreground: oklch(0.88 0.14 25);
--default: oklch(0.274 0.006 286.033/0.5);
--default-foreground: oklch(0.985 0.01 285.805);
--info: oklch(0.391 0.09 240.876/0.5);
--info-foreground: oklch(0.88 0.06 230);
--warning: oklch(0.414 0.112 45.904/0.5);
--warning-foreground: oklch(0.924 0.12 95.746);
--success: oklch(0.378 0.077 168.94/0.5);
--success-foreground: oklch(0.92 0.09 160);
--error: oklch(0.41 0.159 10.272/0.5);
--error-foreground: oklch(0.88 0.14 25);
--border: oklch(0.38 0.041 260.031);
/* Layer 1: theme inputs */
--canvas: oklch(0.32 0.059 188.42);
--surface: oklch(0.21 0.034 264.665);
--surface-raised: oklch(0.279 0.041 260.031);
--content: oklch(0.968 0.007 247.896);
--brand: oklch(0.6 0.13 188.745);
--on-brand: oklch(1 0 0);
--link: oklch(0.702 0.183 293.541);
--info: oklch(0.88 0.06 230);
--warning: oklch(0.924 0.12 95.746);
--success: oklch(0.92 0.09 160);
--danger: oklch(0.88 0.14 25);
--input-checked: oklch(1 0 0);
--label-surface: oklch(from var(--panel-bg) calc(l + 0.04) c h);
--login-aurora-1: oklch(0.76 0.28 148);
--login-aurora-2: oklch(0.70 0.23 192);
--login-aurora-3: oklch(0.63 0.25 268);
--login-aurora-4: oklch(0.67 0.27 312);
/* Mode-sensitive semantic roles */
--surface-subtle: oklch(from var(--surface-raised) calc(l + 0.04) c h);
--surface-muted: oklch(from var(--surface-raised) calc(l + 0.09) c h);
--content-muted: oklch(0.704 0.04 256.788);
--info-surface: oklch(from var(--info) 0.34 0.07 h);
--warning-surface: oklch(from var(--warning) 0.35 0.08 h);
--success-surface: oklch(from var(--success) 0.33 0.06 h);
--danger-surface: oklch(from var(--danger) 0.34 0.09 h);
/* Mode-sensitive component roles */
--header-bg: var(--surface);
--header-interactive-bg: oklch(from var(--header-bg) calc(l + 0.24) c h);
--header-glass-bg: color-mix(in oklab, var(--header-bg) 90%, transparent);
--tooltip-bg: oklch(from var(--surface) calc(l + 0.06) c h);
--terminal-bg: oklch(0.18 0.03 260);
--terminal-foreground: oklch(1 0 0);
--overlay-base: oklch(0 0 0);
--progress-bar-start: oklch(0.4318 0.0865 166.91);
--progress-bar-end: oklch(62.1% 0.145 189.632);
--header-bg: oklch(from var(--page-bg) l c h);
--header-interactive: oklch(from var(--header-bg) calc(l + 0.24) c h);
--page-bg: oklch(0.21 0.034 264.665);
--panel-bg: oklch(0.279 0.041 260.031);
--tooltip-bg: oklch(from var(--page-bg) calc(l + 0.06) c h);
--terminal-content: oklch(1 0 0);
--progress-track-bg: oklch(0.372 0.044 257.287);
--progress-start: oklch(0.4318 0.0865 166.91);
--progress-end: oklch(0.621 0.145 189.632);
--input-checked-content: oklch(1 0 0);
--button-secondary-bg: oklch(0.372 0.044 257.287);
--button-secondary-content: oklch(0.928 0.006 264.531);
--button-muted-content: oklch(0.704 0.04 256.788);
--neutral-status-surface: oklch(0.274 0.006 286.033);
--neutral-status-content: oklch(0.985 0.01 285.805);
}
@theme inline {
/* Base Colors */
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-page-bg: var(--page-bg);
--color-panel-bg: var(--panel-bg);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-border: var(--border);
/* Component Colors */
--color-header-bg: var(--header-bg);
--color-header-interactive: var(--header-interactive);
--color-progress-bar-start: var(--progress-bar-start);
--color-progress-bar-end: var(--progress-bar-end);
--color-terminal-bg: var(--terminal-bg);
--color-terminal-foreground: var(--terminal-foreground);
--color-tooltip-bg: var(--tooltip-bg);
--color-overlay-base: var(--overlay-base);
/* Layer 1 */
--color-canvas: var(--canvas);
--color-surface: var(--surface);
--color-surface-raised: var(--surface-raised);
--color-content: var(--content);
--color-brand: var(--brand);
--color-on-brand: var(--on-brand);
--color-link: var(--link);
--color-input-checked: var(--input-checked);
--color-label-surface: var(--label-surface);
/* Semantic & Status Colors */
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-default: var(--default);
--color-default-foreground: var(--default-foreground);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-danger: var(--danger);
--color-error: var(--error);
--color-error-foreground: var(--error-foreground);
/* Layer 2: semantic */
--color-surface-subtle: var(--surface-subtle);
--color-surface-muted: var(--surface-muted);
--color-content-muted: var(--content-muted);
--color-content-subtle: var(--content-subtle);
--color-brand-faint: var(--brand-faint);
--color-brand-soft: var(--brand-soft);
--color-brand-emphasis: var(--brand-emphasis);
--color-brand-emphasis-hover: var(--brand-emphasis-hover);
--color-brand-hover: var(--brand-hover);
--color-focus-ring: var(--focus-ring);
--color-border-faint: var(--border-faint);
--color-border-subtle: var(--border-subtle);
--color-border-strong: var(--border-strong);
--color-glass-surface: var(--glass-surface);
--color-glass-raised: var(--glass-raised);
--color-scrim: var(--scrim);
--color-info-surface: var(--info-surface);
--color-info-content: var(--info-content);
--color-info-border: var(--info-border);
--color-warning-surface: var(--warning-surface);
--color-warning-content: var(--warning-content);
--color-warning-border: var(--warning-border);
--color-success-surface: var(--success-surface);
--color-success-content: var(--success-content);
--color-success-border: var(--success-border);
--color-danger-surface: var(--danger-surface);
--color-danger-content: var(--danger-content);
--color-danger-border: var(--danger-border);
/* Layer 2: component */
--color-header-bg: var(--header-bg);
--color-header-interactive-bg: var(--header-interactive-bg);
--color-header-glass-bg: var(--header-glass-bg);
--color-tooltip-bg: var(--tooltip-bg);
--color-terminal-bg: var(--terminal-bg);
--color-terminal-content: var(--terminal-content);
--color-progress-track-bg: var(--progress-track-bg);
--color-progress-start: var(--progress-start);
--color-progress-end: var(--progress-end);
--color-input-bg: var(--input-bg);
--color-input-checked-content: var(--input-checked-content);
--color-button-secondary-bg: var(--button-secondary-bg);
--color-button-secondary-hover-bg: var(--button-secondary-hover-bg);
--color-button-secondary-content: var(--button-secondary-content);
--color-button-secondary-border: var(--button-secondary-border);
--color-button-muted-bg: var(--button-muted-bg);
--color-button-muted-hover-bg: var(--button-muted-hover-bg);
--color-button-muted-content: var(--button-muted-content);
--color-button-muted-border: var(--button-muted-border);
--color-neutral-status-surface: var(--neutral-status-surface);
--color-neutral-status-content: var(--neutral-status-content);
--color-neutral-status-border: var(--neutral-status-border);
--color-card-action-bg: var(--card-action-bg);
--color-interface-badge-bg: var(--interface-badge-bg);
--color-segmented-control-bg: var(--segmented-control-bg);
--color-ifacebox-header-bg: var(--ifacebox-header-bg);
--color-table-header-bg: var(--table-header-bg);
--color-table-row-hover-bg: var(--table-row-hover-bg);
--color-table-row-alternate-bg: var(--table-row-alternate-bg);
--font-sans: var(--font-sans);
--font-mono: var(--font-mono);
--spacing: var(--spacing);
--container-max-width: var(--container-max-width);
--radius-sm: calc(var(--radius-base) * 0.25);
--radius: calc(var(--radius-base) * 0.5);
--radius-md: calc(var(--radius-base) * 0.75);
--radius-lg: var(--radius-base);
--radius-xl: calc(var(--radius-base) * 1.5);
--radius-sm: calc(var(--radius-base) * 0.25);
--radius: calc(var(--radius-base) * 0.5);
--radius-md: calc(var(--radius-base) * 0.75);
--radius-lg: var(--radius-base);
--radius-xl: calc(var(--radius-base) * 1.5);
--radius-2xl: calc(var(--radius-base) * 2);
--radius-3xl: calc(var(--radius-base) * 3);
--radius-4xl: calc(var(--radius-base) * 4);
@@ -1,31 +1,31 @@
.label {
@apply bg-default text-default-foreground rounded-full px-3 py-1 text-xs font-bold uppercase;
@apply bg-neutral-status-surface text-neutral-status-content rounded-full px-3 py-1 text-xs font-bold uppercase;
&.important {
@apply bg-info text-info-foreground;
@apply bg-info-surface text-info-content;
}
&.warning {
@apply bg-error text-error-foreground;
@apply bg-danger-surface text-danger-content;
}
&.success {
@apply bg-success text-success-foreground;
@apply bg-success-surface text-success-content;
}
&.notice {
@apply bg-warning text-warning-foreground;
@apply bg-warning-surface text-warning-content;
}
}
.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-[box-shadow] duration-200 hover:shadow-md max-md:gap-1 max-md:text-xs;
@apply border-border-subtle bg-interface-badge-bg text-content inline-flex items-center gap-1.5 overflow-visible rounded-full border px-1 py-1.5 text-sm font-medium shadow-sm transition-[box-shadow] 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;
@apply text-content;
}
}
@@ -35,7 +35,7 @@
}
.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-[box-shadow,border-color,background-color] duration-200 hover:shadow-md max-md:gap-1.5 max-md:px-2.5 max-md:py-1.5 max-md:text-xs;
@apply border-border-subtle bg-interface-badge-bg text-content hover:border-border-strong hover:bg-interface-badge-bg inline-flex cursor-default flex-wrap items-center gap-2 rounded-2xl border px-3 py-2 text-sm font-normal shadow-sm transition-[box-shadow,border-color,background-color] 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 & {
@@ -61,7 +61,7 @@
}
&.ifacebadge-active {
@apply border-primary font-semibold;
@apply border-brand font-semibold;
}
&.large {
@@ -23,11 +23,11 @@ input[type="reset"],
.cbi-button-link,
.cbi-button-up,
.cbi-button-down {
@apply border-secondary bg-secondary text-secondary-foreground hover:bg-secondary/90;
@apply border-button-secondary-border bg-button-secondary-bg text-button-secondary-content hover:bg-button-secondary-hover-bg;
}
.drag-handle {
@apply border-muted bg-muted text-muted-foreground hover:bg-muted/90;
@apply border-button-muted-border bg-button-muted-bg text-button-muted-content hover:bg-button-muted-hover-bg;
}
.btn.primary,
@@ -36,18 +36,18 @@ input[type="reset"],
.cbi-button-reload,
.cbi-button-add,
.cbi-button-edit {
@apply border-primary bg-primary hover:bg-primary/90 text-primary-foreground;
@apply border-brand bg-brand hover:bg-brand-hover text-on-brand;
}
.cbi-button-positive,
.cbi-button-fieldadd,
.cbi-button-save {
@apply border-primary/25 bg-primary/25 text-primary hover:bg-primary/30;
@apply border-brand-emphasis bg-brand-emphasis text-brand hover:bg-brand-emphasis-hover;
}
.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;
@apply border-danger-border bg-danger-surface text-danger-content hover:bg-danger-border;
}
@@ -9,7 +9,7 @@
}
#maincontent & {
@apply border-border/30 bg-panel-bg hover:border-border/50 border shadow-lg hover:shadow-xl;
@apply border-border-faint bg-surface-raised hover:border-border-subtle border shadow-lg hover:shadow-xl;
}
& > .cbi-title {
@@ -19,7 +19,7 @@
@apply flex-1;
& .label[data-clickable] {
@apply text-foreground bg-label-surface;
@apply text-content bg-card-action-bg;
@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;
}
@@ -42,7 +42,7 @@
}
& h3 {
@apply text-foreground border-border/50 border-b pb-4 max-md:mx-0 max-md:pb-2;
@apply text-content border-border-subtle border-b pb-4 max-md:mx-0 max-md:pb-2;
}
& div[style*="display:grid"] {
@@ -63,14 +63,14 @@
}
.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;
@apply border-border-subtle bg-glass-raised hover:border-border-strong max-md:border-border-subtle 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-[background-color,border-color,color] 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;
@apply border-border-subtle bg-ifacebox-header-bg text-content w-full rounded-t-2xl border-b px-4 py-3 text-center font-semibold tracking-tight transition-[background-color,border-color,color] 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)]!;
@@ -88,19 +88,19 @@
}
&.active {
@apply border-primary bg-primary text-primary-foreground;
@apply border-brand bg-brand text-on-brand;
}
}
& .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;
@apply text-content 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;
@apply text-content space-y-1.5 max-md:space-y-1 max-md:text-sm max-md:leading-5;
.network-status-table & {
@apply w-full;
@@ -138,7 +138,7 @@
}
& .cbi-tooltip-container {
@apply text-foreground static inline-flex cursor-help items-center justify-center;
@apply text-content static inline-flex cursor-help items-center justify-center;
& .cbi-tooltip {
@apply bottom-0 md:left-0;
@@ -6,7 +6,7 @@
}
&:not(.btn):not(.cbi-button) {
@apply border-border/70 bg-page-bg rounded-2xl border;
@apply border-border-subtle bg-surface rounded-2xl border;
& > ul > li {
&[placeholder] {
@apply hidden;
@@ -50,10 +50,10 @@
}
&.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;
@apply border-border-subtle bg-glass-surface 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;
@apply text-content-muted hover:bg-brand-soft min-h-9 w-full cursor-pointer px-3 py-1.5 font-medium;
}
}
@@ -77,7 +77,7 @@
}
&[open] {
@apply border-primary ring-primary/20 relative ring-2;
@apply border-brand ring-focus-ring relative ring-2;
& > ul.dropdown {
@apply block w-auto max-w-none;
@@ -86,7 +86,7 @@
@apply flex;
&[selected] {
@apply bg-primary/20 text-primary;
@apply bg-brand-emphasis text-brand;
}
&[unselectable] {
@@ -127,7 +127,7 @@
}
& > .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;
@apply border-border-subtle flex flex-none shrink-0 cursor-pointer items-center justify-center border-l px-2.5 py-0.5 text-sm text-current;
}
& > .more {
@@ -5,7 +5,7 @@
@apply visible mb-2 grid origin-bottom grid-rows-[1fr] opacity-100 transition-[grid-template-rows,transform,opacity,visibility] duration-300 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;
@apply border-border-subtle bg-glass-surface 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;
}
}
@@ -17,14 +17,14 @@
}
&:not(.toggle) {
@apply hover:bg-border/40 no-underline hover:scale-110;
@apply hover:bg-border-faint no-underline hover:scale-110;
.icon {
@apply object-contain dark:invert;
}
}
&.toggle {
@apply bg-page-bg border-0 shadow-sm;
@apply bg-surface border-0 shadow-sm;
.icon {
@apply transition-transform duration-300 ease-out;
}
@@ -1,6 +1,6 @@
.cbi-input-invalid,
.cbi-value-error {
@apply !border-error/70 focus:!ring-error/40;
@apply !border-danger-border focus:!ring-danger-border;
}
.cbi-value {
@@ -25,10 +25,10 @@
@apply cursor-not-allowed;
}
& .cbi-value-description {
@apply text-muted-foreground relative mt-1 pl-4 leading-none wrap-break-word;
@apply text-content-muted 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];
@apply before:bg-info-content before:absolute before:-left-0.5 before:inline-block before:size-4 before:[mask:url('@assets/icons/info.svg')_center/cover_no-repeat];
}
}
}
@@ -43,15 +43,15 @@
@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-[transform,box-shadow,opacity,border-color,background-color] 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'];
@apply border-border-faint bg-surface-raised 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-[transform,box-shadow,opacity,border-color,background-color] duration-200 select-text max-md:w-full max-md:py-2.5 max-md:pr-8 max-md:pl-3;
@apply after:bg-button-muted-bg after:text-button-muted-content 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;
@apply border-brand bg-brand-faint ring-brand-emphasis scale-105 shadow-lg ring-2;
}
& > span,
@@ -65,7 +65,7 @@
}
& .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-[border-color,background-color] duration-200;
@apply border-border-subtle hover:border-border-strong hover:bg-surface-subtle inline-flex items-center gap-1.5 self-stretch rounded-2xl border border-dashed bg-transparent px-1 py-1 transition-[border-color,background-color] duration-200;
& > input {
@apply min-w-61 flex-1;
@@ -6,7 +6,7 @@ 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-[border-color,box-shadow] duration-200 focus:ring-2 focus:outline-none;
@apply text-content border-border-subtle bg-surface placeholder-content-muted focus:border-brand focus:ring-brand-emphasis relative rounded-2xl border px-3 py-1.5 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-200 focus:ring-2 focus:outline-none;
.table.cbi-section-table & {
@apply w-full;
@@ -23,7 +23,7 @@ input[type="password"],
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-[background-color,border-color,box-shadow] 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;
@apply focus:before:border-brand focus:before:ring-brand-emphasis checked:before:border-brand checked:before:bg-brand before:border-border-subtle before:bg-surface after:bg-input-checked-content hover:before:border-border-strong 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-[background-color,border-color,box-shadow] 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"] {
@@ -1,5 +1,5 @@
.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;
@apply bg-neutral-status-surface text-neutral-status-content border-neutral-status-border 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;
@@ -14,21 +14,21 @@
}
&.success {
@apply border-success/30 bg-success text-success-foreground;
@apply border-success-border bg-success-surface text-success-content;
}
&.info {
@apply border-info/30 bg-info text-info-foreground;
@apply border-info-border bg-info-surface text-info-content;
}
&.warning,
&.notice {
@apply border-warning/30 bg-warning text-warning-foreground;
@apply border-warning-border bg-warning-surface text-warning-content;
}
&.error,
&.danger {
@apply border-error/30 bg-error text-error-foreground;
@apply border-danger-border bg-danger-surface text-danger-content;
}
h4,
@@ -2,40 +2,40 @@
@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;
@apply bg-scrim 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 relative flex w-5xl flex-col gap-4 rounded-3xl border p-6 wrap-break-word whitespace-normal shadow-2xl max-md:w-full max-md:gap-3 max-md:p-4;
@apply border-border-subtle bg-surface relative flex w-5xl flex-col gap-4 rounded-3xl border p-6 wrap-break-word whitespace-normal shadow-2xl max-md:w-full max-md:gap-3 max-md:p-4;
& h4 {
@apply mb-0 text-center;
& em {
@apply text-primary font-semibold;
@apply text-brand font-semibold;
}
}
& h5 {
@apply text-foreground my-3;
@apply text-content my-3;
}
& p {
@apply text-default-foreground text-sm leading-relaxed;
@apply text-content text-sm leading-relaxed;
}
& > ul {
@apply border-border/60 bg-page-bg/60 overflow-auto rounded-2xl border p-3;
@apply border-border-subtle bg-surface-subtle overflow-auto rounded-2xl border p-3;
}
& label.btn {
@apply border-border/60 bg-page-bg/60 text-foreground hover:border-border border;
@apply border-border-subtle bg-surface-subtle text-content hover:border-border-strong border;
}
& pre {
@apply overflow-auto;
&.errors {
@apply border-error/60 bg-error/20 text-error-foreground;
@apply border-danger-border bg-danger-surface text-danger-content;
}
}
@@ -46,7 +46,7 @@
& .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;
@apply border-border-subtle flex shrink-0 gap-3 border-t p-4 max-md:gap-1.5 max-md:p-2.5;
}
& div.left {
@@ -66,22 +66,22 @@
}
& ins {
@apply border-success bg-success/80 text-success-foreground border;
@apply border-success-border bg-success-surface text-success-content border;
}
& del {
@apply border-error bg-error/80 text-error-foreground border;
@apply border-danger-border bg-danger-surface text-danger-content border;
}
& var {
@apply border-info bg-info/80 text-info-foreground border;
@apply border-info-border bg-info-surface text-info-content 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;
@apply border-border-subtle bg-surface-subtle 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;
@apply text-content flex items-center gap-2 text-sm font-medium;
& ins,
& del,
@@ -102,7 +102,7 @@
@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;
@apply bg-neutral-status-surface text-neutral-status-content mt-6 mb-2 rounded-xl px-3 py-2 text-sm font-semibold first:mt-0;
}
& ins,
@@ -8,12 +8,15 @@
*/
.nav-link {
@apply text-foreground hover:bg-header-interactive block rounded-xl px-3 py-1.5 no-underline transition-all duration-150;
@apply text-content hover:bg-header-interactive-bg block rounded-xl px-3 py-1.5 no-underline transition-all duration-150;
}
/* Modifier applied on top of a base link class; repeats its own colors on hover so the base class's hover styles never bleed through. */
/* Mode-agnostic active state: brand text + weight only. The selected-pill
background is a sidebar affordance (set in _layout.css); the mobile drawer
deliberately omits it and uses an accent indicator bar instead (_overlay.css).
Repeats text-brand on hover so the base link's hover color never bleeds through. */
.nav-link-active {
@apply bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary rounded-xl font-medium;
@apply text-brand hover:text-brand font-medium;
}
/* Category rows are group labels, not buttons: no hover surface, just a
@@ -21,7 +24,7 @@
appearance-none + border-0 + shadow-none strip the theme's global
<button> chrome (_button.css), which would otherwise box every row. */
.nav-category {
@apply text-muted-foreground hover:text-foreground focus-visible:ring-primary/40 flex w-full cursor-pointer appearance-none items-center gap-2 rounded-lg border-0 bg-transparent px-3 py-2 text-left text-lg font-semibold tracking-wide shadow-none transition-colors duration-150 select-none focus-visible:ring-2 focus-visible:outline-none;
@apply text-content-muted hover:text-content focus-visible:ring-focus-ring flex w-full cursor-pointer appearance-none items-center gap-2 rounded-lg border-0 bg-transparent px-3 py-2 text-left text-lg font-semibold tracking-wide shadow-none transition-colors duration-150 select-none focus-visible:ring-2 focus-visible:outline-none;
/* Trailing chevron shares arrow-right.svg with the collapsible cards:
points right when closed, rotates to point down when open. */
@@ -35,16 +38,16 @@
/* Open group: label darkens to foreground; the active child's pill is the
sole location anchor, so no primary tint on the label itself. */
.sidebar-group-open > .nav-category {
@apply text-foreground after:rotate-90;
@apply text-content after:rotate-90;
}
/* The desktop sidebar no longer uses previews; the mobile drawer is the
sole consumer and sets its own px/text-size (_overlay.css), so the base
only carries the mode-agnostic bits. */
.nav-category-preview {
@apply text-muted-foreground/60 truncate pb-1;
@apply text-content-subtle truncate pb-1;
& .nav-preview-current {
@apply text-primary;
@apply text-brand;
}
}
@@ -1,44 +1,35 @@
.mobile-menu-overlay {
@apply max-md:bg-header-bg max-md:invisible max-md:fixed max-md:top-14 max-md:right-0 max-md:bottom-0 max-md:left-0 max-md:z-60 max-md:opacity-0 max-md:transition-[visibility,opacity] max-md:duration-300 md:hidden;
@apply max-md:invisible max-md:fixed max-md:inset-0 max-md:z-60 max-md:bg-(--header-bg)/45 max-md:opacity-0 max-md:backdrop-blur-2xl max-md:backdrop-saturate-200 max-md:transition-[visibility,opacity] max-md:duration-280 md:hidden;
&.mobile-menu-open {
@apply max-md:visible max-md:opacity-100;
}
.mobile-nav {
@apply max-md:bg-header-bg max-md:absolute max-md:top-0 max-md:left-0 max-md:flex max-md:h-full max-md:w-full max-md:flex-col;
@apply max-md:flex max-md:h-full max-md:w-full max-md:flex-col max-md:pt-14;
& .mobile-nav-body {
@apply max-md:flex max-md:min-h-0 max-md:flex-1 max-md:flex-col max-md:px-5 max-md:pt-5;
@apply max-md:flex max-md:min-h-0 max-md:flex-1 max-md:flex-col max-md:px-5 max-md:pt-6;
& .mobile-nav-label {
@apply max-md:text-muted-foreground max-md:mb-2 max-md:text-[0.6875rem] max-md:font-semibold max-md:tracking-[0.12em];
@apply max-md:text-content-muted max-md:mb-3 max-md:text-sm max-md:font-medium;
}
}
& .mobile-nav-list {
@apply max-md:m-0 max-md:flex max-md:min-h-0 max-md:flex-1 max-md:list-none max-md:flex-col max-md:overflow-y-auto max-md:p-0 max-md:pb-4;
@apply max-md:m-0 max-md:flex max-md:min-h-0 max-md:flex-1 max-md:-translate-y-2 max-md:list-none max-md:flex-col max-md:overflow-y-auto max-md:overscroll-contain max-md:p-0 max-md:pb-5 max-md:opacity-0 max-md:transition-[translate,opacity] max-md:duration-280 max-md:ease-out;
& .mobile-nav-item {
@apply max-md:shrink-0;
& .mobile-nav-link {
@apply max-md:text-foreground max-md:hover:text-primary max-md:flex max-md:min-h-12 max-md:w-full max-md:items-center max-md:justify-between max-md:gap-4 max-md:px-0 max-md:py-2 max-md:text-lg max-md:leading-tight max-md:font-medium max-md:no-underline max-md:transition-colors max-md:duration-200;
@apply max-md:text-content max-md:hover:text-brand max-md:flex max-md:min-h-13 max-md:w-full max-md:items-center max-md:justify-between max-md:gap-4 max-md:rounded-none max-md:border-0 max-md:bg-transparent max-md:px-0 max-md:py-2.5 max-md:text-left max-md:text-2xl max-md:leading-tight max-md:font-medium max-md:tracking-tight max-md:no-underline max-md:shadow-none max-md:transition-colors max-md:duration-200;
&.nav-link-active {
@apply max-md:text-brand max-md:hover:text-brand;
}
}
& .mobile-nav-link.nav-link-active {
@apply max-md:px-3;
}
/* Keep the sub-link's pl-4 indent aligned with its siblings; only
the right side gains padding to balance the pill. */
& .mobile-nav-sublink.nav-link-active {
@apply max-md:pr-3;
}
/* Category rows reuse the sidebar chevron recipe: arrow-right.svg
via mask, pointing right when collapsed, down when expanded.
justify-between on the link pushes it to the row's end. */
&.has-submenu > .mobile-nav-link {
@apply max-md:after:size-4 max-md:after:shrink-0 max-md:after:bg-current max-md:after:opacity-55 max-md:after:transition-transform max-md:after:duration-200 max-md:after:content-[''] max-md:after:[mask:url('@assets/icons/arrow-right.svg')_center/cover_no-repeat];
}
@@ -47,43 +38,44 @@
@apply max-md:after:rotate-90;
}
& .nav-category-preview {
@apply max-md:px-0 max-md:text-sm;
}
&.submenu-expanded .nav-category-preview {
@apply max-md:hidden;
}
& .mobile-nav-submenu {
@apply max-md:grid max-md:grid-rows-[0fr] max-md:opacity-0 max-md:transition-[grid-template-rows,opacity] max-md:duration-300 max-md:ease-in-out;
& .mobile-nav-submenu-list {
@apply max-md:m-0 max-md:min-h-0 max-md:list-none max-md:overflow-hidden max-md:p-0;
@apply max-md:before:bg-border-subtle max-md:relative max-md:mx-0 max-md:mt-0 max-md:mb-2 max-md:min-h-0 max-md:list-none max-md:overflow-hidden max-md:py-1 max-md:pr-0 max-md:pl-4 max-md:before:absolute max-md:before:top-1 max-md:before:bottom-1 max-md:before:left-0 max-md:before:w-px max-md:before:origin-top max-md:before:scale-y-0 max-md:before:transition-transform max-md:before:duration-300 max-md:before:ease-out max-md:before:content-[''];
}
& .mobile-nav-subitem {
& .mobile-nav-sublink {
@apply max-md:text-default-foreground max-md:hover:text-primary max-md:flex max-md:min-h-10 max-md:w-full max-md:items-center max-md:py-2 max-md:pr-0 max-md:pl-4 max-md:text-[0.9375rem] max-md:font-normal max-md:no-underline max-md:transition-colors max-md:duration-200;
@apply max-md:text-content max-md:hover:text-brand max-md:relative max-md:flex max-md:min-h-10 max-md:w-full max-md:items-center max-md:py-2 max-md:text-[0.9375rem] max-md:font-medium max-md:no-underline max-md:transition-colors max-md:duration-200;
&.nav-link-active {
@apply max-md:text-brand max-md:hover:text-brand max-md:font-semibold;
@apply max-md:before:bg-brand max-md:before:absolute max-md:before:top-1.5 max-md:before:bottom-1.5 max-md:before:-left-4 max-md:before:w-0.5 max-md:before:rounded-full max-md:before:content-[''];
}
}
}
}
&.submenu-expanded .mobile-nav-submenu {
@apply max-md:grid-rows-[1fr] max-md:opacity-100;
& .mobile-nav-submenu-list {
@apply max-md:before:scale-y-100;
}
}
}
}
& .mobile-nav-footer {
@apply max-md:border-border/30 max-md:flex max-md:shrink-0 max-md:items-center max-md:justify-between max-md:border-t max-md:px-5 max-md:py-4;
@apply max-md:border-border-faint max-md:flex max-md:shrink-0 max-md:items-center max-md:justify-between max-md:border-t max-md:px-5 max-md:pt-4 max-md:pb-[max(1rem,env(safe-area-inset-bottom))];
& .mobile-nav-footer-action {
@apply max-md:flex max-md:items-center;
}
& .mobile-nav-logout {
@apply max-md:text-foreground max-md:hover:text-primary max-md:text-sm max-md:font-medium max-md:no-underline max-md:transition-colors max-md:duration-200;
@apply max-md:text-content max-md:hover:text-brand max-md:text-sm max-md:font-medium max-md:no-underline max-md:transition-colors max-md:duration-200;
}
& .theme-switcher {
@@ -93,11 +85,19 @@
}
}
}
&.mobile-menu-open .mobile-nav-list {
@apply max-md:translate-y-0 max-md:opacity-100;
}
}
body.mobile-navigation-open > header {
@apply max-md:z-70 max-md:bg-transparent;
}
[data-nav-type="mega-menu"] {
& .desktop-menu-overlay {
@apply bg-overlay-base/35 pointer-events-none fixed inset-0 z-50 opacity-0 transition-opacity duration-300 max-md:hidden;
@apply bg-scrim pointer-events-none fixed inset-0 z-50 opacity-0 transition-opacity duration-300 max-md:hidden;
&.active {
@apply pointer-events-auto opacity-100 backdrop-blur-sm;
@@ -1,10 +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;
@apply before:text-content bg-progress-track-bg 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-[width] duration-300;
@apply from-progress-start to-progress-end h-full bg-linear-to-r transition-[width] duration-300;
}
}
@@ -1,21 +1,21 @@
.cbi-tabmenu {
@apply border-border/60 bg-label-surface mb-1 flex items-center gap-1 overflow-x-auto rounded-4xl border p-1;
@apply border-border-subtle bg-segmented-control-bg 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)];
@apply after:bg-danger after:text-on-brand 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;
@apply border-danger-border 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;
@apply text-content-muted hover:text-content 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;
@apply bg-content text-surface font-semibold shadow-sm;
}
}
}
@@ -1,5 +1,5 @@
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-[border-color,box-shadow] duration-200 focus:ring-2 focus:outline-none;
@apply text-content border-border-subtle bg-surface focus:border-brand focus:ring-brand-emphasis appearance-none rounded-2xl border px-3 py-1.5 pr-10 text-sm font-normal shadow-sm transition-[border-color,box-shadow] 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;
@@ -1,7 +1,7 @@
.theme-switcher {
@apply bg-page-bg relative inline-flex items-center gap-0 rounded-full shadow-sm backdrop-blur-sm transition-transform 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-transform before:duration-300;
@apply bg-surface relative inline-flex items-center gap-0 rounded-full shadow-sm backdrop-blur-sm transition-transform duration-300 max-md:py-0.5;
@apply border-border-subtle border;
@apply before:bg-border-subtle before:ring-border-subtle 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-transform before:duration-300;
footer & {
@apply max-md:hidden;
@@ -15,7 +15,7 @@
}
& .theme-icon {
@apply text-muted-foreground flex items-center justify-center transition-colors duration-300;
@apply text-content-muted flex items-center justify-center transition-colors duration-300;
& svg {
@apply size-4 transition-transform duration-300;
@@ -23,12 +23,12 @@
}
& .theme-label {
@apply text-muted-foreground hidden text-xs font-medium transition-colors duration-300;
@apply text-content-muted hidden text-xs font-medium transition-colors duration-300;
}
&.active {
& .theme-icon {
@apply text-foreground;
@apply text-content;
& svg {
@apply scale-110;
@@ -36,17 +36,17 @@
}
& .theme-label {
@apply text-foreground;
@apply text-content;
}
}
&:hover:not(.active) {
& .theme-icon {
@apply text-foreground;
@apply text-content;
}
& .theme-label {
@apply text-foreground;
@apply text-content;
}
}
}
@@ -3,16 +3,16 @@
}
.tabs {
@apply border-border relative flex items-center gap-0 overflow-x-auto border-b;
@apply border-border-subtle 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;
@apply text-content-muted hover:text-content 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;
@apply border-content border-b-2;
& > a {
@apply text-foreground font-semibold;
@apply text-content font-semibold;
}
}
}
@@ -1,6 +1,6 @@
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;
@apply border-border-subtle max-md:bg-glass-raised 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;
@@ -17,7 +17,7 @@ table.table,
& .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;
@apply before:border-border-subtle 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;
@@ -25,7 +25,7 @@ table.table,
}
& .cbi-section-table-titles.named {
@apply before:bg-label-surface before:max-md:bg-label-surface before:md:rounded-tl-2xl;
@apply before:bg-table-header-bg before:max-md:bg-table-header-bg before:md:rounded-tl-2xl;
}
& tbody,
@@ -35,7 +35,7 @@ table.table,
& tr,
& .tr {
@apply hover:bg-label-surface transition-colors duration-200 max-md:border-border max-md:flex max-md:flex-wrap max-md:border-b max-md:px-2 max-md:py-2;
@apply hover:bg-table-row-hover-bg transition-colors duration-200 max-md:border-border-subtle 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 {
@@ -80,11 +80,11 @@ table.table,
}
&.cbi-rowstyle-1 {
@apply bg-panel-bg;
@apply bg-surface-raised;
}
&.cbi-rowstyle-2 {
@apply bg-label-surface/50;
@apply bg-table-row-alternate-bg;
}
& > .col-1 {
@@ -130,7 +130,7 @@ table.table,
& th,
& .th {
@apply border-border bg-label-surface border-b px-3 py-3 text-left text-base font-medium max-md:flex-[1_1_50%] max-md:border-0 max-md:text-sm;
@apply border-border-subtle bg-table-header-bg border-b px-3 py-3 text-left text-base font-medium max-md:flex-[1_1_50%] max-md:border-0 max-md:text-sm;
#cbi-samba4 & {
@apply px-0.5 py-1.5;
@@ -145,7 +145,7 @@ table.table,
}
&[data-sortable-row="true"] {
@apply hover:bg-label-surface cursor-pointer select-none after:ml-0.5 after:text-xs;
@apply hover:bg-table-row-hover-bg cursor-pointer select-none after:ml-0.5 after:text-xs;
&[data-sort-direction="asc"] {
@apply after:content-['\25B2'];
}
@@ -163,7 +163,7 @@ table.table,
& 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 border-border-subtle 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 & {
@@ -1,5 +1,5 @@
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-[border-color,box-shadow] duration-200 focus:ring-2 focus:outline-none;
@apply text-content border-border-subtle bg-surface placeholder-content-muted focus:border-brand focus:ring-brand-emphasis min-h-24 w-full resize-y rounded-2xl border px-3 py-2 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-200 focus:ring-2 focus:outline-none;
&[disabled] {
@apply cursor-not-allowed opacity-40 dark:opacity-30;
}
@@ -1,16 +1,16 @@
.cbi-tooltip {
@apply bg-tooltip-bg text-foreground border-border/60 absolute z-110 max-w-xs scale-95 rounded-xl border px-3 py-2 text-xs break-normal whitespace-normal opacity-0 shadow-lg transition-[visibility,opacity,scale] duration-150 ease-out;
@apply bg-tooltip-bg text-content border-border-subtle absolute z-110 max-w-xs scale-95 rounded-xl border px-3 py-2 text-xs break-normal whitespace-normal opacity-0 shadow-lg transition-[visibility,opacity,scale] duration-150 ease-out;
&.error {
@apply border-error/40 bg-error text-error-foreground;
@apply border-danger-border bg-danger-surface text-danger-content;
}
&.success {
@apply border-success/40 bg-success text-success-foreground;
@apply border-success-border bg-success-surface text-success-content;
}
&.info {
@apply border-info/40 bg-info text-info-foreground;
@apply border-info-border bg-info-surface text-info-content;
}
&.notice {
@apply border-warning/40 bg-warning text-warning-foreground;
@apply border-warning-border bg-warning-surface text-warning-content;
}
}
+15 -15
View File
@@ -12,11 +12,11 @@
@layer base {
html {
@apply bg-background h-full font-sans;
@apply bg-canvas h-full font-sans;
}
body {
@apply text-foreground bg-background min-h-full;
@apply text-content bg-canvas min-h-full;
}
}
@@ -55,7 +55,7 @@
}
.login-card {
@apply bg-panel-bg border-border flex flex-col gap-7 rounded-4xl border p-14 max-md:rounded-3xl max-md:p-9;
@apply bg-surface-raised border-border-subtle flex flex-col gap-7 rounded-4xl border p-14 max-md:rounded-3xl max-md:p-9;
}
.login-brand {
@@ -63,11 +63,11 @@
}
.login-divider {
@apply via-border h-px w-full border-0 bg-linear-to-r from-transparent to-transparent animate-[divider-in_0.7s_cubic-bezier(0.16,1,0.3,1)_0.1s_both];
@apply via-border-subtle h-px w-full border-0 bg-linear-to-r from-transparent to-transparent animate-[divider-in_0.7s_cubic-bezier(0.16,1,0.3,1)_0.1s_both];
}
.login-logo {
@apply bg-primary/15 ring-primary/20 flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl ring-1;
@apply bg-brand-soft ring-brand-emphasis flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl ring-1;
& img {
@apply h-6 w-6;
@@ -79,11 +79,11 @@
}
.login-hostname {
@apply text-foreground text-xl font-semibold tracking-tight;
@apply text-content text-xl font-semibold tracking-tight;
}
.login-subtitle {
@apply text-default-foreground text-sm;
@apply text-content text-sm;
}
.login-form {
@@ -99,17 +99,17 @@
}
.login-label {
@apply text-default-foreground text-[0.6875rem] font-semibold tracking-widest uppercase;
@apply text-content text-[0.6875rem] font-semibold tracking-widest uppercase;
}
.input-wrap {
@apply border-border bg-panel-bg relative rounded-2xl border [contain:layout_style];
@apply border-border-subtle bg-surface-raised relative rounded-2xl border [contain:layout_style];
}
/* Focus ring: opacity-only transition runs on compositor thread, not main thread —
border-color changes require a repaint (~400 ms INP); opacity changes do not. */
.input-wrap::after {
@apply border-primary pointer-events-none absolute -inset-px rounded-[calc(var(--radius-2xl)+1px)] border-2 opacity-0 [will-change:opacity] content-[''] [transition:opacity_150ms_ease];
@apply border-brand pointer-events-none absolute -inset-px rounded-[calc(var(--radius-2xl)+1px)] border-2 opacity-0 [will-change:opacity] content-[''] [transition:opacity_150ms_ease];
}
.input-wrap:focus-within::after {
@@ -117,11 +117,11 @@
}
.login-input {
@apply text-foreground placeholder:text-muted-foreground/60 w-full appearance-none rounded-2xl border-0 bg-transparent px-3 py-2.5 text-base outline-none;
@apply text-content placeholder:text-content-subtle w-full appearance-none rounded-2xl border-0 bg-transparent px-3 py-2.5 text-base outline-none;
}
.login-error {
@apply bg-error text-error-foreground border-error/40 rounded-2xl border px-3 py-2 text-center text-sm;
@apply bg-danger-surface text-danger-content border-danger-border rounded-2xl border px-3 py-2 text-center text-sm;
}
.login-actions {
@@ -129,18 +129,18 @@
}
.login-submit {
@apply bg-primary text-primary-foreground w-full cursor-pointer rounded-2xl border-0 py-2.5 text-base font-medium hover:opacity-90 active:opacity-80;
@apply bg-brand text-on-brand w-full cursor-pointer rounded-2xl border-0 py-2.5 text-base font-medium hover:opacity-90 active:opacity-80;
}
.login-footer {
@apply text-muted-foreground absolute right-0 bottom-5 left-0 px-5 text-center text-xs;
@apply text-content-muted absolute right-0 bottom-5 left-0 px-5 text-center text-xs;
& p {
@apply whitespace-normal;
}
& a {
@apply text-primary hover:underline;
@apply text-brand hover:underline;
}
}
}
@@ -34,18 +34,20 @@ return baseclass.extend({
desktop.matches && document.body.dataset.navType === "sidebar";
const resetMobileSubmenus = () => {
document
overlay
.querySelectorAll(".mobile-nav-item.submenu-expanded")
.forEach((item) => item.classList.remove("submenu-expanded"));
.forEach((item) => this.setMobileSubmenuExpanded(item, false));
};
const expandActiveMobileGroup = () => {
document
.querySelector(".mobile-nav-item.has-active")
?.classList.add("submenu-expanded");
const activeGroup = overlay.querySelector(".mobile-nav-item.has-active");
if (activeGroup) this.setMobileSubmenuExpanded(activeGroup, true);
};
const updateToggleState = (expanded) => {
const desktopSidebar = isDesktopSidebar();
// The hamburger ↔ X morph is a mobile-drawer affordance; the desktop
// sidebar toggle stays a static hamburger (see 2026-06-11 redesign
// spec, superseding the unified-toggle "always X when expanded" rule).
@@ -53,11 +55,24 @@ return baseclass.extend({
"is-expanded",
expanded && !desktop.matches,
);
navigationToggle.setAttribute("aria-expanded", expanded);
navigationToggle.setAttribute(
"aria-expanded",
expanded ? "true" : "false",
);
navigationToggle.setAttribute(
"aria-controls",
desktopSidebar ? "sidebar-panel" : "mobile-menu-overlay",
);
const label = expanded && !desktopSidebar ? _("Close") : _("Navigation");
navigationToggle.setAttribute("title", label);
navigationToggle.setAttribute("aria-label", label);
};
const closeMobileNavigation = () => {
overlay.classList.remove("mobile-menu-open");
document.body.classList.remove("mobile-navigation-open");
document.body.style.overflow = "";
resetMobileSubmenus();
};
@@ -88,6 +103,7 @@ return baseclass.extend({
}
overlay.classList.toggle("mobile-menu-open", expanded);
document.body.classList.toggle("mobile-navigation-open", expanded);
document.body.style.overflow = expanded ? "hidden" : "";
if (expanded) expandActiveMobileGroup();
@@ -135,25 +151,35 @@ return baseclass.extend({
syncNavigationState();
document.addEventListener("click", (e) => {
const link = e.target.closest(".mobile-nav-link");
if (!link) return;
const toggle = e.target.closest(".mobile-nav-toggle");
const item = link.closest(".mobile-nav-item");
const submenu = item?.querySelector(".mobile-nav-submenu");
if (submenu) {
if (toggle && overlay.contains(toggle)) {
e.preventDefault();
e.stopPropagation();
const item = toggle.closest(".mobile-nav-item");
if (!item) return;
const isExpanded = item.classList.contains("submenu-expanded");
document
overlay
.querySelectorAll(".mobile-nav-item.submenu-expanded")
.forEach((i) => {
if (i !== item) i.classList.remove("submenu-expanded");
.forEach((expandedItem) => {
if (expandedItem !== item) {
this.setMobileSubmenuExpanded(expandedItem, false);
}
});
item.classList.toggle("submenu-expanded", !isExpanded);
this.setMobileSubmenuExpanded(item, !isExpanded);
return;
}
const destination = e.target.closest(
".mobile-nav-link:not(.mobile-nav-toggle), .mobile-nav-sublink, .mobile-nav-logout",
);
if (destination && overlay.contains(destination)) {
setNavigationExpanded(false);
}
});
},
@@ -163,10 +189,11 @@ return baseclass.extend({
const footerAction = document.querySelector("#mobile-nav-footer-action");
const children = ui.menu.getChildren(tree);
if (!list || !footerAction || !children.length) return;
if (!list) return;
list.innerHTML = "";
footerAction.innerHTML = "";
if (footerAction) footerAction.innerHTML = "";
if (!children.length) return;
children.forEach((child) => {
const submenu = ui.menu.getChildren(child);
@@ -174,44 +201,61 @@ return baseclass.extend({
const isActive = this.isActivePath(child.name);
if (child.name === "logout") {
footerAction.appendChild(
E(
"a",
{
class: "mobile-nav-logout",
href: L.url(url, child.name),
},
[_(child.title)],
),
);
if (footerAction) {
footerAction.appendChild(
E(
"a",
{
class: "mobile-nav-logout",
href: L.url(url, child.name),
},
[_(child.title)],
),
);
}
return;
}
// "has-submenu" gates the drawer's expand chevron in _overlay.css.
// "has-active" drives the auto-expand on drawer open.
const itemClasses = [
"mobile-nav-item",
hasSubmenu ? "has-submenu" : "",
isActive && hasSubmenu ? "has-active" : "",
].filter(Boolean);
const submenuId = `mobile-submenu-${String(child.name).replace(
/[^A-Za-z0-9_-]/g,
"-",
)}`;
const control = hasSubmenu
? E(
"button",
{
class: `mobile-nav-link mobile-nav-toggle${
isActive ? " nav-link-active" : ""
}`,
type: "button",
"aria-expanded": "false",
"aria-controls": submenuId,
},
[_(child.title)],
)
: E(
"a",
{
class: `mobile-nav-link${isActive ? " nav-link-active" : ""}`,
href: L.url(url, child.name),
},
[_(child.title)],
);
const li = E("li", { class: itemClasses.join(" ") }, [
E(
"a",
{
class: `mobile-nav-link${
isActive && !hasSubmenu ? " nav-link-active" : ""
}`,
href: hasSubmenu ? "#" : L.url(url, child.name),
},
[_(child.title)],
),
]);
const li = E("li", { class: itemClasses.join(" ") }, [control]);
if (hasSubmenu) {
li.appendChild(this.buildCategoryPreview(child.name, submenu));
const wrap = E("div", { class: "mobile-nav-submenu" });
const wrap = E("div", {
class: "mobile-nav-submenu",
id: submenuId,
"aria-hidden": "true",
inert: "",
});
const ul = E("ul", { class: "mobile-nav-submenu-list" });
submenu.forEach((item) => {
@@ -333,25 +377,16 @@ return baseclass.extend({
return page == null || L.env.dispatchpath[2] === page;
},
// Decorative, aria-hidden summary used by collapsed mobile groups.
buildCategoryPreview(parentName, submenu) {
const nodes = [];
setMobileSubmenuExpanded(item, expanded) {
const toggle = item.querySelector(".mobile-nav-toggle");
const submenu = item.querySelector(".mobile-nav-submenu");
submenu.forEach((item, i) => {
if (i) nodes.push(" · ");
item.classList.toggle("submenu-expanded", expanded);
toggle?.setAttribute("aria-expanded", expanded ? "true" : "false");
submenu?.setAttribute("aria-hidden", expanded ? "false" : "true");
nodes.push(
this.isActivePath(parentName, item.name)
? E("span", { class: "nav-preview-current" }, [_(item.title)])
: _(item.title),
);
});
return E(
"div",
{ class: "nav-category-preview", "aria-hidden": "true" },
nodes,
);
if (expanded) submenu?.removeAttribute("inert");
else submenu?.setAttribute("inert", "");
},
setSidebarSectionExpanded(item, expanded) {
+2 -1
View File
@@ -11,4 +11,5 @@ yarn.lock
# Superpowers AI workflow docs
docs/superpowers/
.superpowers/
.superpowers/
.worktrees/
+2 -2
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.12.7
PKG_RELEASE:=25
PKG_VERSION:=0.12.8
PKG_RELEASE:=26
PKG_LICENSE:=Apache-2.0
LUCI_MINIFY_CSS:=
@@ -1,2 +1,2 @@
/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-content:"";--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-tracking:initial}}:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:var(--spacing);--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-widest:.1em;--radius-2xl:calc(var(--radius-base)*2);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--container-max-width:var(--container-max-width)}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkitLine truncated
@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-content:"";--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-tracking:initial}}:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:var(--spacing);--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-widest:.1em;--radius-2xl:calc(var(--radius-base)*2);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--container-max-width:var(--container-max-width)}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkitLine truncated
@@ -1,2 +1,2 @@
/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-border-style:solid;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-border-spacing-x:0;--tw-border-spacing-y:0}}:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:var(--spacing);--container-xs:20rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-2xl:calc(var(--radius-base)*2);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--blur-md:12px;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--container-max-width:var(--container-max-width)}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}Line truncated
@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-border-style:solid;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-border-spacing-x:0;--tw-border-spacing-y:0}}:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:var(--spacing);--container-xs:20rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-2xl:calc(var(--radius-base)*2);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--blur-md:12px;--blur-xl:24px;--blur-2xl:40px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--container-max-width:var(--container-max-width)}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{Line truncated
@@ -1 +1 @@
"use strict";"require baseclass";"require ui";return baseclass.extend({__init__(){ui.menu.load().then(tree=>this.render(tree));this.initNavigationControls();this.initUciIndicator()},initUciIndicator(){const original=ui.changes?.setIndicator;if(!original)return;ui.changes.setIndicator=function(n){original.call(this,n);document.querySelector('[data-indicator="uci-changes"]')?.setAttribute("data-count",n||0)}},initNavigationControls(){const overlay=document.querySelector("#mobile-menu-overlay");const navigationToggle=document.querySelector("#navigation-toggle");if(!navigationToggle||!overlay)return;const desktop=window.matchMedia("(min-width: 768px)");const SIDEBAR_COLLAPSED_KEY="aurora.sidebarCollapsed";const isDesktopSidebar=()=>desktop.matches&&document.body.dataset.navType==="sidebar";const resetMobileSubmenus=()=>{document.querySelectorAll(".mobile-nav-item.submenu-expanded").forEach(item=>item.classList.remove("submenu-expanded"))};const expandActiveMobileGroup=()=>{document.querySelector(".mobile-nav-item.has-active")?.classList.add("submenu-expanded")};const updateToggleState=expanded=>{navigationToggle.classList.toggle("is-expanded",expanded&&!desktop.matches);navigationToggle.setAttribute("aria-expanded",expanded)};const closeMobileNavigation=()=>{overlay.classList.remove("mobile-menu-open");document.body.style.overflow="";resetMobileSubmenus()};const getNavigationExpanded=()=>{if(isDesktopSidebar()){return!document.body.classList.contains("sidebar-collapsed")}return!desktop.matches&&overlay.classList.contains("mobile-menu-open")};const setNavigationExpanded=expanded=>{if(isDesktopSidebar()){closeMobileNavigation();const collapsed=!expanded;document.body.classList.toggle("sidebar-collapsed",collapsed);localStorage.setItem(SIDEBAR_COLLAPSED_KEY,collapsed);updateToggleState(expanded);return}if(desktop.matches){closeMobileNavigation();updateToggleState(false);return}overlay.classList.toggle("mobile-menu-open",expanded);document.body.style.overflow=expanded?"hidden":"";if(expanded)expandActiveMobileGroup();else resetMobileSubmenus();updateToggleState(expanded)};const toggleNavigation=()=>setNavigationExpanded(!getNavigationExpanded());const syncNavigationState=()=>{closeMobileNavigation();if(isDesktopSidebar()){const collapsed=localStorage.getItem(SIDEBAR_COLLAPSED_KEY)==="true";document.body.classList.toggle("sidebar-collapsed",collapsed);updateToggleState(!collapsed);return}updateToggleState(false)};navigationToggle.addEventListener("click",e=>{e.stopPropagation();toggleNavigation()});overlay.addEventListener("click",e=>{if(e.target===overlay)setNavigationExpanded(false)});document.addEventListener("keydown",e=>{if(e.key==="Escape"&&overlay.classList.contains("mobile-menu-open")){setNavigationExpanded(false)}});desktop.addEventListener("change",syncNavigationState);syncNavigationState();document.addEventListener("click",e=>{const link=e.target.closest(".mobile-nav-link");if(!link)return;const item=link.closest(".mobile-nav-item");const submenu=item?.querySelector(".mobile-nav-submenu");if(submenu){e.preventDefault();e.stopPropagation();const isExpanded=item.classList.contains("submenu-expanded");document.querySelectorAll(".mobile-nav-item.submenu-expanded").forEach(i=>{if(i!==item)i.classList.remove("submenu-expanded")});item.classList.toggle("submenu-expanded",!isExpanded)}})},renderMobileMenu(tree,url){const list=document.querySelector("#mobile-nav-list");const footerAction=document.querySelector("#mobile-nav-footer-action");const children=ui.menu.getChildren(tree);if(!list||!footerAction||!children.length)return;list.innerHTML="";footerAction.innerHTML="";children.forEach(child=>{const submenu=ui.menu.getChildren(child);const hasSubmenu=submenu.length>0;const isActive=this.isActivePath(child.name);if(child.name==="logout"){footerAction.appendChild(E("a",{class:"mobile-nav-logout",href:L.url(url,child.name)},[_(child.title)]));return}const itemClasses=["mobile-nav-item",hasSubmenu?"has-submenu":"",isActive&&hasSubmenu?"has-active":""].filter(Boolean);const li=E("li",{class:itemClasses.join(" ")},[E("a",{class:`mobile-nav-link${isActive&&!hasSubmenu?" nav-link-active":""}`,href:hasSubmenu?"#":L.url(url,child.name)},[_(child.title)])]);if(hasSubmenu){li.appendChild(this.buildCategoryPreview(child.name,submenu));const wrap=E("div",{class:"mobile-nav-submenu"});const ul=E("ul",{class:"mobile-nav-submenu-list"});submenu.forEach(item=>{const subActive=this.isActivePath(child.name,item.name);ul.appendChild(E("li",{class:"mobile-nav-subitem"},[E("a",{class:`mobile-nav-sublink${subActive?" nav-link-active":""}`,href:L.url(url,child.name,item.name)},[_(item.title)])]))});wrap.appendChild(ul);li.appendChild(wrap)}list.appendChild(li)})},render(tree){this.renderModeMenu(tree);if(L.env.dispatchpath.length>=3){let node=tree;let url="";for(let i=0;i<3&&node;i++){const segment=L.env.dispatchpath[i];node=node.children?.[segment];url+=(url?"/":"")+segment}if(node)this.renderTabMenu(node,url)}},renderTabMenu(tree,url,Line truncated
"use strict";"require baseclass";"require ui";return baseclass.extend({__init__(){ui.menu.load().then(tree=>this.render(tree));this.initNavigationControls();this.initUciIndicator()},initUciIndicator(){const original=ui.changes?.setIndicator;if(!original)return;ui.changes.setIndicator=function(n){original.call(this,n);document.querySelector('[data-indicator="uci-changes"]')?.setAttribute("data-count",n||0)}},initNavigationControls(){const overlay=document.querySelector("#mobile-menu-overlay");const navigationToggle=document.querySelector("#navigation-toggle");if(!navigationToggle||!overlay)return;const desktop=window.matchMedia("(min-width: 768px)");const SIDEBAR_COLLAPSED_KEY="aurora.sidebarCollapsed";const isDesktopSidebar=()=>desktop.matches&&document.body.dataset.navType==="sidebar";const resetMobileSubmenus=()=>{overlay.querySelectorAll(".mobile-nav-item.submenu-expanded").forEach(item=>this.setMobileSubmenuExpanded(item,false))};const expandActiveMobileGroup=()=>{const activeGroup=overlay.querySelector(".mobile-nav-item.has-active");if(activeGroup)this.setMobileSubmenuExpanded(activeGroup,true)};const updateToggleState=expanded=>{const desktopSidebar=isDesktopSidebar();navigationToggle.classList.toggle("is-expanded",expanded&&!desktop.matches);navigationToggle.setAttribute("aria-expanded",expanded?"true":"false");navigationToggle.setAttribute("aria-controls",desktopSidebar?"sidebar-panel":"mobile-menu-overlay");const label=expanded&&!desktopSidebar?_("Close"):_("Navigation");navigationToggle.setAttribute("title",label);navigationToggle.setAttribute("aria-label",label)};const closeMobileNavigation=()=>{overlay.classList.remove("mobile-menu-open");document.body.classList.remove("mobile-navigation-open");document.body.style.overflow="";resetMobileSubmenus()};const getNavigationExpanded=()=>{if(isDesktopSidebar()){return!document.body.classList.contains("sidebar-collapsed")}return!desktop.matches&&overlay.classList.contains("mobile-menu-open")};const setNavigationExpanded=expanded=>{if(isDesktopSidebar()){closeMobileNavigation();const collapsed=!expanded;document.body.classList.toggle("sidebar-collapsed",collapsed);localStorage.setItem(SIDEBAR_COLLAPSED_KEY,collapsed);updateToggleState(expanded);return}if(desktop.matches){closeMobileNavigation();updateToggleState(false);return}overlay.classList.toggle("mobile-menu-open",expanded);document.body.classList.toggle("mobile-navigation-open",expanded);document.body.style.overflow=expanded?"hidden":"";if(expanded)expandActiveMobileGroup();else resetMobileSubmenus();updateToggleState(expanded)};const toggleNavigation=()=>setNavigationExpanded(!getNavigationExpanded());const syncNavigationState=()=>{closeMobileNavigation();if(isDesktopSidebar()){const collapsed=localStorage.getItem(SIDEBAR_COLLAPSED_KEY)==="true";document.body.classList.toggle("sidebar-collapsed",collapsed);updateToggleState(!collapsed);return}updateToggleState(false)};navigationToggle.addEventListener("click",e=>{e.stopPropagation();toggleNavigation()});overlay.addEventListener("click",e=>{if(e.target===overlay)setNavigationExpanded(false)});document.addEventListener("keydown",e=>{if(e.key==="Escape"&&overlay.classList.contains("mobile-menu-open")){setNavigationExpanded(false)}});desktop.addEventListener("change",syncNavigationState);syncNavigationState();document.addEventListener("click",e=>{const toggle=e.target.closest(".mobile-nav-toggle");if(toggle&&overlay.contains(toggle)){e.preventDefault();e.stopPropagation();const item=toggle.closest(".mobile-nav-item");if(!item)return;const isExpanded=item.classList.contains("submenu-expanded");overlay.querySelectorAll(".mobile-nav-item.submenu-expanded").forEach(expandedItem=>{if(expandedItem!==item){this.setMobileSubmenuExpanded(expandedItem,false)}});this.setMobileSubmenuExpanded(item,!isExpanded);return}const destination=e.target.closest(".mobile-nav-link:not(.mobile-nav-toggle), .mobile-nav-sublink, .mobile-nav-logout");if(destination&&overlay.contains(destination)){setNavigationExpanded(false)}})},renderMobileMenu(tree,url){const list=document.querySelector("#mobile-nav-list");const footerAction=document.querySelector("#mobile-nav-footer-action");const children=ui.menu.getChildren(tree);if(!list)return;list.innerHTML="";if(footerAction)footerAction.innerHTML="";if(!children.length)return;children.forEach(child=>{const submenu=ui.menu.getChildren(child);const hasSubmenu=submenu.length>0;const isActive=this.isActivePath(child.name);if(child.name==="logout"){if(footerAction){footerAction.appendChild(E("a",{class:"mobile-nav-logout",href:L.url(url,child.name)},[_(child.title)]))}return}const itemClasses=["mobile-nav-item",hasSubmenu?"has-submenu":"",isActive&&hasSubmenu?"has-active":""].filter(Boolean);const submenuId=`mobile-submenu-${String(child.name).replace(/[^A-Za-z0-9_-]/g,"-")}`;const control=hasSubmenu?E("button",{class:`mobile-nav-link mobile-nav-toggle${isActive?" nav-link-active":""}`,type:"button","aria-expanded":"false","aria-controls":sLine truncated
@@ -75,7 +75,9 @@
const prev = document.documentElement.getAttribute('data-darkmode');
const apply = () => document.documentElement.setAttribute('data-darkmode', next);
if (prev !== null && prev !== next && document.startViewTransition &&
const navOpen = document.body?.classList.contains('mobile-navigation-open');
if (prev !== null && prev !== next && document.startViewTransition && !navOpen &&
!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.startViewTransition(apply);
} else {
@@ -185,13 +187,13 @@
<header>
<div class="header-content">
<div class="navigation-controls">
<div class="navigation-toggle" id="navigation-toggle" title="{{ _('Menu') }}" role="button" aria-expanded="false">
<button class="navigation-toggle" id="navigation-toggle" type="button" title="{{ _('Navigation') }}" aria-label="{{ _('Navigation') }}" aria-controls="mobile-menu-overlay" aria-expanded="false">
<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<line class="navigation-toggle-line navigation-toggle-line-top" x1="2.5" y1="5" x2="17.5" y2="5"/>
<line class="navigation-toggle-line navigation-toggle-line-middle" x1="2.5" y1="10" x2="17.5" y2="10"/>
<line class="navigation-toggle-line navigation-toggle-line-bottom" x1="2.5" y1="15" x2="10" y2="15"/>
</svg>
</div>
</button>
</div>
<a class="brand" href="/">{{ striptags(boardinfo.hostname ?? '?') }}</a>
<ul class="nav" id="topmenu" style="display:none"></ul>
@@ -232,7 +234,7 @@
{% endif %}
{% if (nav_submenu_type == 'sidebar'): %}
<aside class="sidebar-panel" aria-label="{{ _('Navigation') }}">
<aside class="sidebar-panel" id="sidebar-panel" aria-label="{{ _('Navigation') }}">
<nav class="sidebar-panel-inner">
<ul class="sidebar-list" id="sidebar-list"></ul>
<div class="sidebar-footer" id="sidebar-footer"></div>
@@ -246,7 +248,7 @@
{% endif %}
<div class="mobile-menu-overlay" id="mobile-menu-overlay">
<nav class="mobile-nav">
<nav class="mobile-nav" aria-label="{{ _('Navigation') }}">
<div class="mobile-nav-body">
<div class="mobile-nav-label">{{ _('Navigation') }}</div>
<ul class="mobile-nav-list" id="mobile-nav-list">
+4 -4
View File
@@ -1,14 +1,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mihomo-alpha
PKG_VERSION:=2026.06.11
PKG_RELEASE:=12
PKG_VERSION:=2026.06.12
PKG_RELEASE:=13
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
PKG_SOURCE_VERSION:=084a09e4af60d6579a97ef344b31ddd62af44c1c
PKG_SOURCE_VERSION:=793f61ec6798e335a0f8eed3b310a084c3d68514
PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL3.0+
@@ -18,7 +18,7 @@ PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=no-mips16
PKG_BUILD_VERSION:=alpha-084a09e
PKG_BUILD_VERSION:=alpha-793f61e
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_BUILD_TIME:=$(shell date -u -Iseconds)