✨ Sync 2026-09-19 23:15:54

This commit is contained in:
github-actions[bot] committed 2026-09-19 23:15:54 +08:00
1 parent 3ca92a9506
commit f42318f91e
21 files changed
+256 -116

No files matched your search

+1 -1
View File
@@ -23,7 +23,7 @@ msgid "Set the router's wireless name and password. For more advanced settings,
msgstr "设置路由器的无线名字和密码,更多高级设置请进入 网络-无线 页面。" msgstr "设置路由器的无线名字和密码,更多高级设置请进入 网络-无线 页面。"
msgid "Leave empty to use ISP DNS" msgid "Leave empty to use ISP DNS"
msgstr "留空则使用阿里DNS" msgstr "留空则使用运营商DNS"
msgid "Enter the main router IP" msgid "Enter the main router IP"
msgstr "请输入主路由IP" msgstr "请输入主路由IP"
@@ -11,12 +11,12 @@ address, so they stay local).
| Metric | Budget | Track | Source | | Metric | Budget | Track | Source |
|---|---|---|---| |---|---|---|---|
| main.css (identity/raw) | ≤ 193 KB | size | production build, 2026-09-17 (190,230 B; +0.6 KB palette tab rows "Parent › Title", unnested short selectors; −0.77 KB sidebar push as two transitions instead of run keyframes; +42 B replayed nav skips the fade; +~2 KB custom-background mode, +~0.5 KB router progress bar / live region; the bar is now Turbo-shaped — width/opacity only, inserted per navigation; −1.24 KB unblurred mega-menu curtain, delayed visibility, instant nav-pill colours) | | main.css (identity/raw) | ≤ 187 KB | size | production build, 2026-09-19 (185,262 B; −4,968 B pseudo-elements as nested rules, one `content` each; 2026-09-17: 190,230 B; +0.6 KB palette tab rows "Parent › Title", unnested short selectors; −0.77 KB sidebar push as two transitions instead of run keyframes; +42 B replayed nav skips the fade; +~2 KB custom-background mode, +~0.5 KB router progress bar / live region; the bar is now Turbo-shaped — width/opacity only, inserted per navigation; −1.24 KB unblurred mega-menu curtain, delayed visibility, instant nav-pill colours) |
| login.css (identity/raw) | ≤ 12 KB | size | production build, 2026-07 (10,935 B, token-pruned) | | login.css (identity/raw) | ≤ 12 KB | size | production build, 2026-09-19 (11,972 B; +211 B: the prune's re-minify now targets the theme floor, which restores `-webkit-backdrop-filter`) |
| menu-aurora.js (identity/raw) | ≤ 23 KB | size | production build, 2026-09-17 (22,665 B; +1.3 KB palette tabs: third-level nodes, redirect parents folded into their tabs, legacy recents mapped, parent-aware scoring, path words matched segment by segment; −0.24 KB sidebar toggle is a class flip; −0.09 KB pre-paint nav cache, its crumb renderer moved into header.ut (the replay itself is per-response HTML, see below); +0.8 KB palette recents: record on pick, pure-LRU browse order, storage validation; +0.2 KB ">" logout command) | | menu-aurora.js (identity/raw) | ≤ 23 KB | size | production build, 2026-09-17 (22,665 B; +1.3 KB palette tabs: third-level nodes, redirect parents folded into their tabs, legacy recents mapped, parent-aware scoring, path words matched segment by segment; −0.24 KB sidebar toggle is a class flip; −0.09 KB pre-paint nav cache, its crumb renderer moved into header.ut (the replay itself is per-response HTML, see below); +0.8 KB palette recents: record on pick, pure-LRU browse order, storage validation; +0.2 KB ">" logout command) |
| router-aurora.js (identity/raw, Navigation-API browsers only) | ≤ 16 KB | size | production build, 2026-09-13 (15,771 B, shipped from @eamonxg/luci-theme-devkit; 2026-08: 14,844 B: template shells fetched, per-render listener teardown, timeout-as-failure, expiry gate, readonly folding, node css, wildcard actions, trickling progress bar, same-URL reload rule, visibility gate, contract check) | | router-aurora.js (identity/raw, Navigation-API browsers only) | ≤ 16 KB | size | production build, 2026-09-13 (15,771 B, shipped from @eamonxg/luci-theme-devkit; 2026-08: 14,844 B: template shells fetched, per-render listener teardown, timeout-as-failure, expiry gate, readonly folding, node css, wildcard actions, trickling progress bar, same-URL reload rule, visibility gate, contract check) |
| Default logo (identity/raw) | ≤ 16 KB | size | production build, 2026-07 (15,057 B) | | Default logo (identity/raw) | ≤ 16 KB | size | production build, 2026-07 (15,057 B) |
| Core admin cold theme assets (identity/raw) | ≤ 268.5 KB | size | main CSS + menu JS + router JS + default font + logo, 2026-09-17 (267,303 B; +1.9 KB palette tabs; −1.1 KB sidebar push and nav cache; the router is a one-time cost that removes per-click dispatcher work; +1.0 KB palette recents and logout command; −1.24 KB mega-menu curtain) | | Core admin cold theme assets (identity/raw) | ≤ 264 KB | size | main CSS + menu JS + router JS + default font + logo, 2026-09-19 (262,335 B; −4,968 B nested pseudo-element rules; 2026-09-17: 267,303 B; +1.9 KB palette tabs; −1.1 KB sidebar push and nav cache; the router is a one-time cost that removes per-click dispatcher work; +1.0 KB palette recents and logout command; −1.24 KB mega-menu curtain) |
| Login cold theme assets, excluding configured background (identity/raw) | ≤ 55 KB | size | login CSS + default font + logo, 2026-07 (49,572 B) | | Login cold theme assets, excluding configured background (identity/raw) | ≤ 55 KB | size | login CSS + default font + logo, 2026-07 (49,572 B) |
| Admin HTML inline scripts added per full load (identity, never cached) | — | size | header.ut, 2026-09-16: pre-paint nav replay ≈ +0.5 KB (mega-menu/dropdown) / ≈ +1.9 KB (sidebar, with the shared crumb renderer); login page +0.07 KB. Template shells the router fetches carry it too. | | Admin HTML inline scripts added per full load (identity, never cached) | — | size | header.ut, 2026-09-16: pre-paint nav replay ≈ +0.5 KB (mega-menu/dropdown) / ≈ +1.9 KB (sidebar, with the shared crumb renderer); login page +0.07 KB. Template shells the router fetches carry it too. |
| Blocking requests before first paint | ≤ 4 | count | current waterfall | | Blocking requests before first paint | ≤ 4 | count | current waterfall |
@@ -48,6 +48,16 @@ Budget revisions require a new baseline entry under `../baselines/`.
trace, 4× CPU, median of 3: repaints 287 → 112, main-thread animations trace, 4× CPU, median of 3: repaints 287 → 112, main-thread animations
33 → 8. With `--disable-gpu`, dropped frames per open went 3–5 → 0. 33 → 8. With `--disable-gpu`, dropped frames per open went 3–5 → 0.
- Build targets (2026-09-19): `LIGHTNINGCSS_TARGETS` is the theme floor (Chrome/Edge 111, Firefox 128,
Safari 16.4), not `last 4 versions`. Only the login prune's re-minify reads it — Vite overrides
`css.lightningcss.targets` with `build.cssTarget` for the main build — and the old query (floor
Safari 26.1) had stripped the login card's `-webkit-backdrop-filter`. `app.webmanifest` icon paths
fixed (they still pointed into the flattened `pwa/` directory and 404ed).
- Nested pseudo-elements (2026-09-19): 36 `@apply` lines moved their `before:`/`after:` utilities into
`&::before`/`&::after` blocks (`@variant hover` where the hover media gate must stay); `content:var(--tw-content)`
202 → 27, main.css −4,968 B, computed styles identical over `.dev/mocks`.
- Client-side router (`router-aurora.js`, `.dev/docs/router.md`, - Client-side router (`router-aurora.js`, `.dev/docs/router.md`,
2026-08-16): view/alias/firstchild/overview navigations become 2026-08-16): view/alias/firstchild/overview navigations become
same-document swaps on Navigation-API browsers, MPA elsewhere. same-document swaps on Navigation-API browsers, MPA elsewhere.
@@ -66,6 +76,7 @@ Budget revisions require a new baseline entry under `../baselines/`.
|---|---|---| |---|---|---|
| Long-lived cache headers for versioned CSS/JS | L2 | after LuCI build-time `?v=$(PKG_VERSION)`, kills per-click 304s if headers permit disk/memory cache reuse | | Long-lived cache headers for versioned CSS/JS | L2 | after LuCI build-time `?v=$(PKG_VERSION)`, kills per-click 304s if headers permit disk/memory cache reuse |
| `defer` head scripts | L1 | needs on-device timing verification | | `defer` head scripts | L1 | needs on-device timing verification |
| Source-level `@apply` weight: ~~nest `&::before` instead of stacked `before:` variants (190 repeated `content:var(--tw-content)`)~~ (landed 2026-09-19), light `@utility` for transitions and shadows | S3 | ≤ ~20 KB of main.css by byte attribution; gate with a computed-style diff over `.dev/mocks` |
### Notes ### Notes
@@ -79,6 +90,15 @@ Budget revisions require a new baseline entry under `../baselines/`.
`/luci-static/aurora/login.css?v=1.0.7`. Do not re-propose manual `/luci-static/aurora/login.css?v=1.0.7`. Do not re-propose manual
cache-versioning for these links unless inspecting the installed package cache-versioning for these links unless inspecting the installed package
or live HTML proves the rewrite did not happen. or live HTML proves the rewrite did not happen.
- **No CSS post-processing** (2026-09-19) — mangling `--tw-*` measured 190,230 → 165,672 B raw but
only ~1 KB after gzip, and packages/flash are compressed: it buys a few ms on the first load per
version at the price of a custom build step, unreadable production variables and noisy committed
artifacts. Rejected; reduce at the source instead (see Pending).
- **Light `@utility` for transitions / shadows — deferred by the maintainer (2026-09-19).** Ceiling by
static resolution of the built sheet: transitions 54 rules, 15,323 → 7,668 B (−7.7 KB); shadows 50
rules, 9,419 → 2,299 B (−7.1 KB), of which only the 40 shadow-only rules (−5.4 KB) are safe — focus
states set a ring alone and rely on Tailwind's five-variable `box-shadow` composition. It changes
declarations, so only a computed-style diff plus a manual pass over hover/focus can gate it.
- **No gzip on the target uhttpd** — budgets and the bench harness use raw - **No gzip on the target uhttpd** — budgets and the bench harness use raw
identity bytes. Do not add precompressed sidecars unless the deployed HTTP identity bytes. Do not add precompressed sidecars unless the deployed HTTP
server is changed and live response headers prove negotiation works. server is changed and live response headers prove negotiation works.
@@ -8,13 +8,13 @@
"theme_color": "#f8fafc", "theme_color": "#f8fafc",
"icons": [ "icons": [
{ {
"src": "/luci-static/aurora/images/pwa/app-icon-192x192.png", "src": "/luci-static/aurora/images/app-icon-192x192.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png", "type": "image/png",
"purpose": "any maskable" "purpose": "any maskable"
}, },
{ {
"src": "/luci-static/aurora/images/pwa/app-icon-512x512.png", "src": "/luci-static/aurora/images/app-icon-512x512.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png", "type": "image/png",
"purpose": "any maskable" "purpose": "any maskable"
+26 -8
View File
@@ -63,7 +63,9 @@ header {
the visible travel, clamped to 240–480ms). */ the visible travel, clamped to 240–480ms). */
& .desktop-menu-sheet { & .desktop-menu-sheet {
@apply bg-mega-menu-bg absolute inset-x-0 top-0 h-[calc(var(--mega-menu-height,0px)+3.5rem)] -translate-y-full overflow-hidden transition-[translate] duration-(--mega-menu-duration,300ms) ease-[cubic-bezier(0.4,0,0.6,1)] motion-reduce:transition-none; @apply bg-mega-menu-bg absolute inset-x-0 top-0 h-[calc(var(--mega-menu-height,0px)+3.5rem)] -translate-y-full overflow-hidden transition-[translate] duration-(--mega-menu-duration,300ms) ease-[cubic-bezier(0.4,0,0.6,1)] motion-reduce:transition-none;
@apply after:border-hairline after:pointer-events-none after:absolute after:inset-0 after:border-b after:shadow-xl after:transition-opacity after:duration-(--mega-menu-duration,300ms) after:content-[''] motion-reduce:after:transition-none; &::after {
@apply border-hairline pointer-events-none absolute inset-0 border-b shadow-xl transition-opacity duration-(--mega-menu-duration,300ms) content-[''] motion-reduce:transition-none;
}
} }
/* The counter-transform must mirror the sheet's endpoints and timing /* The counter-transform must mirror the sheet's endpoints and timing
@@ -79,7 +81,9 @@ header {
} }
&.closing .desktop-menu-sheet { &.closing .desktop-menu-sheet {
@apply after:opacity-0; &::after {
@apply opacity-0;
}
} }
/* Category panels live inside .desktop-menu-canvas, not the nav items: /* Category panels live inside .desktop-menu-canvas, not the nav items:
@@ -330,27 +334,41 @@ header {
/* Same hover language as .navigation-toggle and .cmdk-trigger: a scale /* Same hover language as .navigation-toggle and .cmdk-trigger: a scale
nudge, never a background plate. */ nudge, never a background plate. */
& span[data-indicator] { & span[data-indicator] {
@apply before:text-text size-5 cursor-pointer text-[0px] transition-transform duration-150 before:absolute before:size-5 before:bg-current hover:scale-105 active:scale-95; @apply size-5 cursor-pointer text-[0px] transition-transform duration-150 hover:scale-105 active:scale-95;
&::before {
@apply text-text absolute size-5 bg-current content-[''];
}
&[data-indicator="media_error"] { &[data-indicator="media_error"] {
@apply before:[mask:var(--icon-error)_center/cover_no-repeat]; &::before {
@apply [mask:var(--icon-error)_center/cover_no-repeat];
}
} }
&[data-indicator="poll-status"] { &[data-indicator="poll-status"] {
&[data-style="active"] { &[data-style="active"] {
@apply before:[mask:var(--icon-refresh)_center/cover_no-repeat]; &::before {
@apply [mask:var(--icon-refresh)_center/cover_no-repeat];
}
} }
&[data-style="inactive"] { &[data-style="inactive"] {
@apply before:[mask:var(--icon-refresh-off)_center/cover_no-repeat]; &::before {
@apply [mask:var(--icon-refresh-off)_center/cover_no-repeat];
}
} }
} }
&[data-indicator="uci-changes"] { &[data-indicator="uci-changes"] {
@apply relative before:[mask:var(--icon-settings)_center/cover_no-repeat]; @apply relative;
&::before {
@apply [mask:var(--icon-settings)_center/cover_no-repeat];
}
&[data-count]:not([data-count="0"]) { &[data-count]:not([data-count="0"]) {
@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)]; &::after {
@apply bg-danger text-on-brand absolute -top-0.5 -right-0.5 z-10 flex min-h-3 min-w-3 items-center justify-center rounded-full px-0.5 text-[8px] leading-none font-bold shadow-sm content-[attr(data-count)];
}
} }
} }
} }
@@ -80,7 +80,9 @@ footer {
.spinning { .spinning {
@apply relative inline-block pl-8!; @apply relative inline-block pl-8!;
@apply before:absolute before:top-1/2 before:left-[6px] before:size-5 before:-translate-y-1/2 before:animate-spin before:bg-current before:[mask:var(--icon-spinning)_center/cover_no-repeat]; &::before {
@apply absolute top-1/2 left-[6px] size-5 -translate-y-1/2 animate-spin bg-current content-[''] [mask:var(--icon-spinning)_center/cover_no-repeat];
}
#view > & { #view > & {
@apply first:mx-auto first:grid first:min-h-48 first:w-fit first:place-items-center first:max-md:min-h-[calc(100dvh-4rem)]; @apply first:mx-auto first:grid first:min-h-48 first:w-fit first:place-items-center first:max-md:min-h-[calc(100dvh-4rem)];
} }
@@ -20,18 +20,36 @@
& .label[data-clickable] { & .label[data-clickable] {
@apply text-text bg-surface-sunken; @apply text-text bg-surface-sunken;
@apply inline-flex size-7 cursor-pointer items-center justify-center p-0 before:size-4 before:bg-current before:transition-transform before:duration-150 hover:shadow-md active:scale-95 max-md:size-6; @apply inline-flex size-7 cursor-pointer items-center justify-center p-0 hover:shadow-md active:scale-95 max-md:size-6;
&::before {
@apply size-4 bg-current transition-transform duration-150 content-[''];
}
} }
& span[data-indicator="poll-status"] { & span[data-indicator="poll-status"] {
@apply relative size-5 cursor-pointer text-[0px] before:absolute before:size-5 before:bg-current before:transition-transform before:duration-150 before:ease-out hover:before:scale-110 active:before:scale-95; @apply relative size-5 cursor-pointer text-[0px];
&::before {
@apply absolute size-5 bg-current transition-transform duration-150 ease-out content-[''];
}
@variant hover {
&::before {
@apply scale-110;
}
}
&:active::before {
@apply scale-95;
}
&[data-style="active"] { &[data-style="active"] {
@apply before:rotate-0 before:[mask:var(--icon-arrow-right)_center/cover_no-repeat]; &::before {
@apply rotate-0 [mask:var(--icon-arrow-right)_center/cover_no-repeat];
}
} }
&[data-style="inactive"] { &[data-style="inactive"] {
@apply before:rotate-90 before:[mask:var(--icon-arrow-right)_center/cover_no-repeat]; &::before {
@apply rotate-90 [mask:var(--icon-arrow-right)_center/cover_no-repeat];
}
} }
} }
} }
@@ -28,7 +28,9 @@
@apply text-text-muted relative mt-1 pl-4 leading-none wrap-break-word; @apply text-text-muted relative mt-1 pl-4 leading-none wrap-break-word;
&:not(:empty) { &:not(:empty) {
@apply before:bg-info before:absolute before:-left-0.5 before:inline-block before:size-4 before:[mask:var(--icon-info)_center/cover_no-repeat]; &::before {
@apply bg-info absolute -left-0.5 inline-block size-4 content-[''] [mask:var(--icon-info)_center/cover_no-repeat];
}
} }
} }
} }
@@ -44,7 +46,9 @@
& .item { & .item {
@apply border-hairline bg-surface 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-150 select-text max-md:w-full max-md:py-2.5 max-md:pr-8 max-md:pl-3; @apply border-hairline bg-surface 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-150 select-text max-md:w-full max-md:py-2.5 max-md:pr-8 max-md:pl-3;
@apply after:bg-surface-sunken after:text-text-muted 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']; &::after {
@apply bg-surface-sunken text-text-muted absolute top-2.5 right-2 inline-flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded-xl text-sm font-medium content-['\00D7'];
}
&.dragging { &.dragging {
@apply scale-95 cursor-grabbing opacity-50 shadow-2xl; @apply scale-95 cursor-grabbing opacity-50 shadow-2xl;
@@ -23,15 +23,45 @@ input[type="password"],
input[type="radio"], input[type="radio"],
input[type="checkbox"] { input[type="checkbox"] {
@apply focus:before:border-brand focus:before:ring-focus-ring checked:before:border-brand checked:before:bg-brand before:border-hairline before:bg-control-bg after:bg-on-brand hover:before:border-hairline relative mr-3 inline-block h-4 w-4 cursor-pointer appearance-none align-middle 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-150 after:absolute after:top-0.5 after:left-0.5 after:h-3 after:w-3 after:opacity-0 after:transition-opacity after:duration-150 checked:after:opacity-100 focus:before:ring-2 focus:before:outline-none disabled:cursor-not-allowed; @apply relative mr-3 inline-block h-4 w-4 cursor-pointer appearance-none align-middle disabled:cursor-not-allowed;
&::before {
@apply border-hairline bg-control-bg absolute top-0 left-0 h-4 w-4 border transition-[background-color,border-color,box-shadow] duration-150 content-[''];
}
&::after {
@apply bg-on-brand absolute top-0.5 left-0.5 h-3 w-3 opacity-0 transition-opacity duration-150 content-[''];
}
&:checked::before {
@apply border-brand bg-brand;
}
&:checked::after {
@apply opacity-100;
}
@variant hover {
&::before {
@apply border-hairline;
}
}
&:focus::before {
@apply border-brand ring-focus-ring ring-2 outline-none;
}
} }
input[type="radio"] { input[type="radio"] {
@apply before:rounded-full after:[mask:var(--icon-radio)_center/cover_no-repeat]; &::before {
@apply rounded-full;
}
&::after {
@apply [mask:var(--icon-radio)_center/cover_no-repeat];
}
} }
input[type="checkbox"] { input[type="checkbox"] {
@apply before:rounded after:[mask:var(--icon-check)_center/cover_no-repeat]; &::before {
@apply rounded;
}
&::after {
@apply [mask:var(--icon-check)_center/cover_no-repeat];
}
} }
.cbi-checkbox { .cbi-checkbox {
@@ -41,12 +41,22 @@
.navigation-group-toggle { .navigation-group-toggle {
/* size-4.5 ≈ the row's text height — 3.5 read as undersized next to the /* size-4.5 ≈ the row's text height — 3.5 read as undersized next to the
text-lg category labels, on desktop and in the mobile drawer alike. */ text-lg category labels, on desktop and in the mobile drawer alike. */
@apply after:size-4.5 after:shrink-0 after:bg-current after:opacity-55 after:transition-[transform,opacity] after:duration-[250ms] after:content-[''] after:[mask:var(--icon-arrow-right)_center/cover_no-repeat] hover:after:opacity-100; &::after {
@apply size-4.5 shrink-0 bg-current opacity-55 transition-[transform,opacity] duration-[250ms] content-[''] [mask:var(--icon-arrow-right)_center/cover_no-repeat];
}
@variant hover {
&::after {
@apply opacity-100;
}
}
} }
/* An expanded group's label turns brand and its arrow rotates open. */ /* An expanded group's label turns brand and its arrow rotates open. */
.navigation-group.is-expanded > .navigation-group-toggle { .navigation-group.is-expanded > .navigation-group-toggle {
@apply text-brand after:rotate-90; @apply text-brand;
&::after {
@apply rotate-90;
}
} }
/* The active group keeps its brand label even when the user manually /* The active group keeps its brand label even when the user manually
@@ -1,7 +1,12 @@
.cbi-progressbar { .cbi-progressbar {
@apply before:text-text bg-surface-sunken 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:before:text-xs max-md:before:leading-normal; @apply bg-surface-sunken relative h-3.5 w-full cursor-help overflow-hidden rounded-full max-md:h-4;
&::before {
@apply text-text absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-2xl text-xs whitespace-nowrap content-[attr(title)] max-md:text-xs max-md:leading-normal;
}
[data-page="admin-system-package-manager"] & { [data-page="admin-system-package-manager"] & {
@apply max-sm:before:text-[10px]; &::before {
@apply max-sm:text-[10px];
}
} }
& > div { & > div {
@@ -4,7 +4,9 @@
& li { & li {
@apply relative m-0 min-w-fit shrink-0 list-none; @apply relative m-0 min-w-fit shrink-0 list-none;
&[data-errors] { &[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)]; &::after {
@apply bg-danger text-on-brand absolute -top-0.5 -right-1.5 z-20 inline-flex min-h-4 min-w-4 items-center justify-center rounded-full px-1.5 py-0.5 text-xs font-semibold content-[attr(data-errors)];
}
& > a { & > a {
@apply border-hairline border; @apply border-hairline border;
@@ -1,7 +1,9 @@
.theme-switcher { .theme-switcher {
@apply bg-surface-sunken relative inline-flex items-center gap-0 rounded-full shadow-sm transition-transform duration-150 max-md:py-0.5; @apply bg-surface-sunken relative inline-flex items-center gap-0 rounded-full shadow-sm transition-transform duration-150 max-md:py-0.5;
@apply border-hairline border; @apply border-hairline border;
@apply before:bg-surface-overlay 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:transition-transform before:duration-[250ms]; &::before {
@apply bg-surface-overlay absolute top-1 left-1 z-0 h-[calc(100%-0.5rem)] w-[calc(33.333%-0.5rem)] rounded-full shadow-md transition-transform duration-[250ms] content-[''];
}
footer & { footer & {
@apply max-md:hidden; @apply max-md:hidden;
@@ -52,14 +54,20 @@
} }
&:has(.theme-option[data-theme="device"].active) { &:has(.theme-option[data-theme="device"].active) {
@apply before:translate-x-0; &::before {
@apply translate-x-0;
}
} }
&:has(.theme-option[data-theme="light"].active) { &:has(.theme-option[data-theme="light"].active) {
@apply before:translate-x-[calc(100%+0.5rem)]; &::before {
@apply translate-x-[calc(100%+0.5rem)];
}
} }
&:has(.theme-option[data-theme="dark"].active) { &:has(.theme-option[data-theme="dark"].active) {
@apply before:translate-x-[calc(200%+1rem)]; &::before {
@apply translate-x-[calc(200%+1rem)];
}
} }
} }
@@ -17,15 +17,21 @@ table.table,
& .cbi-section-table-titles.named, & .cbi-section-table-titles.named,
& .cbi-section-table-descr.named, & .cbi-section-table-descr.named,
& .cbi-section-table-row[data-title] { & .cbi-section-table-row[data-title] {
@apply before:border-hairline 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; &::before {
@apply border-hairline table-cell px-3 py-3 align-middle text-base font-semibold content-[attr(data-title)] max-md:flex max-md:flex-[0_0_100%] max-md:px-3 max-md:py-2.5 max-md:text-sm md:border-b;
}
&:not([data-title]), &:not([data-title]),
&:has(td.cbi-section-table-titles) { &:has(td.cbi-section-table-titles) {
@apply before:content-none; &::before {
@apply content-none;
}
} }
} }
& .cbi-section-table-titles.named { & .cbi-section-table-titles.named {
@apply before:text-text-subtle before:text-xs before:font-semibold before:tracking-wider before:uppercase; &::before {
@apply text-text-subtle text-xs font-semibold tracking-wider uppercase;
}
} }
& tbody, & tbody,
@@ -48,7 +54,9 @@ table.table,
&:last-child { &:last-child {
@apply max-md:border-b-0; @apply max-md:border-b-0;
&[data-title] { &[data-title] {
@apply before:border-b-0; &::before {
@apply border-b-0;
}
} }
.td { .td {
@apply border-b-0; @apply border-b-0;
@@ -124,12 +132,19 @@ table.table,
} }
&[data-sortable-row="true"] { &[data-sortable-row="true"] {
@apply hover:bg-hover-faint cursor-pointer select-none after:ml-0.5 after:text-xs; @apply hover:bg-hover-faint cursor-pointer select-none;
&::after {
@apply ml-0.5 text-xs content-[''];
}
&[data-sort-direction="asc"] { &[data-sort-direction="asc"] {
@apply after:content-['\25B2']; &::after {
@apply content-['\25B2'];
}
} }
&[data-sort-direction="desc"] { &[data-sort-direction="desc"] {
@apply after:content-['\25BC']; &::after {
@apply content-['\25BC'];
}
} }
} }
} }
@@ -143,7 +158,9 @@ table.table,
& td, & td,
& .td { & .td {
@apply border-hairline table-cell border-b px-3 py-3 align-middle wrap-break-word whitespace-normal max-md:flex-[1_1_50%] max-md:border-0 max-md:px-1 max-md:py-1; @apply border-hairline table-cell border-b px-3 py-3 align-middle wrap-break-word whitespace-normal max-md:flex-[1_1_50%] max-md:border-0 max-md:px-1 max-md:py-1;
@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; &::before {
@apply hidden content-[attr(data-title)] max-md:mb-1 max-md:block max-md:text-xs max-md:font-semibold max-md:tracking-wider;
}
#cbi-samba4 & { #cbi-samba4 & {
@apply px-0.5 py-1.5; @apply px-0.5 py-1.5;
@@ -154,7 +171,10 @@ table.table,
} }
#wifi_assoclist_table & { #wifi_assoclist_table & {
@apply max-md:flex-[0_0_100%] max-md:px-3 max-md:py-2 before:max-md:mb-1.5; @apply max-md:flex-[0_0_100%] max-md:px-3 max-md:py-2;
&::before {
@apply max-md:mb-1.5;
}
} }
& > input[type="text"], & > input[type="text"],
@@ -17,11 +17,8 @@ test("production assets stay within raw-transfer budgets", () => {
const font = bytes("aurora/fonts/lato-v24-latin-regular.woff2"); const font = bytes("aurora/fonts/lato-v24-latin-regular.woff2");
const logo = bytes("aurora/images/logo.svg"); const logo = bytes("aurora/images/logo.svg");
// 192K: the custom-background mode (scheme D surfaces + shared page-bg // 187K: pseudo-elements are nested rules, one content declaration each.
// layer) added ~1.4 KB of rules; 193K: the router's progress bar and assert.ok(main <= 187_000, "main.css exceeds 187 KB");
// live region. The total-transfer budget below is unchanged and still
// binds.
assert.ok(main <= 193_000, "main.css exceeds 193 KB");
assert.ok(login <= 12_000, "login.css exceeds 12 KB"); assert.ok(login <= 12_000, "login.css exceeds 12 KB");
// 22K: palette recents (record on pick, pure-LRU browse order, storage // 22K: palette recents (record on pick, pure-LRU browse order, storage
// validation) added ~0.8 KB and the ">" logout command ~0.2 KB. The total // validation) added ~0.8 KB and the ">" logout command ~0.2 KB. The total
@@ -40,8 +37,8 @@ test("production assets stay within raw-transfer budgets", () => {
assert.ok(router <= 16_000, "router-aurora.js exceeds 16 KB"); assert.ok(router <= 16_000, "router-aurora.js exceeds 16 KB");
assert.ok(logo <= 16_000, "logo.svg exceeds 16 KB"); assert.ok(logo <= 16_000, "logo.svg exceeds 16 KB");
assert.ok( assert.ok(
main + menu + router + font + logo <= 268_500, main + menu + router + font + logo <= 264_000,
"admin assets exceed 268.5 KB", "admin assets exceed 264 KB",
); );
assert.ok(login + font + logo <= 55_000, "login assets exceed 55 KB"); assert.ok(login + font + logo <= 55_000, "login assets exceed 55 KB");
}); });
@@ -121,3 +118,59 @@ test("package roots contain no macOS metadata", () => {
visit(resolve(projectRoot, "ucode")); visit(resolve(projectRoot, "ucode"));
assert.deepEqual(offenders, []); assert.deepEqual(offenders, []);
}); });
test("the web manifest's icons exist in the package", () => {
const manifest = JSON.parse(readFileSync(asset("aurora/images/app.webmanifest"), "utf8"));
assert.ok(manifest.icons.length > 0);
for (const { src } of manifest.icons) {
assert.match(src, /^\/luci-static\//);
assert.ok(statSync(asset(src.replace(/^\/luci-static\//, ""))).isFile(), src);
}
});
test("login.css keeps the Safari 16.4 backdrop-filter prefix", () => {
const css = readFileSync(asset("aurora/login.css"), "utf8");
const count = (needle) => css.split(needle).length - 1;
const prefixed = count("-webkit-backdrop-filter:");
assert.ok(prefixed > 0);
assert.equal(count("backdrop-filter:") - prefixed, prefixed);
});
test("no rule repeats a declaration, vendor-prefixed ones aside", () => {
for (const sheet of ["aurora/main.css", "aurora/login.css"]) {
const css = readFileSync(asset(sheet), "utf8");
const repeated = [];
const blocks = [[]];
let quote = "";
let parens = 0;
let start = 0;
const close = (end) => {
const declaration = css.slice(start, end).trim();
const seen = blocks.at(-1);
if (declaration && !declaration.startsWith("-webkit-")) {
if (seen.includes(declaration)) repeated.push(declaration);
seen.push(declaration);
}
start = end + 1;
};
for (let i = 0; i < css.length; i++) {
const char = css[i];
if (quote) {
if (char === "\\") i++;
else if (char === quote) quote = "";
} else if (char === '"' || char === "'") quote = char;
else if (char === "(") parens++;
else if (char === ")") parens--;
else if (parens) continue;
else if (char === ";") close(i);
else if (char === "{") {
blocks.push([]);
start = i + 1;
} else if (char === "}") {
close(i);
blocks.pop();
}
}
assert.deepEqual(repeated, [], sheet);
}
});
@@ -73,12 +73,13 @@ test("shared navigation styles define active and expanded states", () => {
// Weight is the surface's call — the two run different scales. // Weight is the surface's call — the two run different scales.
assert.doesNotMatch(directActive, /font-(?:normal|medium|semibold|bold)/); assert.doesNotMatch(directActive, /font-(?:normal|medium|semibold|bold)/);
// An expanded group's label turns brand and rotates its arrow open. // An expanded group's label turns brand and rotates its arrow open.
assertIncludesUtilities(expandedToggle, ["after:rotate-90", "text-brand"]); assertIncludesUtilities(expandedToggle, ["text-brand"]);
assertIncludesUtilities(getBlock(expandedToggle, "&::after"), ["rotate-90"]);
// The active group keeps a brand label even when manually collapsed, so the // The active group keeps a brand label even when manually collapsed, so the
// current section stays marked while its pill is hidden — but it must not // current section stays marked while its pill is hidden — but it must not
// rotate the arrow open in that collapsed state. // rotate the arrow open in that collapsed state.
assertIncludesUtilities(activeGroupToggle, ["text-brand"]); assertIncludesUtilities(activeGroupToggle, ["text-brand"]);
assert.doesNotMatch(activeGroupToggle, /after:rotate-90/); assert.doesNotMatch(activeGroupToggle, /rotate-90/);
// The pill shape lives with the pill fill in the shared recipe, so the // The pill shape lives with the pill fill in the shared recipe, so the
// hover/active background is rounded the same way on desktop and mobile. // hover/active background is rounded the same way on desktop and mobile.
assertIncludesUtilities(sublink, [ assertIncludesUtilities(sublink, [
@@ -92,8 +93,8 @@ test("shared navigation styles define active and expanded states", () => {
"font-semibold", "font-semibold",
"bg-brand-subtle", "bg-brand-subtle",
]); ]);
// The left accent bar is gone — no before:* rail on the active sublink. // The left accent bar is gone — no ::before rail on the active sublink.
assert.doesNotMatch(activeSublink, /before:/); assert.doesNotMatch(activeSublink, /before/);
}); });
test("one first-level row recipe serves both kinds on both surfaces", () => { test("one first-level row recipe serves both kinds on both surfaces", () => {
@@ -154,9 +155,9 @@ test("shared navigation styles own accordion animation without a guide rail", ()
); );
const submenu = getBlock(navigationStyles, ".navigation-submenu-list"); const submenu = getBlock(navigationStyles, ".navigation-submenu-list");
assertIncludesUtilities(toggle, [ assertIncludesUtilities(getBlock(toggle, "&::after"), [
"after:transition-[transform,opacity]", "transition-[transform,opacity]",
"after:duration-[250ms]", "duration-[250ms]",
]); ]);
assert.match(toggle, /var\(--icon-arrow-right\)/); assert.match(toggle, /var\(--icon-arrow-right\)/);
assertIncludesUtilities(region, [ assertIncludesUtilities(region, [
@@ -167,9 +168,9 @@ test("shared navigation styles own accordion animation without a guide rail", ()
"duration-[250ms]", "duration-[250ms]",
]); ]);
assertIncludesUtilities(expandedRegion, ["grid-rows-[1fr]", "opacity-100"]); assertIncludesUtilities(expandedRegion, ["grid-rows-[1fr]", "opacity-100"]);
// The vertical guide rail is removed: the submenu list carries no before:* // The vertical guide rail is removed: the submenu list carries no ::before
// hairline anymore. // hairline anymore.
assert.doesNotMatch(submenu, /before:bg-hairline/); assert.doesNotMatch(submenu, /before/);
}); });
test("desktop sidebar styles only provide desktop navigation density", () => { test("desktop sidebar styles only provide desktop navigation density", () => {
+1 -1
View File
@@ -29,7 +29,7 @@ const BUILD_OUTPUT = resolve(PROJECT_ROOT, "htdocs/luci-static");
const PATCH_SRC_DIR = resolve(CURRENT_DIR, "src/media/patches"); const PATCH_SRC_DIR = resolve(CURRENT_DIR, "src/media/patches");
const LIGHTNINGCSS_TARGETS = browserslistToTargets( const LIGHTNINGCSS_TARGETS = browserslistToTargets(
browserslist("last 4 versions, Firefox ESR, not dead"), browserslist("chrome >= 111, edge >= 111, firefox >= 128, safari >= 16.4, ios_saf >= 16.4"),
); );
// See luci-theme.config.js. Empty today: the log viewer needs only // See luci-theme.config.js. Empty today: the log viewer needs only
+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_TITLE:=Aurora Theme (A modern browser theme built with Vite and Tailwind CSS)
LUCI_DEPENDS:=+luci-base LUCI_DEPENDS:=+luci-base
PKG_VERSION:=1.3.8 PKG_VERSION:=1.3.9
PKG_RELEASE:=82 PKG_RELEASE:=83
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
LUCI_MINIFY_CSS:= LUCI_MINIFY_CSS:=
@@ -8,13 +8,13 @@
"theme_color": "#f8fafc", "theme_color": "#f8fafc",
"icons": [ "icons": [
{ {
"src": "/luci-static/aurora/images/pwa/app-icon-192x192.png", "src": "/luci-static/aurora/images/app-icon-192x192.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png", "type": "image/png",
"purpose": "any maskable" "purpose": "any maskable"
}, },
{ {
"src": "/luci-static/aurora/images/pwa/app-icon-512x512.png", "src": "/luci-static/aurora/images/app-icon-512x512.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png", "type": "image/png",
"purpose": "any maskable" "purpose": "any maskable"
@@ -1,2 +1,2 @@
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */ /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
@layer properties{@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-content:"";--tw-shadow:0 0 #0000;--tw-inset-shadow:0 0 #0000;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-shadow:0 0 #0000;--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%}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--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}}@layer base{*,:before,:after{box-sizing:border-box}body,hr,p,button,input{margin:0}button,input{font:inherit}a{text-decoration-line:none}[hidden]{display:none!important}}@layer components,utilities;:root{--bg:#f7fafc;--surface:#fff;--text:#121a22;--brand:#0085b7;--on-brand:#fff;--danger:#8d1925;--text-muted:#5f666d;--text-subtle:#7f858b;--hairline:#121a2221;--brand-subtle:#ddecf5;--danger-surface:#ffe8e6;--control-bg:#fff;--app-shadow-md:0 4px 16px #00000014, 0 1px 3px #0000000a;--font-sans:"Lato", ui-sans-serif, system-ui, sans-serif;--spacing:.25rem;--radius-base:.5rem}@supports (color:lab(0% 0 0)){:root{--bg:lab(98.1553% -.760227 -1.25223);--surface:lab(100% 0 0);--text:lab(8.89727% -1.68239 -6.93074);--brand:lab(51.3503% -19.237 -40.2116);--on-brand:lab(100% 0 0);--danger:lab(31.1495% 47.9256 25.8661);--text-muted:lab(42.8254% -1.57365 -4.8763);--text-subtle:lab(55.3248% -1.4126 -4.053);--hairline:lab(8.89727% -1.68239 -6.93074/.13);--brand-subtle:lab(92.5794% -3.9458 -6.17858);--danger-surface:lab(93.849% 11.2841 5.29771);--control-bg:lab(100.011% -.760317 -1.25225);--app-shadow-md:0 4px 16px lab(0% 0 0/.08), 0 1px 3px lab(0% 0 0/.04)}}[data-darkmode=true]{--bg:#05070e;--surface:#141822;--text:#f9fafb;--brand:#00958e;--on-brand:#fff;--danger:#f17070;--text-muted:#909297;--text-subtle:#5d6067;--hairline:#f9fafb1a;--brand-subtle:#061a20;--danger-surface:#541f20;--control-bg:#0a0e17;--app-shadow-md:0 10px 28px #0000006b}@supports (color:lab(0% 0 0)){[data-darkmode=true]{--bg:lab(1.93894% .0855997 -3.22397);--surface:lab(8.24713% -.0405461 -7.31381);--text:lab(98.252% -.0618994 -.756907);--brand:lab(55.0978% -44.5567 -7.62978);--on-brand:lab(100% 0 0);--danger:lab(63.5705% 50.8105 25.3639);--text-muted:lab(60.5379% -.225931 -3.05105);--text-subtle:lab(40.6865% -.278354 -4.23647);--hairline:lab(98.252% -.0618994 -.756907/.1);--brand-subtle:lab(7.95734% -6.34954 -6.72844);--danger-surface:lab(20.3014% 25.4342 12.827);--control-bg:lab(3.9802% .0812709 -5.64623);--app-shadow-md:0 10px 28px lab(0% 0 0/.42)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-property:none!important;animation:none!important}.spinning:before{animation:var(--animate-spin)!important}}html{background-color:var(--bg);min-height:100dvh;font-family:var(--font-sans);color-scheme:light}html[data-darkmode=true]{color-scheme:dark}html body{background-color:var(--bg);min-height:100dvh}.page-bg{pointer-events:none;background-image:var(--page-bg-lqip,var(--page-bg));background-position:50%;background-repeat:no-repeat;background-size:cover;position:fixed;inset:0;transform:translateZ(0)}.page-bg:after{pointer-events:none;background-image:var(--page-bg);opacity:0;--tw-content:"";content:var(--tw-content);background-position:50%;background-repeat:no-repeat;background-size:cover;transition:opacity .5s;position:absolute;inset:0}.page-bg.full-loaded:after{opacity:1}@keyframes divider-in{0%{opacity:0;transform:scaleX(.15)}}.login-screen{min-height:100dvh;padding-inline:calc(var(--spacing) * 5);padding-bottom:calc(var(--spacing) * 14);flex-direction:column;justify-content:center;align-items:center;display:flex;position:relative}.login-shell{width:100%;max-width:var(--container-md)}.page-bg{--page-bg:var(--login-bg);--page-bg-lqip:var(--login-bg-lqip)}body[data-bg] .page-bg:before{pointer-events:none;z-index:1;--tw-content:"";content:var(--tw-content);background:var(--bg);position:absolute;inset:0}@supports (color:color-mix(in lab, red, red)){body[data-bg] .page-bg:before{background:color-mix(in srgb,var(--bg) var(--login-bg-scrim,0%),transparent)}}body[data-bg] .login-card{backdrop-filter:blur(var(--login-bg-blur,0px)) saturate(150%);background:var(--surface)}@supports (color:color-mix(in lab, red, red)){body[data-bg] .login-card{background:color-mix(in Line truncated @layer properties{@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-content:"";--tw-shadow:0 0 #0000;--tw-inset-shadow:0 0 #0000;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-shadow:0 0 #0000;--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%}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--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}}@layer base{*,:before,:after{box-sizing:border-box}body,hr,p,button,input{margin:0}button,input{font:inherit}a{text-decoration-line:none}[hidden]{display:none!important}}@layer components,utilities;:root{--bg:#f7fafc;--surface:#fff;--text:#121a22;--brand:#0085b7;--on-brand:#fff;--danger:#8d1925;--text-muted:#5f666d;--text-subtle:#7f858b;--hairline:#121a2221;--brand-subtle:#ddecf5;--danger-surface:#ffe8e6;--control-bg:#fff;--app-shadow-md:0 4px 16px #00000014, 0 1px 3px #0000000a;--font-sans:"Lato", ui-sans-serif, system-ui, sans-serif;--spacing:.25rem;--radius-base:.5rem}@supports (color:lab(0% 0 0)){:root{--bg:lab(98.1553% -.760227 -1.25223);--surface:lab(100% 0 0);--text:lab(8.89727% -1.68239 -6.93074);--brand:lab(51.3503% -19.237 -40.2116);--on-brand:lab(100% 0 0);--danger:lab(31.1495% 47.9256 25.8661);--text-muted:lab(42.8254% -1.57365 -4.8763);--text-subtle:lab(55.3248% -1.4126 -4.053);--hairline:lab(8.89727% -1.68239 -6.93074/.13);--brand-subtle:lab(92.5794% -3.9458 -6.17858);--danger-surface:lab(93.849% 11.2841 5.29771);--control-bg:lab(100.011% -.760317 -1.25225);--app-shadow-md:0 4px 16px lab(0% 0 0/.08), 0 1px 3px lab(0% 0 0/.04)}}[data-darkmode=true]{--bg:#05070e;--surface:#141822;--text:#f9fafb;--brand:#00958e;--on-brand:#fff;--danger:#f17070;--text-muted:#909297;--text-subtle:#5d6067;--hairline:#f9fafb1a;--brand-subtle:#061a20;--danger-surface:#541f20;--control-bg:#0a0e17;--app-shadow-md:0 10px 28px #0000006b}@supports (color:lab(0% 0 0)){[data-darkmode=true]{--bg:lab(1.93894% .0855997 -3.22397);--surface:lab(8.24713% -.0405461 -7.31381);--text:lab(98.252% -.0618994 -.756907);--brand:lab(55.0978% -44.5567 -7.62978);--on-brand:lab(100% 0 0);--danger:lab(63.5705% 50.8105 25.3639);--text-muted:lab(60.5379% -.225931 -3.05105);--text-subtle:lab(40.6865% -.278354 -4.23647);--hairline:lab(98.252% -.0618994 -.756907/.1);--brand-subtle:lab(7.95734% -6.34954 -6.72844);--danger-surface:lab(20.3014% 25.4342 12.827);--control-bg:lab(3.9802% .0812709 -5.64623);--app-shadow-md:0 10px 28px lab(0% 0 0/.42)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-property:none!important;animation:none!important}.spinning:before{animation:var(--animate-spin)!important}}html{background-color:var(--bg);min-height:100dvh;font-family:var(--font-sans);--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}html[data-darkmode=true]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}html body{background-color:var(--bg);min-height:100dvh}.page-bg{pointer-events:none;background-image:var(--page-bg-lqip,var(--page-bg));background-position:50%;background-repeat:no-repeat;background-size:cover;position:fixed;inset:0;transform:translateZ(0)}.page-bg:after{pointer-events:none;background-image:var(--page-bg);opacity:0;--tw-content:"";content:var(--tw-content);background-position:50%;background-repeat:no-repeat;background-size:cover;transition:opacity .5s;position:absolute;inset:0}.page-bg.full-loaded:after{opacity:1}@keyframes divider-in{0%{opacity:0;transform:scaleX(.15)}}.login-screen{min-height:100dvh;padding-inline:calc(var(--spacing) * 5);padding-bottom:calc(var(--spacing) * 14);flex-direction:column;justify-content:center;align-items:center;display:flex;position:relative}.login-shell{width:100%;max-width:var(--container-md)}.page-bg{--page-bg:var(--login-bg);--page-bg-lqip:var(--login-bg-lqip)}body[data-bg] .page-bg:before{pointer-events:none;z-index:1;--tw-content:"";content:var(--tw-content);background:var(--bg);position:absolute;inset:0}@supports (color:color-mix(in lab, red, red)){body[data-bg] .page-bg:before{background:color-mix(in srgb,var(--bg) var(--login-bg-scrim,0%),transparent)}}body[data-bg] .login-card{-webkit-backdrop-filter:blur(var(--login-bg-blur,0px)) saturate(150%);backdrop-filLine truncated
@@ -1,2 +1,2 @@
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */ /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
@layer properties{@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-content:"";--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-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-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-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}}}@layer theme{: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;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--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)}}@layer base{*,: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 (notLine truncated @layer properties{@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-content:"";--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-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-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-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}}}@layer theme{: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;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--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)}}@layer base{*,: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 (notLine truncated
-51
View File
@@ -1,51 +0,0 @@
#
# Copyright (C) 2016-2020 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=webui-aria2
PKG_RELEASE:=3
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2026-05-31
PKG_SOURCE_URL:=https://github.com/Ryahn/webui-aria2.git
PKG_SOURCE_VERSION:=5a613d8b049ad07b919884890551e78760c71e22
PKG_MIRROR_HASH:=skip
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Hsing-Wang Liao <kuoruan@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/webui-aria2
SECTION:=net
CATEGORY:=Network
SUBMENU:=Download Manager
TITLE:=An interface to interact with aria2
URL:=https://github.com/ziahamza/webui-aria2
DEPENDS:=+aria2
PKGARCH:=all
endef
define Package/webui-aria2/description
The aim for this project is to create the worlds best and hottest
interface to interact with aria2. Very simple to use.
endef
define Build/Compile
endef
define Package/webui-aria2/install
$(INSTALL_DIR) $(1)/www/webui-aria2
$(CP) \
$(PKG_BUILD_DIR)/docs/* \
$(PKG_BUILD_DIR)/{LICENSE,favicon.ico} \
$(1)/www/webui-aria2
endef
$(eval $(call BuildPackage,webui-aria2))