diff --git a/html/configuration.html b/html/configuration.html index a24be56..88a19ec 100644 --- a/html/configuration.html +++ b/html/configuration.html @@ -1,11 +1,13 @@ - + xTeVe - - + + + + @@ -16,7 +18,7 @@ -
+
diff --git a/html/create-first-user.html b/html/create-first-user.html index fc99edd..301ced6 100644 --- a/html/create-first-user.html +++ b/html/create-first-user.html @@ -1,11 +1,13 @@ - +xTeVe - - + + + + @@ -13,7 +15,7 @@ -
+

Create user account

diff --git a/html/css/base.css b/html/css/base.css index 43f1c7f..7985635 100644 --- a/html/css/base.css +++ b/html/css/base.css @@ -1,32 +1,14 @@ -:root { - --bg-0: #07111d; - --bg-1: #0c1a2b; - --bg-2: #12233a; - --panel: #102238; - --panel-soft: #0f1f33; - --line: #274462; - --line-soft: #1b334d; - --text: #e9f5ff; - --text-muted: #b7cee1; - --accent: #35d2ff; - --accent-strong: #12b9ff; - --accent-soft: rgba(53, 210, 255, 0.2); - --ok: #2fd18a; - --warn: #ffc15a; - --error: #ff6f6f; - --radius-s: 10px; - --radius-m: 14px; - --radius-l: 18px; - --shadow-1: 0 20px 45px rgba(0, 0, 0, 0.32); - --shadow-2: 0 12px 30px rgba(0, 0, 0, 0.28); -} +/* + * base.css - reset, typography, links, focus styles, skip link, generic + * form elements and small utility classes. Loaded after tokens.css. + */ * { -webkit-appearance: none; -moz-appearance: none; -ms-appearance: none; box-sizing: border-box; - font-family: "Space Grotesk", "Avenir Next", "Trebuchet MS", sans-serif; + font-family: var(--font-sans); letter-spacing: 0.02em; } @@ -37,17 +19,17 @@ ::-webkit-scrollbar-track { border-radius: 999px; - background: rgba(7, 17, 29, 0.65); + background: var(--scroll-track); } ::-webkit-scrollbar-thumb { border-radius: 999px; - border: 2px solid rgba(7, 17, 29, 0.6); - background: linear-gradient(180deg, #2d597f, #1e4060); + border: 2px solid var(--scroll-track); + background: linear-gradient(180deg, var(--scroll-thumb-a), var(--scroll-thumb-b)); } ::-webkit-scrollbar-thumb:hover { - background: linear-gradient(180deg, #3678ac, #20537c); + background: linear-gradient(180deg, var(--scroll-thumb-hover-a), var(--scroll-thumb-hover-b)); } ::-webkit-scrollbar-corner { @@ -61,9 +43,9 @@ body { color: var(--text); font-size: 14px; background: - radial-gradient(circle at 15% 12%, rgba(64, 132, 183, 0.22), transparent 32%), - radial-gradient(circle at 88% 2%, rgba(18, 185, 255, 0.16), transparent 30%), - linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 56%, #060d17 100%); + radial-gradient(circle at 15% 12%, var(--bg-glow-1), transparent 32%), + radial-gradient(circle at 88% 2%, var(--bg-glow-2), transparent 30%), + linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 56%, var(--bg-deep) 100%); } body { @@ -75,7 +57,7 @@ a { } a:hover { - color: #8de7ff; + color: var(--accent-hover); } h1, @@ -122,7 +104,7 @@ pre { white-space: pre-wrap; line-height: 1.55; letter-spacing: 0.015em; - font-family: "IBM Plex Mono", "SFMono-Regular", "Consolas", monospace; + font-family: var(--font-mono); } hr { @@ -153,7 +135,7 @@ button { } :focus-visible { - outline: 2px solid #91eaff; + outline: 2px solid var(--focus-ring-soft); outline-offset: 2px; } @@ -171,7 +153,7 @@ textarea { width: 100%; border-radius: var(--radius-s); border: 1px solid var(--line); - background-color: rgba(10, 22, 36, 0.78); + background-color: var(--surface-input); color: var(--text); padding: 10px 11px; transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease; @@ -184,45 +166,15 @@ input[type=number]:focus, select:focus, textarea:focus { border-color: var(--accent); - box-shadow: 0 0 0 3px rgba(53, 210, 255, 0.17); - background-color: rgba(9, 25, 40, 0.95); + box-shadow: 0 0 0 3px var(--accent-ring); + background-color: var(--surface-input-focus); } input[type=text]::placeholder, input[type=search]::placeholder, input[type=password]::placeholder, textarea::placeholder { - color: #7e9ab4; -} - -input[type=button], -input[type=submit], -button { - cursor: pointer; - border: 1px solid transparent; - border-radius: 999px; - color: #03101a; - padding: 10px 18px; - margin: 8px 8px 8px 0; - font-weight: 700; - letter-spacing: 0.03em; - background: linear-gradient(135deg, #67e8ff 0%, #12b9ff 100%); - box-shadow: 0 10px 22px rgba(18, 185, 255, 0.3); - transition: transform 0.15s ease, box-shadow 0.2s ease, filter 0.2s ease; -} - -input[type=button]:hover, -input[type=submit]:hover, -button:hover { - transform: translateY(-1px); - filter: brightness(1.05); - box-shadow: 0 12px 24px rgba(18, 185, 255, 0.36); -} - -input[type=button]:active, -input[type=submit]:active, -button:active { - transform: translateY(0); + color: var(--text-placeholder); } input[type=button]:focus-visible, @@ -236,80 +188,43 @@ input[type=text]:focus-visible, input[type=search]:focus-visible, input[type=password]:focus-visible, input[type=number]:focus-visible { - outline: 2px solid #7de5ff; + outline: 2px solid var(--focus-ring); outline-offset: 2px; } -input[type=button].delete { - color: #fff; - background: linear-gradient(135deg, #ff7f7f 0%, #e94343 100%); - box-shadow: 0 10px 20px rgba(233, 67, 67, 0.35); -} - -input[type=button].cancel { - color: #ffd8d8; - border-color: rgba(255, 111, 111, 0.45); - background: rgba(87, 22, 22, 0.45); - box-shadow: none; -} - -input[type=button].black, -input[type=submit].black { - color: #d8ecff; - border-color: var(--line); - background: rgba(14, 32, 50, 0.85); - box-shadow: none; -} - -input[type=button].center { - margin-right: auto; - margin-left: auto; -} - -input[type=button].save { - margin-left: auto; -} - -input[type=checkbox] { - width: 20px; - height: 20px; - border: 1px solid var(--line); - border-radius: 6px; - background-color: rgba(10, 22, 36, 0.86); - cursor: pointer; - position: relative; -} - -input[type=checkbox]:checked { - border-color: #89ebff; - background-color: #39d6ff; -} - -input[type=checkbox]:before { - content: ""; -} - -input[type=checkbox]:checked:before { - content: "\2713"; - color: #032033; - font-size: 14px; - font-weight: 800; +.skip-link { position: absolute; - top: -1px; - left: 3px; + top: 10px; + left: 10px; + z-index: 2600; + border-radius: 999px; + padding: 8px 12px; + font-size: 12px; + font-weight: 700; + color: var(--text-on-accent); + background: var(--accent-gradient); + transform: translateY(-180%); + transition: transform 0.2s ease; } -.changed { - border-color: #8de7ff !important; - box-shadow: 0 0 0 3px rgba(53, 210, 255, 0.2) !important; +.skip-link:focus-visible { + transform: translateY(0); } -.notAvailable { - opacity: 0.58; - cursor: not-allowed; - border-color: rgba(255, 111, 111, 0.45) !important; +.sr-only { + border: 0 !important; + clip: rect(0 0 0 0) !important; + height: 1px !important; + margin: -1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + white-space: nowrap !important; + width: 1px !important; } +/* Utility classes */ + .pointer { cursor: pointer; } @@ -364,37 +279,6 @@ input[type=checkbox]:checked:before { text-align: center; } -.skip-link { - position: absolute; - top: 10px; - left: 10px; - z-index: 2600; - border-radius: 999px; - padding: 8px 12px; - font-size: 12px; - font-weight: 700; - color: #03131f; - background: linear-gradient(135deg, #7be8ff 0%, #19c1ff 100%); - transform: translateY(-180%); - transition: transform 0.2s ease; -} - -.skip-link:focus-visible { - transform: translateY(0); -} - -.sr-only { - border: 0 !important; - clip: rect(0 0 0 0) !important; - height: 1px !important; - margin: -1px !important; - overflow: hidden !important; - padding: 0 !important; - position: absolute !important; - white-space: nowrap !important; - width: 1px !important; -} - .floatRight { float: right; } @@ -423,9 +307,6 @@ input[type=checkbox]:checked:before { display: none; } -.noBulk { -} - .notVisible { display: none; opacity: 0; @@ -437,259 +318,10 @@ input[type=checkbox]:checked:before { opacity: 1; } -.menu-active { - color: #011019; -} - -.menu-notActive { -} - -.menu { - border: 1px solid var(--accent); -} - .half { width: 45%; } -.screenLogHidden { - transform: translate(0, -110px); -} - -.infoMsg { - color: #87b0d1; -} - -.errorMsg { - color: #ff8d8d; -} - -.warningMsg { - color: var(--warn); -} - -.debugMsg { - color: #d687ff; -} - -.News, -.Movie, -.Series, -.Sports, -.Kids { - border-left: 3px solid transparent; - padding-left: 8px; -} - -.News { - border-color: #ff8f6e; -} - -.Movie { - border-color: #46a4ff; -} - -.Series { - border-color: #ffd267; -} - -.Sports { - border-color: #5ee495; -} - -.Kids { - border-color: #f6a8ff; -} - -#loading { - position: fixed; - inset: 0; - z-index: 2000; - background-color: rgba(5, 12, 20, 0.72); - backdrop-filter: blur(1.5px); -} - -.loader { - width: 52px; - height: 52px; - border-radius: 50%; - border: 4px solid transparent; - border-top-color: #58ddff; - border-right-color: #12b9ff; - animation: spin 0.9s linear infinite; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - margin: auto; -} - -#popup { - position: fixed; - inset: 0; - background-color: rgba(3, 9, 16, 0.72); - backdrop-filter: blur(2px); - z-index: 1500; - padding: 16px; -} - -#popup-custom, -#mapping-detail, -#user-detail, -#file-detail { - margin: 0 auto; - max-width: 760px; - max-height: calc(100vh - 36px); - overflow: auto; - border-radius: var(--radius-l); - border: 1px solid var(--line); - background: linear-gradient(180deg, rgba(17, 34, 56, 0.97) 0%, rgba(12, 27, 44, 0.97) 100%); - box-shadow: var(--shadow-1); - padding: 16px; - animation: popupIn 0.2s ease; -} - -#popup-custom h3 { - margin-bottom: 8px; - text-align: center; - color: #d5efff; -} - -.popup-title { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; - margin-bottom: 10px; -} - -.popup-title h3 { - margin: 0; - text-align: left; -} - -#popup-custom .popup-title h3 { - margin: 0; - text-align: left; -} - -.popup-close { - min-width: 40px; - min-height: 40px; - margin: 0; - padding: 0; - border-radius: 999px; - border: 1px solid var(--line); - color: #d9f0ff; - background: rgba(14, 32, 50, 0.9); - box-shadow: none; - font-size: 20px; - line-height: 1; -} - -.popup-close:hover { - color: #ffffff; - border-color: #5bc8ed; -} - -#popup-custom table, -#content_settings table, -#mapping-detail-table, -#user-detail-table { - width: 100%; - table-layout: fixed; - border-collapse: separate; - border-spacing: 0 8px; -} - -#popup-custom td, -#content_settings td, -#mapping-detail-table td, -#user-detail-table td { - padding: 2px 6px; - vertical-align: middle; -} - -#popup-custom td.left, -#mapping-detail-table td.left, -#user-detail-table td.left { - width: 38%; - color: var(--text-muted); -} - -#popup-custom input[type=text], -#popup-custom input[type=password], -#mapping-detail input[type=text], -#content_settings input[type=text], -#content_settings input[type=password] { - width: 100%; -} - -#mapping-detail img { - display: block; - max-height: 44px; - margin: 8px auto 12px; -} - -#file-detail input[type=text] { - width: 100%; -} - -.interaction, -#interaction { - margin-top: 16px; - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 8px; - float: right; -} - -.interaction input[type=button], -.interaction input[type=submit] { - margin: 0; - min-width: 110px; -} - -#popup-interaction { - margin-top: 14px; - display: flex; - flex-wrap: wrap; - justify-content: flex-end; - gap: 8px; -} - -#notification { - position: fixed; - right: 12px; - top: 12px; - width: 260px; - max-height: calc(100vh - 24px); - overflow: auto; - border-radius: var(--radius-m); - border: 1px solid var(--line); - background: rgba(10, 22, 36, 0.92); - box-shadow: var(--shadow-2); -} - -#notification .element { - margin: 8px; - border-radius: 10px; - border-left: 4px solid var(--ok); - background: rgba(17, 35, 56, 0.84); - padding: 8px; -} - -#notification h5 { - padding: 0; - margin-bottom: 6px; -} - -#notification p { - font-size: 11px; -} - .tableEllipsis { width: 150px; overflow: hidden; @@ -718,81 +350,3 @@ input[type=checkbox]:checked:before { transform: translateY(0) scale(1); } } - -@media only screen and (max-width: 619px) { - h1 { - font-size: 1.46rem; - } - - #popup { - padding: 0; - } - - #popup-custom, - #mapping-detail, - #user-detail, - #file-detail { - max-width: none; - width: 100%; - height: 100%; - max-height: 100%; - border-radius: 0; - border: 0; - padding: 10px 10px calc(14px + env(safe-area-inset-bottom)); - } - - #popup-custom table { - border-spacing: 0 10px; - } - - #popup-custom tr { - display: block; - border: 1px solid var(--line-soft); - border-radius: 10px; - padding: 8px 8px 10px; - background: rgba(12, 26, 42, 0.8); - } - - #popup-custom td { - display: block; - width: 100%; - padding: 4px 2px; - } - - #popup-custom td.left { - width: 100%; - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.06em; - } - - #popup-interaction { - position: sticky; - bottom: 0; - z-index: 5; - margin-top: 10px; - padding-top: 10px; - background: linear-gradient(180deg, rgba(12, 27, 44, 0.1) 0%, rgba(12, 27, 44, 0.96) 30%); - } - - .interaction, - #interaction { - justify-content: stretch; - } - - .interaction input[type=button], - .interaction input[type=submit], - #popup-interaction input[type=button] { - width: 100%; - min-height: 44px; - } - - .popup-title h3 { - font-size: 1.02rem; - } - - .popup-close { - min-width: 44px; - min-height: 44px; - } -} diff --git a/html/css/components.css b/html/css/components.css new file mode 100644 index 0000000..b65e0bb --- /dev/null +++ b/html/css/components.css @@ -0,0 +1,775 @@ +/* + * components.css - buttons, inputs, tables, status cards, connection + * indicator, popups, menu, log lines and badges. Loaded after base.css. + * Responsive overrides for these components live in layout.css. + */ + +/* Buttons */ + +input[type=button], +input[type=submit], +button { + cursor: pointer; + border: 1px solid transparent; + border-radius: 999px; + color: var(--text-on-accent); + padding: 10px 18px; + margin: 8px 8px 8px 0; + font-weight: 700; + letter-spacing: 0.03em; + background: var(--accent-gradient); + box-shadow: 0 10px 22px var(--accent-shadow); + transition: transform 0.15s ease, box-shadow 0.2s ease, filter 0.2s ease; +} + +input[type=button]:hover, +input[type=submit]:hover, +button:hover { + transform: translateY(-1px); + filter: brightness(1.05); + box-shadow: 0 12px 24px var(--accent-shadow-strong); +} + +input[type=button]:active, +input[type=submit]:active, +button:active { + transform: translateY(0); +} + +input[type=button].delete { + color: var(--text-on-error); + background: linear-gradient(135deg, var(--error-bright) 0%, var(--error-strong) 100%); + box-shadow: 0 10px 20px var(--error-shadow); +} + +input[type=button].cancel { + color: var(--error-text-soft); + border-color: var(--error-soft); + background: var(--error-surface); + box-shadow: none; +} + +input[type=button].black, +input[type=submit].black { + color: var(--text-heading); + border-color: var(--line); + background: var(--surface-raised); + box-shadow: none; +} + +input[type=button].center { + margin-right: auto; + margin-left: auto; +} + +input[type=button].save { + margin-left: auto; +} + +/* Checkbox */ + +input[type=checkbox] { + width: 20px; + height: 20px; + border: 1px solid var(--line); + border-radius: 6px; + background-color: var(--surface-input); + cursor: pointer; + position: relative; +} + +input[type=checkbox]:checked { + border-color: var(--checkbox-checked-border); + background-color: var(--checkbox-checked); +} + +input[type=checkbox]:before { + content: ""; +} + +input[type=checkbox]:checked:before { + content: "\2713"; + color: var(--text-on-accent); + font-size: 14px; + font-weight: 800; + position: absolute; + top: -1px; + left: 3px; +} + +/* Input states */ + +.changed { + border-color: var(--accent-hover) !important; + box-shadow: 0 0 0 3px var(--accent-soft) !important; +} + +.notAvailable { + opacity: 0.58; + cursor: not-allowed; + border-color: var(--error-soft) !important; +} + +.wizard { + margin: 10px 0; +} + +/* Sidebar menu */ + +#branch { + min-height: 18px; + margin: 2px 0 6px; + text-align: center; + font-size: 11px; + color: var(--error-text); + letter-spacing: 0.08em; + text-transform: uppercase; +} + +#main-menu { + display: flex; + flex-direction: column; + gap: 7px; + overflow: auto; + padding-right: 4px; +} + +#main-menu li { + display: flex; + align-items: center; + gap: 10px; + min-height: 42px; + padding: 8px 11px; + border-radius: 12px; + border: 1px solid transparent; + background: var(--surface-1); +} + +#main-menu li:hover { + border-color: var(--accent-soft); + transform: translateX(2px); +} + +#main-menu li:focus-visible { + border-color: var(--accent-border); + transform: translateX(2px); + box-shadow: 0 0 0 3px var(--accent-soft); +} + +#main-menu li.menu-active { + border-color: var(--accent-border); + background: var(--accent-gradient); + box-shadow: 0 10px 18px var(--accent-shadow); +} + +#main-menu li.menu-active p { + color: var(--text-on-accent); +} + +#main-menu li.menu-active img { + filter: brightness(0.04) saturate(120%); +} + +nav img { + display: block; + width: 18px; + height: 18px; + max-width: 18px; + max-height: 18px; + flex: 0 0 auto; +} + +nav p { + margin: 0; + padding: 0; + text-align: left; + font-size: 12px; + font-weight: 600; + color: var(--text-heading); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.menu-active { + color: var(--text-on-accent); +} + +.menu { + border: 1px solid var(--accent); +} + +/* Connection indicator */ + +#connection-indicator { + margin-left: auto; + padding: 5px 11px; + border-radius: 999px; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.05em; + text-transform: uppercase; +} + +#connection-indicator.status-idle { + color: var(--text-heading); + border: 1px solid var(--line-strong); + background: var(--surface-raised); +} + +#connection-indicator.status-busy { + color: var(--text-on-accent); + border: 1px solid var(--accent-bright); + background: var(--accent-gradient); +} + +#connection-indicator.status-online { + color: var(--text-on-ok); + border: 1px solid var(--ok-border); + background: linear-gradient(135deg, var(--ok-bright) 0%, var(--ok-mid) 100%); +} + +#connection-indicator.status-offline { + color: var(--text-on-error); + border: 1px solid var(--error-border); + background: linear-gradient(135deg, var(--error-bright) 0%, var(--error-strong) 100%); +} + +/* Server info and stream tables */ + +#clientInfo, +#activeStreams, +#inactiveStreams { + width: 100%; + border-collapse: separate; + border-spacing: 7px; + background: var(--surface-0); +} + +#clientInfo { + padding: 7px 10px 6px; + border-bottom: 1px solid var(--line-soft); +} + +#clientInfo tr { + vertical-align: top; +} + +#clientInfo .tdKey, +#clientInfo .tdVal, +#activeStreams .tdKey, +#inactiveStreams .tdKey, +#activeStreams .tdVal, +#inactiveStreams .tdVal, +#logInfo .tdVal, +#mappingInfo .tdVal { + border: 1px solid var(--line-soft); + border-radius: 8px; + padding: 7px 8px; + vertical-align: middle; + font-family: var(--font-mono); +} + +#clientInfo .tdKey, +#activeStreams .tdKey, +#inactiveStreams .tdKey { + color: var(--accent-text); + font-size: 10px; + text-transform: uppercase; +} + +#clientInfo .tdVal, +#activeStreams .tdVal, +#inactiveStreams .tdVal { + color: var(--text-muted); + font-size: 11px; + word-break: break-word; +} + +#clientInfo .tdVal a { + color: var(--accent-text); + text-decoration: none; + border-bottom: 1px dotted var(--link-underline); + word-break: break-all; +} + +#clientInfo .tdVal a:hover, +#clientInfo .tdVal a:focus { + color: var(--accent-text-hover); + border-bottom-color: var(--accent-text-hover); + text-decoration: none; +} + +#myStreamsBox { + border-bottom: 1px solid var(--line-soft); + background: var(--surface-1); + transition: all 0.2s ease; +} + +#allStreams { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + padding: 8px; +} + +#activeStreams, +#inactiveStreams { + max-height: 120px; + overflow-y: auto; +} + +#inactiveStreams .tdKey { + color: var(--error-text); +} + +/* Status cards */ + +.dashboard-cards { + display: grid; + grid-template-columns: repeat(6, minmax(130px, 1fr)); + gap: 9px; + padding: 10px 14px; + border-bottom: 1px solid var(--line-soft); + background: var(--surface-0); +} + +.status-card { + border: 1px solid var(--line-soft); + border-radius: 12px; + background: var(--surface-2); + padding: 10px; + min-height: 74px; + display: flex; + flex-direction: column; + justify-content: center; + gap: 4px; +} + +.status-card-label { + color: var(--text-soft); + font-size: 10px; + text-transform: uppercase; + letter-spacing: 0.07em; +} + +.status-card-value { + color: var(--text); + font-size: 14px; + font-weight: 700; + overflow: hidden; + text-overflow: ellipsis; +} + +.status-card.status-card-ok { + border-color: var(--ok-soft); + background: linear-gradient(180deg, var(--ok-surface-top) 0%, var(--ok-surface-bottom) 100%); +} + +.status-card.status-card-warn { + border-color: var(--warn-soft); + background: linear-gradient(180deg, var(--warn-surface-top) 0%, var(--warn-surface-bottom) 100%); +} + +.status-card.status-card-error { + border-color: var(--error-soft); + background: linear-gradient(180deg, var(--error-surface-top) 0%, var(--error-surface-bottom) 100%); +} + +/* Content table */ + +#box-wrapper { + width: 100%; + overflow: auto; + border: 1px solid var(--line-soft); + border-radius: 12px; + background: var(--surface-1); +} + +#content_table { + width: 100%; + border-collapse: collapse; +} + +#content_table .content_table_header { + position: sticky; + top: 0; + z-index: 2; + background: linear-gradient(180deg, var(--table-head-top), var(--table-head-bottom)); + border-bottom: 1px solid var(--line); +} + +#content_table .content_table_header td { + color: var(--accent-text); + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.07em; + padding: 10px 8px; +} + +#content_table tr { + border-left: 3px solid transparent; + border-bottom: 1px solid var(--row-line); + transition: background-color 0.2s ease; +} + +#content_table tr:hover { + background-color: var(--row-hover); +} + +#content_table tr[tabindex], +#content_table td[tabindex] { + cursor: pointer; +} + +#content_table tr[tabindex]:focus-visible, +#content_table td[tabindex]:focus-visible, +.keyboard-clickable:focus-visible { + outline: 2px solid var(--focus-ring); + outline-offset: -2px; + background-color: var(--row-focus); +} + +#content_table td { + padding: 7px 8px; + vertical-align: middle; +} + +#content_table img { + display: block; + width: auto; + max-width: 34px; + max-height: 30px; + margin: 0 auto; +} + +#content_table input[type=text] { + min-width: 48px; + max-width: 76px; + margin: 0; + padding: 6px 7px; + border-radius: 8px; + text-align: left; +} + +#content_table input[type=checkbox] { + margin: 0 auto; +} + +#content_table .mapping-edit-button { + min-height: 32px; + min-width: 64px; + margin: 0; + padding: 5px 10px; + font-size: 11px; + line-height: 1; +} + +#content_table tr.activeEPG { + border-left-color: var(--ok); +} + +#content_table tr.notActiveEPG { + border-left-color: var(--error); +} + +/* Settings */ + +#settings { + padding: 10px; +} + +#content_settings h4 { + margin: 15px 0 8px; + color: var(--text-heading); +} + +#content_settings table { + border: 1px solid var(--line-soft); + border-radius: 12px; + background: var(--surface-1); + overflow: hidden; +} + +#content_settings td { + border-bottom: 1px solid var(--row-line); +} + +#content_settings tr:last-child td { + border-bottom: 0; +} + +#content_settings pre { + color: var(--text-soft); + font-size: 11px; +} + +/* Popup and detail tables */ + +#popup-custom table, +#content_settings table, +#mapping-detail-table, +#user-detail-table { + width: 100%; + table-layout: fixed; + border-collapse: separate; + border-spacing: 0 8px; +} + +#popup-custom td, +#content_settings td, +#mapping-detail-table td, +#user-detail-table td { + padding: 2px 6px; + vertical-align: middle; +} + +#popup-custom td.left, +#mapping-detail-table td.left, +#user-detail-table td.left { + width: 38%; + color: var(--text-muted); +} + +#popup-custom input[type=text], +#popup-custom input[type=password], +#mapping-detail input[type=text], +#content_settings input[type=text], +#content_settings input[type=password] { + width: 100%; +} + +#mapping-detail img { + display: block; + max-height: 44px; + margin: 8px auto 12px; +} + +#file-detail input[type=text] { + width: 100%; +} + +/* Loading and popups */ + +#loading { + position: fixed; + inset: 0; + z-index: 2000; + background-color: var(--overlay); + backdrop-filter: blur(1.5px); +} + +.loader { + width: 52px; + height: 52px; + border-radius: 50%; + border: 4px solid transparent; + border-top-color: var(--loader); + border-right-color: var(--accent-strong); + animation: spin 0.9s linear infinite; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: auto; +} + +#popup { + position: fixed; + inset: 0; + background-color: var(--overlay); + backdrop-filter: blur(2px); + z-index: 1500; + padding: 16px; +} + +#popup-custom, +#mapping-detail, +#user-detail, +#file-detail { + margin: 0 auto; + max-width: 760px; + max-height: calc(100vh - 36px); + overflow: auto; + border-radius: var(--radius-l); + border: 1px solid var(--line); + background: linear-gradient(180deg, var(--panel-top) 0%, var(--panel-bottom) 100%); + box-shadow: var(--shadow-1); + padding: 16px; + animation: popupIn 0.2s ease; +} + +#popup-custom h3 { + margin-bottom: 8px; + text-align: center; + color: var(--text-heading); +} + +.popup-title { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 10px; +} + +.popup-title h3 { + margin: 0; + text-align: left; +} + +#popup-custom .popup-title h3 { + margin: 0; + text-align: left; +} + +.popup-close { + min-width: 40px; + min-height: 40px; + margin: 0; + padding: 0; + border-radius: 999px; + border: 1px solid var(--line); + color: var(--text-heading); + background: var(--surface-raised); + box-shadow: none; + font-size: 20px; + line-height: 1; +} + +.popup-close:hover { + color: var(--text); + border-color: var(--accent); +} + +.interaction, +#interaction { + margin-top: 16px; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + float: right; +} + +.interaction input[type=button], +.interaction input[type=submit] { + margin: 0; + min-width: 110px; +} + +#popup-interaction { + margin-top: 14px; + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 8px; +} + +/* Notifications */ + +#notification { + position: fixed; + right: 12px; + top: 12px; + width: 260px; + max-height: calc(100vh - 24px); + overflow: auto; + border-radius: var(--radius-m); + border: 1px solid var(--line); + background: var(--surface-solid); + box-shadow: var(--shadow-2); +} + +#notification .element { + margin: 8px; + border-radius: 10px; + border-left: 4px solid var(--ok); + background: var(--surface-3); + padding: 8px; +} + +#notification h5 { + padding: 0; + margin-bottom: 6px; +} + +#notification p { + font-size: 11px; +} + +/* Log lines */ + +#content_log { + padding: 8px; +} + +#content_log pre { + margin-bottom: 5px; + padding: 8px; + border-radius: 8px; + background: var(--surface-1); + white-space: pre-wrap; + overflow-wrap: anywhere; + word-break: break-word; + line-height: 1.45; +} + +#logScreen p { + white-space: pre; + font-family: var(--font-mono); + font-size: 12px; + line-height: 1.55; +} + +.screenLogHidden { + transform: translate(0, -110px); +} + +.infoMsg { + color: var(--info); +} + +.errorMsg { + color: var(--error-text); +} + +.warningMsg { + color: var(--warn); +} + +.debugMsg { + color: var(--debug); +} + +/* Category badges */ + +.News, +.Movie, +.Series, +.Sports, +.Kids { + border-left: 3px solid transparent; + padding-left: 8px; +} + +.News { + border-color: #ff8f6e; +} + +.Movie { + border-color: #46a4ff; +} + +.Series { + border-color: #ffd267; +} + +.Sports { + border-color: #5ee495; +} + +.Kids { + border-color: #f6a8ff; +} diff --git a/html/css/screen.css b/html/css/layout.css similarity index 52% rename from html/css/screen.css rename to html/css/layout.css index 1f26d0b..efd5a56 100644 --- a/html/css/screen.css +++ b/html/css/layout.css @@ -1,3 +1,10 @@ +/* + * layout.css - shell layout (sidebar, header, content wrapper), the auth / + * wizard box pages and every responsive breakpoint. Loaded last. + */ + +/* Application shell */ + #layout { display: grid; grid-template-columns: 290px minmax(0, 1fr); @@ -15,8 +22,8 @@ border-radius: var(--radius-l); border: 1px solid var(--line); background: - linear-gradient(180deg, rgba(18, 36, 58, 0.95) 0%, rgba(10, 23, 38, 0.95) 100%), - radial-gradient(circle at 20% 0%, rgba(53, 210, 255, 0.12), transparent 48%); + linear-gradient(180deg, var(--panel-top) 0%, var(--panel-bottom) 100%), + radial-gradient(circle at 20% 0%, var(--panel-glow), transparent 48%); box-shadow: var(--shadow-2); overflow: hidden; } @@ -28,100 +35,25 @@ padding: 14px; } -#branch { - min-height: 18px; - margin: 2px 0 6px; - text-align: center; - font-size: 11px; - color: #ff9f8d; - letter-spacing: 0.08em; - text-transform: uppercase; -} - #logo { width: 100%; height: 76px; border-radius: 12px; border: 1px solid var(--line-soft); background: - linear-gradient(180deg, rgba(26, 49, 73, 0.55), rgba(13, 28, 45, 0.6)), + linear-gradient(180deg, var(--logo-tint-top), var(--logo-tint-bottom)), url("../img/logo_w_600x200.png") center no-repeat; background-size: contain; margin-bottom: 12px; } -#main-menu { - display: flex; - flex-direction: column; - gap: 7px; - overflow: auto; - padding-right: 4px; -} - -#main-menu li { - display: flex; - align-items: center; - gap: 10px; - min-height: 42px; - padding: 8px 11px; - border-radius: 12px; - border: 1px solid transparent; - background: rgba(11, 25, 40, 0.58); -} - -#main-menu li:hover { - border-color: var(--accent-soft); - transform: translateX(2px); -} - -#main-menu li:focus-visible { - border-color: rgba(103, 232, 255, 0.62); - transform: translateX(2px); - box-shadow: 0 0 0 3px rgba(53, 210, 255, 0.23); -} - -#main-menu li.menu-active { - border-color: rgba(103, 232, 255, 0.55); - background: linear-gradient(135deg, #6fe6ff 0%, #1cc5ff 100%); - box-shadow: 0 10px 18px rgba(28, 197, 255, 0.3); -} - -#main-menu li.menu-active p { - color: #03111a; -} - -#main-menu li.menu-active img { - filter: brightness(0.04) saturate(120%); -} - -nav img { - display: block; - width: 18px; - height: 18px; - max-width: 18px; - max-height: 18px; - flex: 0 0 auto; -} - -nav p { - margin: 0; - padding: 0; - text-align: left; - font-size: 12px; - font-weight: 600; - color: #d7eefe; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - .layout-right { min-width: 0; border-radius: var(--radius-l); border: 1px solid var(--line); background: - linear-gradient(180deg, rgba(17, 34, 54, 0.94) 0%, rgba(10, 20, 34, 0.96) 100%), - radial-gradient(circle at 100% 0%, rgba(53, 210, 255, 0.08), transparent 34%); + linear-gradient(180deg, var(--panel-top) 0%, var(--panel-bottom) 100%), + radial-gradient(circle at 100% 0%, var(--panel-glow), transparent 34%); box-shadow: var(--shadow-2); display: flex; flex-direction: column; @@ -134,14 +66,14 @@ nav p { gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--line-soft); - background: rgba(10, 22, 36, 0.52); + background: var(--surface-0); } #shell-title { margin: 0; font-size: 1.08rem; font-weight: 700; - color: #d8f1ff; + color: var(--text-heading); letter-spacing: 0.04em; } @@ -153,176 +85,7 @@ nav p { font-size: 12px; } -#connection-indicator { - margin-left: auto; - padding: 5px 11px; - border-radius: 999px; - font-size: 11px; - font-weight: 700; - letter-spacing: 0.05em; - text-transform: uppercase; -} - -#connection-indicator.status-idle { - color: #d8edff; - border: 1px solid #3a5877; - background: rgba(20, 42, 66, 0.65); -} - -#connection-indicator.status-busy { - color: #072031; - border: 1px solid #7ee8ff; - background: linear-gradient(135deg, #7be8ff 0%, #33cdff 100%); -} - -#connection-indicator.status-online { - color: #052219; - border: 1px solid #9ff0c8; - background: linear-gradient(135deg, #92f0c0 0%, #4fce93 100%); -} - -#connection-indicator.status-offline { - color: #ffe5e5; - border: 1px solid #ff9e9e; - background: linear-gradient(135deg, #ff7e7e 0%, #d34d4d 100%); -} - -#clientInfo, -#activeStreams, -#inactiveStreams { - width: 100%; - border-collapse: separate; - border-spacing: 7px; - background: rgba(8, 20, 33, 0.54); -} - -#clientInfo { - padding: 7px 10px 6px; - border-bottom: 1px solid var(--line-soft); -} - -#clientInfo tr { - vertical-align: top; -} - -#clientInfo .tdKey, -#clientInfo .tdVal, -#activeStreams .tdKey, -#inactiveStreams .tdKey, -#activeStreams .tdVal, -#inactiveStreams .tdVal, -#logInfo .tdVal, -#mappingInfo .tdVal { - border: 1px solid var(--line-soft); - border-radius: 8px; - padding: 7px 8px; - vertical-align: middle; - font-family: "IBM Plex Mono", "SFMono-Regular", "Consolas", monospace; -} - -#clientInfo .tdKey, -#activeStreams .tdKey, -#inactiveStreams .tdKey { - color: #53d9ff; - font-size: 10px; - text-transform: uppercase; -} - -#clientInfo .tdVal, -#activeStreams .tdVal, -#inactiveStreams .tdVal { - color: var(--text-muted); - font-size: 11px; - word-break: break-word; -} - -#clientInfo .tdVal a { - color: #8fdcff; - text-decoration: none; - border-bottom: 1px dotted rgba(143, 220, 255, 0.6); - word-break: break-all; -} - -#clientInfo .tdVal a:hover, -#clientInfo .tdVal a:focus { - color: #d7f4ff; - border-bottom-color: #d7f4ff; - text-decoration: none; -} - -.dashboard-cards { - display: grid; - grid-template-columns: repeat(6, minmax(130px, 1fr)); - gap: 9px; - padding: 10px 14px; - border-bottom: 1px solid var(--line-soft); - background: rgba(8, 18, 30, 0.45); -} - -.status-card { - border: 1px solid var(--line-soft); - border-radius: 12px; - background: rgba(13, 31, 49, 0.8); - padding: 10px; - min-height: 74px; - display: flex; - flex-direction: column; - justify-content: center; - gap: 4px; -} - -.status-card-label { - color: #8fb3cf; - font-size: 10px; - text-transform: uppercase; - letter-spacing: 0.07em; -} - -.status-card-value { - color: #e8f5ff; - font-size: 14px; - font-weight: 700; - overflow: hidden; - text-overflow: ellipsis; -} - -.status-card.status-card-ok { - border-color: rgba(67, 191, 130, 0.48); - background: linear-gradient(180deg, rgba(20, 54, 44, 0.9) 0%, rgba(12, 38, 31, 0.95) 100%); -} - -.status-card.status-card-warn { - border-color: rgba(255, 193, 90, 0.5); - background: linear-gradient(180deg, rgba(68, 50, 20, 0.86) 0%, rgba(44, 32, 14, 0.96) 100%); -} - -.status-card.status-card-error { - border-color: rgba(255, 111, 111, 0.5); - background: linear-gradient(180deg, rgba(73, 26, 26, 0.84) 0%, rgba(47, 19, 19, 0.96) 100%); -} - -#myStreamsBox { - border-bottom: 1px solid var(--line-soft); - background: rgba(10, 22, 36, 0.62); - transition: all 0.2s ease; -} - -#allStreams { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 8px; - padding: 8px; -} - -#activeStreams, -#inactiveStreams { - max-height: 120px; - overflow-y: auto; -} - -#inactiveStreams .tdKey { - color: #ff8f8f; -} +/* Content wrapper */ #content { display: block; @@ -332,7 +95,7 @@ nav p { #content h3 { margin-bottom: 6px; - color: #d4edff; + color: var(--text-heading); } #content-interaction { @@ -353,162 +116,14 @@ nav p { display: none; } -#box-wrapper { - width: 100%; - overflow: auto; - border: 1px solid var(--line-soft); - border-radius: 12px; - background: rgba(10, 21, 34, 0.72); -} - -#content_table, -#mapping-detail-table { - width: 100%; - border-collapse: collapse; -} - -#content_table .content_table_header { - position: sticky; - top: 0; - z-index: 2; - background: linear-gradient(180deg, rgba(23, 46, 72, 0.98), rgba(16, 32, 50, 0.98)); - border-bottom: 1px solid var(--line); -} - -#content_table .content_table_header td { - color: #8fd8ff; - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.07em; - padding: 10px 8px; -} - -#content_table tr { - border-left: 3px solid transparent; - border-bottom: 1px solid rgba(29, 55, 80, 0.72); - transition: background-color 0.2s ease; -} - -#content_table tr:hover { - background-color: rgba(28, 53, 79, 0.5); -} - -#content_table tr[tabindex], -#content_table td[tabindex] { - cursor: pointer; -} - -#content_table tr[tabindex]:focus-visible, -#content_table td[tabindex]:focus-visible, -.keyboard-clickable:focus-visible { - outline: 2px solid #7de5ff; - outline-offset: -2px; - background-color: rgba(39, 73, 106, 0.56); -} - -#content_table td { - padding: 7px 8px; - vertical-align: middle; -} - -#content_table img { - display: block; - width: auto; - max-width: 34px; - max-height: 30px; - margin: 0 auto; -} - -#content_table input[type=text] { - min-width: 48px; - max-width: 76px; - margin: 0; - padding: 6px 7px; - border-radius: 8px; - text-align: left; -} - -#content_table input[type=checkbox] { - margin: 0 auto; -} - -#content_table .mapping-edit-button { - min-height: 32px; - min-width: 64px; - margin: 0; - padding: 5px 10px; - font-size: 11px; - line-height: 1; -} - -#content_table tr.activeEPG { - border-left-color: #2ed486; -} - -#content_table tr.notActiveEPG { - border-left-color: #ff6868; -} - -#settings { - padding: 10px; -} - -#content_settings h4 { - margin: 15px 0 8px; - color: #d6efff; -} - -#content_settings table { - border: 1px solid var(--line-soft); - border-radius: 12px; - background: rgba(10, 22, 35, 0.62); - border-collapse: separate; - border-spacing: 0; - overflow: hidden; -} - -#content_settings td { - padding: 9px 8px; - border-bottom: 1px solid rgba(31, 57, 82, 0.62); -} - -#content_settings tr:last-child td { - border-bottom: 0; -} - -#content_settings pre { - color: #9ab7d0; - font-size: 11px; -} - -#content_log { - padding: 8px; -} - -#content_log pre { - margin-bottom: 5px; - padding: 8px; - border-radius: 8px; - background: rgba(13, 31, 49, 0.72); - white-space: pre-wrap; - overflow-wrap: anywhere; - word-break: break-word; - line-height: 1.45; -} - -#logScreen p { - white-space: pre; - font-family: "IBM Plex Mono", "SFMono-Regular", "Consolas", monospace; - font-size: 12px; - line-height: 1.55; -} +/* Login, first-user, wizard and maintenance box */ #box { width: min(680px, calc(100% - 24px)); margin: 14px auto; border-radius: var(--radius-l); border: 1px solid var(--line); - background: linear-gradient(180deg, rgba(16, 35, 56, 0.95) 0%, rgba(11, 24, 38, 0.96) 100%); + background: linear-gradient(180deg, var(--panel-top) 0%, var(--panel-bottom) 100%); box-shadow: var(--shadow-2); min-height: 430px; display: flex; @@ -523,14 +138,14 @@ nav p { border-radius: 12px; border: 1px solid var(--line); background: - linear-gradient(180deg, rgba(16, 35, 56, 0.84), rgba(11, 24, 38, 0.9)), + linear-gradient(180deg, var(--logo-tint-top), var(--logo-tint-bottom)), url("../img/logo_w_600x200.png") center no-repeat; background-size: 300px auto; } #headline { border-bottom: 1px solid var(--line); - background: rgba(10, 22, 37, 0.55); + background: var(--surface-0); padding: 14px; } @@ -560,10 +175,6 @@ nav p { min-width: 120px; } -.wizard { - margin: 10px 0; -} - .auth-screen { display: flex; flex-direction: column; @@ -578,6 +189,8 @@ nav p { display: table-cell; } +/* Breakpoints */ + @media only screen and (max-width: 1300px) { .dashboard-cards { grid-template-columns: repeat(3, minmax(130px, 1fr)); @@ -622,7 +235,7 @@ nav p { inset: 0; z-index: 1000; pointer-events: none; - background: rgba(3, 9, 15, 0.48); + background: var(--overlay-soft); opacity: 0; transition: opacity 0.2s ease; } @@ -698,7 +311,7 @@ nav p { padding: 8px; border: 1px solid var(--line-soft); border-radius: 12px; - background: rgba(9, 22, 36, 0.92); + background: var(--surface-solid); backdrop-filter: blur(6px); } @@ -771,7 +384,7 @@ nav p { gap: 8px; border-spacing: 0; white-space: normal; - background: rgba(8, 20, 33, 0.44); + background: var(--surface-0); } #clientInfo tr { @@ -791,16 +404,16 @@ nav p { justify-content: center; gap: 4px; padding: 10px 9px; - background: rgba(17, 34, 53, 0.5); + background: var(--surface-2); } #clientInfo .tdVal::before { content: attr(data-label); - color: #8bb9d7; + color: var(--text-soft); font-size: 9px; letter-spacing: 0.07em; text-transform: uppercase; - font-family: "Space Grotesk", "Avenir Next", "Trebuchet MS", sans-serif; + font-family: var(--font-sans); line-height: 1.2; } @@ -829,7 +442,7 @@ nav p { border-radius: 12px; margin-bottom: 10px; padding: 6px; - background: rgba(11, 24, 39, 0.86); + background: var(--surface-3); } #content_table td { @@ -841,12 +454,12 @@ nav p { grid-template-columns: minmax(92px, 36%) 1fr; align-items: center; gap: 8px; - background: rgba(17, 34, 53, 0.5); + background: var(--surface-2); } #content_table td::before { content: attr(data-label); - color: #8bb9d7; + color: var(--text-soft); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; @@ -967,6 +580,84 @@ nav p { } } +@media only screen and (max-width: 619px) { + h1 { + font-size: 1.46rem; + } + + #popup { + padding: 0; + } + + #popup-custom, + #mapping-detail, + #user-detail, + #file-detail { + max-width: none; + width: 100%; + height: 100%; + max-height: 100%; + border-radius: 0; + border: 0; + padding: 10px 10px calc(14px + env(safe-area-inset-bottom)); + } + + #popup-custom table { + border-spacing: 0 10px; + } + + #popup-custom tr { + display: block; + border: 1px solid var(--line-soft); + border-radius: 10px; + padding: 8px 8px 10px; + background: var(--surface-2); + } + + #popup-custom td { + display: block; + width: 100%; + padding: 4px 2px; + } + + #popup-custom td.left { + width: 100%; + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.06em; + } + + #popup-interaction { + position: sticky; + bottom: 0; + z-index: 5; + margin-top: 10px; + padding-top: 10px; + background: linear-gradient(180deg, var(--sticky-fade-from) 0%, var(--sticky-fade-to) 30%); + } + + .interaction, + #interaction { + justify-content: stretch; + } + + .interaction input[type=button], + .interaction input[type=submit], + #popup-interaction input[type=button] { + width: 100%; + min-height: 44px; + } + + .popup-title h3 { + font-size: 1.02rem; + } + + .popup-close { + min-width: 44px; + min-height: 44px; + } +} + @media only screen and (max-width: 430px) { #clientInfo { grid-template-columns: 1fr; diff --git a/html/css/tokens.css b/html/css/tokens.css new file mode 100644 index 0000000..a68ca39 --- /dev/null +++ b/html/css/tokens.css @@ -0,0 +1,313 @@ +/* + * tokens.css - design tokens (colours, spacing, radii, fonts, shadows). + * + * Load order: tokens.css, base.css, components.css, layout.css. + * + * The dark palette is the default. A light palette is applied when the user + * agent prefers a light colour scheme, and either palette can be forced with + * or , which always wins + * over the media query. Only colour tokens change between themes. + */ + +:root { + color-scheme: dark; + + /* Fonts */ + --font-sans: "Space Grotesk", "Avenir Next", "Trebuchet MS", sans-serif; + --font-mono: "IBM Plex Mono", "SFMono-Regular", "Consolas", monospace; + + /* Radii and shadows */ + --radius-s: 10px; + --radius-m: 14px; + --radius-l: 18px; + --shadow-1: 0 20px 45px rgba(0, 0, 0, 0.32); + --shadow-2: 0 12px 30px rgba(0, 0, 0, 0.28); + + /* Page background */ + --bg-0: #07111d; + --bg-1: #0c1a2b; + --bg-2: #12233a; + --bg-deep: #060d17; + --bg-glow-1: rgba(64, 132, 183, 0.22); + --bg-glow-2: rgba(18, 185, 255, 0.16); + + /* Panels and surfaces (translucent tints layered over the page) */ + --panel-top: rgba(17, 34, 56, 0.97); + --panel-bottom: rgba(12, 27, 44, 0.97); + --panel-glow: rgba(53, 210, 255, 0.12); + --surface-0: rgba(8, 20, 33, 0.54); + --surface-1: rgba(10, 22, 36, 0.72); + --surface-2: rgba(13, 31, 49, 0.8); + --surface-3: rgba(17, 35, 56, 0.84); + --surface-solid: rgba(10, 22, 36, 0.92); + --surface-raised: rgba(14, 32, 50, 0.85); + --surface-input: rgba(10, 22, 36, 0.78); + --surface-input-focus: rgba(9, 25, 40, 0.95); + --logo-tint-top: rgba(26, 49, 73, 0.55); + --logo-tint-bottom: rgba(13, 28, 45, 0.6); + --table-head-top: rgba(23, 46, 72, 0.98); + --table-head-bottom: rgba(16, 32, 50, 0.98); + --row-line: rgba(29, 55, 80, 0.72); + --row-hover: rgba(28, 53, 79, 0.5); + --row-focus: rgba(39, 73, 106, 0.56); + --overlay: rgba(3, 9, 16, 0.72); + --overlay-soft: rgba(3, 9, 15, 0.48); + --sticky-fade-from: rgba(12, 27, 44, 0.1); + --sticky-fade-to: rgba(12, 27, 44, 0.96); + --scroll-track: rgba(7, 17, 29, 0.65); + --scroll-thumb-a: #2d597f; + --scroll-thumb-b: #1e4060; + --scroll-thumb-hover-a: #3678ac; + --scroll-thumb-hover-b: #20537c; + + /* Lines */ + --line: #274462; + --line-soft: #1b334d; + --line-strong: #3a5877; + + /* Text */ + --text: #e9f5ff; + --text-heading: #d6efff; + --text-muted: #b7cee1; + --text-soft: #8fb3cf; + --text-placeholder: #7e9ab4; + --text-on-accent: #03101a; + --text-on-ok: #052219; + --text-on-error: #ffe5e5; + + /* Accent */ + --accent: #35d2ff; + --accent-strong: #12b9ff; + --accent-bright: #67e8ff; + --accent-hover: #8de7ff; + --accent-text: #8fd8ff; + --accent-text-hover: #d7f4ff; + --accent-soft: rgba(53, 210, 255, 0.2); + --accent-ring: rgba(53, 210, 255, 0.17); + --accent-border: rgba(103, 232, 255, 0.55); + --accent-shadow: rgba(18, 185, 255, 0.3); + --accent-shadow-strong: rgba(18, 185, 255, 0.36); + --accent-gradient: linear-gradient(135deg, var(--accent-bright) 0%, var(--accent-strong) 100%); + --link-underline: rgba(143, 220, 255, 0.6); + --focus-ring: #7de5ff; + --focus-ring-soft: #91eaff; + --checkbox-checked: #39d6ff; + --checkbox-checked-border: #89ebff; + --loader: #58ddff; + + /* Status */ + --ok: #2fd18a; + --ok-bright: #92f0c0; + --ok-mid: #4fce93; + --ok-border: #9ff0c8; + --ok-soft: rgba(67, 191, 130, 0.48); + --ok-surface-top: rgba(20, 54, 44, 0.9); + --ok-surface-bottom: rgba(12, 38, 31, 0.95); + --warn: #ffc15a; + --warn-soft: rgba(255, 193, 90, 0.5); + --warn-surface-top: rgba(68, 50, 20, 0.86); + --warn-surface-bottom: rgba(44, 32, 14, 0.96); + --error: #ff6f6f; + --error-text: #ff8d8d; + --error-text-soft: #ffd8d8; + --error-bright: #ff7f7f; + --error-strong: #e94343; + --error-border: #ff9e9e; + --error-soft: rgba(255, 111, 111, 0.45); + --error-surface: rgba(87, 22, 22, 0.45); + --error-surface-top: rgba(73, 26, 26, 0.84); + --error-surface-bottom: rgba(47, 19, 19, 0.96); + --error-shadow: rgba(233, 67, 67, 0.35); + --info: #87b0d1; + --debug: #d687ff; +} + +/* + * Light palette. Only tokens that differ from the dark palette are listed. + * The same block appears twice on purpose: once for the media query (skipped + * when dark is forced with data-theme="dark") and once for the explicit + * data-theme="light" override. Keep the two copies identical. + */ +@media (prefers-color-scheme: light) { + :root:not([data-theme="dark"]) { + color-scheme: light; + + --bg-0: #e9eff5; + --bg-1: #f5f8fb; + --bg-2: #dfe7ef; + --bg-deep: #dfe7ef; + --bg-glow-1: rgba(64, 132, 183, 0.14); + --bg-glow-2: rgba(18, 185, 255, 0.12); + + --panel-top: rgba(255, 255, 255, 0.97); + --panel-bottom: rgba(246, 249, 252, 0.97); + --panel-glow: rgba(18, 185, 255, 0.08); + --surface-0: rgba(255, 255, 255, 0.55); + --surface-1: rgba(255, 255, 255, 0.75); + --surface-2: rgba(236, 243, 249, 0.85); + --surface-3: rgba(232, 240, 247, 0.9); + --surface-solid: rgba(255, 255, 255, 0.94); + --surface-raised: rgba(228, 236, 244, 0.9); + --surface-input: rgba(255, 255, 255, 0.85); + --surface-input-focus: rgba(255, 255, 255, 1); + --logo-tint-top: rgba(15, 31, 48, 0.96); + --logo-tint-bottom: rgba(11, 23, 39, 0.98); + --table-head-top: rgba(232, 240, 248, 0.98); + --table-head-bottom: rgba(222, 232, 243, 0.98); + --row-line: rgba(100, 130, 160, 0.3); + --row-hover: rgba(0, 90, 150, 0.07); + --row-focus: rgba(0, 90, 150, 0.14); + --overlay: rgba(20, 35, 52, 0.5); + --overlay-soft: rgba(20, 35, 52, 0.35); + --sticky-fade-from: rgba(246, 249, 252, 0.1); + --sticky-fade-to: rgba(246, 249, 252, 0.96); + --scroll-track: rgba(200, 214, 228, 0.6); + --scroll-thumb-a: #9fb6cb; + --scroll-thumb-b: #7f9bb3; + --scroll-thumb-hover-a: #7f9bb3; + --scroll-thumb-hover-b: #61819c; + + --line: #b9cadb; + --line-soft: #d3dfea; + --line-strong: #9fb4c8; + + --text: #142434; + --text-heading: #0f2033; + --text-muted: #4a6379; + --text-soft: #526a80; + --text-placeholder: #58708a; + --text-on-error: #4a0c0c; + + --accent: #0069a8; + --accent-hover: #00517f; + --accent-text: #0b6a95; + --accent-text-hover: #003a5c; + --accent-soft: rgba(0, 105, 168, 0.2); + --accent-ring: rgba(0, 105, 168, 0.18); + --accent-border: rgba(0, 105, 168, 0.5); + --accent-shadow: rgba(0, 105, 168, 0.22); + --accent-shadow-strong: rgba(0, 105, 168, 0.3); + --link-underline: rgba(11, 106, 149, 0.5); + --focus-ring: #0a7fc0; + --focus-ring-soft: #0a7fc0; + --checkbox-checked: #12b9ff; + --checkbox-checked-border: #0a7fc0; + --loader: #0a7fc0; + + --ok: #12734a; + --ok-bright: #a9efcc; + --ok-mid: #5fd39b; + --ok-border: #4fb884; + --ok-soft: rgba(18, 115, 74, 0.45); + --ok-surface-top: rgba(226, 246, 235, 0.95); + --ok-surface-bottom: rgba(208, 238, 222, 0.98); + --warn: #7f5300; + --warn-soft: rgba(183, 121, 31, 0.5); + --warn-surface-top: rgba(253, 243, 224, 0.95); + --warn-surface-bottom: rgba(248, 232, 200, 0.98); + --error: #c62828; + --error-text: #b02020; + --error-text-soft: #8a1a1a; + --error-bright: #f6a5a5; + --error-strong: #e07575; + --error-border: #d95c5c; + --error-soft: rgba(198, 40, 40, 0.45); + --error-surface: rgba(255, 220, 220, 0.6); + --error-surface-top: rgba(253, 232, 232, 0.95); + --error-surface-bottom: rgba(248, 214, 214, 0.98); + --error-shadow: rgba(198, 40, 40, 0.25); + --info: #3f6785; + --debug: #7a35b5; + } +} + +:root[data-theme="light"] { + color-scheme: light; + + --bg-0: #e9eff5; + --bg-1: #f5f8fb; + --bg-2: #dfe7ef; + --bg-deep: #dfe7ef; + --bg-glow-1: rgba(64, 132, 183, 0.14); + --bg-glow-2: rgba(18, 185, 255, 0.12); + + --panel-top: rgba(255, 255, 255, 0.97); + --panel-bottom: rgba(246, 249, 252, 0.97); + --panel-glow: rgba(18, 185, 255, 0.08); + --surface-0: rgba(255, 255, 255, 0.55); + --surface-1: rgba(255, 255, 255, 0.75); + --surface-2: rgba(236, 243, 249, 0.85); + --surface-3: rgba(232, 240, 247, 0.9); + --surface-solid: rgba(255, 255, 255, 0.94); + --surface-raised: rgba(228, 236, 244, 0.9); + --surface-input: rgba(255, 255, 255, 0.85); + --surface-input-focus: rgba(255, 255, 255, 1); + --logo-tint-top: rgba(15, 31, 48, 0.96); + --logo-tint-bottom: rgba(11, 23, 39, 0.98); + --table-head-top: rgba(232, 240, 248, 0.98); + --table-head-bottom: rgba(222, 232, 243, 0.98); + --row-line: rgba(100, 130, 160, 0.3); + --row-hover: rgba(0, 90, 150, 0.07); + --row-focus: rgba(0, 90, 150, 0.14); + --overlay: rgba(20, 35, 52, 0.5); + --overlay-soft: rgba(20, 35, 52, 0.35); + --sticky-fade-from: rgba(246, 249, 252, 0.1); + --sticky-fade-to: rgba(246, 249, 252, 0.96); + --scroll-track: rgba(200, 214, 228, 0.6); + --scroll-thumb-a: #9fb6cb; + --scroll-thumb-b: #7f9bb3; + --scroll-thumb-hover-a: #7f9bb3; + --scroll-thumb-hover-b: #61819c; + + --line: #b9cadb; + --line-soft: #d3dfea; + --line-strong: #9fb4c8; + + --text: #142434; + --text-heading: #0f2033; + --text-muted: #4a6379; + --text-soft: #526a80; + --text-placeholder: #58708a; + --text-on-error: #4a0c0c; + + --accent: #0069a8; + --accent-hover: #00517f; + --accent-text: #0b6a95; + --accent-text-hover: #003a5c; + --accent-soft: rgba(0, 105, 168, 0.2); + --accent-ring: rgba(0, 105, 168, 0.18); + --accent-border: rgba(0, 105, 168, 0.5); + --accent-shadow: rgba(0, 105, 168, 0.22); + --accent-shadow-strong: rgba(0, 105, 168, 0.3); + --link-underline: rgba(11, 106, 149, 0.5); + --focus-ring: #0a7fc0; + --focus-ring-soft: #0a7fc0; + --checkbox-checked: #12b9ff; + --checkbox-checked-border: #0a7fc0; + --loader: #0a7fc0; + + --ok: #12734a; + --ok-bright: #a9efcc; + --ok-mid: #5fd39b; + --ok-border: #4fb884; + --ok-soft: rgba(18, 115, 74, 0.45); + --ok-surface-top: rgba(226, 246, 235, 0.95); + --ok-surface-bottom: rgba(208, 238, 222, 0.98); + --warn: #7f5300; + --warn-soft: rgba(183, 121, 31, 0.5); + --warn-surface-top: rgba(253, 243, 224, 0.95); + --warn-surface-bottom: rgba(248, 232, 200, 0.98); + --error: #c62828; + --error-text: #b02020; + --error-text-soft: #8a1a1a; + --error-bright: #f6a5a5; + --error-strong: #e07575; + --error-border: #d95c5c; + --error-soft: rgba(198, 40, 40, 0.45); + --error-surface: rgba(255, 220, 220, 0.6); + --error-surface-top: rgba(253, 232, 232, 0.95); + --error-surface-bottom: rgba(248, 214, 214, 0.98); + --error-shadow: rgba(198, 40, 40, 0.25); + --info: #3f6785; + --debug: #7a35b5; +} diff --git a/html/index.html b/html/index.html index e1facf4..819856a 100644 --- a/html/index.html +++ b/html/index.html @@ -1,11 +1,13 @@ - + xTeVe - - + + + + @@ -37,7 +39,7 @@ --> @@ -45,7 +47,7 @@
-

xTeVe Control Panel

+

xTeVe Control Panel

Connecting...

diff --git a/html/login.html b/html/login.html index c0adae0..28adfd6 100644 --- a/html/login.html +++ b/html/login.html @@ -1,11 +1,13 @@ - + xTeVe - - + + + + @@ -13,7 +15,7 @@ -
+

Login

diff --git a/html/maintenance.html b/html/maintenance.html index d38f47d..e6512bd 100644 --- a/html/maintenance.html +++ b/html/maintenance.html @@ -1,18 +1,20 @@ - + xTeVe - - + + + + -
+

Maintenance

@@ -24,7 +26,7 @@ -
+
diff --git a/ts/authentication_ts.ts b/ts/authentication.ts similarity index 100% rename from ts/authentication_ts.ts rename to ts/authentication.ts diff --git a/ts/base_ts.ts b/ts/base.ts similarity index 100% rename from ts/base_ts.ts rename to ts/base.ts diff --git a/ts/configuration_ts.ts b/ts/configuration.ts similarity index 100% rename from ts/configuration_ts.ts rename to ts/configuration.ts diff --git a/ts/logs_ts.ts b/ts/logs.ts similarity index 100% rename from ts/logs_ts.ts rename to ts/logs.ts diff --git a/ts/network_ts.ts b/ts/network.ts similarity index 100% rename from ts/network_ts.ts rename to ts/network.ts diff --git a/ts/settings_ts.ts b/ts/settings.ts similarity index 100% rename from ts/settings_ts.ts rename to ts/settings.ts