Files
small-packages/luci-theme-footstrap
2026-10-26 06:14:13 +08:00
..
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00
2026-10-26 06:14:13 +08:00

luci-theme-footstrap (the package)

A LuCI theme for OpenWrt 24.10.3 and newer (ucode templates). Installing and using it: the repository README. Developer documentation: ../docs/.

Internal name: footstrap. Media path: /luci-static/footstrap.

One theme, one entry

luci.themes carries exactly one entry, Footstrap → /luci-static/footstrap. Layout (top bar by default, or the side menu), mode, palette, density, wallpaper, rounding and every colour — accent, the three status colours, the four surfaces — are client axes on the System → Footstrap page: localStorage plus attributes and inline properties on :root, and nothing is written to the router until "Save as default" is pressed. There are no per-layout or per-mode themes.

There is one menu renderer too, renderMainMenu in fs-chrome.js. The top bar is its own markup, morphed by CSS through :root[data-layout]. No second template, no second renderer, no footstrap-top symlink.

The theme's boundary: it supplies the chrome and the design language; page content is drawn by the view JS of luci-mod-*. The one exception is fs-overview.js, which draws no content of its own and only re-arranges the stock overview sections.

Layout

Makefile                          luci.mk; LUCI_MINIFY_CSS:=0; Build/Prepare (CSS, mangle, strip,
                                  version)
styles/                           CSS SOURCE: layers tokens / base / theme / pages
build-css.sh                      styles/ → htdocs/luci-static/footstrap/cascade.css
mangle-tokens.sh                  shorten the private --fs-* names in a built sheet, then join it to one line
strip-build.sh                    build-tree strip, one mode each: templates, shell, assets
po/                               translation catalogue (Weblate translates this)
ucode/template/themes/footstrap/  header.ut, footer.ut, sysauth.ut, partials/
htdocs/luci-static/footstrap/     cascade.css (generated), logo.svg — no webfonts, and no
                                  wallpaper: the Pattern is one the admin uploads, and a font
                                  is one the admin installs (repo: fonts/set-font.sh)
htdocs/luci-static/resources/     menu-footstrap.js (footer entry), menu-footstrap-common.js,
                                  fs-{fit,menutree,prefs,widgets,chrome,router,sheets,search,
                                  select,appearance,assets,axes,version,overview}.js
root/etc/uci-defaults/            registration and the upload symlinks
root/usr/share/rpcd/acl.d/        ACL: uci footstrap (Save as default) + login-background and pattern uploads

There is no update checker: the theme is installed from the package feed (install.sh adds it), so apk upgrade / opkg upgrade carries it forward like everything else on the router. The System → Footstrap page shows the version it is running and makes no network call to do it.

Do not edit cascade.css — it is generated by build-css.sh from styles/ and is gitignored. Colours go in styles/03-palettes.css, scales and tokens in styles/02-tokens.css.

Working on a router

The normal dev stand is the disposable routers ../owlab.yaml defines, driven by owlab — see ../docs/development.md. dev-sync.sh targets a hardware router over ssh:

./dev-sync.sh          # push to `ssh router` (registers the theme but does NOT activate it)
ssh router 'uci set luci.main.mediaurlbase=/luci-static/footstrap; uci commit luci; rm -f /tmp/luci-indexcache*'
ssh router 'uci set luci.main.mediaurlbase=/luci-static/bootstrap; uci commit luci'   # roll back

Before pushing, see ../docs/verifying.md. The rules and the traps are in ../docs/conventions.md; packaging is in ../docs/package.md.