Files
arr-tui/webos/static/style.css
T
nilsandClaude Opus 5.5 7f6d4d07b9 webOS: a TV app with the views of arr-tui
A TypeScript web app for LG webOS TVs (webOS 5 / Chromium 68 and newer),
driven by the remote: Movies and Series search with the Trakt lists,
Library with status, title and file-property filters and download marks,
seasons and episodes, release search and grab, Downloads, Calendar,
Settings and Log. It talks to Radarr, Sonarr, SABnzbd and Trakt directly
(they answer cross-origin requests); the arr-tui config is baked in at
build time and can be changed on the TV.

dev/screenshots/server.py answers cross-origin requests and accepts writes
for it; webos/dev/drive.mjs drives the app in Chromium for screenshots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 16:51:48 +01:00

251 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* arr-tui for webOS: 1920×1080, read from the couch. Kept to CSS that
webOS 5 (Chromium 68) supports: no flex gap, aspect-ratio or inset. */
:root, :root[data-theme="dark"] {
--bg: #14161b;
--panel: #1d2027;
--panel-2: #262a33;
--line: #333844;
--text: #e9eaee;
--muted: #8f94a0;
--accent: #f2b632;
--accent-text: #14161b;
--sel: #2f3542;
--ok: #7fcc6e;
--warn: #e8b552;
--bad: #f07272;
--dl: #5fadf2;
--shadow: rgba(0, 0, 0, 0.6);
}
:root[data-theme="light"] {
--bg: #f1f2f4;
--panel: #ffffff;
--panel-2: #e8eaee;
--line: #d3d6dd;
--text: #1c1e23;
--muted: #6a6f7b;
--accent: #c98a00;
--accent-text: #ffffff;
--sel: #dfe3ea;
--ok: #2e8b2e;
--warn: #a86b00;
--bad: #c43a3a;
--dl: #1f6fc4;
--shadow: rgba(0, 0, 0, 0.25);
}
* { box-sizing: border-box; }
html, body {
margin: 0;
width: 1920px;
height: 1080px;
overflow: hidden;
background: var(--bg);
color: var(--text);
font: 26px/1.35 "LG Smart UI", "Museo Sans", Roboto, "Segoe UI", Arial, sans-serif;
}
button, input { font: inherit; color: inherit; }
h1, h2 { margin: 0; font-weight: 600; }
.ok { color: var(--ok); }
.warn { color: var(--warn); }
.bad { color: var(--bad); }
.dl { color: var(--dl); }
.muted { color: var(--muted); }
.plain { color: var(--text); }
.bold { font-weight: 600; }
.hidden { display: none !important; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.ellipsis { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.f { outline: none; }
/* --- Shell --- */
.app { display: flex; flex-direction: column; height: 1080px; }
.topbar { display: flex; align-items: center; height: 88px; padding: 0 48px; background: var(--panel); border-bottom: 2px solid var(--line); }
.brand { font-size: 34px; font-weight: 700; color: var(--accent); margin-right: 40px; }
.tabs { display: flex; flex: 1; }
.tabs .tab { margin-right: 6px; }
.status-dots { display: flex; }
.status-dot { margin-left: 22px; font-size: 22px; color: var(--muted); }
.status-dot::before { content: "●"; margin-right: 8px; }
.status-dot.ok::before { color: var(--ok); }
.status-dot.bad::before { color: var(--bad); }
.status-dot.off::before { color: var(--line); }
.content { flex: 1; min-height: 0; padding: 28px 48px 16px; }
.footer { height: 60px; padding: 0 48px; display: flex; align-items: center; background: var(--panel); border-top: 2px solid var(--line); color: var(--muted); font-size: 22px; }
.footer-hints { display: flex; align-items: center; }
.hint { margin-right: 36px; display: inline-flex; align-items: center; }
.key { display: inline-block; min-width: 26px; height: 26px; border-radius: 13px; margin-right: 10px; font-size: 16px; line-height: 26px; text-align: center; font-weight: 700; }
.key.red { background: #e04848; }
.key.green { background: #3fae4a; }
.key.yellow { background: #e3c02c; }
.key.blue { background: #3d7fe0; }
.key.ok, .key.back { background: var(--panel-2); color: var(--text); padding: 0 10px; border-radius: 6px; }
/* --- Buttons, chips, choices, toggles, fields --- */
.btn, .chip, .tab {
border: 2px solid transparent; background: var(--panel-2); border-radius: 10px;
padding: 10px 24px; cursor: pointer; white-space: nowrap;
}
.tab { background: transparent; color: var(--muted); }
.tab.on { color: var(--text); border-bottom-color: var(--accent); border-radius: 10px 10px 0 0; }
.btn.danger { color: var(--bad); }
.btn.ghost { background: transparent; border-color: var(--line); }
.btn:focus, .chip:focus, .tab:focus { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
.btn:disabled { opacity: 0.5; }
.btn-hint { margin-left: 14px; color: var(--muted); font-size: 20px; }
.btn:focus .btn-hint { color: var(--accent-text); }
.chip { border-radius: 30px; margin-right: 12px; font-size: 22px; padding: 8px 22px; }
.chip.on { border-color: var(--accent); }
.toolbar { display: flex; align-items: center; margin-bottom: 18px; flex-wrap: wrap; }
.toolbar > * { margin-right: 14px; }
.choice, .toggle {
display: flex; align-items: center; justify-content: space-between;
padding: 10px 20px; background: var(--panel-2); border: 2px solid transparent; border-radius: 10px; cursor: pointer;
}
.choice-label { color: var(--muted); margin-right: 18px; }
.choice-arrows { color: var(--muted); }
.choice-value { color: var(--text); margin: 0 12px; }
.choice:focus, .toggle:focus { border-color: var(--accent); }
.choice:focus .choice-arrows { color: var(--accent); }
.toggle-box { width: 28px; height: 28px; border: 2px solid var(--muted); border-radius: 6px; margin-right: 16px; position: relative; }
.toggle.on .toggle-box { background: var(--accent); border-color: var(--accent); }
.toggle.on .toggle-box::after { content: "✓"; position: absolute; left: 4px; top: -4px; color: var(--accent-text); font-weight: 700; }
.toggle { justify-content: flex-start; }
.toggle.f-off { opacity: 0.4; }
.field { display: flex; align-items: center; }
.field-label { color: var(--muted); margin-right: 16px; white-space: nowrap; }
input.f, input.search {
background: var(--panel-2); border: 2px solid transparent; border-radius: 10px; padding: 10px 18px; min-width: 260px;
}
input.f:focus { border-color: var(--accent); }
input.search { width: 100%; font-size: 30px; padding: 14px 24px; }
/* --- Lists --- */
.list { display: flex; flex-direction: column; flex: 1; min-height: 0; background: var(--panel); border: 2px solid var(--line); border-radius: 12px; position: relative; }
.list:focus { border-color: var(--accent); }
.list-body { flex: 1; min-height: 0; position: relative; overflow: hidden; padding: 6px 0; }
.list-cols { color: var(--accent); font-size: 22px; border-bottom: 2px solid var(--line); padding: 10px 20px !important; flex-shrink: 0; }
.list-row { display: grid; align-items: center; padding: 0 20px; white-space: nowrap; }
.list-row > * { margin-right: 18px; min-width: 0; }
.list-row.sel-idle { background: var(--panel-2); }
.list-row.sel { background: var(--sel); box-shadow: inset 6px 0 0 var(--accent); }
.list-heading, .cal-day { display: flex; align-items: flex-end; padding: 0 20px 6px !important; color: var(--accent); font-weight: 600; }
.list-placeholder { padding: 24px; color: var(--muted); }
.list-scroll { position: absolute; right: 4px; top: 8px; bottom: 8px; width: 6px; }
.list-thumb { position: absolute; left: 0; right: 0; background: var(--line); border-radius: 3px; }
.dot { color: var(--muted); }
.dot.on { color: var(--ok); }
.dot.dl { color: var(--dl); }
/* --- Views with a details pane on the right --- */
.view { display: flex; height: 100%; }
.search-main, .lib-main, .cal-main { flex: 1; min-width: 0; display: flex; flex-direction: column; margin-right: 32px; }
.detail { width: 600px; flex-shrink: 0; overflow: hidden; background: var(--panel); border-radius: 12px; padding: 28px; position: relative; }
.detail-poster { float: right; width: 220px; margin: 0 0 18px 22px; border-radius: 8px; background: var(--panel-2); min-height: 330px; }
.detail-poster.none { display: none; }
.detail-poster.loading { opacity: 0.3; }
.detail-title { font-size: 34px; line-height: 1.2; margin-bottom: 10px; }
.detail-sub { font-weight: 600; margin-bottom: 8px; }
.detail-facts { color: var(--muted); margin-bottom: 10px; }
.detail-line { font-size: 24px; }
.detail-plot { font-size: 24px; color: var(--text); margin: 16px 0 0; }
.detail-cast { clear: both; padding-top: 16px; font-size: 22px; }
.cast-head { font-weight: 600; margin-top: 8px; }
/* Movies / Series */
.search-bar { margin-bottom: 18px; }
.chips { display: flex; margin-bottom: 14px; }
.grid-status { color: var(--muted); min-height: 36px; }
.grid-scroll { flex: 1; min-height: 0; overflow: hidden; padding: 12px 8px; margin: 0 -8px; }
.grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); grid-column-gap: 22px; grid-row-gap: 26px; }
.card { cursor: pointer; border-radius: 10px; transition: transform 0.12s; }
.card:focus { transform: scale(1.06); }
.card:focus .card-art { box-shadow: 0 0 0 5px var(--accent), 0 10px 24px var(--shadow); }
.card-art { position: relative; padding-top: 150%; background: var(--panel-2); border-radius: 10px; overflow: hidden; }
.card-poster { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
.card-poster.none { display: none; }
.card-fallback { position: absolute; left: 0; top: 0; right: 0; bottom: 0; padding: 16px; display: flex; align-items: center; justify-content: center; text-align: center; color: var(--muted); }
.card-badge { position: absolute; z-index: 2; right: 10px; top: 10px; width: 40px; height: 40px; border-radius: 20px; background: var(--ok); color: #10200d; font-weight: 700; text-align: center; line-height: 40px; }
.card-title { margin-top: 10px; font-size: 22px; font-weight: 600; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.card-sub { display: flex; justify-content: space-between; font-size: 20px; color: var(--muted); }
.card-note { color: var(--muted); }
/* Library */
.lib-count { color: var(--muted); margin-left: auto; margin-right: 0 !important; }
.library-view .field input { min-width: 0; width: 230px; }
.library-view .field-label:empty { display: none; }
.lib-row { grid-template-columns: 30px 1fr 300px 140px; }
/* Releases, episodes, calendar, downloads, log */
.release-row { grid-template-columns: 30px 1fr 220px 130px 80px 200px 90px; font-size: 22px; }
.mark.ok { color: var(--ok); } .mark.warn { color: var(--warn); } .mark.bad { color: var(--bad); }
.release-info { min-height: 110px; padding: 12px 4px 0; font-size: 22px; }
.release-title { color: var(--muted); word-break: break-all; }
.ep-row { grid-template-columns: 30px 60px 1fr 160px 260px; }
.cal-row { grid-template-columns: 80px 30px 360px 1fr 200px; }
.cal-range { color: var(--muted); margin-left: auto; }
.downloads-view { flex-direction: column; }
.downloads-view .list { margin-bottom: 16px; }
.dl-queue { flex: 3; } .dl-arr { flex: 2; } .dl-history { flex: 3; }
.dl-row { grid-template-columns: 1fr 210px 280px 150px 120px; font-size: 22px; }
.dl-problem { color: var(--warn); }
.progress { display: flex; align-items: center; }
.bar { flex: 1; height: 10px; background: var(--panel-2); border-radius: 5px; overflow: hidden; margin-right: 12px; }
.bar-fill { display: block; height: 100%; background: var(--dl); }
.sab-head { font-size: 24px; }
.log-row { grid-template-columns: 140px 1fr; font-size: 22px; }
/* Settings */
.settings-view { display: block; }
.settings-scroll { height: 100%; overflow: hidden; }
.settings-form { max-width: 1100px; }
.settings-form h2 { color: var(--accent); margin: 26px 0 12px; font-size: 28px; }
.settings-form h2:first-child { margin-top: 0; }
.settings-form > .field, .settings-form > .choice, .settings-form > .toggle { margin-bottom: 10px; }
.settings-form .field input { flex: 1; }
.settings-result { max-width: 1100px; margin-top: 20px; }
.test-line { font-size: 24px; }
/* --- Pages (releases, episodes): full screen over the shell --- */
.page { position: fixed; left: 0; top: 0; width: 1920px; height: 1080px; background: var(--bg); z-index: 10; display: flex; flex-direction: column; padding: 36px 48px 24px; }
.page-header { display: flex; align-items: baseline; margin-bottom: 20px; }
.page-header h1 { font-size: 38px; margin-right: 28px; }
.page-status { color: var(--muted); }
.split { flex: 1; min-height: 0; display: flex; }
.split .list { margin-right: 32px; }
.hints { color: var(--muted); font-size: 22px; padding-top: 12px; }
/* --- Dialogs --- */
.dialog { position: fixed; left: 0; top: 0; width: 1920px; height: 1080px; background: rgba(0, 0, 0, 0.6); z-index: 20; display: flex; align-items: center; justify-content: center; }
.dialog-box { width: 900px; max-height: 960px; overflow: hidden; background: var(--panel); border: 2px solid var(--line); border-radius: 16px; padding: 36px; box-shadow: 0 20px 60px var(--shadow); }
.dialog-box h2 { margin-bottom: 20px; font-size: 32px; }
.dialog-box > .btn, .dialog-box > .choice, .dialog-box > .toggle { display: flex; align-items: baseline; width: 100%; margin-bottom: 10px; text-align: left; }
.dialog-box > .choice, .dialog-box > .toggle { align-items: center; }
.dialog-text { white-space: pre-line; margin: 0 0 20px; }
.dialog-hint { color: var(--muted); font-size: 20px; margin: 16px 0 0; }
.row-buttons { display: flex; margin-top: 18px; }
.row-buttons .btn { margin-right: 14px; }
/* --- Toasts --- */
#toasts { position: fixed; right: 48px; bottom: 84px; width: 760px; z-index: 30; }
.toast { background: var(--panel-2); border-left: 6px solid var(--muted); border-radius: 8px; padding: 14px 20px; margin-top: 10px; box-shadow: 0 8px 24px var(--shadow); transition: opacity 0.5s; font-size: 22px; }
.toast-ok { border-left-color: var(--ok); }
.toast-warn { border-left-color: var(--warn); }
.toast-error { border-left-color: var(--bad); }
.toast.gone { opacity: 0; }