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
+