diff --git a/luci-app-daede/Makefile b/luci-app-daede/Makefile index 8d8f3d337..3f3977808 100644 --- a/luci-app-daede/Makefile +++ b/luci-app-daede/Makefile @@ -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) diff --git a/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js b/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js index d3327842d..fe4858b74 100644 --- a/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js +++ b/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js @@ -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; }); }); diff --git a/luci-app-daede/htdocs/luci-static/resources/view/daede/widgets.js b/luci-app-daede/htdocs/luci-static/resources/view/daede/widgets.js index 1c49f76f2..08aac3d25 100644 --- a/luci-app-daede/htdocs/luci-static/resources/view/daede/widgets.js +++ b/luci-app-daede/htdocs/luci-static/resources/view/daede/widgets.js @@ -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() { diff --git a/luci-app-daede/root/etc/uci-defaults/90-luci-app-daede-init b/luci-app-daede/root/etc/uci-defaults/90-luci-app-daede-init index a66ac1a7d..2c2650c62 100644 --- a/luci-app-daede/root/etc/uci-defaults/90-luci-app-daede-init +++ b/luci-app-daede/root/etc/uci-defaults/90-luci-app-daede-init @@ -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() { diff --git a/luci-app-xray/Makefile b/luci-app-xray/Makefile index b9ecd08c9..8c75b524a 100644 --- a/luci-app-xray/Makefile +++ b/luci-app-xray/Makefile @@ -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 diff --git a/luci-app-xray/root/usr/share/xray/feature/fake_dns.mjs b/luci-app-xray/root/usr/share/xray/feature/fake_dns.mjs index f21ff29ca..0de858257 100644 --- a/luci-app-xray/root/usr/share/xray/feature/fake_dns.mjs +++ b/luci-app-xray/root/usr/share/xray/feature/fake_dns.mjs @@ -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 } ]; diff --git a/luci-app-xray/root/usr/share/xray/firewall_include.ut b/luci-app-xray/root/usr/share/xray/firewall_include.ut index 3e17ec7c9..e469e2719 100644 --- a/luci-app-xray/root/usr/share/xray/firewall_include.ut +++ b/luci-app-xray/root/usr/share/xray/firewall_include.ut @@ -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 %} diff --git a/luci-app-xray/root/www/luci-static/resources/view/xray/core.js b/luci-app-xray/root/www/luci-static/resources/view/xray/core.js index b9470c668..213eeaa36 100644 --- a/luci-app-xray/root/www/luci-static/resources/view/xray/core.js +++ b/luci-app-xray/root/www/luci-static/resources/view/xray/core.js @@ -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'; diff --git a/luci-app-xray/root/www/luci-static/resources/view/xray/preview.js b/luci-app-xray/root/www/luci-static/resources/view/xray/preview.js index 1283d908b..3b7c1c29e 100644 --- a/luci-app-xray/root/www/luci-static/resources/view/xray/preview.js +++ b/luci-app-xray/root/www/luci-static/resources/view/xray/preview.js @@ -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.")); diff --git a/luci-theme-aurora/.dev/src/media/_base.css b/luci-theme-aurora/.dev/src/media/_base.css index efacf3ebf..162dbfa63 100644 --- a/luci-theme-aurora/.dev/src/media/_base.css +++ b/luci-theme-aurora/.dev/src/media/_base.css @@ -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; } diff --git a/luci-theme-aurora/.dev/src/media/_layout.css b/luci-theme-aurora/.dev/src/media/_layout.css index d93488ed7..7ca658203 100644 --- a/luci-theme-aurora/.dev/src/media/_layout.css +++ b/luci-theme-aurora/.dev/src/media/_layout.css @@ -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; } } } diff --git a/luci-theme-aurora/.dev/src/media/_patches.css b/luci-theme-aurora/.dev/src/media/_patches.css index 0f530b98d..3380d4e07 100644 --- a/luci-theme-aurora/.dev/src/media/_patches.css +++ b/luci-theme-aurora/.dev/src/media/_patches.css @@ -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; } } diff --git a/luci-theme-aurora/.dev/src/media/_tokens.css b/luci-theme-aurora/.dev/src/media/_tokens.css index d8ec0340b..51d553e2e 100644 --- a/luci-theme-aurora/.dev/src/media/_tokens.css +++ b/luci-theme-aurora/.dev/src/media/_tokens.css @@ -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); diff --git a/luci-theme-aurora/.dev/src/media/components/_badge.css b/luci-theme-aurora/.dev/src/media/components/_badge.css index 4daf98192..c8e60ad1d 100644 --- a/luci-theme-aurora/.dev/src/media/components/_badge.css +++ b/luci-theme-aurora/.dev/src/media/components/_badge.css @@ -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 { diff --git a/luci-theme-aurora/.dev/src/media/components/_button.css b/luci-theme-aurora/.dev/src/media/components/_button.css index c078f8b45..681b7940e 100644 --- a/luci-theme-aurora/.dev/src/media/components/_button.css +++ b/luci-theme-aurora/.dev/src/media/components/_button.css @@ -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; } diff --git a/luci-theme-aurora/.dev/src/media/components/_card.css b/luci-theme-aurora/.dev/src/media/components/_card.css index 4d7532066..7b8146a01 100644 --- a/luci-theme-aurora/.dev/src/media/components/_card.css +++ b/luci-theme-aurora/.dev/src/media/components/_card.css @@ -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; diff --git a/luci-theme-aurora/.dev/src/media/components/_dropdown.css b/luci-theme-aurora/.dev/src/media/components/_dropdown.css index 2a9c3ab69..0b7c9b4be 100644 --- a/luci-theme-aurora/.dev/src/media/components/_dropdown.css +++ b/luci-theme-aurora/.dev/src/media/components/_dropdown.css @@ -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 { diff --git a/luci-theme-aurora/.dev/src/media/components/_float-button.css b/luci-theme-aurora/.dev/src/media/components/_float-button.css index f6e658e6e..b242ec7eb 100644 --- a/luci-theme-aurora/.dev/src/media/components/_float-button.css +++ b/luci-theme-aurora/.dev/src/media/components/_float-button.css @@ -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; } diff --git a/luci-theme-aurora/.dev/src/media/components/_form.css b/luci-theme-aurora/.dev/src/media/components/_form.css index ec7caf898..23e9014fc 100644 --- a/luci-theme-aurora/.dev/src/media/components/_form.css +++ b/luci-theme-aurora/.dev/src/media/components/_form.css @@ -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; diff --git a/luci-theme-aurora/.dev/src/media/components/_input.css b/luci-theme-aurora/.dev/src/media/components/_input.css index a1105bd00..eac8eedbe 100644 --- a/luci-theme-aurora/.dev/src/media/components/_input.css +++ b/luci-theme-aurora/.dev/src/media/components/_input.css @@ -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"] { diff --git a/luci-theme-aurora/.dev/src/media/components/_message.css b/luci-theme-aurora/.dev/src/media/components/_message.css index df3fa48fe..82031c07e 100644 --- a/luci-theme-aurora/.dev/src/media/components/_message.css +++ b/luci-theme-aurora/.dev/src/media/components/_message.css @@ -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, diff --git a/luci-theme-aurora/.dev/src/media/components/_modal.css b/luci-theme-aurora/.dev/src/media/components/_modal.css index 90c464f0b..d6b0a0017 100644 --- a/luci-theme-aurora/.dev/src/media/components/_modal.css +++ b/luci-theme-aurora/.dev/src/media/components/_modal.css @@ -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, diff --git a/luci-theme-aurora/.dev/src/media/components/_nav.css b/luci-theme-aurora/.dev/src/media/components/_nav.css index 88a5a67e2..fbb1ac743 100644 --- a/luci-theme-aurora/.dev/src/media/components/_nav.css +++ b/luci-theme-aurora/.dev/src/media/components/_nav.css @@ -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 {{ striptags(boardinfo.hostname ?? '?') }} @@ -232,7 +234,7 @@ {% endif %} {% if (nav_submenu_type == 'sidebar'): %} -