-
88.4 AM
-
TUNED: Rapture Jazz Network
+
+
-
\ No newline at end of file
diff --git a/website/script.js b/website/script.js
index 205a9b8..e29ccbe 100644
--- a/website/script.js
+++ b/website/script.js
@@ -1,205 +1,108 @@
-// Rapture Radio Local Playlist Configuration (Only containing your 6 downloaded files)
-const playlist = [
- {
- title: "Midnight, The Stars And You (1934) - Al Bowlly",
- src: "audio/Al Bowlly - Midnight,Stars And You.mp3"
- },
- {
- title: "Heartaches (1931) - Al Bowlly",
- src: "audio/Al Bowlly - Heartaches.mp3"
- },
- {
- title: "Belleville (1942) - Django Reinhardt",
- src: "audio/Django Reinhardt - Belleville.mp3"
- },
- {
- title: "Love Is The Sweetest Thing (1932) - Al Bowlly",
- src: "audio/Al Bowlly - Love Is the Sweetest Thing.mp3"
- },
- {
- title: "Nuages (1940) - Django Reinhardt",
- src: "audio/Django Reinhardt - Nuages.mp3"
- },
- {
- title: "Close Your Eyes (1933) - Al Bowlly",
- src: "audio/Al Bowlly - Close Your Eyes.mp3"
- }
-];
+// =========================================================================
+// Rapture Systems Telemetry & Dynamic Dossier Engine (Simplified)
+// =========================================================================
-let currentTrackIndex = 0;
+// Audio Context
let audioCtx;
-let filterNode;
-let sourceNode;
-let isPlaying = false; // Explicit playback tracking flag
-const audioElement = document.getElementById('radio-audio');
-const playButton = document.getElementById('radio-toggle');
-const volumeControl = document.getElementById('volume');
-const nowPlayingText = document.querySelector('.now-playing');
-
-// Load the initial track data
-loadTrack(currentTrackIndex);
-
-// Function to load a track by index
-function loadTrack(index) {
- const track = playlist[index];
- audioElement.src = track.src;
- nowPlayingText.textContent = `TUNED: ${track.title}`;
-}
-
-// Function to initialize Audio Context & Filter
function initAudio() {
- if (audioCtx) return; // Initialize only once
-
+ if (audioCtx) return;
const AudioContext = window.AudioContext || window.webkitAudioContext;
audioCtx = new AudioContext();
-
- sourceNode = audioCtx.createMediaElementSource(audioElement);
-
- // Apply AM Radio Bandpass Filter
- filterNode = audioCtx.createBiquadFilter();
- filterNode.type = 'bandpass';
- filterNode.frequency.value = 1100;
- filterNode.Q.value = 1.8;
-
- // Connection chain
- sourceNode.connect(filterNode);
- filterNode.connect(audioCtx.destination);
}
-// Resilient Play/Pause toggle
-playButton.addEventListener('click', () => {
- initAudio();
-
- if (audioCtx.state === 'suspended') {
- audioCtx.resume();
- }
-
- // Play synthetic mechanical switch SFX
- playSwitchSound();
-
- if (!isPlaying) {
- isPlaying = true;
- playButton.textContent = 'ON';
- playButton.classList.add('active');
-
- audioElement.play().catch(err => {
- console.error("Playback failed. Make sure the local file exists on disk!", err);
- });
- } else {
- audioElement.pause();
- isPlaying = false;
- playButton.textContent = 'OFF';
- playButton.classList.remove('active');
- }
-});
-
-// Auto-play next song when current one ends
-audioElement.addEventListener('ended', () => {
- currentTrackIndex = (currentTrackIndex + 1) % playlist.length;
- loadTrack(currentTrackIndex);
-
- if (isPlaying) {
- audioElement.play().catch(err => {
- console.error("Autoplay failed:", err);
- });
- }
-});
-
-// Adjust volume
-volumeControl.addEventListener('input', (e) => {
- audioElement.volume = e.target.value;
-});
-
-// Dynamic Node Status Monitoring
-function updateNodeStatuses() {
- fetch('status.json')
- .then(res => {
- if (!res.ok) throw new Error("status.json not ready yet");
- return res.json();
- })
- .then(data => {
- updateIndicator('status-ipa', data.ipa);
- updateIndicator('status-control', data.control);
- updateIndicator('status-web', data.web);
- updateIndicator('status-media', data.media);
- })
- .catch(err => {
- console.warn("Status check failed (waiting for script to run on VM):", err);
- });
-}
-
-function updateIndicator(id, isOnline) {
- const el = document.getElementById(id);
- if (!el) return;
- if (isOnline) {
- el.className = "status-indicator online";
- } else {
- el.className = "status-indicator offline";
- }
-}
-
-// Poll status.json every 10 seconds
-setInterval(updateNodeStatuses, 10000);
-updateNodeStatuses(); // Run immediately on page load
-
-// Sound synthesis utilities (Pure Web Audio API, zero downloads required)
+// Synthesizes a polished brass mechanical click for hover events
function playClickSound() {
- if (!audioCtx) return; // Wait for initial user click to enable audio
- if (audioCtx.state === 'suspended') return;
+ initAudio();
+ if (!audioCtx || audioCtx.state === 'suspended') return;
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'sine';
- osc.frequency.setValueAtTime(1400, audioCtx.currentTime); // High pitch click
- osc.frequency.exponentialRampToValueAtTime(400, audioCtx.currentTime + 0.03);
+ osc.frequency.setValueAtTime(1600, audioCtx.currentTime);
+ osc.frequency.exponentialRampToValueAtTime(600, audioCtx.currentTime + 0.02);
- gain.gain.setValueAtTime(0.04, audioCtx.currentTime); // Soft volume
- gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.03); // Rapid decay
+ gain.gain.setValueAtTime(0.025, audioCtx.currentTime);
+ gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.02);
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.start();
- osc.stop(audioCtx.currentTime + 0.03);
+ osc.stop(audioCtx.currentTime + 0.02);
}
-function playSwitchSound() {
- if (!audioCtx) return;
- if (audioCtx.state === 'suspended') return;
+// -------------------------------------------------------------------------
+// Interactive Systems Initialized
+// -------------------------------------------------------------------------
- // Dual oscillator thick mechanical click sound
- const osc1 = audioCtx.createOscillator();
- const osc2 = audioCtx.createOscillator();
- const gain = audioCtx.createGain();
+// -------------------------------------------------------------------------
+// FEATURE: Page-Wide Dynamic Bubble Trail (Following Cursor)
+// -------------------------------------------------------------------------
+let lastBubbleTime = 0;
- osc1.type = 'triangle';
- osc1.frequency.setValueAtTime(180, audioCtx.currentTime);
- osc1.frequency.exponentialRampToValueAtTime(60, audioCtx.currentTime + 0.08);
+function createHoverBubble(e) {
+ const now = Date.now();
+ if (now - lastBubbleTime < 45) return; // High frequency trail
+ lastBubbleTime = now;
- osc2.type = 'sawtooth';
- osc2.frequency.setValueAtTime(260, audioCtx.currentTime);
- osc2.frequency.exponentialRampToValueAtTime(90, audioCtx.currentTime + 0.06);
+ const bubble = document.createElement('span');
+
+ // Alternate between sparkling golden and cyan bubbles
+ const isGold = Math.random() > 0.5;
+ bubble.className = isGold ? 'hover-bubble bubble-gold-sparkle' : 'hover-bubble bubble-cyan-sparkle';
- gain.gain.setValueAtTime(0.12, audioCtx.currentTime);
- gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.1);
+ // Spawn coordinates centered on cursor
+ const size = Math.random() * 6 + 3; // 3px to 9px
+ bubble.style.width = `${size}px`;
+ bubble.style.height = `${size}px`;
+ bubble.style.left = `${e.pageX}px`;
+ bubble.style.top = `${e.pageY}px`;
- osc1.connect(gain);
- osc2.connect(gain);
- gain.connect(audioCtx.destination);
+ const drift = (Math.random() - 0.5) * 60; // Sway range
+ bubble.style.setProperty('--drift', `${drift}px`);
- osc1.start();
- osc2.start();
- osc1.stop(audioCtx.currentTime + 0.1);
- osc2.stop(audioCtx.currentTime + 0.1);
+ document.body.appendChild(bubble);
+
+ // Remove bubble after animation ends
+ setTimeout(() => {
+ bubble.remove();
+ }, 1200);
}
-// Bind mechanical hover sound clicks to all cards
-document.querySelectorAll('.card').forEach(card => {
- card.addEventListener('mouseenter', () => {
+// Bind bubble trail to the entire page body
+document.addEventListener('mousemove', createHoverBubble);
+
+// Audio Context unlock triggers on first mouse click
+document.body.addEventListener('click', () => {
+ initAudio();
+}, { once: true });
+
+// Mechanical hover sound bindings for all links and cards
+document.querySelectorAll('a, button, .tag, .card, .ryan-quote').forEach(el => {
+ el.addEventListener('mouseenter', () => {
playClickSound();
});
});
-
+// Fetch active VM count dynamically from status.json
+function fetchActiveVMs() {
+ fetch('status.json')
+ .then(res => {
+ if (!res.ok) throw new Error();
+ return res.json();
+ })
+ .then(data => {
+ if (data.active_vms !== undefined) {
+ const el = document.getElementById('active-vm-count');
+ if (el) {
+ el.textContent = `${data.active_vms} Virtual Machines`;
+ }
+ }
+ })
+ .catch(() => {
+ // Quietly fall back to default HTML value if not available locally
+ });
+}
+fetchActiveVMs();
diff --git a/website/style.css b/website/style.css
index 6260472..cb61142 100644
--- a/website/style.css
+++ b/website/style.css
@@ -1,20 +1,24 @@
-/* Rapture Dark - Decayed BioShock / Post-Civil War Edition */
+/* =========================================================================
+ Pristine Rapture - Pre-Civil War Luxury Art Deco Edition (Soften Colors)
+ ========================================================================= */
+
:root {
- /* Grungy, Murkier Base Colors */
- --bg-dark: rgb(8, 14, 13); /* Pitch black ocean depth */
- --card-bg: rgba(11, 20, 19, 0.92); /* Darkened, higher opacity glass panels */
- --card-hover: rgba(16, 28, 27, 0.98);
- --border-color: rgba(51, 224, 208, 0.15);
+ /* Softened, Warm Base Colors (Easy on the eyes) */
+ --ocean-dark: rgb(8, 14, 20); /* Deeper, calmer atlantic depths */
+ --velvet-blue: rgb(14, 24, 38); /* Dark slate velvet console backing */
+ --brass-dark: rgb(33, 26, 18); /* Softened dark brass */
+ --ivory-paper: rgb(234, 226, 210); /* Warm, soft aged cream/sepia parchment (not harsh white) */
- /* Corroded, Weathered Accents */
- --cyan-glow: rgb(51, 224, 208); /* Restored bright cyan glow */
- --gold-accent: rgb(212, 175, 55); /* Restored bright Art Deco gold */
- --rust-accent: rgb(186, 84, 48); /* Richer copper/rust accent */
- --text-main: rgb(230, 255, 252); /* Main text: Crisp pale glowing cyan-white */
- --text-muted: rgb(148, 173, 162); /* Lightened algae green-gray for clear contrast */
+ /* Softer Brushed Metallic Accents */
+ --gold-leaf: rgb(204, 172, 107); /* Brushed warm gold (subdued from bright yellow) */
+ --gold-glow: rgba(204, 172, 107, 0.25);
+ --cyan-accent: rgb(80, 168, 168); /* Softer, desaturated sage teal/aquamarine */
+ --text-light: rgb(215, 225, 222); /* Subdued off-white for dark zones */
+ --text-dark: rgb(45, 50, 48); /* Muted dark charcoal ink (less harsh than black) */
+ --text-muted: rgb(125, 142, 145); /* Muted steel grey-blue */
- --green-glow: rgb(52, 133, 96);
- --red-glow: rgb(184, 74, 74);
+ --green-glow: rgb(75, 168, 128); /* Softened forest/sage green */
+ --red-glow: rgb(180, 95, 95); /* Faded terracotta/crimson red */
}
/* Core Settings */
@@ -25,79 +29,26 @@
}
body {
- background-color: var(--bg-dark);
- background-image: url('bg.jpg');
+ background-color: var(--ocean-dark);
+ background-image: linear-gradient(135deg, rgba(8, 14, 20, 0.88) 0%, rgba(12, 22, 34, 0.94) 100%), url('bg.jpg');
background-size: cover;
background-position: center;
background-attachment: fixed;
- color: var(--text-main);
+ color: var(--text-light);
font-family: 'Montserrat', sans-serif;
min-height: 100vh;
overflow-x: hidden;
position: relative;
- /* Custom gold Art Deco pointer cursor */
- cursor: url("data:image/svg+xml;utf8,
"), auto;
+ /* Soft brushed gold pointer */
+ cursor: url("data:image/svg+xml;utf8,
"), auto;
}
-/* Custom glowing cyan pointer cursor on hover elements */
-a, button, input[type="range"], .link-card {
- cursor: url("data:image/svg+xml;utf8,
"), pointer !important;
+/* Custom glowing pointer cursor on hover elements */
+a, button, .tag, .download-dossier-btn, .dep-link, .ryan-quote, .download-btn, .dossier-folder {
+ cursor: url("data:image/svg+xml;utf8,
"), pointer !important;
}
-/* CRT Scanline Overlay Effect layered on top of background image */
-body::before {
- content: '';
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background:
- linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.35) 50%),
- linear-gradient(90deg, rgba(255, 0, 0, 0.03), rgba(0, 255, 0, 0.01), rgba(0, 0, 255, 0.03));
- background-size: 100% 4px, 6px 100%;
- pointer-events: none;
- z-index: 8; /* Moved behind the dashboard container */
-}
-
-/* Heavy vignette shadow for deep-sea bathysphere feeling */
-body::after {
- content: '';
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- box-shadow: inset 0 0 140px rgba(0, 0, 0, 0.95);
- pointer-events: none;
- z-index: 9; /* Moved behind the dashboard container */
-}
-
-/* Ambient Bioluminescent Background Blobs (Dimmed) */
-.glow-blob {
- position: absolute;
- width: 600px;
- height: 600px;
- border-radius: 50%;
- filter: blur(160px);
- opacity: 0.08;
- z-index: 0;
- pointer-events: none;
-}
-
-.blob-cyan {
- background-color: var(--cyan-glow);
- top: -100px;
- right: -100px;
-}
-
-.blob-gold {
- background-color: var(--rust-accent);
- bottom: -200px;
- left: -200px;
-}
-
-/* Slower Murky Floating Bubbles */
+/* Thriving Metropolis - Slower, Murky Floating Bubbles */
.bubbles {
position: fixed;
top: 0;
@@ -112,194 +63,580 @@ body::after {
.bubble {
position: absolute;
bottom: -30px;
- background-color: rgba(40, 180, 168, 0.06);
- border: 1px solid rgba(40, 180, 168, 0.15);
+ background-color: rgba(80, 168, 168, 0.03);
+ border: 1px solid rgba(80, 168, 168, 0.1);
border-radius: 50%;
- animation: floatUp 25s infinite linear;
+ animation: floatUp 30s infinite linear;
}
-.bubble:nth-child(1) { left: 10%; width: 22px; height: 22px; animation-duration: 22s; animation-delay: 2s; }
-.bubble:nth-child(2) { left: 25%; width: 10px; height: 10px; animation-duration: 35s; animation-delay: 5s; }
-.bubble:nth-child(3) { left: 50%; width: 35px; height: 35px; animation-duration: 28s; animation-delay: 0s; }
-.bubble:nth-child(4) { left: 70%; width: 14px; height: 14px; animation-duration: 40s; animation-delay: 8s; }
-.bubble:nth-child(5) { left: 85%; width: 26px; height: 26px; animation-duration: 30s; animation-delay: 4s; }
+.bubble:nth-child(1) { left: 8%; width: 18px; height: 18px; animation-duration: 25s; animation-delay: 1s; }
+.bubble:nth-child(2) { left: 22%; width: 8px; height: 8px; animation-duration: 40s; animation-delay: 6s; }
+.bubble:nth-child(3) { left: 45%; width: 28px; height: 28px; animation-duration: 32s; animation-delay: 0s; }
+.bubble:nth-child(4) { left: 72%; width: 12px; height: 12px; animation-duration: 45s; animation-delay: 4s; }
+.bubble:nth-child(5) { left: 88%; width: 22px; height: 22px; animation-duration: 28s; animation-delay: 8s; }
@keyframes floatUp {
- 0% { transform: translateY(0) translateX(0) scale(0.8); opacity: 0; }
- 10% { opacity: 0.5; }
- 90% { opacity: 0.5; }
- 100% { transform: translateY(-110vh) translateX(80px) scale(1.2); opacity: 0; }
+ 0% { transform: translateY(0) translateX(0) scale(0.9); opacity: 0; }
+ 15% { opacity: 0.3; }
+ 85% { opacity: 0.3; }
+ 100% { transform: translateY(-110vh) translateX(60px) scale(1.1); opacity: 0; }
}
-/* Container & Tarnished Art Deco Outer Border Frame */
+/* Ambient Bioluminescent Background Blobs */
+.glow-blob {
+ position: absolute;
+ width: 600px;
+ height: 600px;
+ border-radius: 50%;
+ filter: blur(180px);
+ opacity: 0.05;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.blob-cyan { background-color: var(--cyan-accent); top: -100px; right: -100px; }
+.blob-gold { background-color: var(--gold-leaf); bottom: -200px; left: -200px; }
+
+/* Pristine Art Deco Container Box */
.container {
- max-width: 1100px;
- margin: 20px auto; /* Reduced from 50px auto */
- padding: 30px; /* Reduced from 40px */
+ max-width: 1150px;
+ margin: 40px auto;
+ padding: 50px;
position: relative;
- z-index: 10; /* Brought to the absolute front so text is clean and un-distorted */
- background: rgba(10, 18, 17, 0.9);
- border-radius: 4px; /* Hard square edges */
- box-shadow: 0 30px 80px rgba(0, 0, 0, 0.8);
+ z-index: 10;
+ background: rgba(8, 15, 25, 0.97); /* Rich dark velvet desk surface */
+ box-shadow: 0 40px 100px rgba(0, 0, 0, 0.95);
}
-.art-deco-frame {
- border: 2px solid var(--gold-accent);
- outline: 6px double var(--rust-accent); /* Double rust frame outline */
- outline-offset: -16px;
+.art-deco-frame-pristine {
+ border: 3px solid var(--gold-leaf);
+ outline: 1px solid var(--gold-leaf);
+ outline-offset: 4px;
}
-/* Header with Flickering Power Effect */
+/* Art Deco Corner Accents (Sunburst Style) */
+.corner-accent {
+ position: absolute;
+ width: 32px;
+ height: 32px;
+ border: 2px solid var(--gold-leaf);
+ z-index: 15;
+ pointer-events: none;
+}
+
+.corner-accent::before {
+ content: '';
+ position: absolute;
+ width: 16px;
+ height: 16px;
+ border: 1px solid var(--gold-leaf);
+}
+
+.top-left { top: 12px; left: 12px; border-right: none; border-bottom: none; }
+.top-left::before { top: 0; left: 0; border-right: none; border-bottom: none; }
+
+.top-right { top: 12px; right: 12px; border-left: none; border-bottom: none; }
+.top-right::before { top: 0; right: 0; border-left: none; border-bottom: none; }
+
+.bottom-left { bottom: 12px; left: 12px; border-right: none; border-top: none; }
+.bottom-left::before { bottom: 0; left: 0; border-right: none; border-top: none; }
+
+.bottom-right { bottom: 12px; right: 12px; border-left: none; border-top: none; }
+.bottom-right::before { bottom: 0; right: 0; border-left: none; border-top: none; }
+
+/* Main Header */
.main-header {
text-align: center;
- margin-bottom: 25px; /* Reduced from 50px */
- padding: 10px 0;
+ margin-bottom: 45px;
+ position: relative;
+ padding: 15px 0;
}
.deco-divider-top, .deco-divider-bottom {
height: 2px;
- background: linear-gradient(90deg, transparent, var(--rust-accent) 20%, var(--gold-accent) 50%, var(--rust-accent) 80%, transparent);
- width: 70%;
+ background: linear-gradient(90deg, transparent, var(--gold-leaf) 30%, var(--gold-leaf) 70%, transparent);
+ width: 60%;
margin: 0 auto;
}
.deco-divider-top { margin-bottom: 15px; }
.deco-divider-bottom { margin-top: 15px; }
+/* Art Deco Sunburst Logo positioned behind the title */
+.sunburst-logo {
+ position: absolute;
+ top: 52%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 320px;
+ height: 180px;
+ background-image: url("data:image/svg+xml;utf8,
");
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ z-index: 1;
+ pointer-events: none;
+}
+
.main-header h1 {
font-family: 'Cinzel', serif;
font-size: 4.5rem;
font-weight: 900;
- letter-spacing: 12px;
+ letter-spacing: 14px;
text-transform: uppercase;
- color: var(--text-main);
- background: linear-gradient(135deg, var(--gold-accent), var(--text-main), var(--rust-accent));
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- animation: lightFlicker 6s infinite;
+ color: var(--gold-leaf);
+ text-shadow: 0 0 25px var(--gold-glow);
+ position: relative;
+ z-index: 2;
+ background: none !important;
+ -webkit-background-clip: unset !important;
+ -webkit-text-fill-color: unset !important;
}
.main-header .subtitle {
- color: var(--cyan-glow);
+ color: var(--cyan-accent);
font-family: 'Cinzel', serif;
font-size: 0.95rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 6px;
margin-top: 8px;
- animation: glowPulse 4s infinite alternate;
+ text-shadow: 0 0 10px rgba(80, 168, 168, 0.2);
+ position: relative;
+ z-index: 2;
}
-/* Dashboard Sections */
+/* Two-Column Grid */
+.portfolio-grid {
+ display: grid;
+ grid-template-columns: 1fr 1.6fr;
+ gap: 40px;
+}
+
+@media (max-width: 900px) {
+ .portfolio-grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* Card Sections */
.card-section {
- margin-bottom: 20px; /* Reduced from 40px */
+ margin-bottom: 30px;
}
.card-section h2 {
font-family: 'Cinzel', serif;
- font-size: 1.3rem;
+ font-size: 1.15rem;
font-weight: 700;
- margin-bottom: 25px;
- color: var(--gold-accent);
- border-bottom: 1px solid rgba(197, 160, 89, 0.2);
- padding-bottom: 12px;
+ margin-bottom: 24px;
+ color: var(--gold-leaf);
+ text-shadow: 0 0 8px var(--gold-glow);
+ text-align: center;
letter-spacing: 3px;
- text-shadow: 0 0 10px rgba(153, 122, 61, 0.2);
-}
-
-/* Grid Layout */
-.grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- gap: 24px;
-}
-
-/* Decayed Glassmorphic Cards */
-.card {
- background: var(--card-bg);
- border: 1px solid var(--border-color);
- border-radius: 4px; /* Harder corners for Art Deco geometric style */
- padding: 24px;
- backdrop-filter: blur(24px); /* Increased blur to strongly diffuse the detailed background */
- -webkit-backdrop-filter: blur(24px);
- transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
display: flex;
- flex-direction: column;
- position: relative;
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6), inset 0 0 20px rgba(0, 0, 0, 0.4);
+ align-items: center;
+ justify-content: center;
+ gap: 15px;
}
-.card::before {
+/* Ornate Art Deco Gold Title Wings */
+.deco-wing {
+ display: inline-block;
+ width: 30px;
+ height: 2px;
+ background: linear-gradient(90deg, transparent, var(--gold-leaf));
+ position: relative;
+}
+
+.deco-wing::before, .deco-wing::after {
content: '';
position: absolute;
- top: 6px;
- left: 6px;
- right: 6px;
- bottom: 6px;
- border: 1px solid rgba(153, 122, 61, 0.05);
+ left: 0;
+ width: 100%;
+ height: 1px;
+ background: var(--gold-leaf);
+}
+.deco-wing::before { top: -4px; opacity: 0.6; }
+.deco-wing::after { top: 4px; opacity: 0.6; }
+
+.main-column .deco-wing {
+ width: 45px;
+}
+
+/* Ivory Parchment Folder Dossiers (Soften to Warm Sepia-Ivory) */
+.dossier-folder {
+ background-color: var(--ivory-paper) !important;
+ background-image: linear-gradient(rgba(0, 0, 0, 0.015) 1px, transparent 1px);
+ background-size: 100% 24px; /* Notebook lines */
+ color: var(--text-dark) !important;
+ border: 1px solid rgba(204, 172, 107, 0.4) !important;
+ outline: 1px solid rgba(204, 172, 107, 0.25);
+ outline-offset: -5px;
+ border-radius: 2px;
+ padding: 32px 26px 26px 26px !important;
+ box-shadow: 0 15px 35px rgba(0, 0, 0, 0.55), inset 0 0 20px rgba(0, 0, 0, 0.02) !important;
+ position: relative;
+ overflow: hidden;
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
+}
+
+.dossier-folder:hover {
+ transform: translateY(-2px);
+ border-color: var(--gold-leaf) !important;
+ box-shadow: 0 20px 45px rgba(0, 0, 0, 0.65), 0 0 12px rgba(204, 172, 107, 0.1) !important;
+}
+
+/* Polished Brass Paperclip Ornament (Dimmed) */
+.brass-clip {
+ position: absolute;
+ top: -8px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 14px;
+ height: 34px;
+ background: linear-gradient(135deg, rgb(220, 190, 120) 0%, rgb(170, 130, 70) 50%, rgb(110, 80, 30) 100%);
+ border: 1px solid rgba(204, 172, 107, 0.6);
+ border-radius: 6px;
+ box-shadow: 0 4px 6px rgba(0,0,0,0.5), inset 0 0 4px rgba(255,255,255,0.3);
+ z-index: 10;
pointer-events: none;
}
-.card-header {
+/* Folder header stamps */
+.card-header-dossier {
display: flex;
+ flex-direction: column;
align-items: center;
- gap: 12px;
- margin-bottom: 16px;
+ margin-bottom: 15px;
+ border-bottom: 1px solid rgba(45, 50, 48, 0.18);
+ padding-bottom: 8px;
}
-.card h3 {
+/* Softened Ink Stamp Look */
+.seal-stamp {
font-family: 'Cinzel', serif;
- font-size: 1.2rem;
- font-weight: 700;
- letter-spacing: 1px;
+ font-weight: 900;
+ font-size: 0.65rem;
+ color: rgb(140, 60, 60); /* Muted Red */
+ border: 2px double rgb(140, 60, 60);
+ padding: 3px 8px;
+ letter-spacing: 1.5px;
+ transform: rotate(-8deg);
+ display: inline-block;
+ opacity: 0.78;
+ margin-bottom: 10px;
+ user-select: none;
}
-.card p {
- font-size: 0.88rem;
- color: var(--text-muted);
- line-height: 1.6;
-}
-
-.card .ip {
- font-family: monospace;
+.dossier-folder .role-title {
+ font-family: 'Cinzel', serif;
font-size: 1.05rem;
- color: var(--cyan-glow);
- margin-bottom: 6px;
- text-shadow: 0 0 8px rgba(40, 180, 168, 0.2);
+ color: var(--text-dark) !important;
+ letter-spacing: 1px;
+ font-weight: bold;
}
-/* Interactive link cards */
-.link-card {
- text-decoration: none;
- color: inherit;
- cursor: pointer;
+.dossier-folder .profile-text {
+ color: var(--text-dark) !important;
+ text-align: justify;
+ line-height: 1.7;
+ font-size: 0.86rem;
}
-.link-card:hover {
- background: var(--card-hover);
- border-color: var(--border-hover);
- transform: scale(1.01);
- box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6), 0 0 15px rgba(153, 122, 61, 0.1);
-}
-
-.action-btn {
- margin-top: auto;
- padding-top: 16px;
+/* Sidebar Dossier Download Button */
+.dossier-folder .download-btn {
+ display: inline-block;
+ width: 100%;
+ padding: 14px;
+ text-align: center;
+ background: linear-gradient(135deg, rgb(38, 30, 22), rgb(20, 16, 12));
+ color: var(--gold-leaf);
font-family: 'Cinzel', serif;
- font-size: 0.8rem;
font-weight: 700;
- color: var(--gold-accent);
+ font-size: 0.85rem;
letter-spacing: 2px;
+ text-transform: uppercase;
+ text-decoration: none;
+ border: 1px solid rgba(204, 172, 107, 0.8);
+ position: relative;
+ overflow: hidden;
+ box-shadow: inset 0 0 10px rgba(204, 172, 107, 0.15);
+ transition: all 0.4s ease;
+ margin-top: 20px;
+}
+
+.dossier-folder .download-btn:hover {
+ color: var(--ivory-paper);
+ background: var(--brass-dark);
+ border-color: var(--gold-leaf);
+ box-shadow: 0 0 20px rgba(204, 172, 107, 0.35);
+}
+
+/* Technical Plasmids (Skills on Paper) */
+.skills-card {
+ display: flex;
+ flex-direction: column;
+ gap: 28px;
+}
+
+.skills-group h3 {
+ font-family: 'Cinzel', serif;
+ font-size: 0.85rem;
+ color: var(--text-dark);
+ margin-bottom: 12px;
+ letter-spacing: 1.5px;
+ font-weight: bold;
+ border-left: 2.5px solid var(--gold-leaf);
+ padding-left: 8px;
+}
+
+.skill-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px 12px;
+}
+
+.dossier-folder .tag {
+ background: rgba(0, 0, 0, 0.03);
+ border: 1px solid rgba(8, 14, 13, 0.12);
+ color: var(--text-dark);
+ font-size: 0.75rem;
+ padding: 6px 14px;
+ font-weight: 600;
transition: all 0.3s ease;
}
-.link-card:hover .action-btn {
- transform: translateX(6px);
- color: var(--cyan-glow);
- text-shadow: 0 0 8px rgba(40, 180, 168, 0.4);
+.dossier-folder .tag:hover {
+ border-color: var(--cyan-accent);
+ background: var(--cyan-accent);
+ color: var(--ivory-paper);
+ text-shadow: none;
+ box-shadow: 0 0 10px rgba(80, 168, 168, 0.25);
}
-/* Pulsing Status Indicators (Flickering) */
+/* Education Cards on Paper */
+.education-card {
+ gap: 15px;
+}
+
+.education-card .edu-item h3 {
+ font-family: 'Cinzel', serif;
+ font-size: 0.95rem;
+ color: var(--text-dark);
+ margin-bottom: 4px;
+ font-weight: bold;
+}
+
+.education-card .edu-detail {
+ font-size: 0.78rem;
+ color: rgba(8, 14, 13, 0.7);
+}
+
+.education-card .edu-divider {
+ height: 1px;
+ background: linear-gradient(90deg, transparent, rgba(8, 14, 13, 0.1), transparent);
+}
+
+/* Featured Project Cards on Paper */
+.projects-list {
+ display: flex;
+ flex-direction: column;
+ gap: 25px;
+}
+
+.project-card {
+ border-left: 3px solid var(--gold-leaf) !important;
+}
+
+.project-card:hover {
+ border-left-color: var(--cyan-accent) !important;
+}
+
+.project-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 12px;
+ border-bottom: 1px solid rgba(8, 14, 13, 0.08);
+ padding-bottom: 8px;
+}
+
+.project-header h3 {
+ font-family: 'Cinzel', serif;
+ font-size: 1rem;
+ font-weight: bold;
+ color: var(--text-dark);
+}
+
+.project-tag {
+ font-family: 'Cinzel', serif;
+ font-size: 0.7rem;
+ color: rgb(140, 60, 60);
+ font-weight: bold;
+ letter-spacing: 1px;
+ border: 1px solid rgba(140, 60, 60, 0.25);
+ padding: 3px 8px;
+}
+
+.project-desc {
+ margin-bottom: 18px;
+ line-height: 1.65;
+}
+
+.project-link {
+ font-family: 'Cinzel', serif;
+ font-size: 0.75rem;
+ font-weight: 700;
+ color: var(--text-dark);
+ text-decoration: none;
+ letter-spacing: 1.5px;
+ transition: all 0.3s ease;
+ align-self: flex-start;
+ border-bottom: 1.5px solid rgba(45, 50, 48, 0.4);
+ padding-bottom: 1px;
+}
+
+.project-link:hover {
+ color: var(--cyan-accent);
+ border-bottom-color: var(--cyan-accent);
+ transform: translateX(4px);
+}
+
+/* Contact Card on Paper */
+.contact-card {
+ gap: 15px;
+}
+
+.contact-links {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ margin-top: 10px;
+}
+
+.contact-item {
+ color: var(--text-dark) !important;
+ text-decoration: none;
+ font-size: 0.85rem;
+ font-family: monospace;
+ font-weight: 600;
+ transition: all 0.3s ease;
+}
+
+.contact-item .label {
+ font-family: 'Cinzel', serif;
+ color: rgb(140, 60, 60);
+ font-weight: 700;
+ margin-right: 5px;
+}
+
+.contact-item:hover {
+ color: var(--cyan-accent) !important;
+}
+
+/* LOWER PORTION: Central Operations Panel (Soften Neon Console) */
+.telemetry-section-pristine h2 {
+ font-family: 'Cinzel', serif;
+ color: var(--gold-leaf);
+}
+
+.operations-card {
+ border-top: 3px solid var(--gold-leaf) !important;
+}
+
+.ops-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 15px;
+ border-bottom: 1px solid rgba(45, 50, 48, 0.15);
+ padding-bottom: 15px;
+ margin-bottom: 15px;
+}
+
+.indicator-group {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.ops-indicator {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background-color: var(--cyan-accent);
+ box-shadow: 0 0 8px var(--cyan-accent);
+ animation: pulse 2.5s infinite alternate;
+}
+
+.ops-header h3 {
+ font-family: 'Cinzel', serif;
+ font-size: 0.9rem;
+ letter-spacing: 1.5px;
+ color: var(--text-dark);
+}
+
+/* Mini Node Monitor Grid */
+.mini-nodes-grid {
+ display: flex;
+ gap: 20px;
+ flex-wrap: wrap;
+}
+
+.mini-node {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.mini-node .node-name {
+ font-family: monospace;
+ font-size: 0.8rem;
+ color: var(--text-dark);
+}
+
+.mini-node:hover .node-name {
+ color: var(--cyan-accent);
+}
+
+/* Telemetry Embedded Iframes */
+.embedded-telemetry {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
+ gap: 24px;
+}
+
+@media (max-width: 500px) {
+ .embedded-telemetry {
+ grid-template-columns: 1fr;
+ }
+}
+
+.telemetry-box {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.telemetry-box h4 {
+ font-family: 'Cinzel', serif;
+ font-size: 0.78rem;
+ color: var(--text-dark);
+ letter-spacing: 1px;
+}
+
+.telemetry-iframe {
+ width: 100%;
+ height: 200px;
+ border: 1px solid var(--gold-leaf);
+ background: var(--ocean-dark);
+ box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.95);
+}
+
+/* Status Indicators */
.status-indicator {
width: 8px;
height: 8px;
@@ -320,12 +657,21 @@ body::after {
}
.online {
- background-color: var(--cyan-glow);
- animation: neonFlicker 8s infinite alternate;
+ background-color: var(--cyan-accent);
+ box-shadow: 0 0 6px var(--cyan-accent);
}
.online::after {
- background-color: var(--cyan-glow);
+ background-color: var(--cyan-accent);
+}
+
+.offline {
+ background-color: var(--red-glow) !important;
+ box-shadow: 0 0 6px var(--red-glow);
+}
+
+.offline::after {
+ background-color: var(--red-glow) !important;
}
@keyframes pulse {
@@ -333,129 +679,12 @@ body::after {
100% { transform: scale(3.5); opacity: 0; }
}
-/* Rapture Radio Player (Decayed Panel look) */
-.radio-card {
- border: 1px double var(--gold-accent) !important;
- outline: 1px solid var(--rust-accent);
- outline-offset: -8px;
- background: rgba(10, 16, 15, 0.95) !important;
- box-shadow: inset 0 0 30px rgba(0,0,0,0.8), 0 10px 30px rgba(0,0,0,0.5) !important;
-}
-
-.radio-controls {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 25px;
-}
-
-/* Rusted Brass Toggle Knob */
-.radio-switch {
- font-family: 'Cinzel', serif;
- font-weight: 700;
- font-size: 1rem;
- background: rgb(8, 12, 11);
- color: var(--text-muted);
- border: 2px solid var(--gold-accent);
- width: 75px;
- height: 75px;
- border-radius: 50%;
- cursor: pointer;
- box-shadow: inset 0 0 15px rgba(0,0,0,0.9), 0 5px 15px rgba(0,0,0,0.4);
- transition: all 0.4s ease;
- display: flex;
- align-items: center;
- justify-content: center;
- position: relative;
-}
-
-.radio-switch::before {
- content: '';
- position: absolute;
- width: 4px;
- height: 20px;
- background: var(--rust-accent);
- top: 6px;
- left: 50%;
- transform: translateX(-50%);
- border-radius: 2px;
- transition: transform 0.4s ease;
-}
-
-.radio-switch.active {
- color: var(--gold-accent);
- border-color: var(--rust-accent);
- box-shadow: 0 0 20px rgba(168, 70, 39, 0.3), inset 0 0 5px rgba(168, 70, 39, 0.2);
- text-shadow: 0 0 8px var(--gold-accent);
-}
-
-.radio-switch.active::before {
- transform: translateX(-50%) rotate(90deg); /* Turn dial 90 degrees when ON */
-}
-
-.radio-info {
- flex-grow: 1;
-}
-
-.radio-info .frequency {
- font-family: 'Cinzel', serif;
- font-size: 1.3rem;
- font-weight: 700;
- color: var(--gold-accent);
- letter-spacing: 2px;
- animation: neonFlicker 5s infinite;
-}
-
-.radio-info .now-playing {
- font-size: 0.85rem;
- color: var(--text-muted);
- font-style: italic;
- margin-top: 6px;
- letter-spacing: 1px;
-}
-
-/* Volume Dial/Slider */
-.volume-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 6px;
-}
-
-.volume-container label {
- font-family: 'Cinzel', serif;
- font-size: 0.75rem;
- color: var(--gold-accent);
- letter-spacing: 1px;
-}
-
-#volume {
- -webkit-appearance: none;
- width: 80px;
- background: var(--bg-dark);
- height: 5px;
- border-radius: 1px;
- outline: none;
- border: 1px solid rgba(197, 160, 89, 0.15);
-}
-
-#volume::-webkit-slider-thumb {
- -webkit-appearance: none;
- width: 14px;
- height: 14px;
- border-radius: 2px; /* Square slider thumb for vintage hardware */
- background: var(--gold-accent);
- border: 1px solid var(--rust-accent);
- cursor: pointer;
- box-shadow: 0 0 4px var(--gold-accent);
-}
-
/* Footer & Andrew Ryan Quote */
.main-footer {
text-align: center;
- margin-top: 30px; /* Reduced from 60px */
- padding-top: 20px; /* Reduced from 30px */
- border-top: 1px solid rgba(153, 122, 61, 0.15);
+ margin-top: 40px;
+ padding-top: 30px;
+ border-top: 1px solid rgba(204, 172, 107, 0.15);
}
.ryan-quote {
@@ -463,79 +692,79 @@ body::after {
font-size: 1.35rem;
font-weight: 400;
letter-spacing: 3px;
- color: var(--gold-accent);
+ color: var(--gold-leaf);
margin-bottom: 12px;
- text-shadow: 0 0 12px rgba(153, 122, 61, 0.2);
- animation: quoteGlow 7s infinite alternate;
+ text-shadow: 0 0 12px rgba(204, 172, 107, 0.15);
+ transition: all 0.3s ease;
+ user-select: none;
+}
+
+.ryan-quote:hover {
+ color: var(--cyan-accent);
+ text-shadow: 0 0 15px var(--cyan-accent);
}
.footer-sub {
color: var(--text-muted);
- font-size: 0.78rem;
+ font-size: 0.75rem;
font-weight: 300;
letter-spacing: 1px;
}
-/* Animations for Decaying Power Grid */
-@keyframes lightFlicker {
- 0%, 19.999%, 22%, 62.999%, 64%, 64.999%, 70%, 100% {
- opacity: 0.98;
- filter: drop-shadow(0 0 20px rgba(197, 160, 89, 0.15));
- }
- 20%, 21.999%, 63%, 63.999%, 65%, 69.999% {
- opacity: 0.45;
- filter: none;
- }
+/* FEATURE: Dynamic Hover Bubbles Styles (Cursor Trail) */
+.hover-bubble {
+ position: absolute;
+ pointer-events: none;
+ z-index: 100;
+ border-radius: 50%;
+ transform: scale(0.6);
+ animation: hoverBubbleFloat 1.2s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;
}
-@keyframes neonFlicker {
- 0%, 19.999%, 21%, 23%, 25%, 54.999%, 56%, 100% {
- opacity: 0.9;
- text-shadow: 0 0 8px var(--cyan-glow);
- }
- 20%, 22.999%, 24%, 55%, 55.999% {
- opacity: 0.3;
- text-shadow: none;
- }
+.bubble-cyan-sparkle {
+ background: radial-gradient(circle, rgba(80, 168, 168, 0.35) 0%, transparent 80%);
+ border: 0.5px solid rgba(80, 168, 168, 0.5);
+ box-shadow: 0 0 6px rgba(80, 168, 168, 0.2);
}
-@keyframes glowPulse {
- 0% { text-shadow: 0 0 5px var(--cyan-glow); }
- 100% { text-shadow: 0 0 15px var(--cyan-glow); }
+.bubble-gold-sparkle {
+ background: radial-gradient(circle, rgba(204, 172, 107, 0.35) 0%, transparent 80%);
+ border: 0.5px solid rgba(204, 172, 107, 0.5);
+ box-shadow: 0 0 6px rgba(204, 172, 107, 0.2);
}
-@keyframes quoteGlow {
- 0% { text-shadow: 0 0 5px rgba(153, 122, 61, 0.1); }
- 100% { text-shadow: 0 0 15px rgba(153, 122, 61, 0.3); }
+@keyframes hoverBubbleFloat {
+ 0% { transform: scale(0.5) translateY(0); opacity: 0.8; }
+ 100% { transform: scale(1.2) translateY(-70px) translateX(var(--drift)); opacity: 0; }
}
-/* Offline status indicator (red) */
-.offline {
- background-color: var(--red-glow) !important;
-}
-
-.offline::after {
- background-color: var(--red-glow) !important;
-}
-
-/* Telemetry Grid & Grafana Embed Iframe Styling */
-.telemetry-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
- gap: 24px;
-}
-
-.telemetry-card {
- height: 380px; /* Generous height to fit Grafana timelines */
- padding: 16px;
-}
-
-.telemetry-iframe {
- width: 100%;
+/* FEATURE: Dynamic Glass Reflection / Light Sweep Effect */
+.dossier-folder::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -150%;
+ width: 50%;
height: 100%;
- border: 1px solid var(--gold-accent);
- background: var(--bg-dark);
- border-radius: 2px;
- box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.9);
+ background: linear-gradient(90deg, transparent, rgba(204, 172, 107, 0.08) 50%, transparent);
+ transform: skewX(-25deg);
+ transition: none;
+ z-index: 5;
+ pointer-events: none;
}
+.dossier-folder:hover::after {
+ left: 150%;
+ transition: left 0.9s cubic-bezier(0.25, 1, 0.5, 1);
+}
+
+/* Stable breathing glow animation */
+@keyframes glowPulse {
+ 0% { text-shadow: 0 0 4px var(--cyan-accent); }
+ 100% { text-shadow: 0 0 10px var(--cyan-accent); }
+}
+
+@keyframes lightFlicker {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.96; }
+}