diff --git a/app/styles/base.css b/app/styles/base.css index 395c18e..87bfb45 100644 --- a/app/styles/base.css +++ b/app/styles/base.css @@ -30,30 +30,31 @@ */ :root { - font-family: sans-serif; + font-family: sans-serif; + line-height: 1.6; } body { - margin:0; - padding:0; - /*Background image with light grey curve.*/ - background-color:#494949; - background-repeat:no-repeat; - background-position:right bottom; - height:100%; - touch-action: none; + margin:0; + padding:0; + /*Background image with light grey curve.*/ + background-color:#494949; + background-repeat:no-repeat; + background-position:right bottom; + height:100%; + touch-action: none; } html { - height:100%; + height:100%; } .noVNC_only_touch.noVNC_hidden { - display: none; + display: none; } .noVNC_disabled { - color: rgb(128, 128, 128); + color: var(--novnc-grey); } /* ---------------------------------------- @@ -62,33 +63,33 @@ html { */ .noVNC_spinner { - position: relative; + position: relative; } .noVNC_spinner, .noVNC_spinner::before, .noVNC_spinner::after { - width: 10px; - height: 10px; - border-radius: 2px; - box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); - animation: noVNC_spinner 1.0s linear infinite; + width: 10px; + height: 10px; + border-radius: 2px; + box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); + animation: noVNC_spinner 1.0s linear infinite; } .noVNC_spinner::before { - content: ""; - position: absolute; - left: 0px; - top: 0px; - animation-delay: -0.1s; + content: ""; + position: absolute; + left: 0px; + top: 0px; + animation-delay: -0.1s; } .noVNC_spinner::after { - content: ""; - position: absolute; - top: 0px; - left: 0px; - animation-delay: 0.1s; + content: ""; + position: absolute; + top: 0px; + left: 0px; + animation-delay: 0.1s; } @keyframes noVNC_spinner { - 0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; } - 25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; } - 50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; } + 0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; } + 25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; } + 50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; } } /* ---------------------------------------- @@ -97,39 +98,39 @@ html { */ .noVNC_center { - /* - * This is a workaround because webkit misrenders transforms and - * uses non-integer coordinates, resulting in blurry content. - * Ideally we'd use "top: 50%; transform: translateY(-50%);" on - * the objects instead. - */ - display: flex; - align-items: center; - justify-content: center; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; + /* + * This is a workaround because webkit misrenders transforms and + * uses non-integer coordinates, resulting in blurry content. + * Ideally we'd use "top: 50%; transform: translateY(-50%);" on + * the objects instead. + */ + display: flex; + align-items: center; + justify-content: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; } .noVNC_center > * { - pointer-events: auto; + pointer-events: auto; } .noVNC_vcenter { - display: flex !important; - flex-direction: column; - justify-content: center; - position: fixed; - top: 0; - left: 0; - height: 100%; - margin: 0 !important; - padding: 0 !important; - pointer-events: none; + display: flex !important; + flex-direction: column; + justify-content: center; + position: fixed; + top: 0; + left: 0; + height: 100%; + margin: 0 !important; + padding: 0 !important; + pointer-events: none; } .noVNC_vcenter > * { - pointer-events: auto; + pointer-events: auto; } /* ---------------------------------------- @@ -138,7 +139,7 @@ html { */ .noVNC_connect_layer { - z-index: 60; + z-index: 60; } /* ---------------------------------------- @@ -147,69 +148,69 @@ html { */ #noVNC_fallback_error { - z-index: 1000; - visibility: hidden; - /* Put a dark background in front of everything but the error, - and don't let mouse events pass through */ - background: rgba(0, 0, 0, 0.8); - pointer-events: all; + z-index: 1000; + visibility: hidden; + /* Put a dark background in front of everything but the error, + and don't let mouse events pass through */ + background: rgba(0, 0, 0, 0.8); + pointer-events: all; } #noVNC_fallback_error.noVNC_open { - visibility: visible; + visibility: visible; } #noVNC_fallback_error > div { - max-width: calc(100vw - 30px - 30px); - max-height: calc(100vh - 30px - 30px); - overflow: auto; + max-width: calc(100vw - 30px - 30px); + max-height: calc(100vh - 30px - 30px); + overflow: auto; - padding: 15px; + padding: 15px; - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - transform: translateY(-50px); - opacity: 0; + transform: translateY(-50px); + opacity: 0; - text-align: center; - font-weight: bold; - color: #fff; + text-align: center; + font-weight: bold; + color: #fff; - border-radius: 10px; - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); - background: rgba(200,55,55,0.8); + border-radius: 12px; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + background: rgba(200,55,55,0.8); } #noVNC_fallback_error.noVNC_open > div { - transform: translateY(0); - opacity: 1; + transform: translateY(0); + opacity: 1; } #noVNC_fallback_errormsg { - font-weight: normal; + font-weight: normal; } #noVNC_fallback_errormsg .noVNC_message { - display: inline-block; - text-align: left; - font-family: monospace; - white-space: pre-wrap; + display: inline-block; + text-align: left; + font-family: monospace; + white-space: pre-wrap; } #noVNC_fallback_error .noVNC_location { - font-style: italic; - font-size: 0.8em; - color: rgba(255, 255, 255, 0.8); + font-style: italic; + font-size: 0.8em; + color: rgba(255, 255, 255, 0.8); } #noVNC_fallback_error .noVNC_stack { - padding: 10px; - margin: 10px; - font-size: 0.8em; - text-align: left; - font-family: monospace; - white-space: pre; - border: 1px solid rgba(0, 0, 0, 0.5); - background: rgba(0, 0, 0, 0.2); - overflow: auto; + padding: 10px; + margin: 10px; + font-size: 0.8em; + text-align: left; + font-family: monospace; + white-space: pre; + border: 1px solid rgba(0, 0, 0, 0.5); + background: rgba(0, 0, 0, 0.2); + overflow: auto; } /* ---------------------------------------- @@ -218,325 +219,333 @@ html { */ #noVNC_control_bar_anchor { - /* The anchor is needed to get z-stacking to work */ - position: fixed; - z-index: 10; + /* The anchor is needed to get z-stacking to work */ + position: fixed; + z-index: 10; - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - /* Edge misrenders animations wihthout this */ - transform: translateX(0); + /* Edge misrenders animations wihthout this */ + transform: translateX(0); } :root.noVNC_connected #noVNC_control_bar_anchor.noVNC_idle { - opacity: 0.8; + opacity: 0.8; } #noVNC_control_bar_anchor.noVNC_right { - left: auto; - right: 0; + left: auto; + right: 0; } #noVNC_control_bar { - position: relative; - left: -100%; + position: relative; + left: -100%; - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - background-color: rgb(110, 132, 163); - border-radius: 0 10px 10px 0; + background-color: var(--novnc-blue); + border-radius: 0 12px 12px 0; - user-select: none; - -webkit-user-select: none; - -webkit-touch-callout: none; /* Disable iOS image long-press popup */ + user-select: none; + -webkit-user-select: none; + -webkit-touch-callout: none; /* Disable iOS image long-press popup */ } #noVNC_control_bar.noVNC_open { - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); - left: 0; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + left: 0; } #noVNC_control_bar::before { - /* This extra element is to get a proper shadow */ - content: ""; - position: absolute; - z-index: -1; - height: 100%; - width: 30px; - left: -30px; - transition: box-shadow 0.5s ease-in-out; + /* This extra element is to get a proper shadow */ + content: ""; + position: absolute; + z-index: -1; + height: 100%; + width: 30px; + left: -30px; + transition: box-shadow 0.5s ease-in-out; } #noVNC_control_bar.noVNC_open::before { - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); } .noVNC_right #noVNC_control_bar { - left: 100%; - border-radius: 10px 0 0 10px; + left: 100%; + border-radius: 12px 0 0 12px; } .noVNC_right #noVNC_control_bar.noVNC_open { - left: 0; + left: 0; } .noVNC_right #noVNC_control_bar::before { - visibility: hidden; + visibility: hidden; } #noVNC_control_bar_handle { - position: absolute; - left: -15px; - top: 0; - transform: translateY(35px); - width: calc(100% + 30px); - height: 50px; - z-index: -1; - cursor: pointer; - border-radius: 5px; - background-color: rgb(83, 99, 122); - background-image: url("../images/handle_bg.svg"); - background-repeat: no-repeat; - background-position: right; - box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5); + position: absolute; + left: -15px; + top: 0; + transform: translateY(35px); + width: calc(100% + 30px); + height: 50px; + z-index: -1; + cursor: pointer; + border-radius: 6px; + background-color: var(--novnc-darkblue); + background-image: url("../images/handle_bg.svg"); + background-repeat: no-repeat; + background-position: right; + box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5); } #noVNC_control_bar_handle:after { - content: ""; - transition: transform 0.5s ease-in-out; - background: url("../images/handle.svg"); - position: absolute; - top: 22px; /* (50px-6px)/2 */ - right: 5px; - width: 5px; - height: 6px; + content: ""; + transition: transform 0.5s ease-in-out; + background: url("../images/handle.svg"); + position: absolute; + top: 22px; /* (50px-6px)/2 */ + right: 5px; + width: 5px; + height: 6px; } #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { - transform: translateX(1px) rotate(180deg); + transform: translateX(1px) rotate(180deg); } :root:not(.noVNC_connected) #noVNC_control_bar_handle { - display: none; + display: none; } .noVNC_right #noVNC_control_bar_handle { - background-position: left; + background-position: left; } .noVNC_right #noVNC_control_bar_handle:after { - left: 5px; - right: 0; - transform: translateX(1px) rotate(180deg); + left: 5px; + right: 0; + transform: translateX(1px) rotate(180deg); } .noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { - transform: none; + transform: none; } /* Larger touch area for the handle, used when a touch screen is available */ #noVNC_control_bar_handle div { - position: absolute; - right: -35px; - top: 0; - width: 50px; - height: 100%; - display: none; + position: absolute; + right: -35px; + top: 0; + width: 50px; + height: 100%; + display: none; } @media (any-pointer: coarse) { - #noVNC_control_bar_handle div { - display: initial; - } + #noVNC_control_bar_handle div { + display: initial; + } } .noVNC_right #noVNC_control_bar_handle div { - left: -35px; - right: auto; + left: -35px; + right: auto; } #noVNC_control_bar > .noVNC_scroll { - max-height: 100vh; /* Chrome is buggy with 100% */ - overflow-x: hidden; - overflow-y: auto; - padding: 0 10px; + max-height: 100vh; /* Chrome is buggy with 100% */ + overflow-x: hidden; + overflow-y: auto; + padding: 0 10px; } #noVNC_control_bar > .noVNC_scroll > * { - display: block; - margin: 10px auto; + display: block; + margin: 10px auto; } /* Control bar hint */ #noVNC_hint_anchor { - position: fixed; - right: -50px; - left: auto; + position: fixed; + right: -50px; + left: auto; } #noVNC_control_bar_anchor.noVNC_right + #noVNC_hint_anchor { - left: -50px; - right: auto; + left: -50px; + right: auto; } #noVNC_control_bar_hint { - position: relative; - transform: scale(0); - width: 100px; - height: 50%; - max-height: 600px; + position: relative; + transform: scale(0); + width: 100px; + height: 50%; + max-height: 600px; - visibility: hidden; - opacity: 0; - transition: 0.2s ease-in-out; - background: transparent; - box-shadow: 0 0 10px black, inset 0 0 10px 10px rgba(110, 132, 163, 0.8); - border-radius: 10px; - transition-delay: 0s; + visibility: hidden; + opacity: 0; + transition: 0.2s ease-in-out; + background: transparent; + box-shadow: 0 0 10px black, inset 0 0 10px 10px var(--novnc-darkblue); + border-radius: 12px; + transition-delay: 0s; } #noVNC_control_bar_hint.noVNC_active { - visibility: visible; - opacity: 1; - transition-delay: 0.2s; - transform: scale(1); + visibility: visible; + opacity: 1; + transition-delay: 0.2s; + transform: scale(1); } #noVNC_control_bar_hint.noVNC_notransition { - transition: none !important; + transition: none !important; } /* Control bar buttons */ #noVNC_control_bar .noVNC_button { - padding: 4px 4px; - vertical-align: middle; - border:1px solid rgba(255, 255, 255, 0.2); - border-radius: 6px; - background-color: transparent; - background-image: unset; /* we don't want the gradiant from input.css */ + min-width: unset; + padding: 4px 4px; + vertical-align: middle; + border:1px solid rgba(255, 255, 255, 0.2); + border-radius: 6px; + background-color: transparent; } #noVNC_control_bar .noVNC_button.noVNC_selected { - border-color: rgba(0, 0, 0, 0.8); - background-color: rgba(0, 0, 0, 0.5); -} -#noVNC_control_bar .noVNC_button.noVNC_selected:not(:disabled):hover { - border-color: rgba(0, 0, 0, 0.4); - background-color: rgba(0, 0, 0, 0.2); -} -#noVNC_control_bar .noVNC_button:not(:disabled):hover { - background-color: rgba(255, 255, 255, 0.2); -} -#noVNC_control_bar .noVNC_button:not(:disabled):active { - padding-top: 5px; - padding-bottom: 3px; -} -#noVNC_control_bar .noVNC_button.noVNC_hidden { - display: none !important; -} - -/* Android browsers don't properly update hover state if touch events are - * intercepted, like they are when clicking on the remote screen. */ -@media (any-pointer: coarse) { - #noVNC_control_bar .noVNC_button:not(:disabled):hover { - background-color: transparent; - } - #noVNC_control_bar .noVNC_button.noVNC_selected:not(:disabled):hover { border-color: rgba(0, 0, 0, 0.8); background-color: rgba(0, 0, 0, 0.5); - } } - +#noVNC_control_bar .noVNC_button.noVNC_hidden { + display: none !important; +} /* Panels */ .noVNC_panel { - transform: translateX(25px); + transform: translateX(25px); - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - box-sizing: border-box; /* so max-width don't have to care about padding */ - max-width: calc(100vw - 75px - 25px); /* minus left and right margins */ - max-height: 100vh; /* Chrome is buggy with 100% */ - overflow-x: hidden; - overflow-y: auto; + box-sizing: border-box; /* so max-width don't have to care about padding */ + max-width: calc(100vw - 75px - 25px); /* minus left and right margins */ + max-height: 100vh; /* Chrome is buggy with 100% */ + overflow-x: hidden; + overflow-y: auto; - visibility: hidden; - opacity: 0; + visibility: hidden; + opacity: 0; - padding: 15px; + padding: 15px; - background: #fff; - border-radius: 10px; - color: #000; - border: 2px solid #E0E0E0; - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + background: #fff; + border-radius: 12px; + color: #000; + border: 2px solid #E0E0E0; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); } .noVNC_panel.noVNC_open { - visibility: visible; - opacity: 1; - transform: translateX(75px); + visibility: visible; + opacity: 1; + transform: translateX(75px); } .noVNC_right .noVNC_vcenter { - left: auto; - right: 0; + left: auto; + right: 0; } .noVNC_right .noVNC_panel { - transform: translateX(-25px); + transform: translateX(-25px); } .noVNC_right .noVNC_panel.noVNC_open { - transform: translateX(-75px); + transform: translateX(-75px); } .noVNC_panel > * { - display: block; - margin: 10px auto; + display: block; + margin: 10px auto; } .noVNC_panel > *:first-child { - margin-top: 0 !important; + margin-top: 0 !important; } .noVNC_panel > *:last-child { - margin-bottom: 0 !important; + margin-bottom: 0 !important; } .noVNC_panel hr { - border: none; - border-top: 1px solid rgb(192, 192, 192); + border: none; + border-top: 1px solid var(--novnc-lightgrey); + width: 100%; /*
inside a flexbox will otherwise be 0px wide */ } .noVNC_panel label { - display: block; - white-space: nowrap; - margin: 5px; + display: block; + white-space: nowrap; + margin: 5px; +} +@media (max-width: 540px) { + /* Allow wrapping on small screens */ + .noVNC_panel label { + white-space: unset; + } } .noVNC_panel li { - margin: 5px; + margin: 5px; +} + +.noVNC_panel button, +.noVNC_panel select, +.noVNC_panel textarea, +.noVNC_panel input:not([type=checkbox]):not([type=radio]) { + margin-left: 6px; + /* Prevent inputs in panels from being too wide */ + max-width: calc(100% - 6px - var(--input-xpadding) * 2); } .noVNC_panel .noVNC_heading { - background-color: rgb(110, 132, 163); - border-radius: 5px; - padding: 5px; - /* Compensate for padding in image */ - padding-right: 8px; - color: white; - font-size: 20px; - white-space: nowrap; + background-color: var(--novnc-blue); + border-radius: 6px; + padding: 5px 8px; + /* Compensate for padding in image */ + padding-right: 11px; + display: flex; + align-items: center; + gap: 6px; + color: white; + font-size: 20px; + font-weight: bold; + white-space: nowrap; } .noVNC_panel .noVNC_heading img { - vertical-align: bottom; + vertical-align: bottom; } -.noVNC_submit { - float: right; +.noVNC_panel form { + display: flex; + flex-direction: column; + gap: 12px +} + +.noVNC_panel .button_row { + margin-top: 10px; + display: flex; + gap: 10px; + justify-content: space-between; +} +.noVNC_panel .button_row *:only-child { + margin-left: auto; /* Align single buttons to the right */ } /* Expanders */ .noVNC_expander { - cursor: pointer; + cursor: pointer; } .noVNC_expander::before { - content: url("../images/expander.svg"); - display: inline-block; - margin-right: 5px; - transition: 0.2s ease-in-out; + content: url("../images/expander.svg"); + display: inline-block; + margin-right: 5px; + transition: 0.2s ease-in-out; } .noVNC_expander.noVNC_open::before { - transform: rotateZ(90deg); + transform: rotateZ(90deg); } .noVNC_expander ~ * { - margin: 5px; - margin-left: 10px; - padding: 5px; - background: rgba(0, 0, 0, 0.05); - border-radius: 5px; + margin: 5px; + margin-left: 10px; + padding: 5px; + background: rgba(0, 0, 0, 0.04); + border-radius: 6px; } .noVNC_expander:not(.noVNC_open) ~ * { - display: none; + display: none; } /* Control bar content */ #noVNC_control_bar .noVNC_logo { - font-size: 13px; + font-size: 13px; } .noVNC_logo + hr { @@ -546,92 +555,92 @@ html { } :root:not(.noVNC_connected) #noVNC_view_drag_button { - display: none; + display: none; } /* noVNC Touch Device only buttons */ :root:not(.noVNC_connected) #noVNC_mobile_buttons { - display: none; + display: none; } @media not all and (any-pointer: coarse) { - /* FIXME: The button for the virtual keyboard is the only button in this - group of "mobile buttons". It is bad to assume that no touch - devices have physical keyboards available. Hopefully we can get - a media query for this: - https://github.com/w3c/csswg-drafts/issues/3871 */ - :root.noVNC_connected #noVNC_mobile_buttons { - display: none; - } + /* FIXME: The button for the virtual keyboard is the only button in this + group of "mobile buttons". It is bad to assume that no touch + devices have physical keyboards available. Hopefully we can get + a media query for this: + https://github.com/w3c/csswg-drafts/issues/3871 */ + :root.noVNC_connected #noVNC_mobile_buttons { + display: none; + } } /* Extra manual keys */ :root:not(.noVNC_connected) #noVNC_toggle_extra_keys_button { - display: none; + display: none; } #noVNC_modifiers { - background-color: rgb(92, 92, 92); - border: none; - padding: 10px; + background-color: var(--novnc-darkgrey); + border: none; + padding: 10px; } /* Shutdown/Reboot */ :root:not(.noVNC_connected) #noVNC_power_button { - display: none; + display: none; } #noVNC_power { } #noVNC_power_buttons { - display: none; + display: none; } #noVNC_power input[type=button] { - width: 100%; + width: 100%; } /* Clipboard */ :root:not(.noVNC_connected) #noVNC_clipboard_button { - display: none; + display: none; } #noVNC_clipboard_text { - width: 360px; - min-width: 150px; - height: 160px; - min-height: 70px; + width: 360px; + min-width: 150px; + height: 160px; + min-height: 70px; - box-sizing: border-box; - max-width: 100%; - /* minus approximate height of title, height of subtitle, and margin */ - max-height: calc(100vh - 10em - 25px); + box-sizing: border-box; + max-width: 100%; + /* minus approximate height of title, height of subtitle, and margin */ + max-height: calc(100vh - 10em - 25px); } /* Settings */ #noVNC_settings { } #noVNC_settings ul { - list-style: none; - padding: 0px; + list-style: none; + padding: 0px; } #noVNC_setting_port { - width: 80px; + width: 80px; } #noVNC_setting_path { - width: 100px; + width: 100px; } /* Version */ .noVNC_version_wrapper { - font-size: small; + font-size: small; } .noVNC_version { - margin-left: 1rem; + margin-left: 1rem; } /* Connection controls */ :root:not(.noVNC_connected) #noVNC_disconnect_button { - display: none; + display: none; } /* ---------------------------------------- @@ -640,64 +649,64 @@ html { */ #noVNC_status { - position: fixed; - top: 0; - left: 0; - width: 100%; - z-index: 100; - transform: translateY(-100%); + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 100; + transform: translateY(-100%); - cursor: pointer; + cursor: pointer; - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - visibility: hidden; - opacity: 0; + visibility: hidden; + opacity: 0; - padding: 5px; + padding: 5px; - display: flex; - flex-direction: row; - justify-content: center; - align-content: center; + display: flex; + flex-direction: row; + justify-content: center; + align-content: center; - line-height: 1.6; - word-wrap: break-word; - color: #fff; + line-height: 1.6; + word-wrap: break-word; + color: #fff; - border-bottom: 1px solid rgba(0, 0, 0, 0.9); + border-bottom: 1px solid rgba(0, 0, 0, 0.9); } #noVNC_status.noVNC_open { - transform: translateY(0); - visibility: visible; - opacity: 1; + transform: translateY(0); + visibility: visible; + opacity: 1; } #noVNC_status::before { - content: ""; - display: inline-block; - width: 25px; - height: 25px; - margin-right: 5px; + content: ""; + display: inline-block; + width: 25px; + height: 25px; + margin-right: 5px; } #noVNC_status.noVNC_status_normal { - background: rgba(128,128,128,0.9); + background: rgba(128,128,128,0.9); } #noVNC_status.noVNC_status_normal::before { - content: url("../images/info.svg") " "; + content: url("../images/info.svg") " "; } #noVNC_status.noVNC_status_error { - background: rgba(200,55,55,0.9); + background: rgba(200,55,55,0.9); } #noVNC_status.noVNC_status_error::before { - content: url("../images/error.svg") " "; + content: url("../images/error.svg") " "; } #noVNC_status.noVNC_status_warn { - background: rgba(180,180,30,0.9); + background: rgba(180,180,30,0.9); } #noVNC_status.noVNC_status_warn::before { - content: url("../images/warning.svg") " "; + content: url("../images/warning.svg") " "; } /* ---------------------------------------- @@ -706,67 +715,63 @@ html { */ #noVNC_connect_dlg { - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - transform: scale(0, 0); - visibility: hidden; - opacity: 0; + transform: scale(0, 0); + visibility: hidden; + opacity: 0; } #noVNC_connect_dlg.noVNC_open { - transform: scale(1, 1); - visibility: visible; - opacity: 1; + transform: scale(1, 1); + visibility: visible; + opacity: 1; } #noVNC_connect_dlg .noVNC_logo { - transition: 0.5s ease-in-out; - padding: 10px; - margin-bottom: 10px; + transition: 0.5s ease-in-out; + padding: 10px; + margin-bottom: 10px; - font-size: 80px; - text-align: center; + font-size: 80px; + text-align: center; - border-radius: 5px; + border-radius: 6px; } @media (max-width: 440px) { - #noVNC_connect_dlg { - max-width: calc(100vw - 100px); - } - #noVNC_connect_dlg .noVNC_logo { - font-size: calc(25vw - 30px); - } + #noVNC_connect_dlg { + max-width: calc(100vw - 100px); + } + #noVNC_connect_dlg .noVNC_logo { + font-size: calc(25vw - 30px); + } } #noVNC_connect_dlg div { - padding: 12px; + padding: 18px; - background-color: rgb(110, 132, 163); - border-radius: 12px; - text-align: center; - font-size: 20px; + background-color: var(--novnc-darkgrey); + border-radius: 12px; + text-align: center; + font-size: 20px; - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); } #noVNC_connect_button { - width: 100%; - padding: 5px 30px; + width: 100%; + padding: 6px 30px; + cursor: pointer; + border-color: transparent; + border-radius: 12px; + background-color: var(--novnc-blue); + color: white; - cursor: pointer; - - border-color: rgb(83, 99, 122); - border-radius: 5px; - - background: linear-gradient(to top, rgb(110, 132, 163), rgb(99, 119, 147)); - color: white; - - /* This avoids it jumping around when :active */ - vertical-align: middle; -} -#noVNC_connect_button:hover { - background: linear-gradient(to top, rgb(110, 132, 163), rgb(105, 125, 155)); + display: flex; + justify-content: center; + place-items: center; + gap: 4px; } #noVNC_connect_button img { - vertical-align: bottom; - height: 1.3em; + vertical-align: bottom; + height: 1.3em; } /* ---------------------------------------- @@ -775,15 +780,15 @@ html { */ #noVNC_verify_server_dlg { - position: relative; + position: relative; - transform: translateY(-50px); + transform: translateY(-50px); } #noVNC_verify_server_dlg.noVNC_open { - transform: translateY(0); + transform: translateY(0); } #noVNC_fingerprint_block { - margin: 10px; + margin: 10px; } /* ---------------------------------------- @@ -792,16 +797,16 @@ html { */ #noVNC_credentials_dlg { - position: relative; + position: relative; - transform: translateY(-50px); + transform: translateY(-50px); } #noVNC_credentials_dlg.noVNC_open { - transform: translateY(0); + transform: translateY(0); } #noVNC_username_block.noVNC_hidden, #noVNC_password_block.noVNC_hidden { - display: none; + display: none; } @@ -812,90 +817,90 @@ html { /* Transition screen */ #noVNC_transition { - transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; - display: flex; - opacity: 0; - visibility: hidden; + display: flex; + opacity: 0; + visibility: hidden; - position: fixed; - top: 0; - left: 0; - bottom: 0; - right: 0; + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; - color: white; - background: rgba(0, 0, 0, 0.5); - z-index: 50; + color: white; + background: rgba(0, 0, 0, 0.5); + z-index: 50; - /*display: flex;*/ - align-items: center; - justify-content: center; - flex-direction: column; + /*display: flex;*/ + align-items: center; + justify-content: center; + flex-direction: column; } :root.noVNC_loading #noVNC_transition, :root.noVNC_connecting #noVNC_transition, :root.noVNC_disconnecting #noVNC_transition, :root.noVNC_reconnecting #noVNC_transition { - opacity: 1; - visibility: visible; + opacity: 1; + visibility: visible; } :root:not(.noVNC_reconnecting) #noVNC_cancel_reconnect_button { - display: none; + display: none; } #noVNC_transition_text { - font-size: 1.5em; + font-size: 1.5em; } /* Main container */ #noVNC_container { - width: 100%; - height: 100%; - background-color: #313131; - border-bottom-right-radius: 800px 600px; - /*border-top-left-radius: 800px 600px;*/ + width: 100%; + height: 100%; + background-color: #313131; + border-bottom-right-radius: 800px 600px; + /*border-top-left-radius: 800px 600px;*/ - /* If selection isn't disabled, long-pressing stuff in the sidebar - can accidentally select the container or the canvas. This can - happen when attempting to move the handle. */ - user-select: none; - -webkit-user-select: none; + /* If selection isn't disabled, long-pressing stuff in the sidebar + can accidentally select the container or the canvas. This can + happen when attempting to move the handle. */ + user-select: none; + -webkit-user-select: none; } #noVNC_keyboardinput { - width: 1px; - height: 1px; - background-color: #fff; - color: #fff; - border: 0; - position: absolute; - left: -40px; - z-index: -1; - ime-mode: disabled; + width: 1px; + height: 1px; + background-color: #fff; + color: #fff; + border: 0; + position: absolute; + left: -40px; + z-index: -1; + ime-mode: disabled; } /*Default noVNC logo.*/ /* From: http://fonts.googleapis.com/css?family=Orbitron:700 */ @font-face { - font-family: 'Orbitron'; - font-style: normal; - font-weight: 700; - src: local('?'), url('Orbitron700.woff') format('woff'), - url('Orbitron700.ttf') format('truetype'); + font-family: 'Orbitron'; + font-style: normal; + font-weight: 700; + src: local('?'), url('Orbitron700.woff') format('woff'), + url('Orbitron700.ttf') format('truetype'); } .noVNC_logo { - color:yellow; - font-family: 'Orbitron', 'OrbitronTTF', sans-serif; - line-height: 0.9; - text-shadow: 0.1em 0.1em 0 black; + color: var(--novnc-yellow); + font-family: 'Orbitron', 'OrbitronTTF', sans-serif; + line-height: 0.9; + text-shadow: 0.1em 0.1em 0 black; } .noVNC_logo span{ - color:green; + color: var(--novnc-green); } #noVNC_bell { - display: none; + display: none; } /* ---------------------------------------- @@ -904,19 +909,19 @@ html { */ @media screen and (max-width: 640px){ - #noVNC_logo { - font-size: 150px; - } + #noVNC_logo { + font-size: 150px; + } } @media screen and (min-width: 321px) and (max-width: 480px) { - #noVNC_logo { - font-size: 110px; - } + #noVNC_logo { + font-size: 110px; + } } @media screen and (max-width: 320px) { - #noVNC_logo { - font-size: 90px; - } + #noVNC_logo { + font-size: 90px; + } } diff --git a/app/styles/constants.css b/app/styles/constants.css new file mode 100644 index 0000000..1123a3e --- /dev/null +++ b/app/styles/constants.css @@ -0,0 +1,30 @@ +/* + * noVNC general CSS constant variables + * Copyright (C) 2025 The noVNC authors + * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) + * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). + */ + +/* ---------- COLORS ----------- */ + +:root { + --novnc-grey: rgb(128, 128, 128); + --novnc-lightgrey: rgb(192, 192, 192); + --novnc-darkgrey: rgb(92, 92, 92); + + /* Transparent to make button colors adapt to the background */ + --novnc-buttongrey: rgba(192, 192, 192, 0.5); + + --novnc-blue: rgb(110, 132, 163); + --novnc-lightblue: rgb(74, 144, 217); + --novnc-darkblue: rgb(83, 99, 122); + + --novnc-green: rgb(0, 128, 0); + --novnc-yellow: rgb(255, 255, 0); +} + +/* ------ MISC PROPERTIES ------ */ + +:root { + --input-xpadding: 1em; +} diff --git a/app/styles/input.css b/app/styles/input.css index 911cf20..8273d70 100644 --- a/app/styles/input.css +++ b/app/styles/input.css @@ -1,32 +1,170 @@ /* * noVNC general input element CSS - * Copyright (C) 2022 The noVNC authors + * Copyright (C) 2025 The noVNC authors * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). */ -/* - * Common for all inputs - */ -input, input::file-selector-button, button, select, textarea { - /* Respect standard font settings */ - font: inherit; +/* ------- SHARED BETWEEN INPUT ELEMENTS -------- */ - /* Disable default rendering */ - appearance: none; - background: none; +input, +textarea, +button, +select, +input::file-selector-button { + padding: 0.5em var(--input-xpadding); + border-radius: 6px; + appearance: none; + text-overflow: ellipsis; - padding: 5px; - border: 1px solid rgb(192, 192, 192); - border-radius: 5px; - color: black; - --bg-gradient: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240)); - background-image: var(--bg-gradient); + /* Respect standard font settings */ + font: inherit; + line-height: 1.6; +} +input:disabled, +textarea:disabled, +button:disabled, +select:disabled, +label[disabled] { + opacity: 0.4; } -/* - * Buttons - */ +input:focus-visible, +textarea:focus-visible, +button:focus-visible, +select:focus-visible, +input:focus-visible::file-selector-button { + outline: 2px solid var(--novnc-lightblue); + outline-offset: 1px; +} + +/* ------- TEXT INPUT -------- */ + +input:not([type]), +input[type=date], +input[type=datetime-local], +input[type=email], +input[type=month], +input[type=number], +input[type=password], +input[type=search], +input[type=tel], +input[type=text], +input[type=time], +input[type=url], +input[type=week], +textarea { + border: 1px solid var(--novnc-lightgrey); + /* Account for borders on text inputs, buttons dont have borders */ + padding: calc(0.5em - 1px) var(--input-xpadding); +} +input:not([type]):focus-visible, +input[type=date]:focus-visible, +input[type=datetime-local]:focus-visible, +input[type=email]:focus-visible, +input[type=month]:focus-visible, +input[type=number]:focus-visible, +input[type=password]:focus-visible, +input[type=search]:focus-visible, +input[type=tel]:focus-visible, +input[type=text]:focus-visible, +input[type=time]:focus-visible, +input[type=url]:focus-visible, +input[type=week]:focus-visible, +textarea:focus-visible { + outline-offset: -1px; +} + +textarea { + margin: unset; /* Remove Firefox's built in margin */ + /* Prevent layout from shifting when scrollbars show */ + scrollbar-gutter: stable; + /* Make textareas show at minimum one line. This does not work when + using box-sizing border-box, in which case, vertical padding and + border width needs to be taken into account. */ + min-height: 1lh; + vertical-align: baseline; /* Firefox gives "text-bottom" by default */ +} + +/* ------- NUMBER PICKERS ------- */ + +/* We can't style the number spinner buttons: + https://github.com/w3c/csswg-drafts/issues/8777 */ +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + /* Get rid of increase/decrease buttons in WebKit */ + appearance: none; +} +input[type=number] { + /* Get rid of increase/decrease buttons in Firefox */ + appearance: textfield; +} + +/* ------- BUTTON ACTIVATIONS -------- */ + +/* A color overlay that depends on the activation level. The level can then be + set for different states on an element, for example hover and click on a +