The whole appliance UI is now configuration for a desktop Debian already ships: a Plasma 6.3 session with a colour scheme, a look and feel package that builds the bar, window rules, and KDE's own Kiosk restrictions. Two things were measured rather than assumed, and both changed a decision. Plasma restarts a crashed panel three times a minute and then gives up, which is the failure a classroom has already had. Four lines of systemd drop-in make it unconditional; the panel then survived eight SIGKILLs a second apart, back each time in 2.4s. Plasma draws a minimised task and a background task identically, so the five states the room needs cannot all be shown. Rather than write a task manager, the classroom removes minimise: clicking a launcher always means show me this. Co-Authored-By: Claude Opus 5 <[email protected]>
63 lines
2.2 KiB
Python
Executable File
63 lines
2.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Generate the light colour scheme from the dark one.
|
|
|
|
There is one set of design tokens, not two themes. The light scheme is the
|
|
same file with the roles swapped, so a colour can only be changed in one
|
|
place and the two can never drift apart.
|
|
"""
|
|
|
|
import pathlib
|
|
import re
|
|
|
|
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
|
COLORS = ROOT / "config" / "plasma" / "colors"
|
|
|
|
# dark value -> light value
|
|
ROLES = {
|
|
"20,28,32": "242,245,244", # window background
|
|
"25,35,40": "233,238,237", # alternate
|
|
"15,23,26": "255,255,255", # view background
|
|
"18,26,30": "236,241,240", # header
|
|
"16,23,26": "228,234,233", # header, inactive
|
|
"30,42,47": "225,231,230", # button alternate
|
|
"230,237,239": "22,35,42", # normal text
|
|
"147,165,170": "96,116,122", # inactive text
|
|
"170,186,191": "80,99,105", # inactive header text
|
|
"125,142,147": "120,138,144",
|
|
"79,179,168": "46,140,130", # accent
|
|
"126,196,255": "26,110,180", # link
|
|
"227,106,106": "192,57,57", # negative
|
|
"224,177,92": "166,116,24", # neutral
|
|
"111,207,151": "38,142,86", # positive
|
|
"156,138,222": "104,80,180", # visited
|
|
"14,21,24": "255,255,255", # text on a selection
|
|
"10,16,18": "255,255,255",
|
|
}
|
|
|
|
HEADER = (
|
|
"# Ekklesia Classroom — light.\n"
|
|
"#\n"
|
|
"# GENERATED from EkklesiaDark.colors by tools/build-light-scheme.\n"
|
|
"# Edit the dark scheme and regenerate; do not edit this file by hand."
|
|
)
|
|
|
|
|
|
def main():
|
|
dark = (COLORS / "EkklesiaDark.colors").read_text()
|
|
|
|
light = dark
|
|
for old, new in sorted(ROLES.items(), key=lambda item: -len(item[0])):
|
|
light = re.sub(rf"(?<![\d,]){re.escape(old)}(?![\d,])", "\0" + new, light)
|
|
|
|
light = light.replace("\0", "")
|
|
light = light.replace("Ekklesia Classroom Dark", "Ekklesia Classroom Light")
|
|
light = light.replace("ColorScheme=EkklesiaDark", "ColorScheme=EkklesiaLight")
|
|
light = light.replace("# Ekklesia Classroom — dark. The default.", HEADER)
|
|
|
|
(COLORS / "EkklesiaLight.colors").write_text(light)
|
|
print("wrote", COLORS / "EkklesiaLight.colors")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|