mirror of
https://github.com/lockfale/OSINT-Framework.git
synced 2026-09-13 13:17:45 +02:00
Add mobile-only theme toggle in header and notes overlay panel (THE-118)
On mobile (<=768px), the legend, notes, and about sections consumed most of the viewport, leaving the D3 tree nearly unusable. This moves the theme toggle into the header as a compact "Light Mode"/"Dark Mode" button, hides the below-tree content, and adds a floating "Notes" button that opens all that content in a full-screen overlay panel (matching the existing tool detail panel pattern). Desktop layout is completely unchanged. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
+164
-5
@@ -260,18 +260,177 @@ a {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Mobile theme toggle (hidden on desktop) */
|
||||
#mobile-theme-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Mobile notes button (hidden on desktop) */
|
||||
#mobile-notes-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Notes overlay (hidden on desktop) */
|
||||
#notes-overlay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Notes panel (hidden on desktop) */
|
||||
#notes-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* === Mobile responsive === */
|
||||
@media (max-width: 768px) {
|
||||
#header {
|
||||
font-size: var(--font-size-lg);
|
||||
top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
}
|
||||
|
||||
#header hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#header-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#mobile-theme-toggle {
|
||||
display: inline-block;
|
||||
background: none;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--font-size-sm);
|
||||
font-family: var(--font-family);
|
||||
padding: var(--space-1) var(--space-2);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#mobile-theme-toggle:hover {
|
||||
color: var(--color-text-primary);
|
||||
border-color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* Hide legend and notes content on mobile */
|
||||
.legend {
|
||||
position: relative;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#notes-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Floating notes button */
|
||||
#mobile-notes-btn {
|
||||
display: block;
|
||||
position: fixed;
|
||||
bottom: var(--space-4);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 20px;
|
||||
padding: var(--space-2) var(--space-5);
|
||||
font-size: var(--font-size-base);
|
||||
font-family: var(--font-family);
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
box-shadow: var(--shadow-md);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#mobile-notes-btn:hover {
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
/* Notes overlay */
|
||||
#notes-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 299;
|
||||
}
|
||||
|
||||
#notes-overlay.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Notes panel */
|
||||
#notes-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: var(--color-surface);
|
||||
z-index: 300;
|
||||
transform: translateX(100%);
|
||||
transition: transform 250ms ease;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
#notes-panel.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
#notes-panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--space-4);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#notes-panel-title {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: bold;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
#notes-panel-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
padding: 2px var(--space-1);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
#notes-panel-close:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
#notes-panel-body {
|
||||
flex: 1;
|
||||
padding: var(--space-4);
|
||||
overflow-y: auto;
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--color-text-primary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
#notes-panel-body h3 {
|
||||
margin-top: var(--space-4);
|
||||
margin-bottom: var(--space-2);
|
||||
}
|
||||
|
||||
#notes-panel-body h3:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-12
@@ -26,7 +26,8 @@
|
||||
</script>
|
||||
<div id="body">
|
||||
<div id="header">
|
||||
OSINT Framework
|
||||
<span id="header-title">OSINT Framework</span>
|
||||
<button id="mobile-theme-toggle" onclick="goDark()">Light Mode</button>
|
||||
<hr/>
|
||||
</div>
|
||||
<div id="search-container">
|
||||
@@ -106,25 +107,41 @@
|
||||
<button id="theme-toggle" onclick="goDark()">Switch to light mode</button>
|
||||
<script>
|
||||
(function() {
|
||||
var isLight = localStorage.getItem("theme") === "light";
|
||||
var btn = document.getElementById("theme-toggle");
|
||||
if (btn && localStorage.getItem("theme") === "light") {
|
||||
btn.textContent = "Switch to dark mode";
|
||||
}
|
||||
if (btn && isLight) btn.textContent = "Switch to dark mode";
|
||||
var mBtn = document.getElementById("mobile-theme-toggle");
|
||||
if (mBtn) mBtn.textContent = isLight ? "Dark Mode" : "Light Mode";
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<h3>Notes</h3>
|
||||
OSINT framework focused on gathering information from free tools or resources. The intention is to help people find free OSINT resources. Some of the sites included might require registration or offer more data for $$$, but you should be able to get at least a portion of the available information for no cost.<br>
|
||||
<div id="notes-content">
|
||||
<h3>Notes</h3>
|
||||
OSINT framework focused on gathering information from free tools or resources. The intention is to help people find free OSINT resources. Some of the sites included might require registration or offer more data for $$$, but you should be able to get at least a portion of the available information for no cost.<br>
|
||||
|
||||
<p>I originally created this framework with an information security point of view. Since then, the response from other fields and disciplines has been incredible. I would love to be able to include any other OSINT resources, especially from fields outside of infosec. Please let me know about anything that might be missing!</p>
|
||||
<p>I originally created this framework with an information security point of view. Since then, the response from other fields and disciplines has been incredible. I would love to be able to include any other OSINT resources, especially from fields outside of infosec. Please let me know about anything that might be missing!</p>
|
||||
|
||||
<h3>For Update Notifications</h3>
|
||||
Follow me on Twitter: <a href="https://twitter.com/jnordine">@jnordine</a><br>
|
||||
Watch or star the project on Github: <a href="https://github.com/lockfale/osint-framework">https://github.com/lockfale/osint-framework</a>
|
||||
<h3>For Update Notifications</h3>
|
||||
Follow me on Twitter: <a href="https://twitter.com/jnordine">@jnordine</a><br>
|
||||
Watch or star the project on Github: <a href="https://github.com/lockfale/osint-framework">https://github.com/lockfale/osint-framework</a>
|
||||
|
||||
<h3>Suggestions, Comments, Feedback</h3>
|
||||
Feedback or new tool suggestions are extremely welcome! Please feel free to reach out on Twitter or submit an issue on Github.
|
||||
<h3>Suggestions, Comments, Feedback</h3>
|
||||
Feedback or new tool suggestions are extremely welcome! Please feel free to reach out on Twitter or submit an issue on Github.
|
||||
</div>
|
||||
|
||||
<!-- Mobile notes button (visible only on mobile) -->
|
||||
<button id="mobile-notes-btn" onclick="toggleNotesPanel()">Notes</button>
|
||||
|
||||
<!-- Mobile notes overlay panel -->
|
||||
<div id="notes-overlay"></div>
|
||||
<div id="notes-panel">
|
||||
<div id="notes-panel-header">
|
||||
<span id="notes-panel-title">Notes</span>
|
||||
<button id="notes-panel-close" onclick="toggleNotesPanel()" aria-label="Close notes">✕</button>
|
||||
</div>
|
||||
<div id="notes-panel-body"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
@@ -766,6 +766,41 @@ function goDark() {
|
||||
if (btn) {
|
||||
btn.textContent = isLight ? "Switch to dark mode" : "Switch to light mode";
|
||||
}
|
||||
var mBtn = document.getElementById("mobile-theme-toggle");
|
||||
if (mBtn) {
|
||||
mBtn.textContent = isLight ? "Dark Mode" : "Light Mode";
|
||||
}
|
||||
// Re-render to pick up new CSS variable values for D3 inline styles.
|
||||
update(root);
|
||||
}
|
||||
|
||||
// Mobile notes panel toggle
|
||||
function toggleNotesPanel() {
|
||||
var panel = document.getElementById("notes-panel");
|
||||
var overlay = document.getElementById("notes-overlay");
|
||||
if (!panel) return;
|
||||
|
||||
var isOpen = panel.classList.toggle("open");
|
||||
if (overlay) overlay.classList.toggle("visible", isOpen);
|
||||
|
||||
// Populate panel body on first open
|
||||
if (isOpen && !panel._populated) {
|
||||
var body = document.getElementById("notes-panel-body");
|
||||
var source = document.getElementById("notes-content");
|
||||
var legend = document.querySelector(".legend");
|
||||
if (body) {
|
||||
body.innerHTML = "";
|
||||
if (legend) body.innerHTML += legend.innerHTML;
|
||||
if (source) body.innerHTML += source.innerHTML;
|
||||
}
|
||||
panel._populated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Close notes panel when overlay is clicked
|
||||
(function() {
|
||||
var overlay = document.getElementById("notes-overlay");
|
||||
if (overlay) {
|
||||
overlay.addEventListener("click", function() { toggleNotesPanel(); });
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user