aboutsummaryrefslogtreecommitdiffstats
path: root/static
diff options
context:
space:
mode:
Diffstat (limited to 'static')
-rw-r--r--static/app.js22
-rw-r--r--static/deck.css55
2 files changed, 50 insertions, 27 deletions
diff --git a/static/app.js b/static/app.js
index b89fbaa..e2da02a 100644
--- a/static/app.js
+++ b/static/app.js
@@ -230,6 +230,28 @@ tabBody.addEventListener("pointerup", (e) => {
});
tabBody.addEventListener("pointercancel", () => { swipe = null; });
+// theme.css is rendered per request from UDT's live files, so re-reading it
+// carries a scheme, wallpaper or font-size change to an open page. The <style>
+// comes after the <link>, so it wins once filled.
+const themeStyle = document.head.appendChild(document.createElement("style"));
+const themeColor = document.querySelector('meta[name="theme-color"]');
+
+async function refreshTheme() {
+ try {
+ const r = await fetch("theme.css", { cache: "no-store" });
+ if (!r.ok) return;
+ const text = await r.text();
+ if (text !== themeStyle.textContent) themeStyle.textContent = text;
+ } catch {
+ // keep the current theme; the next tick retries
+ }
+ const base = getComputedStyle(document.documentElement).getPropertyValue("--udt-base").trim();
+ if (base) themeColor.content = base;
+}
+refreshers.push(refreshTheme);
+refreshTheme();
+setInterval(refreshTheme, 5000);
+
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") refreshers.forEach((fn) => fn());
});
diff --git a/static/deck.css b/static/deck.css
index 684d336..2484e1b 100644
--- a/static/deck.css
+++ b/static/deck.css
@@ -18,6 +18,7 @@
* { box-sizing: border-box; margin: 0; }
+html { font-size: var(--udt-font-size, 14px); }
html, body { height: 100%; }
body {
@@ -25,7 +26,7 @@ body {
flex-direction: column;
background: var(--udt-base);
color: var(--udt-text);
- font: 400 14px/20px "Noto Sans", system-ui, sans-serif;
+ font: 400 1rem/1.43 "Noto Sans", system-ui, sans-serif;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
@@ -126,7 +127,7 @@ body {
.panel .panel-head h2 {
flex: 1;
margin: 0;
- font-size: 13px;
+ font-size: 0.929rem;
font-weight: 600;
letter-spacing: .02em;
color: var(--udt-text);
@@ -145,7 +146,7 @@ body {
.panel-body { flex: 1; min-height: 0; overflow: auto; padding: 14px; }
.section-label {
- font-size: 11px;
+ font-size: 0.786rem;
text-transform: uppercase;
letter-spacing: .08em;
color: var(--udt-overlay0);
@@ -167,11 +168,11 @@ body {
align-items: center;
justify-content: center;
color: var(--udt-overlay0);
- font-size: 22px;
+ font-size: 1.571rem;
}
.music .meta { min-width: 0; }
.music .title {
- font-size: 17px;
+ font-size: 1.214rem;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
@@ -179,13 +180,13 @@ body {
}
.music .controls button { min-height: 40px; min-width: 44px; }
.music .artist, .music .album { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.music .album { font-size: 12px; color: var(--udt-overlay0); }
+.music .album { font-size: 0.857rem; color: var(--udt-overlay0); }
.music .seek { display: flex; align-items: center; gap: 10px; margin: 6px 0 12px; }
.music .seek input { flex: 1; accent-color: var(--udt-accent); }
-.music .time { font-size: 12px; color: var(--udt-subtext0); white-space: nowrap; }
+.music .time { font-size: 0.857rem; color: var(--udt-subtext0); white-space: nowrap; }
.music .controls { display: flex; flex-wrap: wrap; gap: 8px; }
-.sbb .sbb-now { margin-bottom: 8px; font-size: 12px; font-weight: 600; }
+.sbb .sbb-now { margin-bottom: 8px; font-size: 0.857rem; font-weight: 600; }
.grid-stack-item .ui-resizable-se { width: 22px; height: 22px; right: 2px; bottom: 2px; opacity: .45; }
.grid-stack-item:hover .ui-resizable-se { opacity: 1; }
@@ -237,17 +238,17 @@ select {
background: var(--udt-surface1);
min-width: 0;
}
-.mlabel { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--udt-overlay0); }
+.mlabel { font-size: 0.714rem; text-transform: uppercase; letter-spacing: .08em; color: var(--udt-overlay0); }
.mvalue {
- font-size: 26px;
+ font-size: 1.857rem;
font-weight: 600;
line-height: 1.1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
-.msub { font-size: 12px; color: var(--udt-subtext0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-.mfoot { margin-top: 10px; font-size: 12px; color: var(--udt-overlay0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+.msub { font-size: 0.857rem; color: var(--udt-subtext0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+.mfoot { margin-top: 10px; font-size: 0.857rem; color: var(--udt-overlay0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.windows { display: flex; flex-direction: column; gap: 14px; }
.windows .ws { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
@@ -258,7 +259,7 @@ select {
display: flex;
align-items: center;
justify-content: center;
- font-size: 18px;
+ font-size: 1.286rem;
font-weight: 600;
border-radius: 12px;
background: var(--udt-surface1);
@@ -282,7 +283,7 @@ select {
.wrow.on { color: var(--udt-accent); }
.wt { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
.wicon { width: 24px; height: 24px; object-fit: contain; flex: none; }
-.wmenu { flex: none; width: 40px; height: 40px; padding: 0; font-size: 18px; line-height: 1; }
+.wmenu { flex: none; width: 40px; height: 40px; padding: 0; font-size: 1.286rem; line-height: 1; }
.windows .launches { display: flex; flex-wrap: wrap; gap: 8px; }
.wpop {
@@ -299,11 +300,11 @@ select {
border-radius: 12px;
box-shadow: 0 12px 30px rgba(0, 0, 0, .35);
}
-.wpop-title { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.wpop-label { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--udt-overlay0); }
+.wpop-title { font-weight: 600; font-size: 0.929rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.wpop-label { font-size: 0.786rem; text-transform: uppercase; letter-spacing: .08em; color: var(--udt-overlay0); }
.wpop-close { text-align: left; }
.wpop-ws { display: flex; flex-wrap: wrap; gap: 6px; }
-.wpop-ws button { min-width: 44px; min-height: 44px; padding: 0; font-size: 16px; font-weight: 600; }
+.wpop-ws button { min-width: 44px; min-height: 44px; padding: 0; font-size: 1.143rem; font-weight: 600; }
.llm { display: flex; flex-direction: column; gap: 10px; }
.llm-sec {
@@ -328,7 +329,7 @@ select {
.brand.claude { -webkit-mask-image: url(/logos/claude.svg); mask-image: url(/logos/claude.svg); }
.brand.opencode { -webkit-mask-image: url(/logos/opencode.svg); mask-image: url(/logos/opencode.svg); }
.llm-head h3 {
- font-size: 12px;
+ font-size: 0.857rem;
text-transform: uppercase;
letter-spacing: .08em;
color: var(--udt-subtext0);
@@ -337,7 +338,7 @@ select {
.llm-head .model {
margin-left: auto;
max-width: 60%;
- font-size: 12px;
+ font-size: 0.857rem;
color: var(--udt-overlay0);
overflow: hidden;
text-overflow: ellipsis;
@@ -346,8 +347,8 @@ select {
.gauges { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 12px; }
.gauge { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-radius: 12px; background: var(--udt-surface1); }
-.glabel { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--udt-overlay0); }
-.gvalue { font-size: 24px; font-weight: 600; line-height: 1.1; }
+.glabel { font-size: 0.714rem; text-transform: uppercase; letter-spacing: .08em; color: var(--udt-overlay0); }
+.gvalue { font-size: 1.714rem; font-weight: 600; line-height: 1.1; }
.gbar { height: 6px; background: var(--udt-surface2); border-radius: 3px; overflow: hidden; }
.gbar > i { display: block; height: 100%; background: var(--udt-accent); }
.lbig { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 12px; background: var(--udt-surface1); }
@@ -370,7 +371,7 @@ select {
min-height: 92px;
padding: 12px;
font: inherit;
- font-size: 17px;
+ font-size: 1.214rem;
font-weight: 600;
border-radius: 16px;
cursor: pointer;
@@ -379,7 +380,7 @@ select {
color: var(--udt-text);
}
.deck-btn .ico { width: 28px; height: 28px; }
-.deck-btn .num { font-size: 20px; }
+.deck-btn .num { font-size: 1.429rem; }
.deck-btn.rec.on { background: var(--udt-red); border-color: var(--udt-red); color: var(--udt-crust); }
.deck-btn.live.on { background: var(--udt-green); border-color: var(--udt-green); color: var(--udt-crust); }
.deck-btn:active { background: var(--udt-surface1); }
@@ -394,7 +395,7 @@ select {
padding: 12px;
}
.deck-block h3 {
- font-size: 11px;
+ font-size: 0.786rem;
text-transform: uppercase;
letter-spacing: .08em;
color: var(--udt-overlay0);
@@ -410,7 +411,7 @@ select {
min-height: 74px;
padding: 10px;
font: inherit;
- font-size: 14px;
+ font-size: 1rem;
text-align: center;
border-radius: 12px;
cursor: pointer;
@@ -421,7 +422,7 @@ select {
}
.tile { position: relative; }
.tile .ico { width: 22px; height: 22px; flex: none; }
-.tile .gear { position: absolute; right: 6px; top: 4px; font-style: normal; font-size: 11px; opacity: .6; }
+.tile .gear { position: absolute; right: 6px; top: 4px; font-style: normal; font-size: 0.786rem; opacity: .6; }
.tile span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile.on {
background: var(--udt-accent);
@@ -444,7 +445,7 @@ select {
.chan .mute.on { background: var(--udt-red); border-color: var(--udt-red); color: var(--udt-crust); }
.chan-name { flex: none; min-width: 84px; max-width: 34%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chan input[type=range] { flex: 1; min-width: 60px; accent-color: var(--udt-accent); }
-.chan-pct { flex: none; min-width: 40px; text-align: right; font-size: 12px; }
+.chan-pct { flex: none; min-width: 40px; text-align: right; font-size: 0.857rem; }
.deck-offline {
flex: 1;