# Technical Documentation: jerrykuku/luci-theme-argon

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/jerrykuku/luci-theme-argon)

### Overview (`README.md`)

[license]: /LICENSE
[license-badge]: https://img.shields.io/github/license/jerrykuku/luci-theme-argon?style=flat-square&a=1
[prs]: https://github.com/jerrykuku/luci-theme-argon/pulls
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[issues]: https://github.com/jerrykuku/luci-theme-argon/issues/new
[issues-badge]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg?style=flat-square
[release]: https://github.com/jerrykuku/luci-theme-argon/releases
[release-badge]: https://img.shields.io/github/v/release/jerrykuku/luci-theme-argon?style=flat-square
[download]: https://github.com/jerrykuku/luci-theme-argon/releases
[download-badge]: https://img.shields.io/github/downloads/jerrykuku/luci-theme-argon/total?style=flat-square
[contact]: https://t.me/jerryk6
[contact-badge]: https://img.shields.io/badge/Contact-telegram-blue?style=flat-square

<div align="center">
<img src="https://raw.githubusercontent.com/jerrykuku/staff/master/argon_title4.svg">

# A brand new OpenWrt LuCI theme · v3

Argon is **a clean and tidy OpenWrt LuCI theme** that allows<br/>
users to customize their login interface with images or videos.  
It also supports automatic and manual switching between light and dark modes.

[![license][license-badge]][license]
[![prs][prs-badge]][prs]
[![issues][issues-badge]][issues]
[![release][release-badge]][release]
[![download][download-badge]][download]
[![contact][contact-badge]][contact]

**English** · [简体中文](README_ZH.md)

[](Screenshots/argon-3-demo.mp4)

[Watch the desktop demo · MP4](Screenshots/argon-3-demo.mp4)

</div>

## What's new in 3.0

- **Built-in Argon Config.** Manage the theme without a separate plugin.
- **Broad third-party app support.** Refined layouts, forms and tables for most third-party LuCI apps, with desktop/mobile and light/dark adaptations.
- **Two login layouts.** Choose the classic sidebar or centered card.
- **Light and dark.** Switch from the header or follow your system, with customizable accent colors.
- **Your own look.** Adjust login glass effects, set image or video backgrounds, and upload a browser icon and login logo.
- **Desktop and mobile.** Responsive layouts across screen sizes.

## Install

**In 3.0, the theme and configuration features are one package: `luci-theme-argon`. Fresh installations need only this package.** Download the format matching your firmware's native package manager from [Releases](https://github.com/jerrykuku/luci-theme-argon/releases). If the old standalone configuration plugin is installed, follow the migration steps below first.

| Package manager | Package | Install |
| --- | --- | --- |
| `opkg` | `.ipk` | `opkg install ./luci-theme-argon_*.ipk` |
| APK v3 (`apk-tools 3.x`) | `.apk` | `apk add --allow-untrusted ./luci-theme-argon-*.apk` |

Run `opkg update` or `apk update` first. APK v2 cannot read these APK packages; keep your firmware's native package manager.

For translations, install the matching `luci-i18n-argon-config-<language>` package from the same release and in the same format.

Select **Argon** under **System → System → Language and Style → Design**.

<details>
<summary>Already have the old luci-app-argon-config? Migrate to 3.0</summary>

This applies only when the old standalone configuration plugin is installed. Otherwise, skip this section.

The settings page, colors, backgrounds and branding are all included in the theme. The release's `luci-app-argon-config` is an **empty migration package using the old package name**. It preserves existing settings and hands its files over to the theme.

1. Download both `luci-app-argon-config` and `luci-theme-argon` from the **same 3.0 release in the theme repository**, in the same format.
2. Put both files in one directory on the router and open a terminal there. **Do not uninstall the old plugin first.** Choose the command pair for your firmware; run the second command only after the first succeeds.

```sh
# opkg
opkg install ./luci-app-argon-config_*.ipk
opkg install ./luci-theme-argon_*.ipk

# APK v3
apk add --allow-untrusted ./luci-app-argon-config-*.apk
apk add --allow-untrusted ./luci-theme-argon-*.apk
```

The first command replaces the old plugin with the empty migration package. The second installs the integrated theme and restores your settings. Continue configuring it under **System → Argon Config**.

</details>

## Customize

Open **System → Argon Config** for login layouts, colors, glass effects, wallpapers and branding. The header's appearance button switches between **Light mode**, **Dark mode** and **Follow system**; the choice also applies to the login page.

Local image and video backgrounds are supported, along with Bing, Unsplash and Wallhaven wallpapers. Unsplash requires an API access key. Browser icons and login logos accept PNG files, 16–1024 pixels per side, up to 1 MiB; browser icons must be square.

Under **Theme updates**, check the latest stable release, read its release notes and download the package matching your firmware's package manager. Checks use the router's connection to GitHub and cache successful results for five minutes.

When a newer version is available, choose **Update now** and confirm to install the theme using the firmware’s native APK or OPKG package manager, preserving your Argon configuration. The page shows download, verification and installation status plus installation logs, and resumes monitoring after a page refresh. Reload the page after installation. Automatic installation requires a matching release package and SHA256 digest and does not perform downgrades. It updates the main theme package; separate translation packages remain managed by the system package manager.

## Screenshots

Light and dark views of the overview and both login layouts, on desktop and mobile.









## Contributors

<a href="https://github.com/jerrykuku/luci-theme-argon/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=jerrykuku/luci-theme-argon&v=2" />
</a>

Made with [contrib.rocks](https://contrib.rocks).

## Development

See the [development guide](docs/DEVELOPMENT.md) for source builds, LESS, templates, icons and checks.

[Releases](https://github.com/jerrykuku/luci-theme-argon/releases) · [Version history](RELEASE.md) · [Contributors](https://github.com/jerrykuku/luci-theme-argon/graphs/contributors) · [Report an issue](https://github.com/jerrykuku/luci-theme-argon/issues)

Licensed under [Apache-2.0](LICENSE). Thanks to [luci-theme-material](https://github.com/LuttyYang/luci-theme-material/).

---

### Overview (`htdocs/luci-static/argon/background/README.md`)

Drop background here!
accept jpg jpeg png gif webp mp4 webm

---

### Overview (`htdocs/luci-static/argon/icon/README.md`)

# Argon SVG icons / SVG 图标

`copy.svg` 和 `download.svg` 是文件管理操作使用的补充图标，采用24×24画布、2px描边，并通过CSS mask跟随控件颜色；不属于原字体导出清单。

原 `argon.woff2` 中全部 **28 个可见图标**已按原始矢量轮廓导出，字体文件已从主题移除。文件名使用实际服务或功能名称，例如 `status.svg`、`services.svg`、`docker.svg`；Unicode 编码仅保留在对照表中。SVG 使用透明背景和 `viewBox`，可用于 CSS mask 或内联 SVG。

All **28 visible icons** from the former `argon.woff2` font are exported with their original vector outlines; the font files have been removed from the theme. Filenames use service or function names, such as `status.svg`, `services.svg`, and `docker.svg`; Unicode code points are kept in the mapping. SVGs have transparent backgrounds and view boxes, suitable for CSS masks or inline SVG.

`chevron-down.svg` 和 `chevron-right.svg` 在导出后统一重绘为 24×24、2px 描边、圆端点和圆连接。两者互为旋转，保留原字体编码作为功能对照。CSS mask 跟随控件颜色；作为原生 select 或排序按钮的背景图时，使用 SVG 的中性默认颜色。其余 26 个图标保留字体轮廓。对照表中的 `sourceViewBox` 与 `designOverride` 标记这两处设计替换。

The two chevrons are redesigned on a shared 24×24 grid with a 2px stroke, round caps and joins, preserving their original code point mappings. CSS masks inherit the control color; native select and sorting backgrounds use the SVG's neutral default color. The other 26 icons keep their font outlines. Mapping entries record `sourceViewBox` and `designOverride` for these exceptions.

字体共有 33 个字形；`.notdef`、`uni0000`、`nonmarkingreturn`、`uni0001`、`space` 没有可见轮廓，无需生成空 SVG。[font-icons.json](font-icons.json) 记录完整的编码、字形名、文件名、画布尺寸和源字体 SHA-256。画布保留字体坐标与留白，并扩展至包含越界轮廓，避免裁切。

The font contains 33 glyphs. The five invisible glyphs listed above have no SVG output. [font-icons.json](font-icons.json) records code points, glyph names, filenames, canvas sizes, and the source font SHA-256. View boxes preserve font spacing and expand where an outline exceeds the original em square.

一级菜单按节点名称直接匹配 SVG，例如状态 → `status.svg`、系统 → `system.svg`、服务 → `services.svg`、网络 → `network.svg`、Docker → `docker.svg`。缺失时使用 `default.svg`（原字体的软件包图标）。登录输入框使用 `user.svg`、`password.svg`，移动菜单按钮使用 `menu.svg`。主题不再依赖图标字体；对照表中的源文件名与 SHA-256 仅作为导出来源记录，`sourceIncluded: false` 表示源字体不随主题分发。

Top-level menus match their node names directly, for example `status.svg`, `system.svg`, `services.svg`, `network.svg`, and `docker.svg`. Missing icons use `default.svg`, the original package glyph. Login fields use `user.svg` and `password.svg`; the mobile menu toggle uses `menu.svg`. The theme no longer depends on an icon font. The source filename and SHA-256 remain as export provenance; `sourceIncluded: false` records that the original font is not distributed.

| 预览 / Preview | 编码 / Code point | SVG | 图形 / Shape |
| --- | --- | --- | --- |
| <img src="chevron-down.svg" width="32" height="32" alt="Chevron down"> | `U+E20B` | [chevron-down.svg](chevron-down.svg) | 下箭头 / Chevron down |
| <img src="menu.svg" width="32" height="32" alt="Menu"> | `U+E20E` | [menu.svg](menu.svg) | 菜单 / Menu |
| <img src="heart.svg" width="32" height="32" alt="Heart"> | `U+E291` | [heart.svg](heart.svg) | 心形 / Heart |
| <img src="ring.svg" width="32" height="32" alt="Ring"> | `U+E603` | [ring.svg](ring.svg) | 环形 / Ring |
| <img src="delete.svg" width="32" height="32" alt="Trash"> | `U+E900` | [delete.svg](delete.svg) | 删除 / Trash |
| <img src="edit.svg" width="32" height="32" alt="Edit"> | `U+E901` | [edit.svg](edit.svg) | 编辑 / Edit |
| <img src="check.svg" width="32" height="32" alt="Check"> | `U+E902` | [check.svg](check.svg) | 勾选 / Check |
| <img src="loading.svg" width="32" height="32" alt="Loading dots"> | `U+E903` | [loading.svg](loading.svg) | 加载圆点 / Loading dots |
| <img src="transfer.svg" width="32" height="32" alt="Transfer arrows"> | `U+E904` | [transfer.svg](transfer.svg) | 上传下载 / Transfer arrows |
| <img src="close.svg" width="32" height="32" alt="Close"> | `U+E905` | [close.svg](close.svg) | 关闭 / Close |
| <img src="status.svg" width="32" height="32" alt="Dashboard"> | `U+E906` | [status.svg](status.svg) | 状态 / Dashboard |
| <img src="logout.svg" width="32" height="32" alt="Log out"> | `U+E907` | [logout.svg](logout.svg) | 退出 / Log out |
| <img src="network.svg" width="32" height="32" alt="Network"> | `U+E908` | [network.svg](network.svg) | 网络 / Network |
| <img src="services.svg" width="32" height="32" alt="Services"> | `U+E909` | [services.svg](services.svg) | 服务 / Services |
| <img src="system.svg" width="32" height="32" alt="System"> | `U+E90A` | [system.svg](system.svg) | 系统 / System |
| <img src="vpn.svg" width="32" height="32" alt="VPN"> | `U+E90B` | [vpn.svg](vpn.svg) | VPN |
| <img src="nas.svg" width="32" height="32" alt="Database"> | `U+E90C` | [nas.svg](nas.svg) | 存储服务 / NAS |
| <img src="bandwidth_monitor.svg" width="32" height="32" alt="Bandwidth monitor"> | `U+E90D` | [bandwidth_monitor.svg](bandwidth_monitor.svg) | 带宽监控 / Bandwidth monitor |
| <img src="hello-world.svg" width="32" height="32" alt="Hello world"> | `U+E90E` | [hello-world.svg](hello-world.svg) | Hello world |
| <img src="chevron-right.svg" width="32" height="32" alt="Chevron right"> | `U+E90F` | [chevron-right.svg](chevron-right.svg) | 右箭头 / Chevron right |
| <img src="password.svg" width="32" height="32" alt="Unlocked padlock"> | `U+E910` | [password.svg](password.svg) | 密码 / Unlocked padlock |
| <img src="docker.svg" width="32" height="32" alt="Docker"> | `U+E911` | [docker.svg](docker.svg) | Docker |
| <img src="control.svg" width="32" height="32" alt="Controls"> | `U+E912` | [control.svg](control.svg) | 控制 / Controls |
| <img src="statistics.svg" width="32" height="32" alt="Statistics"> | `U+E913` | [statistics.svg](statistics.svg) | 统计 / Statistics |
| <img src="asterisk.svg" width="32" height="32" alt="Asterisk"> | `U+E914` | [asterisk.svg](asterisk.svg) | 星号 / Asterisk |
| <img src="default.svg" width="32" height="32" alt="Package"> | `U+E915` | [default.svg](default.svg) | 默认图标（软件包） / Default (package) |
| <img src="user.svg" width="32" height="32" alt="User"> | `U+E971` | [user.svg](user.svg) | 用户 / User |
| <img src="help.svg" width="32" height="32" alt="Help"> | `U+F059` | [help.svg](help.svg) | 帮助 / Help |

---

### DEVELOPMENT (`docs/DEVELOPMENT.md`)

# Developing Argon 3.0

[简体中文](DEVELOPMENT_ZH.md) · [README](../README.md)

## Build with OpenWrt

From an OpenWrt build tree:

```sh
cd package
git clone https://github.com/jerrykuku/luci-theme-argon.git
cd ..
make menuconfig
# LuCI → Themes → luci-theme-argon
make package/luci-theme-argon/compile V=s
```

Theme settings are included. Select the nested `compat/luci-app-argon-config` package under LuCI applications only when building the migration package. Existing translation names remain `luci-i18n-argon-config-*`.

Release CI builds IPK with the OpenWrt 23.05.5 SDK and APK v3 with the 25.12.5 SDK. Ucode templates ship as source to avoid tying packages to one runtime's bytecode format.

Translations use `PKG_PO_VERSION` to follow the theme release, including `-r<revision>` for APK. IPK translations retain a `v` prefix (for example, `v3.0.1`) so ordinary installation upgrades the broken v3.0.0 `unknown` version. Keep that prefix in future IPK releases. CI reads each translation's internal package metadata and blocks artifact upload and publication if the version is wrong.

## Source map

| Location | Responsibility |
| --- | --- |
| `less/cascade.less` | Style entry point and import order |
| `less/theme.less` | Light/dark palette and semantic color tokens |
| `less/spacing.less`, `less/shape.less` | Spacing and corner tokens |
| `less/components/` | Shared controls, tables, tabs, dialogs and appearance menu |
| `less/pages/`, `less/page-fix.less` | LuCI/plugin adaptations and their import index |
| `less/responsive.less` | Viewport adaptations |
| `htdocs/luci-static/argon/` | Compiled CSS, images, fonts and SVG icons |
| `htdocs/luci-static/resources/` | Theme settings and LuCI JavaScript modules |
| `ucode/template/themes/argon/` | Login and application templates |
| `root/` | UCI defaults, RPC services, ACLs and integration files |
| `po/` | Argon Config translations |
| `tests/` | Behavior and integration checks |

## Styles

Edit LESS sources, then regenerate the committed stylesheet with LESS 4.1.3:

```sh
npm install less@4.1.3
lessc less/cascade.less htdocs/luci-static/argon/css/cascade.css
```

Light and dark modes share this one stylesheet. Each `@theme-palette` row in `theme.less` defines `role: light, dark;`; one value means both modes share it. Use semantic tokens for text, surfaces, borders and states. Legacy variable aliases exist for LuCI compatibility.

Imports run from tokens and base controls through login/application layout, shared components, page adaptations, and responsive rules. Add common behavior to its component module; keep plugin selectors in `pages/`. The `page-fix.less` file is an import index.

Maintain page/card insets and section, field, control and action gaps through spacing tokens. Small screens reduce outer and card insets to `1rem`. Keep long labels wrapping and let form controls shrink to their containers. Escape native CSS `min()` expressions when LESS would evaluate them prematurely.

Corner tokens cover labels, controls, panels, cards and dialogs. Keep the inside edges of joined controls square. Avoid clipping entire cards: dropdowns and tooltips can extend beyond them. Tables handle their own final-row corners and narrow-screen layout.

Preserve native LuCI structures and interactions. Tab bars join their following content containers; section content owns its vertical spacing. Modal actions wrap or stack as space requires, and long content scrolls through the overlay. Dropdown positioning and scrolling remain controlled by LuCI. Restrict hover effects to hover-capable devices and respect reduced motion.

## Templates

LuCI's `header`, `header_login`, `out_header_login`, `sysauth` and footer entry points remain available.

| Template | Responsibility |
| --- | --- |
| `head.ut` | Validated settings, metadata, styles and conditional application resources |
| `sysauth.ut` | Login layout and shared template assembly |
| `login_background.ut` | Wallpaper selection and image/video output |
| `login_form.ut` | Authentication fields, messages and plugin content |
| `page_scripts.ut` | Scripts shared by the footer entry points |

Pass local values through the second argument of `include`. Login pages do not load application LuCI modules. Only `classic` and `centered` are accepted as `login_style`; unknown values fall back to `classic`.

## Configuration and branding

Settings stay in `/etc/config/argon`; the settings route remains `/admin/system/argon-config`. Fresh installs use local backgrounds, classic login, 10px blur and 0.5 panel opacity. Existing options survive upgrades.

New installations derive dark colors from the primary seed. Existing explicit dark colors stay custom. Dark login glass settings can inherit the light values or keep independent overrides. Switching back to automatic/inherited settings retains custom values for later use.

The header appearance menu saves only its mode through `luci.argon_appearance`. The preference is device-wide and requires Argon write access. Keep this independent from pending form settings; failed saves reconcile with the stored mode.

Uploaded branding lives in `/www/luci-static/argon/branding/`; backgrounds live in `/www/luci-static/argon/background/`. Upload/reset operations apply immediately. Branding does not replace packaged images, and both directories are included in configuration-preserving upgrade backups. The browser icon also supplies the touch icon and manifest; existing home-screen shortcuts may need to be added again.

## Menu icons

Top-level menu nodes resolve `htdocs/luci-static/argon/icon/<node-name>.svg`, independently of translated titles. Filenames are case-sensitive and accept letters, digits, underscores and hyphens. Missing icons use `default.svg`.

Use monochrome SVGs with a `viewBox` and transparent background. CSS masks supply theme and interaction colors. Shared chevrons use the same 24×24 grid and 2px round strokes. See the [icon index](../htdocs/luci-static/argon/icon/README.md) for available assets. This mechanism is separate from uploaded browser icons and login logos.

## Checks

Use Node.js 22+, Python 3, LESS 4.1.3 and a Ucode build matching the supported OpenWrt runtime:

```sh
UCODE_BIN=/path/to/ucode sh .github/scripts/check_theme.sh
```

The script checks JavaScript, shell and Ucode syntax, verifies compiled CSS against LESS, and runs the Node/Python tests. CI's Ucode build is defined in [check.yml](../.github/workflows/check.yml).

For UI changes, check the actual affected LuCI pages in light/dark modes and desktop/mobile widths, including keyboard focus, long text and reduced motion where relevant. Network and hardware behavior still needs a suitable OpenWrt environment.

---

### DEVELOPMENT ZH (`docs/DEVELOPMENT_ZH.md`)

# Argon 3.0 开发说明

[English](DEVELOPMENT.md) · [返回 README](../README_ZH.md)

## 源码构建

在 OpenWrt 构建目录中执行：

```sh
cd package
git clone https://github.com/jerrykuku/luci-theme-argon.git
cd ..
make menuconfig
# LuCI → Themes → luci-theme-argon
make package/luci-theme-argon/compile V=s
```

主题设置已内置。仅在需要构建旧插件迁移包时，在 LuCI 应用中额外选择嵌套的 `compat/luci-app-argon-config` 包。语言包继续使用 `luci-i18n-argon-config-*` 名称。

发行 CI 使用 OpenWrt 23.05.5 SDK 构建 IPK、25.12.5 SDK 构建 APK v3。Ucode 模板保留源码，避免绑定某个运行时的字节码格式。

语言包通过 `PKG_PO_VERSION` 跟随主题发行版本，APK 包含 `-r<修订号>`。IPK 语言包固定使用 `v` 前缀（如 `v3.0.1`），使已安装的 v3.0.0 `unknown` 语言包可以直接正常升级；后续版本须保留该前缀。发布前会逐个读取语言包内部元数据，版本不符时阻止上传和发布。

## 目录

| 位置 | 用途 |
| --- | --- |
| `less/cascade.less` | 样式入口及导入顺序 |
| `less/theme.less` | 亮暗配色和语义颜色 token |
| `less/spacing.less`、`less/shape.less` | 间距及圆角 |
| `less/components/` | 通用控件、表格、标签页、弹窗、外观菜单 |
| `less/pages/`、`less/page-fix.less` | LuCI / 插件适配及导入索引 |
| `less/responsive.less` | 视口适配 |
| `htdocs/luci-static/argon/` | 编译后的 CSS、图片、字体和 SVG |
| `htdocs/luci-static/resources/` | 设置页与 LuCI JavaScript 模块 |
| `ucode/template/themes/argon/` | 登录页和后台模板 |
| `root/` | UCI 默认配置、RPC、ACL 及系统集成文件 |
| `po/` | Argon Config 翻译 |
| `tests/` | 行为与集成检查 |

## 样式

修改 LESS 源码后，使用 LESS 4.1.3 重新生成并一同提交 CSS：

```sh
npm install less@4.1.3
lessc less/cascade.less htdocs/luci-static/argon/css/cascade.css
```

亮暗色共用一份样式。`theme.less` 中 `@theme-palette` 每行以 `角色: 亮色, 暗色;` 定义颜色；单值表示两种模式共用。文字、背景、边框和状态使用各自语义 token；旧变量别名仅用于 LuCI 兼容。

导入顺序为 token、基础控件、登录与后台布局、共享组件、页面适配、响应式规则。通用行为放入对应组件模块，插件选择器放在 `pages/`；`page-fix.less` 只维护导入索引。

页面及卡片内缩、section、字段、控件与操作间距使用统一 token；小屏外边距及卡片内缩为 `1rem`。长文案允许换行，控件可收缩到容器宽度。LESS 会提前求值的原生 CSS `min()` 表达式需转义。

圆角 token 覆盖标签、控件、面板、卡片和弹窗；组合控件的内部接缝保持直角。不要裁切整个卡片，避免截断下拉菜单与提示框；表格自行处理末行圆角和窄屏布局。

保留 LuCI 原生结构和交互：标签栏与相邻内容容器衔接，section 内容负责纵向间距；弹窗操作随空间换行或堆叠，长正文通过覆盖层滚动。下拉位置和滚动继续由 LuCI 控制。悬浮效果仅用于支持 hover 的设备，并尊重减少动画偏好。

## 模板

保留 LuCI 的 `header`、`header_login`、`out_header_login`、`sysauth` 和页脚入口。

| 模板 | 用途 |
| --- | --- |
| `head.ut` | 配置校验、元信息、样式及后台资源加载 |
| `sysauth.ut` | 登录布局和模板组装 |
| `login_background.ut` | 壁纸选择及图片 / 视频输出 |
| `login_form.ut` | 认证字段、提示和插件内容 |
| `page_scripts.ut` | 页脚共用脚本 |

通过 `include` 的第二个参数传递局部数据。登录页不加载后台 LuCI 模块。`login_style` 仅接受 `classic`、`centered`，其他值回退为 `classic`。

## 配置与品牌资源

配置保存在 `/etc/config/argon`，设置地址仍为 `/admin/system/argon-config`。首次安装采用本地背景、经典登录、10px 模糊和 0.5 透明度；升级保留已有选项。

新安装根据主色自动生成暗色配色，已有独立暗色主色保留为自定义。暗色登录面板可跟随亮色或单独配置；切回自动 / 跟随时仍保留自定义值。

顶部外观菜单通过 `luci.argon_appearance` 单独保存模式，对整个设备生效，需要 Argon 写权限。保持与未保存表单设置独立；保存失败时核对服务端已保存值。

自定义图标位于 `/www/luci-static/argon/branding/`，背景位于 `/www/luci-static/argon/background/`。上传 / 恢复立即生效，不覆盖内置文件；两个目录均纳入保留配置升级的备份。网站图标也用于 touch icon 和 manifest，已有手机桌面快捷方式可能需要重新添加。

## 菜单图标

一级菜单按节点名查找 `htdocs/luci-static/argon/icon/<节点名>.svg`，与翻译后的标题无关。文件名区分大小写，支持字母、数字、下划线和连字符；缺失时使用 `default.svg`。

使用透明背景、带 `viewBox` 的单色 SVG，CSS mask 负责主题与交互颜色。共享箭头使用 24×24 网格、2px 圆角描边。资源见 [SVG 图标索引](../htdocs/luci-static/argon/icon/README.md)，与用户上传的网站图标 / 登录 Logo 独立。

## 检查

准备 Node.js 22+、Python 3、LESS 4.1.3，以及与目标 OpenWrt 运行时匹配的 Ucode：

```sh
UCODE_BIN=/path/to/ucode sh .github/scripts/check_theme.sh
```

脚本检查 JavaScript、Shell、Ucode 语法，核对 LESS 与 CSS 产物，并运行 Node / Python 测试。CI 的 Ucode 构建步骤见 [check.yml](../.github/workflows/check.yml)。

UI 改动应检查实际受影响页面的亮暗色、桌面与窄屏，以及相关的键盘焦点、长文本和减少动画场景。网络和硬件行为仍需相应 OpenWrt 环境验证。

---

--- METRICS ---
- Files Extracted: 5
- Estimated Token Budget: ~5733 tokens
- Canonical Reference: https://codewiki.google/github.com/jerrykuku/luci-theme-argon
