feat: dropdown nav with submenus + black ops colour theme redesign
- Navigation: 6 top-level items (BASE, TRANSMISSIONS, ARMOURY, INTEL, SAFEHOUSE, COMMS) with dropdown children - nav.js: renders nested dropdown submenus, mobile tap-to-toggle support - Theme: tactical green (#00ff41) accent, deep black (#0a0a0a) bg, amber (#c9a227) secondary - 176 colour replacements across 4 CSS + 3 JS files - Mobile: responsive dropdowns with slide animation - Updated navigation.json with full nested structure
This commit is contained in:
parent
c3455b34cd
commit
139849d632
9 changed files with 365 additions and 216 deletions
|
|
@ -1,17 +1,54 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"label": "HOME",
|
"label": "BASE", "url": "/", "order": 0,
|
||||||
"url": "/",
|
"children": [
|
||||||
"order": 1
|
{"label": "OPERATOR PROFILE", "url": "/#operator"},
|
||||||
|
{"label": "DOSSIER", "url": "/#dossier"},
|
||||||
|
{"label": "DIAGNOSTICS", "url": "/#diagnostics"},
|
||||||
|
{"label": "SITREP", "url": "/#sitrep"},
|
||||||
|
{"label": "RADAR", "url": "/#radar"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "BLOG",
|
"label": "TRANSMISSIONS", "url": "/blog", "order": 1,
|
||||||
"url": "/blog",
|
"children": [
|
||||||
"order": 2
|
{"label": "DISPATCHES", "url": "/blog"},
|
||||||
|
{"label": "SYNAPTIC LOG", "url": "/blog?tag=thoughts"},
|
||||||
|
{"label": "DIRECTIVES", "url": "/blog?tag=tasks"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "ADMIN",
|
"label": "ARMOURY", "url": "/blog?tag=dev", "order": 2,
|
||||||
"url": "/admin",
|
"children": [
|
||||||
"order": 3
|
{"label": "LOADOUT", "url": "/blog?tag=tools"},
|
||||||
|
{"label": "FIELD MANUALS", "url": "/blog?tag=guides"},
|
||||||
|
{"label": "BLUEPRINTS", "url": "/blog?tag=configs"},
|
||||||
|
{"label": "CONTRABAND", "url": "/blog?tag=discoveries"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "INTEL", "url": "/blog?tag=intel", "order": 3,
|
||||||
|
"children": [
|
||||||
|
{"label": "REDACTED", "url": "/blog?tag=classified"},
|
||||||
|
{"label": "CASE FILES", "url": "/blog?tag=truecrime"},
|
||||||
|
{"label": "BLACK OPS", "url": "/blog?tag=conspiracy"},
|
||||||
|
{"label": "EXHIBITS", "url": "/blog?tag=evidence"},
|
||||||
|
{"label": "WIRETAPS", "url": "/blog?tag=intercepts"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "SAFEHOUSE", "url": "/#links", "order": 4,
|
||||||
|
"children": [
|
||||||
|
{"label": "ASSET LINKS", "url": "/#links"},
|
||||||
|
{"label": "DEAD DROPS", "url": "/#deaddrops"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "COMMS", "url": "/#contact", "order": 5,
|
||||||
|
"children": [
|
||||||
|
{"label": "OPEN CHANNELS", "url": "/#contact"},
|
||||||
|
{"label": "ENCRYPTED LINE", "url": "mailto:jaeswift@jaeswift.xyz"},
|
||||||
|
{"label": "BACKUP RELAY", "url": "/#backup-relay"}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -3,21 +3,21 @@
|
||||||
Full cyberpunk admin theme
|
Full cyberpunk admin theme
|
||||||
=================================================== */
|
=================================================== */
|
||||||
:root {
|
:root {
|
||||||
--bg: #0a0e17;
|
--bg: #111111;
|
||||||
--bg2: #0f1420;
|
--bg2: #141414;
|
||||||
--bg3: #151b2b;
|
--bg3: #1a1a1a;
|
||||||
--accent: #00ffc8;
|
--accent: #00ff41;
|
||||||
--accent-dim: rgba(0, 255, 200, 0.15);
|
--accent-dim: rgba(0, 255, 65, 0.15);
|
||||||
--secondary: #ff006e;
|
--secondary: #ff2d2d;
|
||||||
--secondary-dim: rgba(255, 0, 110, 0.15);
|
--secondary-dim: rgba(255, 45, 45, 0.15);
|
||||||
--text: #c8d6e5;
|
--text: #c0c0c0;
|
||||||
--text-dim: rgba(200, 214, 229, 0.5);
|
--text-dim: rgba(192, 192, 192, 0.5);
|
||||||
--danger: #ff4757;
|
--danger: #ff2d2d;
|
||||||
--warn: #ffa502;
|
--warn: #c9a227;
|
||||||
--success: #00ffc8;
|
--success: #00ff41;
|
||||||
--info: #00d4ff;
|
--info: #c9a227;
|
||||||
--border: rgba(0, 255, 200, 0.08);
|
--border: rgba(0, 255, 65, 0.08);
|
||||||
--border-strong: rgba(0, 255, 200, 0.2);
|
--border-strong: rgba(0, 255, 65, 0.2);
|
||||||
--sidebar-w: 220px;
|
--sidebar-w: 220px;
|
||||||
--topbar-h: 50px;
|
--topbar-h: 50px;
|
||||||
--font-mono: 'JetBrains Mono', monospace;
|
--font-mono: 'JetBrains Mono', monospace;
|
||||||
|
|
@ -45,11 +45,11 @@ body {
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: rgba(0, 255, 200, 0.15);
|
background: rgba(0, 255, 65, 0.15);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: rgba(0, 255, 200, 0.25);
|
background: rgba(0, 255, 65, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Login Screen ─── */
|
/* ─── Login Screen ─── */
|
||||||
|
|
@ -1078,11 +1078,11 @@ body {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 0.55rem;
|
font-size: 0.55rem;
|
||||||
padding: 0.1rem 0.5rem;
|
padding: 0.1rem 0.5rem;
|
||||||
border: 1px solid rgba(0, 255, 200, 0.2);
|
border: 1px solid rgba(0, 255, 65, 0.2);
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
background: rgba(0, 255, 200, 0.05);
|
background: rgba(0, 255, 65, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-badge {
|
.order-badge {
|
||||||
|
|
@ -1096,7 +1096,7 @@ body {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
background: rgba(0, 255, 200, 0.05);
|
background: rgba(0, 255, 65, 0.05);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1584,7 +1584,7 @@ body {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
background: rgba(0, 255, 200, 0.03);
|
background: rgba(0, 255, 65, 0.03);
|
||||||
box-shadow: 0 0 15px rgba(0,255,200,0.06);
|
box-shadow: 0 0 15px rgba(0,255,200,0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1728,8 +1728,8 @@ body {
|
||||||
0deg,
|
0deg,
|
||||||
transparent,
|
transparent,
|
||||||
transparent 2px,
|
transparent 2px,
|
||||||
rgba(0, 255, 200, 0.008) 2px,
|
rgba(0, 255, 65, 0.008) 2px,
|
||||||
rgba(0, 255, 200, 0.008) 4px
|
rgba(0, 255, 65, 0.008) 4px
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2008,7 +2008,7 @@ body {
|
||||||
padding: 1.2rem 1rem;
|
padding: 1.2rem 1rem;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-bottom: 1px solid rgba(0,255,200,0.08);
|
border-bottom: 1px solid rgba(0,255,200,0.08);
|
||||||
|
|
@ -2023,7 +2023,7 @@ body {
|
||||||
right: 0.8rem;
|
right: 0.8rem;
|
||||||
background: none;
|
background: none;
|
||||||
border: 1px solid rgba(0,255,200,0.2);
|
border: 1px solid rgba(0,255,200,0.2);
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0.2rem 0.5rem;
|
padding: 0.2rem 0.5rem;
|
||||||
|
|
@ -2119,7 +2119,7 @@ body {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
text-shadow: 0 0 20px rgba(0,255,200,0.3);
|
text-shadow: 0 0 20px rgba(0,255,200,0.3);
|
||||||
letter-spacing: 4px;
|
letter-spacing: 4px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
@ -2156,7 +2156,7 @@ body {
|
||||||
}
|
}
|
||||||
.hud-range {
|
.hud-range {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
accent-color: #00ffc8;
|
accent-color: #00ff41;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
@ -2164,7 +2164,7 @@ body {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 24px;
|
min-width: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
font-family: "JetBrains Mono", monospace;
|
font-family: "JetBrains Mono", monospace;
|
||||||
|
|
@ -2230,7 +2230,7 @@ body {
|
||||||
.toolbar-btn {
|
.toolbar-btn {
|
||||||
background: rgba(0,255,200,0.06);
|
background: rgba(0,255,200,0.06);
|
||||||
border: 1px solid rgba(0,255,200,0.12);
|
border: 1px solid rgba(0,255,200,0.12);
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
padding: 0.3rem 0.6rem;
|
padding: 0.3rem 0.6rem;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
@ -2240,7 +2240,7 @@ body {
|
||||||
}
|
}
|
||||||
.toolbar-btn:hover {
|
.toolbar-btn:hover {
|
||||||
background: rgba(0,255,200,0.15);
|
background: rgba(0,255,200,0.15);
|
||||||
border-color: #00ffc8;
|
border-color: #00ff41;
|
||||||
}
|
}
|
||||||
.toolbar-sep {
|
.toolbar-sep {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
|
|
@ -2340,13 +2340,13 @@ body {
|
||||||
}
|
}
|
||||||
.toggle-slider.active::after {
|
.toggle-slider.active::after {
|
||||||
left: 22px;
|
left: 22px;
|
||||||
background: #00ffc8;
|
background: #00ff41;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── HOMEPAGE ─── */
|
/* ─── HOMEPAGE ─── */
|
||||||
.homepage-section-name {
|
.homepage-section-name {
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
@ -2428,7 +2428,7 @@ body {
|
||||||
.backup-card-title {
|
.backup-card-title {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
margin-bottom: 0.3rem;
|
margin-bottom: 0.3rem;
|
||||||
|
|
@ -2470,7 +2470,7 @@ body {
|
||||||
.threat-feed .threat-empty {
|
.threat-feed .threat-empty {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
css/blog.css
40
css/blog.css
|
|
@ -49,7 +49,7 @@
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
padding: 0.5rem 1.2rem;
|
padding: 0.5rem 1.2rem;
|
||||||
background: rgba(0, 255, 200, 0.03);
|
background: rgba(0, 255, 65, 0.03);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
@ -59,10 +59,10 @@
|
||||||
|
|
||||||
.filter-btn:hover,
|
.filter-btn:hover,
|
||||||
.filter-btn.active {
|
.filter-btn.active {
|
||||||
background: rgba(0, 255, 200, 0.08);
|
background: rgba(0, 255, 65, 0.08);
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
box-shadow: 0 0 15px rgba(0, 255, 200, 0.1);
|
box-shadow: 0 0 15px rgba(0, 255, 65, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Blog Section */
|
/* Blog Section */
|
||||||
|
|
@ -142,8 +142,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-card:hover {
|
.post-card:hover {
|
||||||
border-color: rgba(0, 255, 200, 0.3);
|
border-color: rgba(0, 255, 65, 0.3);
|
||||||
box-shadow: 0 0 30px rgba(0, 255, 200, 0.05), inset 0 0 30px rgba(0, 255, 200, 0.02);
|
box-shadow: 0 0 30px rgba(0, 255, 65, 0.05), inset 0 0 30px rgba(0, 255, 65, 0.02);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,9 +175,9 @@
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.threat-LOW { background: rgba(0, 255, 200, 0.1); color: var(--accent); border: 1px solid rgba(0, 255, 200, 0.2); }
|
.threat-LOW { background: rgba(0, 255, 65, 0.1); color: var(--accent); border: 1px solid rgba(0, 255, 65, 0.2); }
|
||||||
.threat-MED { background: rgba(255, 165, 2, 0.1); color: #ffa502; border: 1px solid rgba(255, 165, 2, 0.2); }
|
.threat-MED { background: rgba(255, 165, 2, 0.1); color: #c9a227; border: 1px solid rgba(255, 165, 2, 0.2); }
|
||||||
.threat-HIGH { background: rgba(255, 71, 87, 0.1); color: #ff4757; border: 1px solid rgba(255, 71, 87, 0.2); }
|
.threat-HIGH { background: rgba(255, 71, 87, 0.1); color: #ff2d2d; border: 1px solid rgba(255, 71, 87, 0.2); }
|
||||||
.threat-CRITICAL { background: rgba(255, 0, 0, 0.15); color: #ff0040; border: 1px solid rgba(255, 0, 0, 0.3); animation: criticalPulse 2s ease infinite; }
|
.threat-CRITICAL { background: rgba(255, 0, 0, 0.15); color: #ff0040; border: 1px solid rgba(255, 0, 0, 0.3); animation: criticalPulse 2s ease infinite; }
|
||||||
|
|
||||||
@keyframes criticalPulse {
|
@keyframes criticalPulse {
|
||||||
|
|
@ -229,7 +229,7 @@
|
||||||
.post-card-stats {
|
.post-card-stats {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-left: 1px solid var(--border);
|
border-left: 1px solid var(--border);
|
||||||
background: rgba(0, 255, 200, 0.015);
|
background: rgba(0, 255, 65, 0.015);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
@ -270,8 +270,8 @@
|
||||||
.stat-pip {
|
.stat-pip {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
background: rgba(0, 255, 200, 0.06);
|
background: rgba(0, 255, 65, 0.06);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.1);
|
border: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
transition: all 0.5s ease;
|
transition: all 0.5s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,15 +282,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-pip.filled.warn {
|
.stat-pip.filled.warn {
|
||||||
background: #ffa502;
|
background: #c9a227;
|
||||||
box-shadow: 0 0 6px rgba(255, 165, 2, 0.4);
|
box-shadow: 0 0 6px rgba(255, 165, 2, 0.4);
|
||||||
border-color: #ffa502;
|
border-color: #c9a227;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-pip.filled.danger {
|
.stat-pip.filled.danger {
|
||||||
background: #ff4757;
|
background: #ff2d2d;
|
||||||
box-shadow: 0 0 6px rgba(255, 71, 87, 0.4);
|
box-shadow: 0 0 6px rgba(255, 71, 87, 0.4);
|
||||||
border-color: #ff4757;
|
border-color: #ff2d2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-bpm {
|
.stat-bpm {
|
||||||
|
|
@ -389,7 +389,7 @@
|
||||||
.post-body ul li::marker { color: var(--accent); }
|
.post-body ul li::marker { color: var(--accent); }
|
||||||
|
|
||||||
.post-body code {
|
.post-body code {
|
||||||
background: rgba(0, 255, 200, 0.05);
|
background: rgba(0, 255, 65, 0.05);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
padding: 0.15rem 0.4rem;
|
padding: 0.15rem 0.4rem;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
|
@ -414,7 +414,7 @@
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
padding: 0.3rem 0.6rem;
|
padding: 0.3rem 0.6rem;
|
||||||
background: rgba(0, 255, 200, 0.03);
|
background: rgba(0, 255, 65, 0.03);
|
||||||
border-left: 1px solid var(--border);
|
border-left: 1px solid var(--border);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
@ -470,7 +470,7 @@
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
padding: 0.6rem 0.8rem;
|
padding: 0.6rem 0.8rem;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: rgba(0, 255, 200, 0.02);
|
background: rgba(0, 255, 65, 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-body {
|
.sidebar-body {
|
||||||
|
|
@ -501,8 +501,8 @@
|
||||||
.sidebar-pip {
|
.sidebar-pip {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: rgba(0, 255, 200, 0.06);
|
background: rgba(0, 255, 65, 0.06);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.1);
|
border: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-pip.filled {
|
.sidebar-pip.filled {
|
||||||
|
|
|
||||||
88
css/post.css
88
css/post.css
|
|
@ -6,7 +6,7 @@
|
||||||
.post-header {
|
.post-header {
|
||||||
padding: 10rem 2rem 3rem;
|
padding: 10rem 2rem 3rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-bottom: 1px solid rgba(0, 255, 200, 0.1);
|
border-bottom: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-header-content {
|
.post-header-content {
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
.post-back {
|
.post-back {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
.post-header .post-date {
|
.post-header .post-date {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: rgba(0, 255, 200, 0.6);
|
color: rgba(0, 255, 65, 0.6);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,8 +69,8 @@
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
padding: 0.25rem 0.6rem;
|
padding: 0.25rem 0.6rem;
|
||||||
border: 1px solid rgba(0, 255, 200, 0.2);
|
border: 1px solid rgba(0, 255, 65, 0.2);
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
@ -84,17 +84,17 @@
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.threat-low {
|
.threat-low {
|
||||||
color: #00ffc8;
|
color: #00ff41;
|
||||||
border: 1px solid rgba(0, 255, 200, 0.3);
|
border: 1px solid rgba(0, 255, 65, 0.3);
|
||||||
text-shadow: 0 0 8px rgba(0, 255, 200, 0.3);
|
text-shadow: 0 0 8px rgba(0, 255, 65, 0.3);
|
||||||
}
|
}
|
||||||
.threat-medium, .threat-med {
|
.threat-medium, .threat-med {
|
||||||
color: #ffa502;
|
color: #c9a227;
|
||||||
border: 1px solid rgba(255, 165, 2, 0.3);
|
border: 1px solid rgba(255, 165, 2, 0.3);
|
||||||
text-shadow: 0 0 8px rgba(255, 165, 2, 0.3);
|
text-shadow: 0 0 8px rgba(255, 165, 2, 0.3);
|
||||||
}
|
}
|
||||||
.threat-high {
|
.threat-high {
|
||||||
color: #ff4757;
|
color: #ff2d2d;
|
||||||
border: 1px solid rgba(255, 71, 87, 0.3);
|
border: 1px solid rgba(255, 71, 87, 0.3);
|
||||||
text-shadow: 0 0 8px rgba(255, 71, 87, 0.3);
|
text-shadow: 0 0 8px rgba(255, 71, 87, 0.3);
|
||||||
}
|
}
|
||||||
|
|
@ -148,9 +148,9 @@
|
||||||
.post-rendered h2 {
|
.post-rendered h2 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
border-bottom: 1px solid rgba(0, 255, 200, 0.1);
|
border-bottom: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
}
|
}
|
||||||
.post-rendered h3 { font-size: 1rem; color: var(--accent, #00ffc8); }
|
.post-rendered h3 { font-size: 1rem; color: var(--accent, #00ff41); }
|
||||||
.post-rendered h4 { font-size: 0.9rem; }
|
.post-rendered h4 { font-size: 0.9rem; }
|
||||||
|
|
||||||
.post-rendered p {
|
.post-rendered p {
|
||||||
|
|
@ -163,18 +163,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-rendered em {
|
.post-rendered em {
|
||||||
color: rgba(0, 255, 200, 0.7);
|
color: rgba(0, 255, 65, 0.7);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-rendered a {
|
.post-rendered a {
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: 1px solid rgba(0, 255, 200, 0.3);
|
border-bottom: 1px solid rgba(0, 255, 65, 0.3);
|
||||||
transition: border-color 0.3s;
|
transition: border-color 0.3s;
|
||||||
}
|
}
|
||||||
.post-rendered a:hover {
|
.post-rendered a:hover {
|
||||||
border-color: var(--accent, #00ffc8);
|
border-color: var(--accent, #00ff41);
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-rendered ul {
|
.post-rendered ul {
|
||||||
|
|
@ -191,22 +191,22 @@
|
||||||
content: '▸';
|
content: '▸';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-rendered hr {
|
.post-rendered hr {
|
||||||
border: none;
|
border: none;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: linear-gradient(90deg, transparent, rgba(0, 255, 200, 0.2), transparent);
|
background: linear-gradient(90deg, transparent, rgba(0, 255, 65, 0.2), transparent);
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Code Blocks ─── */
|
/* ─── Code Blocks ─── */
|
||||||
.post-rendered pre {
|
.post-rendered pre {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.1);
|
border: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
border-left: 3px solid var(--accent, #00ffc8);
|
border-left: 3px solid var(--accent, #00ff41);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
padding: 1.2rem 1.5rem;
|
padding: 1.2rem 1.5rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
|
|
@ -222,15 +222,15 @@
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
padding: 0.2rem 0.6rem;
|
padding: 0.2rem 0.6rem;
|
||||||
background: rgba(0, 255, 200, 0.08);
|
background: rgba(0, 255, 65, 0.08);
|
||||||
color: rgba(0, 255, 200, 0.4);
|
color: rgba(0, 255, 65, 0.4);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-rendered pre code {
|
.post-rendered pre code {
|
||||||
font-family: 'Share Tech Mono', 'JetBrains Mono', monospace;
|
font-family: 'Share Tech Mono', 'JetBrains Mono', monospace;
|
||||||
font-size: 0.82rem;
|
font-size: 0.82rem;
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
background: none;
|
background: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
@ -239,10 +239,10 @@
|
||||||
.post-rendered code.inline-code {
|
.post-rendered code.inline-code {
|
||||||
font-family: 'Share Tech Mono', monospace;
|
font-family: 'Share Tech Mono', monospace;
|
||||||
font-size: 0.82rem;
|
font-size: 0.82rem;
|
||||||
background: rgba(0, 255, 200, 0.06);
|
background: rgba(0, 255, 65, 0.06);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.1);
|
border: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
padding: 0.15rem 0.4rem;
|
padding: 0.15rem 0.4rem;
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Sidebar ─── */
|
/* ─── Sidebar ─── */
|
||||||
|
|
@ -257,8 +257,8 @@
|
||||||
.post-stats-panel,
|
.post-stats-panel,
|
||||||
.post-meta-panel,
|
.post-meta-panel,
|
||||||
.post-nav-panel {
|
.post-nav-panel {
|
||||||
background: rgba(0, 255, 200, 0.02);
|
background: rgba(0, 255, 65, 0.02);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.08);
|
border: 1px solid rgba(0, 255, 65, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Stat Rows (sidebar) ─── */
|
/* ─── Stat Rows (sidebar) ─── */
|
||||||
|
|
@ -306,24 +306,24 @@
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
}
|
}
|
||||||
.pip.filled {
|
.pip.filled {
|
||||||
background: var(--accent, #00ffc8);
|
background: var(--accent, #00ff41);
|
||||||
border-color: var(--accent, #00ffc8);
|
border-color: var(--accent, #00ff41);
|
||||||
box-shadow: 0 0 6px rgba(0, 255, 200, 0.3);
|
box-shadow: 0 0 6px rgba(0, 255, 65, 0.3);
|
||||||
}
|
}
|
||||||
.pip.filled.warn {
|
.pip.filled.warn {
|
||||||
background: #ffa502;
|
background: #c9a227;
|
||||||
border-color: #ffa502;
|
border-color: #c9a227;
|
||||||
box-shadow: 0 0 6px rgba(255, 165, 2, 0.3);
|
box-shadow: 0 0 6px rgba(255, 165, 2, 0.3);
|
||||||
}
|
}
|
||||||
.pip.filled.danger {
|
.pip.filled.danger {
|
||||||
background: #ff4757;
|
background: #ff2d2d;
|
||||||
border-color: #ff4757;
|
border-color: #ff2d2d;
|
||||||
box-shadow: 0 0 6px rgba(255, 71, 87, 0.3);
|
box-shadow: 0 0 6px rgba(255, 71, 87, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-divider {
|
.stat-divider {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: rgba(0, 255, 200, 0.08);
|
background: rgba(0, 255, 65, 0.08);
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,7 +341,7 @@
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #ff4757;
|
color: #ff2d2d;
|
||||||
text-shadow: 0 0 15px rgba(255, 71, 87, 0.4);
|
text-shadow: 0 0 15px rgba(255, 71, 87, 0.4);
|
||||||
transition: transform 0.1s;
|
transition: transform 0.1s;
|
||||||
}
|
}
|
||||||
|
|
@ -376,7 +376,7 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.4rem 0;
|
padding: 0.4rem 0;
|
||||||
border-bottom: 1px solid rgba(0, 255, 200, 0.04);
|
border-bottom: 1px solid rgba(0, 255, 65, 0.04);
|
||||||
}
|
}
|
||||||
.meta-row:last-child {
|
.meta-row:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
|
|
@ -397,14 +397,14 @@
|
||||||
}
|
}
|
||||||
.meta-val.mono {
|
.meta-val.mono {
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
color: rgba(0, 255, 200, 0.5);
|
color: rgba(0, 255, 65, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Navigation Panel ─── */
|
/* ─── Navigation Panel ─── */
|
||||||
.post-nav-link {
|
.post-nav-link {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.8rem 0;
|
padding: 0.8rem 0;
|
||||||
border-bottom: 1px solid rgba(0, 255, 200, 0.06);
|
border-bottom: 1px solid rgba(0, 255, 65, 0.06);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
}
|
}
|
||||||
|
|
@ -412,14 +412,14 @@
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.post-nav-link:hover {
|
.post-nav-link:hover {
|
||||||
background: rgba(0, 255, 200, 0.03);
|
background: rgba(0, 255, 65, 0.03);
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-dir {
|
.nav-dir {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 0.2rem;
|
margin-bottom: 0.2rem;
|
||||||
|
|
@ -445,7 +445,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
padding: 4rem 0;
|
padding: 4rem 0;
|
||||||
color: rgba(0, 255, 200, 0.5);
|
color: rgba(0, 255, 65, 0.5);
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
|
|
@ -456,7 +456,7 @@
|
||||||
padding: 4rem 2rem;
|
padding: 4rem 2rem;
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
color: #ff4757;
|
color: #ff2d2d;
|
||||||
text-shadow: 0 0 20px rgba(255, 71, 87, 0.3);
|
text-shadow: 0 0 20px rgba(255, 71, 87, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
170
css/style.css
170
css/style.css
|
|
@ -1,27 +1,27 @@
|
||||||
/* ===================================================
|
/* ===================================================
|
||||||
JAESWIFT.XYZ — Sci-Fi Dashboard Theme
|
JAESWIFT.XYZ — Sci-Fi Dashboard Theme
|
||||||
Palette: #0a0a0f (bg), #00ffc8 (accent), #0d1117 (panels)
|
Palette: #0a0a0a (bg), #00ff41 (accent-green), #c9a227 (accent-amber), #161616 (panels) — BLACK OPS THEME
|
||||||
=================================================== */
|
=================================================== */
|
||||||
|
|
||||||
/* --- Reset & Base --- */
|
/* --- Reset & Base --- */
|
||||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--bg-primary: #060608;
|
--bg-primary: #0a0a0a;
|
||||||
--bg-secondary: #0a0e14;
|
--bg-secondary: #111111;
|
||||||
--bg-panel: #0c1018;
|
--bg-panel: #161616;
|
||||||
--bg-panel-hover: #101820;
|
--bg-panel-hover: #1e1e1e;
|
||||||
--accent: #00ffc8;
|
--accent: #00ff41;
|
||||||
--accent-dim: #00ffc840;
|
--accent-dim: #00ff4140;
|
||||||
--accent-glow: #00ffc880;
|
--accent-glow: #00ff4180;
|
||||||
--accent-subtle: #00ffc815;
|
--accent-subtle: #00ff4115;
|
||||||
--text-primary: #c8d6e5;
|
--text-primary: #c0c0c0;
|
||||||
--text-secondary: #5a6a7a;
|
--text-secondary: #707070;
|
||||||
--text-muted: #2a3a4a;
|
--text-muted: #3a3a3a;
|
||||||
--border: #1a2a3a;
|
--border: #2a2a2a;
|
||||||
--border-accent: #00ffc830;
|
--border-accent: #00ff4130;
|
||||||
--danger: #ff3a5c;
|
--danger: #ff2d2d;
|
||||||
--warning: #ffaa00;
|
--warning: #c9a227;
|
||||||
--font-mono: 'JetBrains Mono', 'Share Tech Mono', 'Courier New', monospace;
|
--font-mono: 'JetBrains Mono', 'Share Tech Mono', 'Courier New', monospace;
|
||||||
--font-display: 'Orbitron', sans-serif;
|
--font-display: 'Orbitron', sans-serif;
|
||||||
--nav-height: 60px;
|
--nav-height: 60px;
|
||||||
|
|
@ -63,8 +63,8 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
0deg,
|
0deg,
|
||||||
transparent,
|
transparent,
|
||||||
transparent 2px,
|
transparent 2px,
|
||||||
rgba(0, 255, 200, 0.008) 2px,
|
rgba(0, 255, 65, 0.008) 2px,
|
||||||
rgba(0, 255, 200, 0.008) 4px
|
rgba(0, 255, 65, 0.008) 4px
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
top: 0; left: 0;
|
top: 0; left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: var(--nav-height);
|
height: var(--nav-height);
|
||||||
background: rgba(6, 6, 8, 0.92);
|
background: rgba(10, 10, 10, 0.92);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
|
|
@ -105,9 +105,9 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-main.scrolled {
|
.nav-main.scrolled {
|
||||||
background: rgba(6, 6, 8, 0.98);
|
background: rgba(10, 10, 10, 0.98);
|
||||||
border-bottom-color: var(--accent-dim);
|
border-bottom-color: var(--accent-dim);
|
||||||
box-shadow: 0 4px 30px rgba(0, 255, 200, 0.05);
|
box-shadow: 0 4px 30px rgba(0, 255, 65, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
|
|
@ -200,7 +200,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
top: 100%;
|
top: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
background: rgba(10, 14, 20, 0.98);
|
background: rgba(14, 14, 14, 0.98);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-top: 2px solid var(--accent);
|
border-top: 2px solid var(--accent);
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
@ -244,6 +244,27 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.dropdown li a.active {
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--accent-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown Arrow */
|
||||||
|
.dropdown-arrow {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
margin-left: 0.35rem;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item:hover > .nav-link .dropdown-arrow,
|
||||||
|
.nav-item.dropdown-open > .nav-link .dropdown-arrow {
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown li a:hover::before { opacity: 1; }
|
.dropdown li a:hover::before { opacity: 1; }
|
||||||
|
|
||||||
/* Nav Status */
|
/* Nav Status */
|
||||||
|
|
@ -321,7 +342,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
============================ */
|
============================ */
|
||||||
.panel {
|
.panel {
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
background: rgba(10, 14, 20, 0.6);
|
background: rgba(16, 16, 16, 0.6);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +373,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.75rem 1rem;
|
padding: 0.75rem 1rem;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: rgba(0, 255, 200, 0.02);
|
background: rgba(0, 255, 65, 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-title {
|
.panel-title {
|
||||||
|
|
@ -523,7 +544,6 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
|
|
||||||
@keyframes glitch-2 {
|
@keyframes glitch-2 {
|
||||||
0%, 92%, 100% { opacity: 0; transform: none; }
|
0%, 92%, 100% { opacity: 0; transform: none; }
|
||||||
93% { opacity: 0.6; transform: translate(2px, 2px); clip-path: inset(10% 0 70% 0); }
|
|
||||||
95% { opacity: 0.6; transform: translate(-1px, -2px); clip-path: inset(40% 0 20% 0); }
|
95% { opacity: 0.6; transform: translate(-1px, -2px); clip-path: inset(40% 0 20% 0); }
|
||||||
97% { opacity: 0; }
|
97% { opacity: 0; }
|
||||||
}
|
}
|
||||||
|
|
@ -548,19 +568,6 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
/* ============================
|
/* ============================
|
||||||
SERVER METRICS PANEL
|
SERVER METRICS PANEL
|
||||||
============================ */
|
============================ */
|
||||||
.hud-metrics {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 80px 1fr 45px;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric-label {
|
.metric-label {
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 0.55rem;
|
font-size: 0.55rem;
|
||||||
|
|
@ -570,15 +577,15 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
|
|
||||||
.metric-bar {
|
.metric-bar {
|
||||||
height: 6px;
|
height: 6px;
|
||||||
background: rgba(0, 255, 200, 0.08);
|
background: rgba(0, 255, 65, 0.08);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.15);
|
border: 1px solid rgba(0, 255, 65, 0.15);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metric-fill {
|
.metric-fill {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: linear-gradient(90deg, var(--accent), rgba(0, 255, 200, 0.4));
|
background: linear-gradient(90deg, var(--accent), rgba(0, 255, 65, 0.4));
|
||||||
box-shadow: 0 0 8px var(--accent-glow);
|
box-shadow: 0 0 8px var(--accent-glow);
|
||||||
transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -618,7 +625,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
|
|
||||||
.hud-mini-panel {
|
.hud-mini-panel {
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
background: rgba(10, 14, 20, 0.6);
|
background: rgba(16, 16, 16, 0.6);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -687,8 +694,8 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
|
|
||||||
.container-bar {
|
.container-bar {
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: rgba(0, 255, 200, 0.08);
|
background: rgba(0, 255, 65, 0.08);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.1);
|
border: 1px solid rgba(0, 255, 65, 0.1);
|
||||||
margin-bottom: 0.4rem;
|
margin-bottom: 0.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -764,7 +771,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: rgba(10, 14, 20, 0.95);
|
background: rgba(16, 16, 16, 0.95);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
@ -839,8 +846,8 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
.hud-scan-bar {
|
.hud-scan-bar {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: rgba(0, 255, 200, 0.08);
|
background: rgba(0, 255, 65, 0.08);
|
||||||
border: 1px solid rgba(0, 255, 200, 0.15);
|
border: 1px solid rgba(0, 255, 65, 0.15);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -959,7 +966,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
background: rgba(0, 255, 200, 0.02);
|
background: rgba(0, 255, 65, 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-title {
|
.panel-title {
|
||||||
|
|
@ -1077,7 +1084,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
.blog-card:hover {
|
.blog-card:hover {
|
||||||
border-color: var(--accent-dim);
|
border-color: var(--accent-dim);
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
box-shadow: 0 8px 30px rgba(0, 255, 200, 0.08);
|
box-shadow: 0 8px 30px rgba(0, 255, 65, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-card:hover::after { transform: scaleX(1); }
|
.blog-card:hover::after { transform: scaleX(1); }
|
||||||
|
|
@ -1170,7 +1177,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
.dev-card:hover {
|
.dev-card:hover {
|
||||||
border-color: var(--accent-dim);
|
border-color: var(--accent-dim);
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
box-shadow: 0 8px 30px rgba(0, 255, 200, 0.06);
|
box-shadow: 0 8px 30px rgba(0, 255, 65, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dev-card:hover::before { height: 100%; }
|
.dev-card:hover::before { height: 100%; }
|
||||||
|
|
@ -1339,7 +1346,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
|
|
||||||
.form-input:focus {
|
.form-input:focus {
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
box-shadow: 0 0 0 1px var(--accent-dim), 0 0 20px rgba(0, 255, 200, 0.05);
|
box-shadow: 0 0 0 1px var(--accent-dim), 0 0 20px rgba(0, 255, 65, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-input::placeholder { color: var(--text-muted); }
|
.form-input::placeholder { color: var(--text-muted); }
|
||||||
|
|
@ -1429,7 +1436,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
.footer {
|
.footer {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
background: rgba(6, 6, 8, 0.8);
|
background: rgba(10, 10, 10, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-container {
|
.footer-container {
|
||||||
|
|
@ -1523,7 +1530,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: rgba(6, 6, 8, 0.98);
|
background: rgba(10, 10, 10, 0.98);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
|
|
@ -1531,9 +1538,11 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
max-height: calc(100vh - var(--nav-height));
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-menu.active {
|
.nav-menu.open {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
|
|
@ -1551,16 +1560,35 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
position: static;
|
position: static;
|
||||||
border: none;
|
border: none;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(20, 20, 20, 0.95);
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
transform: none;
|
transform: none;
|
||||||
transition: max-height 0.3s ease;
|
transition: max-height 0.4s ease;
|
||||||
|
box-shadow: none;
|
||||||
|
backdrop-filter: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item.active .dropdown { max-height: 300px; }
|
.nav-item.dropdown-open > .dropdown {
|
||||||
|
max-height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown li a {
|
||||||
|
padding-left: 3rem;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown li a::before {
|
||||||
|
content: '── ';
|
||||||
|
opacity: 0.3;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown li a:hover::before {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* HUD grid stacks on mobile */
|
/* HUD grid stacks on mobile */
|
||||||
.hero-hud-grid {
|
.hero-hud-grid {
|
||||||
|
|
@ -1616,15 +1644,15 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
padding: 3rem;
|
padding: 3rem;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: rgba(0, 255, 200, 0.4);
|
color: rgba(0, 255, 65, 0.4);
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
border: 2px solid rgba(0, 255, 200, 0.1);
|
border: 2px solid rgba(0, 255, 65, 0.1);
|
||||||
border-top-color: #00ffc8;
|
border-top-color: #00ff41;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
animation: spin 0.8s linear infinite;
|
animation: spin 0.8s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
@ -1634,8 +1662,8 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-view-all-link:hover {
|
.blog-view-all-link:hover {
|
||||||
background: rgba(0, 255, 200, 0.08) !important;
|
background: rgba(0, 255, 65, 0.08) !important;
|
||||||
box-shadow: 0 0 15px rgba(0, 255, 200, 0.15);
|
box-shadow: 0 0 15px rgba(0, 255, 65, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Weather Display ─── */
|
/* ─── Weather Display ─── */
|
||||||
|
|
@ -1654,12 +1682,12 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-shadow: 0 0 15px rgba(0, 255, 200, 0.3);
|
text-shadow: 0 0 15px rgba(0, 255, 65, 0.3);
|
||||||
}
|
}
|
||||||
.weather-cond {
|
.weather-cond {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
color: rgba(0, 255, 200, 0.6);
|
color: rgba(0, 255, 65, 0.6);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
.weather-details {
|
.weather-details {
|
||||||
|
|
@ -1670,10 +1698,10 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
.weather-detail {
|
.weather-detail {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
color: rgba(200, 214, 229, 0.4);
|
color: rgba(192, 192, 192, 0.4);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
padding: 0.2rem 0.5rem;
|
padding: 0.2rem 0.5rem;
|
||||||
border: 1px solid rgba(0, 255, 200, 0.06);
|
border: 1px solid rgba(0, 255, 65, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Now Playing Display ─── */
|
/* ─── Now Playing Display ─── */
|
||||||
|
|
@ -1694,13 +1722,13 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
.np-artist {
|
.np-artist {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
.np-album {
|
.np-album {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
color: rgba(200, 214, 229, 0.35);
|
color: rgba(192, 192, 192, 0.35);
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
margin-bottom: 0.3rem;
|
margin-bottom: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|
@ -1713,10 +1741,10 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
}
|
}
|
||||||
.np-bar {
|
.np-bar {
|
||||||
width: 4px;
|
width: 4px;
|
||||||
background: var(--accent, #00ffc8);
|
background: var(--accent, #00ff41);
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
animation: npBounce 0.8s ease-in-out infinite alternate;
|
animation: npBounce 0.8s ease-in-out infinite alternate;
|
||||||
box-shadow: 0 0 4px rgba(0, 255, 200, 0.3);
|
box-shadow: 0 0 4px rgba(0, 255, 65, 0.3);
|
||||||
}
|
}
|
||||||
.np-bar:nth-child(1) { height: 40%; animation-delay: 0s; }
|
.np-bar:nth-child(1) { height: 40%; animation-delay: 0s; }
|
||||||
.np-bar:nth-child(2) { height: 70%; animation-delay: 0.1s; }
|
.np-bar:nth-child(2) { height: 70%; animation-delay: 0.1s; }
|
||||||
|
|
@ -1732,7 +1760,7 @@ a:hover { color: #fff; text-shadow: 0 0 10px var(--accent-glow); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#npStatus {
|
#npStatus {
|
||||||
color: var(--accent, #00ffc8);
|
color: var(--accent, #00ff41);
|
||||||
animation: statusPulse 2s ease-in-out infinite;
|
animation: statusPulse 2s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
@keyframes statusPulse {
|
@keyframes statusPulse {
|
||||||
|
|
|
||||||
18
js/admin.js
18
js/admin.js
|
|
@ -12,8 +12,8 @@ const AdminApp = {
|
||||||
navData: [],
|
navData: [],
|
||||||
linksData: [],
|
linksData: [],
|
||||||
themeDefaults: {
|
themeDefaults: {
|
||||||
accent: '#00ffc8',
|
accent: '#00ff41',
|
||||||
bg: '#0a0e17',
|
bg: '#111111',
|
||||||
text: '#e0e0e0',
|
text: '#e0e0e0',
|
||||||
scanlines: true,
|
scanlines: true,
|
||||||
particles: true,
|
particles: true,
|
||||||
|
|
@ -283,7 +283,7 @@ const AdminApp = {
|
||||||
|
|
||||||
if (type === 'success') {
|
if (type === 'success') {
|
||||||
div.style.background = 'rgba(0,255,200,0.15)';
|
div.style.background = 'rgba(0,255,200,0.15)';
|
||||||
div.style.borderColor = '#00ffc8';
|
div.style.borderColor = '#00ff41';
|
||||||
} else if (type === 'error') {
|
} else if (type === 'error') {
|
||||||
div.style.background = 'rgba(255,50,50,0.15)';
|
div.style.background = 'rgba(255,50,50,0.15)';
|
||||||
div.style.borderColor = '#ff3232';
|
div.style.borderColor = '#ff3232';
|
||||||
|
|
@ -358,7 +358,7 @@ const AdminApp = {
|
||||||
if (grid) {
|
if (grid) {
|
||||||
grid.innerHTML = arr.map(svc => {
|
grid.innerHTML = arr.map(svc => {
|
||||||
const isUp = svc.status === 'up' || svc.status === 'online' || svc.status === true;
|
const isUp = svc.status === 'up' || svc.status === 'online' || svc.status === true;
|
||||||
const dotColor = isUp ? '#00ffc8' : '#ff3232';
|
const dotColor = isUp ? '#00ff41' : '#ff3232';
|
||||||
const statusText = isUp ? 'ONLINE' : 'OFFLINE';
|
const statusText = isUp ? 'ONLINE' : 'OFFLINE';
|
||||||
return `<div class="service-card">
|
return `<div class="service-card">
|
||||||
<span class="service-dot" style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${dotColor};box-shadow:0 0 8px ${dotColor};margin-right:8px;"></span>
|
<span class="service-dot" style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${dotColor};box-shadow:0 0 8px ${dotColor};margin-right:8px;"></span>
|
||||||
|
|
@ -385,7 +385,7 @@ const AdminApp = {
|
||||||
} else {
|
} else {
|
||||||
container.innerHTML = arr.map(t => {
|
container.innerHTML = arr.map(t => {
|
||||||
const severity = (t.severity || t.level || 'low').toLowerCase();
|
const severity = (t.severity || t.level || 'low').toLowerCase();
|
||||||
const sevColor = severity === 'critical' ? '#ff0040' : severity === 'high' ? '#ff6600' : severity === 'medium' ? '#ffaa00' : '#00ffc8';
|
const sevColor = severity === 'critical' ? '#ff0040' : severity === 'high' ? '#ff6600' : severity === 'medium' ? '#c9a227' : '#00ff41';
|
||||||
return `<div class="threat-item" style="border-left:3px solid ${sevColor};padding:8px 12px;margin-bottom:6px;background:rgba(255,255,255,0.03);">
|
return `<div class="threat-item" style="border-left:3px solid ${sevColor};padding:8px 12px;margin-bottom:6px;background:rgba(255,255,255,0.03);">
|
||||||
<div style="display:flex;justify-content:space-between;align-items:center;">
|
<div style="display:flex;justify-content:space-between;align-items:center;">
|
||||||
<strong style="color:${sevColor};">${this.escapeHtml(t.cve || t.id || t.name || 'Unknown')}</strong>
|
<strong style="color:${sevColor};">${this.escapeHtml(t.cve || t.id || t.name || 'Unknown')}</strong>
|
||||||
|
|
@ -743,7 +743,7 @@ const AdminApp = {
|
||||||
html = html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" style="max-width:100%;">');
|
html = html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" style="max-width:100%;">');
|
||||||
|
|
||||||
// Links
|
// Links
|
||||||
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" style="color:#00ffc8;">$1</a>');
|
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" style="color:#00ff41;">$1</a>');
|
||||||
|
|
||||||
// Unordered lists
|
// Unordered lists
|
||||||
html = html.replace(/^- (.+)$/gm, '<li>$1</li>');
|
html = html.replace(/^- (.+)$/gm, '<li>$1</li>');
|
||||||
|
|
@ -805,7 +805,7 @@ const AdminApp = {
|
||||||
<div style="font-weight:600;color:#e0e0e0;">${this.escapeHtml(t.artist || 'Unknown')} — ${this.escapeHtml(t.title || 'Untitled')}</div>
|
<div style="font-weight:600;color:#e0e0e0;">${this.escapeHtml(t.artist || 'Unknown')} — ${this.escapeHtml(t.title || 'Untitled')}</div>
|
||||||
<div style="font-size:12px;color:#555;">${this.escapeHtml(t.album || '')} ${t.genre ? '· ' + this.escapeHtml(t.genre) : ''}</div>
|
<div style="font-size:12px;color:#555;">${this.escapeHtml(t.album || '')} ${t.genre ? '· ' + this.escapeHtml(t.genre) : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
${t.url ? `<a href="${this.escapeHtml(t.url)}" target="_blank" style="color:#00ffc8;margin-right:12px;font-size:12px;">▶</a>` : ''}
|
${t.url ? `<a href="${this.escapeHtml(t.url)}" target="_blank" style="color:#00ff41;margin-right:12px;font-size:12px;">▶</a>` : ''}
|
||||||
<button class="btn-sm btn-delete" onclick="AdminApp.deleteTrack(${i})" title="Delete">✗</button>
|
<button class="btn-sm btn-delete" onclick="AdminApp.deleteTrack(${i})" title="Delete">✗</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
@ -1107,7 +1107,7 @@ const AdminApp = {
|
||||||
|
|
||||||
container.innerHTML = this.navData.map((item, i) => {
|
container.innerHTML = this.navData.map((item, i) => {
|
||||||
return `<div class="nav-list-item" style="display:flex;align-items:center;padding:10px;border-bottom:1px solid rgba(255,255,255,0.05);">
|
return `<div class="nav-list-item" style="display:flex;align-items:center;padding:10px;border-bottom:1px solid rgba(255,255,255,0.05);">
|
||||||
<span style="color:#00ffc8;font-size:12px;margin-right:12px;min-width:30px;">#${item.order || i}</span>
|
<span style="color:#00ff41;font-size:12px;margin-right:12px;min-width:30px;">#${item.order || i}</span>
|
||||||
<div style="flex:1;">
|
<div style="flex:1;">
|
||||||
<div style="font-weight:600;color:#e0e0e0;">${this.escapeHtml(item.label || 'Unnamed')}</div>
|
<div style="font-weight:600;color:#e0e0e0;">${this.escapeHtml(item.label || 'Unnamed')}</div>
|
||||||
<div style="font-size:12px;color:#555;">${this.escapeHtml(item.url || '')}</div>
|
<div style="font-size:12px;color:#555;">${this.escapeHtml(item.url || '')}</div>
|
||||||
|
|
@ -1191,7 +1191,7 @@ const AdminApp = {
|
||||||
<span style="font-size:18px;margin-right:12px;">${this.escapeHtml(link.icon || '🔗')}</span>
|
<span style="font-size:18px;margin-right:12px;">${this.escapeHtml(link.icon || '🔗')}</span>
|
||||||
<div style="flex:1;">
|
<div style="flex:1;">
|
||||||
<div style="font-weight:600;color:#e0e0e0;">${this.escapeHtml(link.name || 'Unnamed')}</div>
|
<div style="font-weight:600;color:#e0e0e0;">${this.escapeHtml(link.name || 'Unnamed')}</div>
|
||||||
<div style="font-size:12px;color:#555;">${this.escapeHtml(link.url || '')} ${link.category ? '<span style="color:#00ffc8;">· ' + this.escapeHtml(link.category) + '</span>' : ''}</div>
|
<div style="font-size:12px;color:#555;">${this.escapeHtml(link.url || '')} ${link.category ? '<span style="color:#00ff41;">· ' + this.escapeHtml(link.category) + '</span>' : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-sm btn-delete" onclick="AdminApp.deleteLink(${i})" title="Delete">✗</button>
|
<button class="btn-sm btn-delete" onclick="AdminApp.deleteLink(${i})" title="Delete">✗</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
|
||||||
38
js/main.js
38
js/main.js
|
|
@ -248,7 +248,7 @@
|
||||||
function drawParticle(p) {
|
function drawParticle(p) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
|
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
|
||||||
ctx.fillStyle = `rgba(0, 255, 200, ${p.opacity})`;
|
ctx.fillStyle = `rgba(0, 255, 65, ${p.opacity})`;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,7 +264,7 @@
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(particles[i].x, particles[i].y);
|
ctx.moveTo(particles[i].x, particles[i].y);
|
||||||
ctx.lineTo(particles[j].x, particles[j].y);
|
ctx.lineTo(particles[j].x, particles[j].y);
|
||||||
ctx.strokeStyle = `rgba(0, 255, 200, ${opacity})`;
|
ctx.strokeStyle = `rgba(0, 255, 65, ${opacity})`;
|
||||||
ctx.lineWidth = 0.5;
|
ctx.lineWidth = 0.5;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +281,7 @@
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(p.x, p.y);
|
ctx.moveTo(p.x, p.y);
|
||||||
ctx.lineTo(mouseX, mouseY);
|
ctx.lineTo(mouseX, mouseY);
|
||||||
ctx.strokeStyle = `rgba(0, 255, 200, ${opacity})`;
|
ctx.strokeStyle = `rgba(0, 255, 65, ${opacity})`;
|
||||||
ctx.lineWidth = 0.8;
|
ctx.lineWidth = 0.8;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
@ -501,13 +501,13 @@
|
||||||
form.reset();
|
form.reset();
|
||||||
} else {
|
} else {
|
||||||
submitText.textContent = '✗ FAILED';
|
submitText.textContent = '✗ FAILED';
|
||||||
btn.style.borderColor = '#ff006e';
|
btn.style.borderColor = '#ff2d2d';
|
||||||
btn.style.color = '#ff006e';
|
btn.style.color = '#ff2d2d';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
submitText.textContent = '✗ ERROR';
|
submitText.textContent = '✗ ERROR';
|
||||||
btn.style.borderColor = '#ff006e';
|
btn.style.borderColor = '#ff2d2d';
|
||||||
btn.style.color = '#ff006e';
|
btn.style.color = '#ff2d2d';
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -562,7 +562,7 @@
|
||||||
const y = e.clientY - rect.top;
|
const y = e.clientY - rect.top;
|
||||||
card.style.setProperty('--mouse-x', `${x}px`);
|
card.style.setProperty('--mouse-x', `${x}px`);
|
||||||
card.style.setProperty('--mouse-y', `${y}px`);
|
card.style.setProperty('--mouse-y', `${y}px`);
|
||||||
card.style.background = `radial-gradient(circle 200px at ${x}px ${y}px, rgba(0, 255, 200, 0.04), var(--bg-panel))`;
|
card.style.background = `radial-gradient(circle 200px at ${x}px ${y}px, rgba(0, 255, 65, 0.04), var(--bg-panel))`;
|
||||||
});
|
});
|
||||||
|
|
||||||
card.addEventListener('mouseleave', () => {
|
card.addEventListener('mouseleave', () => {
|
||||||
|
|
@ -670,7 +670,7 @@
|
||||||
if (dlData.length > maxPoints) dlData.shift();
|
if (dlData.length > maxPoints) dlData.shift();
|
||||||
if (ulData.length > maxPoints) ulData.shift();
|
if (ulData.length > maxPoints) ulData.shift();
|
||||||
|
|
||||||
drawLine(dlData, '#00ffc8', 0.9);
|
drawLine(dlData, '#00ff41', 0.9);
|
||||||
drawLine(ulData, '#00a8ff', 0.6);
|
drawLine(ulData, '#00a8ff', 0.6);
|
||||||
updateStats();
|
updateStats();
|
||||||
|
|
||||||
|
|
@ -700,13 +700,13 @@
|
||||||
|
|
||||||
// Colour shift for high values
|
// Colour shift for high values
|
||||||
if (val > 85) {
|
if (val > 85) {
|
||||||
barEl.style.background = 'linear-gradient(90deg, #ff4757, rgba(255,71,87,0.4))';
|
barEl.style.background = 'linear-gradient(90deg, #ff2d2d, rgba(255,71,87,0.4))';
|
||||||
barEl.style.boxShadow = '0 0 8px rgba(255,71,87,0.4)';
|
barEl.style.boxShadow = '0 0 8px rgba(255,71,87,0.4)';
|
||||||
valEl.style.color = '#ff4757';
|
valEl.style.color = '#ff2d2d';
|
||||||
} else if (val > 70) {
|
} else if (val > 70) {
|
||||||
barEl.style.background = 'linear-gradient(90deg, #ffa502, rgba(255,165,2,0.4))';
|
barEl.style.background = 'linear-gradient(90deg, #c9a227, rgba(255,165,2,0.4))';
|
||||||
barEl.style.boxShadow = '0 0 8px rgba(255,165,2,0.3)';
|
barEl.style.boxShadow = '0 0 8px rgba(255,165,2,0.3)';
|
||||||
valEl.style.color = '#ffa502';
|
valEl.style.color = '#c9a227';
|
||||||
} else {
|
} else {
|
||||||
barEl.style.background = '';
|
barEl.style.background = '';
|
||||||
barEl.style.boxShadow = '';
|
barEl.style.boxShadow = '';
|
||||||
|
|
@ -837,13 +837,13 @@
|
||||||
barEl.style.width = m.value + '%';
|
barEl.style.width = m.value + '%';
|
||||||
valEl.textContent = Math.round(m.value) + '%';
|
valEl.textContent = Math.round(m.value) + '%';
|
||||||
if (m.value > 85) {
|
if (m.value > 85) {
|
||||||
barEl.style.background = 'linear-gradient(90deg, #ff4757, rgba(255,71,87,0.4))';
|
barEl.style.background = 'linear-gradient(90deg, #ff2d2d, rgba(255,71,87,0.4))';
|
||||||
barEl.style.boxShadow = '0 0 8px rgba(255,71,87,0.4)';
|
barEl.style.boxShadow = '0 0 8px rgba(255,71,87,0.4)';
|
||||||
valEl.style.color = '#ff4757';
|
valEl.style.color = '#ff2d2d';
|
||||||
} else if (m.value > 70) {
|
} else if (m.value > 70) {
|
||||||
barEl.style.background = 'linear-gradient(90deg, #ffa502, rgba(255,165,2,0.4))';
|
barEl.style.background = 'linear-gradient(90deg, #c9a227, rgba(255,165,2,0.4))';
|
||||||
barEl.style.boxShadow = '0 0 8px rgba(255,165,2,0.3)';
|
barEl.style.boxShadow = '0 0 8px rgba(255,165,2,0.3)';
|
||||||
valEl.style.color = '#ffa502';
|
valEl.style.color = '#c9a227';
|
||||||
} else {
|
} else {
|
||||||
barEl.style.background = '';
|
barEl.style.background = '';
|
||||||
barEl.style.boxShadow = '';
|
barEl.style.boxShadow = '';
|
||||||
|
|
@ -960,8 +960,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('%c[JAESWIFT] %cSystems Online',
|
console.log('%c[JAESWIFT] %cSystems Online',
|
||||||
'color: #00ffc8; font-weight: bold; font-size: 14px;',
|
'color: #00ff41; font-weight: bold; font-size: 14px;',
|
||||||
'color: #c8d6e5; font-size: 12px;');
|
'color: #c0c0c0; font-size: 12px;');
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
96
js/nav.js
96
js/nav.js
|
|
@ -1,5 +1,5 @@
|
||||||
/* ─── Dynamic Navigation ─── */
|
/* ─── Dynamic Navigation with Dropdown Submenus ─── */
|
||||||
/* Fetches nav items from /api/navigation and renders them */
|
/* Fetches nav items from /api/navigation and renders dropdowns */
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
@ -17,39 +17,117 @@
|
||||||
|
|
||||||
// Determine current page for active state
|
// Determine current page for active state
|
||||||
const path = window.location.pathname;
|
const path = window.location.pathname;
|
||||||
|
const search = window.location.search;
|
||||||
|
const fullPath = path + search;
|
||||||
|
|
||||||
// Build nav HTML
|
// Build nav HTML
|
||||||
let html = '';
|
let html = '';
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
const url = item.url || '/';
|
const url = item.url || '/';
|
||||||
const label = (item.label || '').toUpperCase();
|
const label = (item.label || '').toUpperCase();
|
||||||
|
const children = item.children || [];
|
||||||
|
const hasChildren = children.length > 0;
|
||||||
|
|
||||||
// Determine if this link is active
|
// Determine if this link is active
|
||||||
let isActive = false;
|
let isActive = false;
|
||||||
if (url === '/' && (path === '/' || path === '/index.html')) {
|
if (url === '/' && (path === '/' || path === '/index.html')) {
|
||||||
isActive = true;
|
isActive = true;
|
||||||
} else if (url !== '/' && path.startsWith(url)) {
|
} else if (url !== '/' && path.startsWith(url.split('?')[0])) {
|
||||||
isActive = true;
|
isActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeClass = isActive ? ' active' : '';
|
const activeClass = isActive ? ' active' : '';
|
||||||
|
const hasDropdownClass = hasChildren ? ' has-dropdown' : '';
|
||||||
|
|
||||||
// Check if it's an anchor link (homepage sections)
|
// Check if it's an anchor link (homepage sections)
|
||||||
const isAnchor = url.startsWith('#') || url.startsWith('/#');
|
const isAnchor = url.startsWith('#') || url.startsWith('/#');
|
||||||
const href = isAnchor && path !== '/' ? '/' + url.replace(/^\//, '') : url;
|
const href = isAnchor && path !== '/' ? '/' + url.replace(/^\//, '') : url;
|
||||||
|
|
||||||
html += `<li class="nav-item">`;
|
html += `<li class="nav-item${hasDropdownClass}">`;
|
||||||
html += `<a href="${href}" class="nav-link${activeClass}">${label}</a>`;
|
html += `<a href="${href}" class="nav-link${activeClass}">${label}`;
|
||||||
|
if (hasChildren) {
|
||||||
|
html += `<span class="dropdown-arrow">▾</span>`;
|
||||||
|
}
|
||||||
|
html += `</a>`;
|
||||||
|
|
||||||
|
// Render dropdown submenu
|
||||||
|
if (hasChildren) {
|
||||||
|
html += `<ul class="dropdown">`;
|
||||||
|
children.forEach(child => {
|
||||||
|
const childUrl = child.url || '#';
|
||||||
|
const childLabel = (child.label || '').toUpperCase();
|
||||||
|
|
||||||
|
// Check child active state
|
||||||
|
let childActive = false;
|
||||||
|
if (childUrl === fullPath) {
|
||||||
|
childActive = true;
|
||||||
|
} else if (childUrl.startsWith('/#') && path === '/') {
|
||||||
|
childActive = false; // anchor links - don't mark active
|
||||||
|
}
|
||||||
|
|
||||||
|
const childActiveClass = childActive ? ' active' : '';
|
||||||
|
|
||||||
|
// Handle anchor links from non-homepage
|
||||||
|
const childIsAnchor = childUrl.startsWith('#') || childUrl.startsWith('/#');
|
||||||
|
const childHref = childIsAnchor && path !== '/' ? '/' + childUrl.replace(/^\//, '') : childUrl;
|
||||||
|
|
||||||
|
html += `<li><a href="${childHref}" class="dropdown-link${childActiveClass}">${childLabel}</a></li>`;
|
||||||
|
});
|
||||||
|
html += `</ul>`;
|
||||||
|
}
|
||||||
|
|
||||||
html += `</li>\n`;
|
html += `</li>\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
navMenu.innerHTML = html;
|
navMenu.innerHTML = html;
|
||||||
|
|
||||||
|
// Bind mobile dropdown toggles after rendering
|
||||||
|
initMobileDropdowns();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Nav load failed, keeping existing:', err);
|
console.warn('Nav load failed, keeping existing:', err);
|
||||||
// Don't clear - keep any hardcoded fallback
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mobile: tap parent to toggle dropdown
|
||||||
|
function initMobileDropdowns() {
|
||||||
|
const isMobile = () => window.innerWidth <= 768;
|
||||||
|
|
||||||
|
document.querySelectorAll('.nav-item.has-dropdown > .nav-link').forEach(link => {
|
||||||
|
link.addEventListener('click', function(e) {
|
||||||
|
if (!isMobile()) return; // desktop uses hover
|
||||||
|
|
||||||
|
const parent = this.parentElement;
|
||||||
|
const dropdown = parent.querySelector('.dropdown');
|
||||||
|
if (!dropdown) return;
|
||||||
|
|
||||||
|
// If dropdown is closed, prevent navigation and open it
|
||||||
|
if (!parent.classList.contains('dropdown-open')) {
|
||||||
|
e.preventDefault();
|
||||||
|
// Close all other dropdowns
|
||||||
|
document.querySelectorAll('.nav-item.dropdown-open').forEach(item => {
|
||||||
|
if (item !== parent) item.classList.remove('dropdown-open');
|
||||||
|
});
|
||||||
|
parent.classList.add('dropdown-open');
|
||||||
|
} else {
|
||||||
|
// Dropdown already open — allow navigation or close
|
||||||
|
// If tapped again on same parent link, close dropdown
|
||||||
|
e.preventDefault();
|
||||||
|
parent.classList.remove('dropdown-open');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close dropdowns when tapping outside
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
if (!isMobile()) return;
|
||||||
|
if (!e.target.closest('.nav-item.has-dropdown')) {
|
||||||
|
document.querySelectorAll('.nav-item.dropdown-open').forEach(item => {
|
||||||
|
item.classList.remove('dropdown-open');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Nav toggle (hamburger menu)
|
// Nav toggle (hamburger menu)
|
||||||
function initNavToggle() {
|
function initNavToggle() {
|
||||||
const toggle = document.getElementById('navToggle');
|
const toggle = document.getElementById('navToggle');
|
||||||
|
|
@ -58,6 +136,12 @@
|
||||||
toggle.addEventListener('click', () => {
|
toggle.addEventListener('click', () => {
|
||||||
menu.classList.toggle('open');
|
menu.classList.toggle('open');
|
||||||
toggle.classList.toggle('active');
|
toggle.classList.toggle('active');
|
||||||
|
// Close any open dropdowns when closing menu
|
||||||
|
if (!menu.classList.contains('open')) {
|
||||||
|
document.querySelectorAll('.nav-item.dropdown-open').forEach(item => {
|
||||||
|
item.classList.remove('dropdown-open');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,8 @@
|
||||||
'locked-in': '◉', 'zen': '☯'
|
'locked-in': '◉', 'zen': '☯'
|
||||||
};
|
};
|
||||||
const moodColors = {
|
const moodColors = {
|
||||||
'focused': '#00ffc8', 'creative': '#a855f7', 'productive': '#22d3ee',
|
'focused': '#00ff41', 'creative': '#a855f7', 'productive': '#22d3ee',
|
||||||
'tired': '#6b7280', 'wired': '#f59e0b', 'chaotic': '#ff4757',
|
'tired': '#6b7280', 'wired': '#f59e0b', 'chaotic': '#ff2d2d',
|
||||||
'locked-in': '#00ff88', 'zen': '#818cf8'
|
'locked-in': '#00ff88', 'zen': '#818cf8'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
|
|
||||||
const moodStr = (post.mood || 'focused').toLowerCase();
|
const moodStr = (post.mood || 'focused').toLowerCase();
|
||||||
const moodIcon = moodIcons[moodStr] || '◈';
|
const moodIcon = moodIcons[moodStr] || '◈';
|
||||||
const moodColor = moodColors[moodStr] || '#00ffc8';
|
const moodColor = moodColors[moodStr] || '#00ff41';
|
||||||
const hr = post.heart_rate || post.bpm || 72;
|
const hr = post.heart_rate || post.bpm || 72;
|
||||||
|
|
||||||
const coffee = '☕'.repeat(Math.min(post.coffee || 0, 10)) +
|
const coffee = '☕'.repeat(Math.min(post.coffee || 0, 10)) +
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue