323 lines
6.2 KiB
CSS
323 lines
6.2 KiB
CSS
|
* {
|
|||
|
margin: 0;
|
|||
|
padding: 0
|
|||
|
}
|
|||
|
|
|||
|
/* Basic reset */
|
|||
|
html,
|
|||
|
body {
|
|||
|
margin: 0;
|
|||
|
padding: 0;
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
background: #1d2021;
|
|||
|
overflow: hidden;
|
|||
|
/* No default scrollbars */
|
|||
|
font-family: "JetBrains Mono", serif;
|
|||
|
font-optical-sizing: auto;
|
|||
|
font-weight: 400;
|
|||
|
font-style: normal;
|
|||
|
font-size: 20px;
|
|||
|
}
|
|||
|
|
|||
|
h1 {
|
|||
|
font-size: 48px;
|
|||
|
color: #ebdbb2;
|
|||
|
}
|
|||
|
|
|||
|
h2 {
|
|||
|
font-size: 36px;
|
|||
|
color: #ebdbb2;
|
|||
|
}
|
|||
|
|
|||
|
h3 {
|
|||
|
font-size: 28px;
|
|||
|
color: #ebdbb2;
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* Main Container (holds racks + cables)
|
|||
|
*******************************************/
|
|||
|
#patch-container {
|
|||
|
position: relative;
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
overflow: hidden;
|
|||
|
}
|
|||
|
|
|||
|
/* SVG overlay for cables, on top of racks */
|
|||
|
#cable-overlay {
|
|||
|
position: absolute;
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
z-index: 9999;
|
|||
|
/* put cables on top */
|
|||
|
pointer-events: none;
|
|||
|
/* let clicks pass through by default */
|
|||
|
}
|
|||
|
|
|||
|
/* Each cable path can be clicked on => remove */
|
|||
|
.cable-path {
|
|||
|
pointer-events: auto;
|
|||
|
/* re-enable clicks for cable paths specifically */
|
|||
|
cursor: pointer;
|
|||
|
transition: stroke 0.2s;
|
|||
|
}
|
|||
|
|
|||
|
.cable-path:hover {
|
|||
|
stroke: #cc241d !important;
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* Data center (the racks)
|
|||
|
*******************************************/
|
|||
|
#datacenter {
|
|||
|
position: absolute;
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
right: 0;
|
|||
|
bottom: 0;
|
|||
|
display: flex;
|
|||
|
/* If you want horizontal scrolling if there are many racks, use:
|
|||
|
overflow-x: auto;
|
|||
|
*/
|
|||
|
overflow-x: auto;
|
|||
|
overflow-y: hidden;
|
|||
|
z-index: 1;
|
|||
|
/* behind cable overlay */
|
|||
|
}
|
|||
|
|
|||
|
.rack {
|
|||
|
width: 16em;
|
|||
|
/* each rack’s width */
|
|||
|
/* fill all available vertical space */
|
|||
|
background: #282828;
|
|||
|
border: 2px solid #3c3836;
|
|||
|
margin: 10px;
|
|||
|
box-sizing: border-box;
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
/* stack servers top to bottom */
|
|||
|
}
|
|||
|
|
|||
|
.rack-title {
|
|||
|
text-align: center;
|
|||
|
text-transform: uppercase;
|
|||
|
font-size: 14px;
|
|||
|
color: #ebdbb2;
|
|||
|
margin: 8px 0;
|
|||
|
letter-spacing: 1px;
|
|||
|
}
|
|||
|
|
|||
|
.server {
|
|||
|
background: #32302f;
|
|||
|
border: 1px solid #3c3836;
|
|||
|
margin: 6px;
|
|||
|
/* spacing within the rack */
|
|||
|
}
|
|||
|
|
|||
|
.server-under-construction {
|
|||
|
/* Diagonal stripes:
|
|||
|
repeating-linear-gradient(angle, color1 start, color1 end, color2 start, color2 end) */
|
|||
|
background: repeating-linear-gradient(
|
|||
|
45deg,
|
|||
|
#282828 0,
|
|||
|
#282828 12px,
|
|||
|
#32302f 12px,
|
|||
|
#32302f 24px
|
|||
|
);
|
|||
|
color:#000;
|
|||
|
border: 2px dashed #282828; /* Give it a dashed border for effect */
|
|||
|
}
|
|||
|
|
|||
|
.server-row {
|
|||
|
padding: 5px 8px;
|
|||
|
box-sizing: border-box;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
justify-content: space-between;
|
|||
|
}
|
|||
|
|
|||
|
.text-row {
|
|||
|
font-size: 14px;
|
|||
|
color: #ebdbb2;
|
|||
|
}
|
|||
|
|
|||
|
.port-row {
|
|||
|
gap: 8px;
|
|||
|
display: flex;
|
|||
|
justify-content: right;
|
|||
|
}
|
|||
|
|
|||
|
/* If you want a spacer between servers, you can use a simple div with .spacer. */
|
|||
|
.spacer {
|
|||
|
height: 20px;
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************
|
|||
|
* Port + LED styling
|
|||
|
*******************************************/
|
|||
|
.port {
|
|||
|
position: relative;
|
|||
|
width: 1rem;
|
|||
|
height: 1rem;
|
|||
|
background: #32302f;
|
|||
|
border: 2px solid #504945;
|
|||
|
border-radius: 50%;
|
|||
|
cursor: pointer;
|
|||
|
}
|
|||
|
|
|||
|
.port:hover {
|
|||
|
background: #7c6f64;
|
|||
|
border-color: #ebdbb2;
|
|||
|
}
|
|||
|
|
|||
|
a:link {
|
|||
|
color: #b16286;
|
|||
|
}
|
|||
|
|
|||
|
/* visited link */
|
|||
|
a:visited {
|
|||
|
color: #8f3f71;
|
|||
|
}
|
|||
|
|
|||
|
/* mouse over link */
|
|||
|
a:hover {
|
|||
|
color: #d3869b;
|
|||
|
}
|
|||
|
|
|||
|
/* selected link */
|
|||
|
a:active {
|
|||
|
color: #b16286;
|
|||
|
}
|
|||
|
|
|||
|
.led {
|
|||
|
position: absolute;
|
|||
|
top: -5px;
|
|||
|
right: -5px;
|
|||
|
width: .4rem;
|
|||
|
height: .4rem;
|
|||
|
background: #1d2021;
|
|||
|
/* off state */
|
|||
|
border: 2px solid #504945;
|
|||
|
border-radius: 50%;
|
|||
|
box-shadow: 0 0 2px #000;
|
|||
|
}
|
|||
|
|
|||
|
.temp-row {
|
|||
|
position: relative;
|
|||
|
flex: 1;
|
|||
|
}
|
|||
|
.temp-label {
|
|||
|
color: #eee;
|
|||
|
font-size: 11px;
|
|||
|
margin-right: 8px;
|
|||
|
}
|
|||
|
.temp-bar {
|
|||
|
flex: 1;
|
|||
|
height: 10px;
|
|||
|
background: linear-gradient(to right, #f80, #f00);
|
|||
|
box-shadow: 0 0 6px rgba(255,80,0,0.5);
|
|||
|
animation: flickerHeat 1.5s infinite ease-in-out alternate;
|
|||
|
}
|
|||
|
@keyframes flickerHeat {
|
|||
|
0% { opacity: 1; transform: scaleX(1); }
|
|||
|
100% { opacity: 0.7; transform: scaleX(1.05); }
|
|||
|
}
|
|||
|
|
|||
|
/***************************************************
|
|||
|
* POWER USAGE LIGHTS (Random Blink)
|
|||
|
***************************************************/
|
|||
|
.power-lights-row {
|
|||
|
gap: 4px;
|
|||
|
}
|
|||
|
.power-light {
|
|||
|
width: 10px; height: 10px;
|
|||
|
background: #222;
|
|||
|
border: 2px solid #555;
|
|||
|
border-radius: 2px;
|
|||
|
box-shadow: 0 0 2px #000;
|
|||
|
}
|
|||
|
.power-light.lit {
|
|||
|
background: #0f0; /* or something bright to indicate usage */
|
|||
|
}
|
|||
|
|
|||
|
/************************************************
|
|||
|
* FAN SPACER: Animated fans
|
|||
|
************************************************/
|
|||
|
.fans {
|
|||
|
background: #7c6f64;
|
|||
|
margin: 6px;
|
|||
|
/* spacing within the rack */
|
|||
|
}
|
|||
|
|
|||
|
.fan-row {
|
|||
|
display: flex;
|
|||
|
gap: 10px;
|
|||
|
justify-content: center;
|
|||
|
padding: 5px 0;
|
|||
|
}
|
|||
|
|
|||
|
.fan {
|
|||
|
width: 5rem;
|
|||
|
height: 5rem;
|
|||
|
border-radius: 50%;
|
|||
|
background-image: url('fan.svg');
|
|||
|
filter: invert(29%) sepia(3%) saturate(1342%) hue-rotate(338deg) brightness(93%) contrast(90%);
|
|||
|
animation: spin 1s linear infinite;
|
|||
|
transform-origin: center;
|
|||
|
background-size: contain;
|
|||
|
background-repeat: no-repeat;
|
|||
|
background-position: center;
|
|||
|
transition: all 1s linear;
|
|||
|
}
|
|||
|
|
|||
|
.fan:hover {
|
|||
|
animation: 5s;
|
|||
|
}
|
|||
|
|
|||
|
@keyframes spin {
|
|||
|
0% {
|
|||
|
transform: rotate(0deg);
|
|||
|
}
|
|||
|
|
|||
|
100% {
|
|||
|
transform: rotate(360deg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/************************************************
|
|||
|
* NAS SPACER: Random blinking drive lights
|
|||
|
************************************************/
|
|||
|
.nas {
|
|||
|
background: #504945;
|
|||
|
border: 1px solid #7c6f64;
|
|||
|
margin: 6px;
|
|||
|
/* spacing within the rack */
|
|||
|
}
|
|||
|
|
|||
|
.drive-lights-row {
|
|||
|
display: flex;
|
|||
|
gap: 4px;
|
|||
|
justify-content: center;
|
|||
|
padding: 5px 0;
|
|||
|
flex-wrap: wrap;
|
|||
|
/* if many lights, wrap to next line */
|
|||
|
}
|
|||
|
|
|||
|
.drive-light {
|
|||
|
width: 12px;
|
|||
|
height: 12px;
|
|||
|
background: #1d2021;
|
|||
|
/* off by default */
|
|||
|
border: 2px solid #504945;
|
|||
|
border-radius: 2px;
|
|||
|
box-shadow: 0 0 2px #000;
|
|||
|
}
|
|||
|
|
|||
|
.drive-light.lit {
|
|||
|
background: #b8bb26;
|
|||
|
/* or any color you like */
|
|||
|
}
|