mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
The VM's XML editor takes most of the window's height and is framed like a form field. The review dialog shows removed and added lines on a red and green tint, and each part of the diff starts with its line number instead of the unified diff's @@ header.
278 lines
8.2 KiB
CSS
278 lines
8.2 KiB
CSS
/*!
|
|
* WebVirtCloud (http://github.com/retspen/webvirtcloud)
|
|
* Code licensed under the Apache License v2.0.
|
|
* For details, see http://www.apache.org/licenses/LICENSE-2.0.
|
|
*/
|
|
|
|
/* pages stop at Bootstrap's lg container width (960px): its xl and xxl
|
|
widths (1140px, 1320px) leave the panel's forms and lists too wide */
|
|
@media (min-width: 1200px) {
|
|
.container {
|
|
max-width: 960px;
|
|
}
|
|
}
|
|
|
|
/* a count or label badge: text-bg-light keeps a light background with the
|
|
theme's light-text colour, white on grey in Darkly, Superhero and Vapor;
|
|
the page's own colours read in every theme */
|
|
.badge.text-bg-light.border {
|
|
color: var(--bs-body-color) !important;
|
|
background-color: var(--bs-body-bg) !important;
|
|
}
|
|
|
|
/* an outlined secondary button (Cancel, a row's menu): Bootstrap draws it
|
|
in the theme's secondary colour, near the page background in Cyborg,
|
|
Darkly, Slate, Solar, Superhero and Vapor; the page's own text colours
|
|
read in every theme, its hover stays the theme's */
|
|
.btn-outline-secondary {
|
|
color: var(--bs-body-color);
|
|
border-color: var(--bs-secondary-color);
|
|
}
|
|
|
|
#editor {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
}
|
|
|
|
/* Tom Select's control keeps the text colour of the select it replaces:
|
|
its own stylesheet fixes one, unreadable on some Bootswatch themes */
|
|
.ts-wrapper.form-select .ts-control,
|
|
.ts-wrapper.form-select .ts-control input {
|
|
color: inherit;
|
|
}
|
|
|
|
.xmlheight {
|
|
height: 364px;
|
|
}
|
|
|
|
.ace_editor {
|
|
height: 350px;
|
|
}
|
|
|
|
/* the VM's XML editor: as tall as most of the window, framed like a form field */
|
|
.xml-editor .ace_editor {
|
|
height: max(350px, 65vh);
|
|
border: var(--bs-border-width) solid var(--bs-border-color);
|
|
border-radius: var(--bs-border-radius);
|
|
}
|
|
|
|
/* the review dialog's diff: added and removed lines on a tint, a hunk starts with its line number */
|
|
.xml-diff > div {
|
|
padding: 0 .5rem;
|
|
}
|
|
.xml-diff .diff-add {
|
|
background-color: rgba(var(--bs-success-rgb), .12);
|
|
}
|
|
.xml-diff .diff-del {
|
|
background-color: rgba(var(--bs-danger-rgb), .12);
|
|
}
|
|
.xml-diff .diff-hunk:not(:first-child) {
|
|
margin-top: .75rem;
|
|
}
|
|
|
|
/* headers of sortable tables (static/js/sort_tables.js): the sorted one shows
|
|
its direction, up for ascending */
|
|
th[role=columnheader]:not([data-sort-method="none"]) {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
th[aria-sort]:not([data-sort-method="none"])::after {
|
|
content: "";
|
|
display: inline-block;
|
|
margin-left: 0.4em;
|
|
vertical-align: middle;
|
|
border: 0.3em solid transparent;
|
|
border-top-color: currentColor;
|
|
}
|
|
|
|
th[aria-sort="ascending"]:not([data-sort-method="none"])::after {
|
|
border-top-color: transparent;
|
|
border-bottom-color: currentColor;
|
|
}
|
|
|
|
/* a phone keeps Bootstrap's own cell padding: some themes (Zephyr) double
|
|
it, and a list's last column no longer fits the screen */
|
|
@media (max-width: 575.98px) {
|
|
.table > :not(caption) > * > * {
|
|
padding-left: 0.5rem;
|
|
padding-right: 0.5rem;
|
|
}
|
|
}
|
|
|
|
/* a choice shown as a card around its radio button (the VM's disk source,
|
|
a new pool's type): the chosen card by its border only, as the
|
|
Bootswatch dark themes keep light "subtle" backgrounds */
|
|
.source-option {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.source-option:has(input:checked) {
|
|
border-color: var(--bs-primary) !important;
|
|
box-shadow: inset 0 0 0 1px var(--bs-primary);
|
|
}
|
|
|
|
.source-option:has(input:focus-visible) {
|
|
outline: 2px solid var(--bs-primary);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.host-collapsed tr[host] {
|
|
display: none;
|
|
}
|
|
|
|
/* a live chart (static/js/charts.js) fills the width of its card at this height */
|
|
.chart {
|
|
height: 160px;
|
|
}
|
|
|
|
/* the host's sections (computes/host_nav.html) on one line in every theme:
|
|
one font size, and the divider spaced alike on its two sides (Zephyr
|
|
doubles the space after it) */
|
|
.host-nav .breadcrumb {
|
|
--bs-breadcrumb-item-padding-x: .5rem;
|
|
font-size: .875rem;
|
|
}
|
|
|
|
.host-nav .breadcrumb-item + .breadcrumb-item::before {
|
|
padding-right: var(--bs-breadcrumb-item-padding-x);
|
|
}
|
|
|
|
/* the power tab's states: the current one filled, the others a ring */
|
|
.power-dot {
|
|
width: .8rem;
|
|
height: .8rem;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
border: 2px solid var(--bs-border-color);
|
|
}
|
|
.power-dot.bg-success, .power-dot.bg-warning, .power-dot.bg-secondary { border-color: transparent; }
|
|
/* the access tab's two login buttons line up */
|
|
.access-act { min-width: 9rem; }
|
|
|
|
/* the options tab: one row per device the guest sees, its name, its control and a note */
|
|
.option-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
column-gap: 1rem;
|
|
row-gap: .25rem;
|
|
padding: .6rem 0;
|
|
}
|
|
.option-name { flex: 0 0 8rem; }
|
|
|
|
/* the resize tab: one cell per vCPU up to the maximum, filled when on; memory now within its maximum */
|
|
.vcpu-cell {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 2.25rem;
|
|
height: 2.25rem;
|
|
padding: 0 .4rem;
|
|
border-radius: var(--bs-border-radius);
|
|
border: 2px solid var(--bs-primary);
|
|
background: var(--bs-body-bg);
|
|
color: var(--bs-primary);
|
|
font-size: .875rem;
|
|
font-weight: 600;
|
|
}
|
|
.vcpu-cell.on { background: var(--bs-primary); color: #fff; }
|
|
button.vcpu-cell:not(:disabled):hover { box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .25); }
|
|
button.vcpu-cell:disabled { opacity: .65; }
|
|
.memory-bar {
|
|
width: min(18rem, 100%);
|
|
height: .9rem;
|
|
border: 2px solid var(--bs-primary);
|
|
border-radius: var(--bs-border-radius);
|
|
overflow: hidden;
|
|
}
|
|
.memory-bar-now { height: 100%; background: var(--bs-primary); }
|
|
.resize-act { min-width: 9rem; }
|
|
|
|
/* the boot order: the devices the VM tries in turn, numbered and joined by a line */
|
|
.boot-chain { counter-reset: boot; }
|
|
.boot-node { position: relative; padding: .5rem 0; }
|
|
.boot-chain > .boot-node { counter-increment: boot; }
|
|
.boot-step {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
width: 1.75rem;
|
|
height: 1.75rem;
|
|
border-radius: 50%;
|
|
border: 2px solid var(--bs-primary);
|
|
color: var(--bs-primary);
|
|
background: var(--bs-body-bg);
|
|
font-size: .8rem;
|
|
font-weight: 600;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
.boot-chain .boot-step::before { content: counter(boot); }
|
|
.boot-chain > .boot-node:not(:last-child)::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(.875rem - 1px);
|
|
top: calc(50% + .875rem);
|
|
height: calc(100% - 1.75rem);
|
|
border-left: 2px solid var(--bs-border-color);
|
|
}
|
|
.boot-spare .boot-step { visibility: hidden; }
|
|
/* on a narrow screen a device's buttons go below its name, not over it */
|
|
.boot-text { min-width: 10rem; flex-basis: 10rem; }
|
|
.boot-chain .boot-spare-only, .boot-spare .boot-chain-only { display: none !important; }
|
|
|
|
/* the snapshots tab: the VM's history as a line, newest first; now on top, the snapshot the VM goes on from filled */
|
|
.snap-line { position: relative; padding-left: 1.75rem; }
|
|
.snap-line::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(.5rem - 1px);
|
|
top: .75rem;
|
|
bottom: .75rem;
|
|
border-left: 2px solid var(--bs-border-color);
|
|
}
|
|
.snap-node { position: relative; padding: .5rem 0; }
|
|
.snap-dot {
|
|
position: absolute;
|
|
left: -1.75rem;
|
|
top: .75rem;
|
|
width: 1rem;
|
|
height: 1rem;
|
|
border-radius: 50%;
|
|
border: 2px solid var(--bs-primary);
|
|
background: var(--bs-body-bg);
|
|
}
|
|
.snap-dot.bg-success, .snap-dot.bg-warning, .snap-dot.bg-secondary { border-color: transparent; }
|
|
.snap-dot.snap-current { background: var(--bs-primary); }
|
|
.snap-dot.snap-none { border-color: var(--bs-border-color); }
|
|
|
|
/* the network tab: a NIC as a cable to its source, solid while its link is up, dashed while down */
|
|
.nic-wire {
|
|
position: relative;
|
|
flex: 0 0 3.5rem;
|
|
margin-inline: .25rem;
|
|
color: var(--bs-secondary-color);
|
|
border-top: 2px dashed currentColor;
|
|
}
|
|
.nic-wire::before, .nic-wire::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: -4px;
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: currentColor;
|
|
}
|
|
.nic-wire::before { left: -3px; }
|
|
.nic-wire::after { right: -3px; }
|
|
.nic-wire.nic-up { color: var(--bs-success); border-top-style: solid; }
|
|
|
|
/* a log message keeps a readable width when its table scrolls on a phone */
|
|
.log-message {
|
|
min-width: 16rem;
|
|
}
|