Move server rack inline styles to CSS classes
Replace the per-element inline positioning in createServerRack() with rack-*-pos utility classes in style.css. Also stop drawing a random switch face brand from a list (only Framework ships) and simplify the hero-click terminal toggle to use the shared expand/collapse helpers.
This commit is contained in:
+14
-54
@@ -60,7 +60,8 @@ function createServerRack() {
|
|||||||
const totalPageHeight = document.documentElement.scrollHeight;
|
const totalPageHeight = document.documentElement.scrollHeight;
|
||||||
const totalUnits = Math.max(Math.ceil((totalPageHeight - 100 - barHeight) / unitHeight), 10);
|
const totalUnits = Math.max(Math.ceil((totalPageHeight - 100 - barHeight) / unitHeight), 10);
|
||||||
|
|
||||||
const brands = ['Framework'];
|
// Only one brand in the rack for now
|
||||||
|
const RACK_BRAND = 'Framework';
|
||||||
|
|
||||||
const services = ['Borg', 'Gitea', 'Nextcloud', 'Jellyfin', 'Open WebUI', 'llama.cpp', 'Immich', 'LiteLLM', 'Caddy', 'Nginx', 'Samba', 'Slopbox'];
|
const services = ['Borg', 'Gitea', 'Nextcloud', 'Jellyfin', 'Open WebUI', 'llama.cpp', 'Immich', 'LiteLLM', 'Caddy', 'Nginx', 'Samba', 'Slopbox'];
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ function createServerRack() {
|
|||||||
|
|
||||||
const brandLabel = document.createElement('div');
|
const brandLabel = document.createElement('div');
|
||||||
brandLabel.className = 'eth-brand';
|
brandLabel.className = 'eth-brand';
|
||||||
brandLabel.textContent = brands[Math.floor(Math.random() * brands.length)];
|
brandLabel.textContent = RACK_BRAND;
|
||||||
switchFace.appendChild(brandLabel);
|
switchFace.appendChild(brandLabel);
|
||||||
|
|
||||||
const portCount = Math.floor(Math.random() * 4) + 5;
|
const portCount = Math.floor(Math.random() * 4) + 5;
|
||||||
@@ -139,19 +140,12 @@ function createServerRack() {
|
|||||||
bar.className = 'grill-v-bar';
|
bar.className = 'grill-v-bar';
|
||||||
grillV.appendChild(bar);
|
grillV.appendChild(bar);
|
||||||
}
|
}
|
||||||
grillV.style.position = 'absolute';
|
grillV.classList.add('rack-grill-v-pos');
|
||||||
grillV.style.left = '16px';
|
|
||||||
grillV.style.top = '50%';
|
|
||||||
grillV.style.transform = 'translateY(-50%)';
|
|
||||||
face.appendChild(grillV);
|
face.appendChild(grillV);
|
||||||
|
|
||||||
const fanContainer = document.createElement('div');
|
const fanContainer = document.createElement('div');
|
||||||
fanContainer.className = 'fan-container';
|
fanContainer.className = 'fan-container';
|
||||||
fanContainer.style.position = 'absolute';
|
fanContainer.classList.add('rack-fans-pos');
|
||||||
fanContainer.style.right = '16px';
|
|
||||||
fanContainer.style.top = '50%';
|
|
||||||
fanContainer.style.transform = 'translateY(-50%)';
|
|
||||||
fanContainer.style.zIndex = '1';
|
|
||||||
|
|
||||||
const fanCount = Math.floor(Math.random() * 2) + 1;
|
const fanCount = Math.floor(Math.random() * 2) + 1;
|
||||||
const fanSpeeds = ['fan-slow', 'fan-medium', 'fan-fast'];
|
const fanSpeeds = ['fan-slow', 'fan-medium', 'fan-fast'];
|
||||||
@@ -174,10 +168,7 @@ function createServerRack() {
|
|||||||
|
|
||||||
const ledGroup = document.createElement('div');
|
const ledGroup = document.createElement('div');
|
||||||
ledGroup.className = 'led-group';
|
ledGroup.className = 'led-group';
|
||||||
ledGroup.style.position = 'absolute';
|
ledGroup.classList.add('rack-leds-pos-top');
|
||||||
ledGroup.style.top = '8px';
|
|
||||||
ledGroup.style.left = '50%';
|
|
||||||
ledGroup.style.transform = 'translateX(-50%)';
|
|
||||||
|
|
||||||
const ledCount = Math.floor(Math.random() * 3) + 1;
|
const ledCount = Math.floor(Math.random() * 3) + 1;
|
||||||
const blinkClasses = ['led-blink-1', 'led-blink-2', 'led-blink-3', 'led-blink-4'];
|
const blinkClasses = ['led-blink-1', 'led-blink-2', 'led-blink-3', 'led-blink-4'];
|
||||||
@@ -201,18 +192,12 @@ function createServerRack() {
|
|||||||
bar.className = 'grill-h-bar';
|
bar.className = 'grill-h-bar';
|
||||||
grillH.appendChild(bar);
|
grillH.appendChild(bar);
|
||||||
}
|
}
|
||||||
grillH.style.position = 'absolute';
|
grillH.classList.add('rack-grill-h-pos');
|
||||||
grillH.style.left = '50%';
|
|
||||||
grillH.style.top = '50%';
|
|
||||||
grillH.style.transform = 'translate(-50%, -50%)';
|
|
||||||
face.appendChild(grillH);
|
face.appendChild(grillH);
|
||||||
|
|
||||||
const ledGroup = document.createElement('div');
|
const ledGroup = document.createElement('div');
|
||||||
ledGroup.className = 'led-group';
|
ledGroup.className = 'led-group';
|
||||||
ledGroup.style.position = 'absolute';
|
ledGroup.classList.add('rack-leds-pos-right');
|
||||||
ledGroup.style.right = '16px';
|
|
||||||
ledGroup.style.top = '50%';
|
|
||||||
ledGroup.style.transform = 'translateY(-50%)';
|
|
||||||
|
|
||||||
const ledCount = Math.floor(Math.random() * 3) + 1;
|
const ledCount = Math.floor(Math.random() * 3) + 1;
|
||||||
const blinkClasses = ['led-blink-1', 'led-blink-2', 'led-blink-3', 'led-blink-4'];
|
const blinkClasses = ['led-blink-1', 'led-blink-2', 'led-blink-3', 'led-blink-4'];
|
||||||
@@ -230,13 +215,7 @@ function createServerRack() {
|
|||||||
} else {
|
} else {
|
||||||
// Drive bays
|
// Drive bays
|
||||||
const driveBayContainer = document.createElement('div');
|
const driveBayContainer = document.createElement('div');
|
||||||
driveBayContainer.style.display = 'flex';
|
driveBayContainer.className = 'rack-drives-pos';
|
||||||
driveBayContainer.style.gap = '8px';
|
|
||||||
driveBayContainer.style.alignItems = 'center';
|
|
||||||
driveBayContainer.style.position = 'absolute';
|
|
||||||
driveBayContainer.style.left = '50%';
|
|
||||||
driveBayContainer.style.top = '50%';
|
|
||||||
driveBayContainer.style.transform = 'translate(-50%, -50%)';
|
|
||||||
|
|
||||||
const driveBays = Math.floor(Math.random() * 3) + 6;
|
const driveBays = Math.floor(Math.random() * 3) + 6;
|
||||||
for (let b = 0; b < driveBays; b++) {
|
for (let b = 0; b < driveBays; b++) {
|
||||||
@@ -248,10 +227,7 @@ function createServerRack() {
|
|||||||
|
|
||||||
const ledGroup = document.createElement('div');
|
const ledGroup = document.createElement('div');
|
||||||
ledGroup.className = 'led-group';
|
ledGroup.className = 'led-group';
|
||||||
ledGroup.style.position = 'absolute';
|
ledGroup.classList.add('rack-leds-pos-right-tight');
|
||||||
ledGroup.style.right = '10px';
|
|
||||||
ledGroup.style.top = '50%';
|
|
||||||
ledGroup.style.transform = 'translateY(-50%)';
|
|
||||||
|
|
||||||
const ledCount = Math.floor(Math.random() * 3) + 1;
|
const ledCount = Math.floor(Math.random() * 3) + 1;
|
||||||
const blinkClasses = ['led-blink-1', 'led-blink-2', 'led-blink-3', 'led-blink-4'];
|
const blinkClasses = ['led-blink-1', 'led-blink-2', 'led-blink-3', 'led-blink-4'];
|
||||||
@@ -319,28 +295,12 @@ heroEl.addEventListener('mouseup', () => { heroMouseDown = false; });
|
|||||||
// Toggle terminal expansion when clicking the hero section
|
// Toggle terminal expansion when clicking the hero section
|
||||||
heroEl.addEventListener('click', (e) => {
|
heroEl.addEventListener('click', (e) => {
|
||||||
if (e.target.closest('.btn')) return;
|
if (e.target.closest('.btn')) return;
|
||||||
if (activeTerminal && activeTerminal._mobileInput) {
|
if (!activeTerminal) return;
|
||||||
if (activeTerminal.classList.contains('grown')) {
|
if (activeTerminal.classList.contains('grown')) {
|
||||||
activeTerminal.classList.remove('grown');
|
collapseTerminal(activeTerminal);
|
||||||
activeTerminal.classList.remove('opaque');
|
activeTerminal._mobileInput?.blur();
|
||||||
const face = activeTerminal.closest('.server-face');
|
|
||||||
const unit = face?.closest('.rack-unit');
|
|
||||||
face?.classList.remove('grown');
|
|
||||||
unit?.classList.remove('grown');
|
|
||||||
heroEl.classList.remove('shifted');
|
|
||||||
activeTerminal._mobileInput.blur();
|
|
||||||
document.querySelector('.rack-container')?.classList.remove('opaque');
|
|
||||||
} else {
|
} else {
|
||||||
activeTerminal._mobileInput.focus();
|
expandTerminal(activeTerminal);
|
||||||
activeTerminal.classList.add('grown');
|
|
||||||
activeTerminal.classList.add('opaque');
|
|
||||||
const face = activeTerminal.closest('.server-face');
|
|
||||||
const unit = face?.closest('.rack-unit');
|
|
||||||
face?.classList.add('grown');
|
|
||||||
unit?.classList.add('grown');
|
|
||||||
heroEl.classList.add('shifted');
|
|
||||||
document.querySelector('.rack-container')?.classList.add('opaque');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1882,3 +1882,56 @@ footer p {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Rack decoration placement (moved out of inline styles in script.js) */
|
||||||
|
.rack-grill-v-pos {
|
||||||
|
position: absolute;
|
||||||
|
left: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rack-grill-h-pos {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rack-fans-pos {
|
||||||
|
position: absolute;
|
||||||
|
right: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rack-leds-pos-top {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rack-leds-pos-right {
|
||||||
|
position: absolute;
|
||||||
|
right: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rack-leds-pos-right-tight {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rack-drives-pos {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user