🚀 Sync 2026-09-03 03:25:04

This commit is contained in:
github-actions[bot] committed 2026-09-03 03:25:04 +08:00
1 parent 351528cefe
commit 4ee3788dd4
17 files changed
+243 -41

No files matched your search

@@ -289,6 +289,49 @@ function parse_ss_subflows(raw, endpoints)
return subflows
end
-- Live per-subflow TCP metrics preferring omr-sockdiag -- a raw
-- NETLINK_SOCK_DIAG/INET_DIAG query of the kernel's tcp_info straight off
-- the socket (see the omr-sockdiag package) -- over parsing "ss -tin" text.
-- Same preference order omr-metrics' 040-metrics post-tracking hook already
-- uses for its own per-WAN subflow collection. omr-sockdiag already emits
-- JSON with the field names this table already uses, so there is no text
-- parsing left to do here at all, only the same WAN attribution
-- parse_ss_subflows does above (a connection's local_ip matched against the
-- endpoints list -- omr-sockdiag has no MPTCP awareness of its own, it only
-- knows sockets).
--
-- Returns nil when the output is not usable, so the caller can fall back to
-- parse_ss_subflows. omr-sockdiag itself prints "[]" both when no sockets
-- match and when the kernel query cannot be opened; if endpoints exist, let
-- the ss fallback disambiguate that case instead of hiding live subflows.
function parse_sockdiag_subflows(raw, endpoints)
local ok, rows = pcall(jsonc.parse, raw or "")
if not ok or type(rows) ~= "table" then return nil end
if #rows == 0 and #endpoints > 0 then return nil end
local by_addr = {}
for _, ep in ipairs(endpoints) do by_addr[ep.address] = ep end
local subflows = {}
for _, row in ipairs(rows) do
local ep = by_addr[row.local_ip]
if ep then
subflows[#subflows + 1] = {
dev = ep.dev, endpoint_id = ep.id, backup = ep.backup,
local_ip = row.local_ip, local_port = row.local_port,
remote_ip = row.remote_ip, remote_port = row.remote_port,
cwnd = row.cwnd, ssthresh = row.ssthresh,
rtt = row.rtt, rttvar = row.rttvar, min_rtt = row.min_rtt,
retrans = row.retrans, retrans_total = row.retrans_total,
bytes_sent = row.bytes_sent, bytes_acked = row.bytes_acked,
bytes_retrans = row.bytes_retrans, bytes_received = row.bytes_received,
pacing_rate = row.pacing_rate, delivery_rate = row.delivery_rate,
}
end
end
return subflows
end
-- Per-WAN endpoint cross-check: for every interface the router considers
-- multipath-enabled, is its device actually registered as an MPTCP
-- endpoint? If not, that WAN can never carry an MPTCP subflow no matter
@@ -839,7 +882,10 @@ local methods = {
for _, w in ipairs(wans) do
if w.device ~= "" then dev_to_name[w.device] = w.name end
end
local subflows = parse_ss_subflows(exec_output("ss -tin 2>/dev/null"), endpoints)
local subflows = parse_sockdiag_subflows(exec_output("omr-sockdiag 2>/dev/null"), endpoints)
if not subflows then
subflows = parse_ss_subflows(exec_output("ss -tin 2>/dev/null"), endpoints)
end
for _, sf in ipairs(subflows) do
sf.wan = dev_to_name[sf.dev] or sf.dev
end
+1 -1
View File
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.9.2
PKG_RELEASE:=108
PKG_RELEASE:=109
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
@@ -1838,7 +1838,7 @@ function gen_config(var)
end
end
end
if dns_outboundTag == "blackhole" then
if value.outboundTag == "blackhole" then
table.insert(dns_out_rules, {
action = "return",
rCode = 0,
+3 -3
View File
@@ -18,12 +18,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-proto-wwand
PKG_RELEASE:=5
PKG_RELEASE:=6
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/ddimension/luci-proto-wwand.git
PKG_SOURCE_VERSION:=35f0323f5621eb06e69991f5819ff53e4ca8cc7a
PKG_SOURCE_DATE:=2026-08-31
PKG_SOURCE_VERSION:=cc0bbfe522c7bc941a25f1ad14dfb2874660311b
PKG_SOURCE_DATE:=2026-09-02
PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL-2.0-only
+1 -1
View File
@@ -17,7 +17,7 @@ LUCI_NAME:=luci-theme-footstrap
FOOTSTRAP_VERSION?=
ifneq ($(FOOTSTRAP_VERSION),)
PKG_VERSION:=$(FOOTSTRAP_VERSION)
PKG_RELEASE:=53
PKG_RELEASE:=54
endif
LUCI_TITLE:=Footstrap Theme
@@ -763,9 +763,19 @@ function build() {
]);
}
/* This tab is mounted in the stock System form, so LuCI's own Save & Apply footer sits under a
* page it does not save — asked on the forum, topic 251930. Above the first section, because
* the misreading happens before anyone scrolls to Defaults. A bare `.alert-message`:
* theme/35-alerts.css keeps the tinted variants for a STATUS and a flat panel for a note. */
const note = E('div', { 'class': 'alert-message fs-ap-note' }, [
E('p', {}, [ _('Changes apply at once and live in this browser.', 'footstrap') ]),
E('p', {}, [ _('To keep them on the router, use Save as default under Defaults — not Save & Apply at the foot of the page.', 'footstrap') ])
]);
/* Colours and Surfaces are one fold: the same job, split into two headings only because a
* figure and the sheet it sits on are read differently */
const page = E('div', { 'class': 'fs-ap' }, [
note,
section(_('Interface', 'footstrap'), shell),
foldable(_('Colours', 'footstrap'),
colours.concat([ E('div', { 'class': 'fs-ap-head fs-ap-sub' }, [ E('h4', {}, [ _('Surfaces', 'footstrap') ]) ]) ], surfaces),
+41 -8
View File
@@ -35,7 +35,7 @@ msgctxt "footstrap"
msgid "Auto-collapse"
msgstr "Colapso automático"
#: htdocs/luci-static/resources/fs-appearance.js:773
#: htdocs/luci-static/resources/fs-appearance.js:783
msgctxt "footstrap"
msgid "Background"
msgstr "Fondo"
@@ -55,6 +55,11 @@ msgctxt "footstrap"
msgid "Cards"
msgstr "Tarjetas"
#: htdocs/luci-static/resources/fs-appearance.js:771
msgctxt "footstrap"
msgid "Changes apply at once and live in this browser."
msgstr "Los cambios se aplican al instante y viven en este navegador."
#: htdocs/luci-static/resources/fs-appearance.js:454
msgctxt "footstrap"
msgid "Choose SVG"
@@ -70,13 +75,13 @@ msgctxt "footstrap"
msgid "Clearly visible %s"
msgstr "Bien visible %s"
#: htdocs/luci-static/resources/fs-chrome.js:430
#: htdocs/luci-static/resources/fs-chrome.js:447
#: ucode/template/themes/footstrap/header.ut:138
msgid "Collapse menu"
msgstr "Contraer menú"
#: htdocs/luci-static/resources/fs-appearance.js:465
#: htdocs/luci-static/resources/fs-appearance.js:770
#: htdocs/luci-static/resources/fs-appearance.js:780
msgctxt "footstrap"
msgid "Colours"
msgstr "Colores"
@@ -123,7 +128,7 @@ msgctxt "footstrap"
msgid "Dark"
msgstr "Oscuro"
#: htdocs/luci-static/resources/fs-appearance.js:774
#: htdocs/luci-static/resources/fs-appearance.js:784
msgctxt "footstrap"
msgid "Defaults"
msgstr "Predeterminados"
@@ -143,7 +148,7 @@ msgctxt "footstrap"
msgid "Easy to read %s"
msgstr "Se lee bien %s"
#: htdocs/luci-static/resources/fs-chrome.js:430
#: htdocs/luci-static/resources/fs-chrome.js:447
msgid "Expand menu"
msgstr "Expandir menú"
@@ -179,7 +184,7 @@ msgctxt "footstrap"
msgid "Hard to read %s — large text only"
msgstr "Se lee mal %s: solo texto grande"
#: htdocs/luci-static/resources/fs-appearance.js:769
#: htdocs/luci-static/resources/fs-appearance.js:779
msgctxt "footstrap"
msgid "Interface"
msgstr "Interfaz"
@@ -397,7 +402,7 @@ msgctxt "footstrap"
msgid "Submenus"
msgstr "Submenús"
#: htdocs/luci-static/resources/fs-appearance.js:771
#: htdocs/luci-static/resources/fs-appearance.js:781
msgctxt "footstrap"
msgid "Surfaces"
msgstr "Superficies"
@@ -410,7 +415,7 @@ msgstr "Sistema"
msgid "System running in recovery (initramfs) mode."
msgstr "El sistema se está ejecutando en modo de recuperación (initramfs)."
#: htdocs/luci-static/resources/fs-select.js:647
#: htdocs/luci-static/resources/fs-select.js:662
msgid "Table"
msgstr "Tabla"
@@ -492,6 +497,15 @@ msgctxt "footstrap"
msgid "Tint strength"
msgstr "Intensidad del tinte"
#: htdocs/luci-static/resources/fs-appearance.js:772
msgctxt "footstrap"
msgid ""
"To keep them on the router, use Save as default under Defaults — not Save & "
"Apply at the foot of the page."
msgstr ""
"Para guardarlos en el router, usa «Guardar como predeterminado» en "
"Predeterminados, no «Guardar y aplicar» al pie de la página."
#: htdocs/luci-static/resources/fs-appearance.js:190
msgctxt "footstrap"
msgid "Too faint to read %s"
@@ -558,6 +572,25 @@ msgid ""
"the uploaded file could not be removed either; it is still on the router."
msgstr "tampoco se pudo eliminar el archivo subido; sigue en el router."
#~ msgctxt "footstrap"
#~ msgid ""
#~ "Everything here applies the moment you change it and is remembered in "
#~ "this browser only — the Save & Apply button at the foot of the page "
#~ "belongs to the System form and does not store it."
#~ msgstr ""
#~ "Todo lo de aquí se aplica en el momento en que lo cambias y se recuerda "
#~ "solo en este navegador: el botón «Guardar y aplicar» del pie de la página "
#~ "pertenece al formulario del Sistema y no lo guarda."
#~ msgctxt "footstrap"
#~ msgid ""
#~ "To make the current look the router's default for every browser, use Save "
#~ "as default under Defaults below."
#~ msgstr ""
#~ "Para que el aspecto actual sea el predeterminado del router para todos "
#~ "los navegadores, usa «Guardar como predeterminado» en Predeterminados más "
#~ "abajo."
#~ msgid "Loading view…"
#~ msgstr "Cargando vista…"
+40 -8
View File
@@ -31,7 +31,7 @@ msgctxt "footstrap"
msgid "Auto-collapse"
msgstr "Сворачивать"
#: htdocs/luci-static/resources/fs-appearance.js:773
#: htdocs/luci-static/resources/fs-appearance.js:783
msgctxt "footstrap"
msgid "Background"
msgstr "Фон"
@@ -51,6 +51,11 @@ msgctxt "footstrap"
msgid "Cards"
msgstr "Карточки"
#: htdocs/luci-static/resources/fs-appearance.js:771
msgctxt "footstrap"
msgid "Changes apply at once and live in this browser."
msgstr "Изменения применяются сразу и живут в этом браузере."
#: htdocs/luci-static/resources/fs-appearance.js:454
msgctxt "footstrap"
msgid "Choose SVG"
@@ -66,13 +71,13 @@ msgctxt "footstrap"
msgid "Clearly visible %s"
msgstr "Хорошо видна %s"
#: htdocs/luci-static/resources/fs-chrome.js:430
#: htdocs/luci-static/resources/fs-chrome.js:447
#: ucode/template/themes/footstrap/header.ut:138
msgid "Collapse menu"
msgstr "Свернуть меню"
#: htdocs/luci-static/resources/fs-appearance.js:465
#: htdocs/luci-static/resources/fs-appearance.js:770
#: htdocs/luci-static/resources/fs-appearance.js:780
msgctxt "footstrap"
msgid "Colours"
msgstr "Цвета"
@@ -117,7 +122,7 @@ msgctxt "footstrap"
msgid "Dark"
msgstr "Тёмная"
#: htdocs/luci-static/resources/fs-appearance.js:774
#: htdocs/luci-static/resources/fs-appearance.js:784
msgctxt "footstrap"
msgid "Defaults"
msgstr "Умолчания"
@@ -137,7 +142,7 @@ msgctxt "footstrap"
msgid "Easy to read %s"
msgstr "Хорошо читается %s"
#: htdocs/luci-static/resources/fs-chrome.js:430
#: htdocs/luci-static/resources/fs-chrome.js:447
msgid "Expand menu"
msgstr "Развернуть меню"
@@ -173,7 +178,7 @@ msgctxt "footstrap"
msgid "Hard to read %s — large text only"
msgstr "Плохо читается %s — только крупный текст"
#: htdocs/luci-static/resources/fs-appearance.js:769
#: htdocs/luci-static/resources/fs-appearance.js:779
msgctxt "footstrap"
msgid "Interface"
msgstr "Интерфейс"
@@ -390,7 +395,7 @@ msgctxt "footstrap"
msgid "Submenus"
msgstr "Подменю"
#: htdocs/luci-static/resources/fs-appearance.js:771
#: htdocs/luci-static/resources/fs-appearance.js:781
msgctxt "footstrap"
msgid "Surfaces"
msgstr "Поверхности"
@@ -403,7 +408,7 @@ msgstr "Система"
msgid "System running in recovery (initramfs) mode."
msgstr "Система работает в режиме восстановления (initramfs)."
#: htdocs/luci-static/resources/fs-select.js:647
#: htdocs/luci-static/resources/fs-select.js:662
msgid "Table"
msgstr "Таблица"
@@ -485,6 +490,15 @@ msgctxt "footstrap"
msgid "Tint strength"
msgstr "Насыщенность оттенка"
#: htdocs/luci-static/resources/fs-appearance.js:772
msgctxt "footstrap"
msgid ""
"To keep them on the router, use Save as default under Defaults — not Save & "
"Apply at the foot of the page."
msgstr ""
"Чтобы сохранить их на роутере, нажмите «Сохранить по умолчанию» в разделе «По "
"умолчанию», а не «Сохранить и применить» внизу страницы."
#: htdocs/luci-static/resources/fs-appearance.js:190
msgctxt "footstrap"
msgid "Too faint to read %s"
@@ -551,6 +565,24 @@ msgid ""
"the uploaded file could not be removed either; it is still on the router."
msgstr "загруженный файл тоже не удалось удалить — он остался на роутере."
#~ msgctxt "footstrap"
#~ msgid ""
#~ "Everything here applies the moment you change it and is remembered in "
#~ "this browser only — the Save & Apply button at the foot of the page "
#~ "belongs to the System form and does not store it."
#~ msgstr ""
#~ "Всё на этой странице применяется в момент изменения и запоминается только "
#~ "в этом браузере — кнопка «Сохранить и применить» внизу страницы "
#~ "принадлежит форме «Система» и настройки внешнего вида не сохраняет."
#~ msgctxt "footstrap"
#~ msgid ""
#~ "To make the current look the router's default for every browser, use Save "
#~ "as default under Defaults below."
#~ msgstr ""
#~ "Чтобы текущий вид стал умолчанием роутера для всех браузеров, нажмите "
#~ "«Сохранить по умолчанию» в разделе «По умолчанию» ниже."
#~ msgid "Loading view…"
#~ msgstr "Загрузка представления…"
@@ -25,7 +25,7 @@ msgctxt "footstrap"
msgid "Auto-collapse"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:773
#: htdocs/luci-static/resources/fs-appearance.js:783
msgctxt "footstrap"
msgid "Background"
msgstr ""
@@ -45,6 +45,11 @@ msgctxt "footstrap"
msgid "Cards"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:771
msgctxt "footstrap"
msgid "Changes apply at once and live in this browser."
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:454
msgctxt "footstrap"
msgid "Choose SVG"
@@ -60,13 +65,13 @@ msgctxt "footstrap"
msgid "Clearly visible %s"
msgstr ""
#: htdocs/luci-static/resources/fs-chrome.js:430
#: htdocs/luci-static/resources/fs-chrome.js:447
#: ucode/template/themes/footstrap/header.ut:138
msgid "Collapse menu"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:465
#: htdocs/luci-static/resources/fs-appearance.js:770
#: htdocs/luci-static/resources/fs-appearance.js:780
msgctxt "footstrap"
msgid "Colours"
msgstr ""
@@ -111,7 +116,7 @@ msgctxt "footstrap"
msgid "Dark"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:774
#: htdocs/luci-static/resources/fs-appearance.js:784
msgctxt "footstrap"
msgid "Defaults"
msgstr ""
@@ -131,7 +136,7 @@ msgctxt "footstrap"
msgid "Easy to read %s"
msgstr ""
#: htdocs/luci-static/resources/fs-chrome.js:430
#: htdocs/luci-static/resources/fs-chrome.js:447
msgid "Expand menu"
msgstr ""
@@ -165,7 +170,7 @@ msgctxt "footstrap"
msgid "Hard to read %s — large text only"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:769
#: htdocs/luci-static/resources/fs-appearance.js:779
msgctxt "footstrap"
msgid "Interface"
msgstr ""
@@ -380,7 +385,7 @@ msgctxt "footstrap"
msgid "Submenus"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:771
#: htdocs/luci-static/resources/fs-appearance.js:781
msgctxt "footstrap"
msgid "Surfaces"
msgstr ""
@@ -393,7 +398,7 @@ msgstr ""
msgid "System running in recovery (initramfs) mode."
msgstr ""
#: htdocs/luci-static/resources/fs-select.js:647
#: htdocs/luci-static/resources/fs-select.js:662
msgid "Table"
msgstr ""
@@ -469,6 +474,13 @@ msgctxt "footstrap"
msgid "Tint strength"
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:772
msgctxt "footstrap"
msgid ""
"To keep them on the router, use Save as default under Defaults — not Save & "
"Apply at the foot of the page."
msgstr ""
#: htdocs/luci-static/resources/fs-appearance.js:190
msgctxt "footstrap"
msgid "Too faint to read %s"
+34 -2
View File
@@ -18,8 +18,8 @@
* pre-paint switch in partials/head.ut (a router default outside the whitelist becomes
* '' and the page paints in the default palette), the label map in fs-appearance.js (an
* unnamed palette is missing from the picker, not broken), and matrix() in
* tools/lib/gallery.mjs — a palette absent there is one export-tier.mjs and
* a11y-gallery.mjs never measure, so it ships ungated.
* tools/lib/gallery.mjs — a palette absent there is one export-tier.mjs,
* a11y-gallery.mjs and placeholder-ink.mjs never measure, so it ships ungated.
* Nothing else: layout, components and the --*-color-* export bridge key off these tokens, and
* every tint, shadow and hairline is a color-mix() over them.
*
@@ -99,6 +99,26 @@
--fs-good: var(--fs-good-base);
--fs-warn: var(--fs-warn-base);
--fs-danger: var(--fs-danger-base);
/* The ink of a value that is NOT there — the `placeholder` attribute and the dropdown's
* `li[placeholder]` row. LuCI writes an option's DEFAULT there (`form.Value.placeholder`:
* 128 for the log buffer, 514 for the log port), so an ink that reads as body text tells
* the reader a field is set when it is empty — reported against 0.14.8, forum topic 251930
* posts 82-83. --fs-dim was that ink and is not far enough away: on footstrap light's
* --fs-panel2 it measures 11.12:1 against the text's 14.84:1, which is two blacks.
*
* Derived, not hand-listed per palette, so it follows a palette that has not been written
* yet. The formula is spelt once and the STRENGTH is a token of its own, because it is the
* only part that varies — per mode here, and again under prefers-contrast:more
* (theme/95-a11y-media.css); restating the whole mix in each of those four places cost 79 B
* of shipped sheet and gave three more copies to keep in step. That is also why it lives
* here rather than in 02-tokens.css's ladder — the same reason --fs-accent-soft does.
*
* Light lands at 3.99-4.48:1 across the four palettes, 43-44% of the way from the value's
* ink to the field: under AA on purpose, see the dark half below for the whole argument.
* oklch because the step is a LIGHTNESS one — srgb at the same 55% stops at 3.58:1. Held by
* `npm run placeholder`. */
--fs-placeholder-mix: 55%;
--fs-placeholder: color-mix(in oklch, var(--fs-text) var(--fs-placeholder-mix), var(--fs-panel2));
/* The hues the user picked, in degrees. Declared here and not only inline by
* head.ut/fs-prefs.js, so the stylesheet stands on its own: a var() with no definition
* anywhere is invalid at computed-value time and takes the whole declaration down. */
@@ -158,6 +178,18 @@
:root[data-darkmode="true"] {
--fs-tint-c: calc((.011 + .016 * max(0, cos((var(--fs-tint-h) - 258) * 1deg))
- .004 * max(0, cos((var(--fs-tint-h) - 55) * 1deg))) * var(--fs-tint-strength));
/* 64%, against the 55% above, and the difference is what a dark palette can afford: its ink
* starts at 6.45:1 on --fs-panel2 where the light one has 14.84:1, so the same percentage
* would buy a hint nobody can read. It lands at 3.43-6.05:1, 33-35% of the range.
*
* BOTH modes ship below AA, and that is the decision this token exists to record: a hint
* mistaken for a value makes a reader configure the wrong thing, while a hint at 3.43:1
* makes them look twice. The AA-clearing mixes (62/80%) were measured first and moved only
* 37% and 20% of the range — the same fault, quieter. 3:1 (SC 1.4.11, and SC 1.4.3's
* large-text floor) is the line NOT crossed, worst 3.43:1; prefers-contrast:more buys the
* AA ink back in both modes (theme/95-a11y-media.css); and `placeholder-ink` holds all
* three states, axe-core being excluded from this row for the same reason. */
--fs-placeholder-mix: 64%;
}
:root[data-tint="hue"] { --fs-bg: oklch(from var(--fs-bg-base) l var(--fs-tint-c) var(--fs-tint-h)); }
@@ -9,7 +9,7 @@
* — `background: var(--fs-good-soft)` becomes invalid at computed-value time and computes to
* `unset`, which is `initial` for a non-inherited property. IACVT does not fall back to an earlier
* declaration in the same block, so the two-declaration trick that works for `background:
* color-mix(…)` written literally does nothing for a token. 38 tokens are affected; without this
* color-mix(…)` written literally does nothing for a token. 36 tokens are affected; without this
* block a browser below the floor paints borders in currentcolor and loses every soft surface.
*
* color-mix() lands in Chrome 111, Firefox 113 and Safari 16.2 (all 2022-2023). See docs/css.md
@@ -62,6 +62,12 @@
* take the fixed dialog scrim. Losing it entirely would leave login text over a photo. */
--fs-photo-scrim: var(--fs-scrim);
/* placeholder ink: the quietest ink the palette states outright. Below the floor the
* hint is back to reading like a value, which is the pre-0.14.9 look and still the
* safer degradation — an unresolvable token takes `color` down to `unset`, and an
* inherited near-black placeholder over a light field beats an unstyled one. */
--fs-placeholder: var(--fs-faint);
/* export tier — third-party apps read these, so they must resolve to something.
* -medium keeps the hue, -low degrades to the dim text colour it was mixed toward. */
--border-color-high: var(--fs-border);
@@ -173,8 +173,10 @@
/* Checkbox/radio drawing: theme/60-inputs.css — absorbed whole (it undoes the generic input
* box, which lives there now). */
/* --fs-placeholder, not --fs-dim: a placeholder carries the option's DEFAULT and must not read
* as a value the reader typed (03-palettes.css has the numbers). */
::placeholder {
color: var(--fs-dim);
color: var(--fs-placeholder);
}
/* Transitions and the focus/hover ring are the theme's one ring token (--fs-focus-ring /
@@ -12,6 +12,11 @@
* the only page that draws it: an axis control is not chrome. */
.fs-ap { display: flex; flex-direction: column; gap: var(--fs-space-5); }
/* The page note (fs-appearance.js). Only the outer margins: `.alert-message p` carries
* --fs-space-1 top and bottom, which at the box's own edges adds to the panel's padding and
* makes a two-sentence note look loose against every other alert on the theme. */
.fs-ap-note p:first-child { margin-top: 0; }
.fs-ap-note p:last-child { margin-bottom: 0; }
/* Grouping headings INSIDE the tab pane, not cards: the pane is already inside the stock
* .cbi-section card, and a second border around each group is a box in a box. A hairline above
* each group does the same job — except for the first, which sits under the tab strip. */
@@ -98,8 +98,8 @@
.cbi-dropdown.cbi-button > .open {
margin-inline-start: .5em;
}
/* display only: the placeholder's ink is the theme's own `li[placeholder]` --fs-faint below
* (base's --fs-dim had already lost to it by layer — moving it would recolour the row) */
/* display only: the placeholder's ink is the theme's own `li[placeholder]` --fs-placeholder
* below — the same token base/30-forms.css gives the attribute */
.cbi-dropdown:not(.btn):not(.cbi-button) > ul > li[placeholder] {
display: none;
}
@@ -246,7 +246,16 @@
.cbi-dropdown > ul > li > form,
.cbi-dropdown > ul > li label { font-family: inherit; }
.cbi-dropdown:not(.btn):not(.cbi-button) > ul > li[display]:not([display="0"]) { border-inline-start: 0; }
.cbi-dropdown > ul > li[placeholder] { color: var(--fs-faint); }
/* The same ink the `placeholder` attribute takes in base/30-forms.css — "-- Please choose --" is
* the absence of a value, not one.
*
* It repeats the row rule's two selectors instead of writing `> ul > li[placeholder]` once,
* because that shorter form (0,2,2) LOSES to the row's own `color: var(--fs-text)` (0,3,2) and
* the placeholder row rendered in the value's ink on every form dropdown — dead from the day it
* was written, and only visible once `placeholder-ink` measured the row. Each selector here
* out-specifies its counterpart above: (0,4,2) over (0,3,2), (0,3,2) over (0,2,2). */
.cbi-dropdown:not(.btn):not(.cbi-button) > ul > li[placeholder],
.cbi-dropdown > ul.dropdown > li[placeholder] { color: var(--fs-placeholder); }
/* the multiselect's inline filter/create inputs — moved from base with the generic `input`
* box in theme/60-inputs.css: in base these beat it in-layer, left behind they would lose
* to it by layer and render as free-standing 210px fields inside the open list */
@@ -55,7 +55,10 @@
font-family: inherit; font-size: var(--fs-type-lg); font-weight: var(--fs-weight); line-height: 1.4;
}
.fs-search-row .fs-search-input:focus { outline: none; box-shadow: none; }
.fs-search-row .fs-search-input::placeholder { color: var(--fs-faint); font-weight: var(--fs-weight); }
/* one placeholder ink for the whole theme (03-palettes.css) — this row is not measured by
* `placeholder-ink`, the gallery having no search dialog, and must not drift from the fields
* that are */
.fs-search-row .fs-search-input::placeholder { color: var(--fs-placeholder); font-weight: var(--fs-weight); }
.fs-search-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--fs-space-1-5); }
@@ -52,6 +52,13 @@
* measures rather than takes on trust: below 80 the fainter ink drops under AA on footstrap
* dark's --fs-panel2 (4.51:1 at 80), above 82 the high-to-low ramp falls under the 0.10
* spread the tier promises (0.098 at 84); 82 clears both, at 4.68:1 and 0.110.
* - --fs-placeholder, in BOTH modes. It is the one token the theme ships deliberately under AA
* (3.99-4.48:1 light, 3.43-6.05:1 dark): a hint has to move far enough not to read as a
* typed value, and a dark palette has only 6.45:1 of ink to spend. A reader who asked the OS
* for more contrast has said which of the two they want, so the mixes go back to the
* AA-clearing 62% and 80% — 4.98:1 and 4.61:1, at 37% and 20% of the ink-to-field range
* instead of 44% and 34%. Only --fs-placeholder-mix moves: the mix itself is spelt once, in
* 03-palettes.css. `placeholder-ink` measures this pass as well.
* - the focus ring: --fs-focus-ring is a tint of the accent (--fs-accent-soft, 10% light and
* 15% dark), so at "more contrast" it carries the accent at 60% instead. Its sibling
* --fs-focus-ring-solo is already the solid accent and needs no restatement here. */
@@ -65,7 +72,12 @@
--fs-good-line: var(--fs-good); --fs-good-line-hi: var(--fs-good);
--fs-warn-line: var(--fs-warn); --fs-warn-line-hi: var(--fs-warn);
--fs-danger-line: var(--fs-danger); --fs-danger-line-hi: var(--fs-danger);
/* the placeholder is the one token shipped under AA (see the note above); this reader
* asked for contrast, so both modes buy the AA ink back, at the percentages that clear
* it. Light here, dark in the block below — per mode exactly as in 03-palettes.css. */
--fs-placeholder-mix: 62%;
}
:root[data-darkmode="true"] { --fs-placeholder-mix: 80%; }
}
/* forced-colors (Windows High Contrast) — the OS replaces every colour the theme picked, and
+2 -2
View File
@@ -43,12 +43,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=wwand
PKG_RELEASE:=18
PKG_RELEASE:=19
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git
PKG_SOURCE_VERSION:=fb4a8ff34967a5ae1d6e882dcd78b8339f5f99d1
PKG_SOURCE_DATE:=2026-08-31
PKG_SOURCE_DATE:=2026-09-02
PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL-2.0-only