Fix style, especially for reactive display

This makes the header adjust dynamically for mobile.
This commit is contained in:
Andre Heinecke 2025-06-13 05:45:30 +02:00
parent 538a25cb24
commit 24d36304ba
No known key found for this signature in database
GPG Key ID: 2978E9D40CBABA5C
2 changed files with 516 additions and 67 deletions

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en" class="no-js">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -7,14 +7,23 @@
<link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/style.css">
<meta name="description" content="ΞSUS Project - Open Source Philosophy for Human and AI Consciousness"> <meta name="description" content="ΞSUS Project - Open Source Philosophy for Human and AI Consciousness">
<meta name="keywords" content="AI, consciousness, physics, atoms, collaboration, open source"> <meta name="keywords" content="AI, consciousness, physics, atoms, collaboration, open source">
<script>
// Remove no-js class if JavaScript is enabled
document.documentElement.classList.remove('no-js');
</script>
</head> </head>
<body> <body>
<header class="site-header"> <header class="site-header">
<div class="container"> <div class="container">
<div class="header-content"> <div class="header-content">
<!-- Mobile TOC Toggle (left side) -->
<button id="mobile-toc-toggle" class="mobile-toc-toggle" aria-label="Toggle Table of Contents">🗂️</button>
<div class="logo"> <div class="logo">
<a href="index.html"><h1>ΞSUS</h1></a> <a href="index.html"><h1>ΞSUS</h1></a>
</div> </div>
<!-- Desktop Navigation -->
<nav class="main-nav"> <nav class="main-nav">
<a href="index.html#about">About</a> <a href="index.html#about">About</a>
<a href="index.html#achievement">Achievement</a> <a href="index.html#achievement">Achievement</a>
@ -24,10 +33,41 @@
<a href="https://git.esus.name/">Git</a> <a href="https://git.esus.name/">Git</a>
</nav> </nav>
<div id="google_translate_element" class="translate-button"></div> <div id="google_translate_element" class="translate-button"></div>
<!-- Mobile Menu Toggle -->
<button id="mobile-menu-toggle" class="mobile-menu-toggle" aria-label="Toggle Menu"></button>
</div>
<!-- Mobile TOC Dropdown -->
<div id="mobile-toc-dropdown" class="mobile-toc-dropdown">
<div class="mobile-toc-content">
$toc$
</div>
</div> </div>
</div> </div>
</header> </header>
<!-- Mobile Menu Overlay -->
<div id="mobile-menu-overlay" class="mobile-menu-overlay">
<div id="mobile-menu" class="mobile-menu">
<div class="mobile-menu-header">
<h2>Menu</h2>
<button id="mobile-menu-close" class="mobile-menu-close" aria-label="Close Menu">×</button>
</div>
<nav class="mobile-menu-nav">
<a href="index.html#about">About</a>
<a href="index.html#achievement">Achievement</a>
<a href="index.html#resources">Resources</a>
<a href="philosophy.html">Philosophy</a>
<a href="blog.html">Blog</a>
<a href="https://git.esus.name/">Git</a>
</nav>
<div class="mobile-menu-translate">
<div id="google_translate_element_mobile"></div>
</div>
</div>
</div>
<div id="page-layout"> <div id="page-layout">
<aside id="toc-wrapper" class="toc hidden collapsed"> <aside id="toc-wrapper" class="toc hidden collapsed">
<button id="toc-toggle" aria-label="Toggle Table of Contents">☰ Table of Contents</button> <button id="toc-toggle" aria-label="Toggle Table of Contents">☰ Table of Contents</button>
@ -55,11 +95,22 @@
<!-- Google Translate Script --> <!-- Google Translate Script -->
<script type="text/javascript"> <script type="text/javascript">
function googleTranslateElementInit() { function googleTranslateElementInit() {
// Desktop translate element
new google.translate.TranslateElement({ new google.translate.TranslateElement({
pageLanguage: 'en', pageLanguage: 'en',
includedLanguages: '', includedLanguages: '',
layout: google.translate.TranslateElement.InlineLayout.SIMPLE layout: google.translate.TranslateElement.InlineLayout.SIMPLE
}, 'google_translate_element'); }, 'google_translate_element');
// Mobile translate element (in menu)
const mobileElement = document.getElementById('google_translate_element_mobile');
if (mobileElement) {
new google.translate.TranslateElement({
pageLanguage: 'en',
includedLanguages: '',
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
}, 'google_translate_element_mobile');
}
} }
</script> </script>
<script type="text/javascript" <script type="text/javascript"
@ -71,9 +122,87 @@
const tocWrapper = document.getElementById("toc-wrapper"); const tocWrapper = document.getElementById("toc-wrapper");
const tocListItems = tocWrapper?.querySelectorAll("li") ?? []; const tocListItems = tocWrapper?.querySelectorAll("li") ?? [];
const toggleBtn = document.getElementById("toc-toggle"); const toggleBtn = document.getElementById("toc-toggle");
const mobileTocToggle = document.getElementById("mobile-toc-toggle");
const mobileTocDropdown = document.getElementById("mobile-toc-dropdown");
const mobileMenuToggle = document.getElementById("mobile-menu-toggle");
const mobileMenuOverlay = document.getElementById("mobile-menu-overlay");
const mobileMenu = document.getElementById("mobile-menu");
const mobileMenuClose = document.getElementById("mobile-menu-close");
// Show TOC if it has 5 or more items // Check if TOC has items and should be shown
if (tocListItems.length >= 5) { const hasTocItems = tocListItems.length >= 5;
// Mobile TOC functionality
if (mobileTocToggle && mobileTocDropdown) {
if (hasTocItems) {
mobileTocToggle.style.display = '';
mobileTocToggle.addEventListener("click", (e) => {
e.stopPropagation();
mobileTocToggle.classList.toggle("active");
mobileTocDropdown.classList.toggle("active");
});
// Close mobile TOC when clicking outside
document.addEventListener("click", (e) => {
if (!mobileTocDropdown.contains(e.target) && e.target !== mobileTocToggle) {
mobileTocToggle.classList.remove("active");
mobileTocDropdown.classList.remove("active");
}
});
// Handle mobile TOC link clicks
mobileTocDropdown.addEventListener("click", (e) => {
if (e.target.tagName === "A" && e.target.getAttribute("href")?.startsWith("#")) {
e.preventDefault();
const targetId = e.target.getAttribute("href").substring(1);
const targetElement = document.getElementById(targetId);
if (targetElement) {
// Close mobile TOC
mobileTocToggle.classList.remove("active");
mobileTocDropdown.classList.remove("active");
// Smooth scroll to target
targetElement.scrollIntoView({ behavior: "smooth", block: "start" });
}
}
});
} else {
mobileTocToggle.style.display = 'none';
}
}
// Mobile menu functionality
if (mobileMenuToggle && mobileMenuOverlay && mobileMenu) {
const openMobileMenu = () => {
mobileMenuOverlay.classList.add("active");
mobileMenu.classList.add("active");
document.body.style.overflow = "hidden";
};
const closeMobileMenu = () => {
mobileMenuOverlay.classList.remove("active");
mobileMenu.classList.remove("active");
document.body.style.overflow = "";
};
mobileMenuToggle.addEventListener("click", openMobileMenu);
mobileMenuClose.addEventListener("click", closeMobileMenu);
// Close when clicking overlay
mobileMenuOverlay.addEventListener("click", (e) => {
if (e.target === mobileMenuOverlay) {
closeMobileMenu();
}
});
// Close menu when clicking on links
mobileMenu.querySelectorAll("a").forEach(link => {
link.addEventListener("click", closeMobileMenu);
});
}
// Desktop TOC functionality
if (hasTocItems) {
tocWrapper.classList.remove("hidden"); tocWrapper.classList.remove("hidden");
// On mobile/tablet, start collapsed // On mobile/tablet, start collapsed
@ -109,7 +238,7 @@
}, 250); }, 250);
}); });
// Smooth scroll to anchors // Smooth scroll to anchors (desktop TOC)
tocWrapper?.addEventListener('click', (e) => { tocWrapper?.addEventListener('click', (e) => {
if (e.target.tagName === 'A' && e.target.getAttribute('href')?.startsWith('#')) { if (e.target.tagName === 'A' && e.target.getAttribute('href')?.startsWith('#')) {
e.preventDefault(); e.preventDefault();
@ -140,11 +269,18 @@
tocWrapper?.querySelectorAll('a').forEach(a => { tocWrapper?.querySelectorAll('a').forEach(a => {
a.classList.remove('active'); a.classList.remove('active');
}); });
mobileTocDropdown?.querySelectorAll('a').forEach(a => {
a.classList.remove('active');
});
// Add active class to current section // Add active class to current section
const activeLink = tocWrapper?.querySelector(`a[href="#${id}"]`); const activeLink = tocWrapper?.querySelector(`a[href="#${id}"]`);
const mobileActiveLink = mobileTocDropdown?.querySelector(`a[href="#${id}"]`);
if (activeLink) { if (activeLink) {
activeLink.classList.add('active'); activeLink.classList.add('active');
} }
if (mobileActiveLink) {
mobileActiveLink.classList.add('active');
}
} }
} }
}); });

View File

@ -46,41 +46,19 @@ body {
padding: 0 2rem; padding: 0 2rem;
} }
/* Header */
.site-header {
background: var(--background);
border-bottom: 2px solid var(--border-color);
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 1000;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
gap: 1rem;
}
.xi-symbol { .xi-symbol {
width: 32px; width: 32px;
height: 32px; height: 32px;
} }
.logo h1 { .logo {
display: flex;
font-size: 1.8rem; font-size: 1.8rem;
font-weight: 700; font-weight: 700;
color: var(--primary-color);
} }
.main-nav { .main-nav {
display: flex;
gap: 2rem; gap: 2rem;
} }
@ -518,7 +496,8 @@ code {
} }
.header-content { .header-content {
flex-direction: column; flex-direction: row;
flex-wrap: nowrap;
gap: 1rem; gap: 1rem;
} }
@ -733,3 +712,337 @@ button:focus {
left: 15px; left: 15px;
} }
} }
/* Header */
.site-header {
background: var(--background);
border-bottom: 2px solid var(--border-color);
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 1000;
}
/* Desktop header layout - Logo left, Nav center, Translate right */
.header-content {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 2rem;
}
.logo {
display: flex;
align-items: center;
gap: 1rem;
grid-column: 1;
justify-self: start;
order: unset; /* Ensure no order conflicts */
}
.xi-symbol {
width: 32px;
height: 32px;
}
.logo h1 {
font-size: 1.8rem;
font-weight: 700;
color: var(--primary-color);
}
/* Mobile TOC in header - hidden by default on desktop */
.mobile-toc-toggle {
display: none;
grid-column: unset; /* Don't participate in grid on desktop */
}
/* Navigation - centered on desktop */
.main-nav {
display: flex;
gap: 2rem;
grid-column: 2;
justify-self: center;
order: unset; /* Ensure no order conflicts */
}
.main-nav a {
color: var(--text-color);
text-decoration: none;
font-weight: 600;
transition: color 0.2s ease;
}
.main-nav a:hover {
color: var(--accent-color);
}
/* Translate button - right aligned on desktop */
.translate-button {
grid-column: 3;
justify-self: end;
order: unset; /* Ensure no order conflicts */
}
/* Mobile menu toggle - hidden on desktop */
.mobile-menu-toggle {
display: none;
background: none;
border: 1px solid var(--border-color);
border-radius: 4px;
cursor: pointer;
padding: 0.5rem;
color: var(--text-color);
font-size: 1.5rem;
line-height: 1;
grid-column: unset; /* Don't participate in grid on desktop */
transition: all 0.2s ease;
}
.mobile-menu-toggle:hover {
background: var(--background-light);
color: var(--accent-color);
}
/* Mobile menu overlay */
.mobile-menu-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
}
.mobile-menu {
position: fixed;
top: 0;
right: -100%;
width: 80%;
max-width: 300px;
height: 100%;
background: var(--background);
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
transition: right 0.3s ease;
z-index: 1001;
overflow-y: auto;
}
.mobile-menu.active {
right: 0;
}
.mobile-menu-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
border-bottom: 1px solid var(--border-color);
}
.mobile-menu-close {
background: none;
border: none;
cursor: pointer;
font-size: 1.5rem;
color: var(--text-color);
padding: 0.5rem;
}
.mobile-menu-nav {
padding: 1rem;
}
.mobile-menu-nav a {
display: block;
padding: 0.75rem 1rem;
color: var(--text-color);
text-decoration: none;
font-weight: 600;
transition: background-color 0.2s ease;
border-radius: 4px;
}
.mobile-menu-nav a:hover {
background: var(--background-light);
color: var(--accent-color);
}
.mobile-menu-translate {
padding: 1rem;
border-top: 1px solid var(--border-color);
}
/* Mobile TOC dropdown */
.mobile-toc-dropdown {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: var(--background);
border: 1px solid var(--border-color);
border-top: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
max-height: 70vh;
overflow-y: auto;
z-index: 998;
margin: 0; /* Ensure no margin offsets */
}
.mobile-toc-dropdown.active {
display: block;
}
.mobile-toc-content {
padding: 1rem;
}
/* Mobile-specific header styles */
@media (max-width: 768px) {
.site-header {
padding: 0.75rem 0;
}
.container {
position: relative;
overflow: visible; /* Allow dropdown to extend outside */
}
/* Change header layout for mobile - TOC left, Logo center, Menu right */
.header-content {
display: flex;
grid-template-columns: unset;
justify-content: space-between;
gap: 0.5rem;
padding: 0 0.5rem; /* Add some padding to prevent buttons touching edges */
position: relative; /* For absolute positioned logo */
}
/* Logo centered on mobile */
.logo {
position: absolute;
left: 50%;
transform: translateX(-50%);
justify-self: unset;
grid-column: unset; /* Reset grid column */
order: unset; /* Reset any order property */
z-index: 1; /* Ensure logo is above but not clickable over buttons */
pointer-events: none; /* Allow clicks to pass through to buttons behind */
}
/* Make logo link clickable */
.logo a {
pointer-events: auto;
}
/* Reset grid properties for nav and translate on mobile */
.main-nav,
.translate-button {
grid-column: unset;
}
.logo h1 {
font-size: 1.5rem;
}
/* Show mobile TOC toggle on left */
.mobile-toc-toggle {
display: block;
background: none;
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 0.5rem 0.75rem;
cursor: pointer;
font-weight: 600;
color: var(--text-color);
transition: all 0.2s ease;
white-space: nowrap;
order: -1; /* Ensure it comes first */
min-width: 50px; /* Ensure consistent width */
}
.mobile-toc-toggle:hover,
.mobile-toc-toggle.active {
background: var(--background-light);
color: var(--accent-color);
}
/* Hide desktop navigation and translate button */
.main-nav,
.translate-button {
display: none;
}
/* Show mobile menu toggle on right */
.mobile-menu-toggle {
display: block;
order: 999; /* Ensure it comes last */
min-width: 50px; /* Match TOC button width */
text-align: center;
}
/* Hide desktop TOC */
#page-layout .toc {
display: none !important;
}
/* Ensure mobile menu overlay is available */
.mobile-menu-overlay {
display: block;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.mobile-menu-overlay.active {
opacity: 1;
pointer-events: auto;
}
}
/* No-JS fallback - show full menu */
.no-js .mobile-menu-toggle,
.no-js .mobile-toc-toggle {
display: none !important;
}
.no-js .main-nav,
.no-js .translate-button {
display: flex !important;
}
@media (max-width: 768px) {
.no-js .header-content {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
}
.no-js .logo {
position: static;
transform: none;
flex: 0 0 100%;
text-align: center;
justify-content: center;
}
.no-js .main-nav {
flex: 1 1 auto;
flex-wrap: wrap;
gap: 0.5rem;
justify-content: center;
}
.no-js .main-nav a {
padding: 0.5rem;
font-size: 0.9rem;
}
.no-js .translate-button {
flex: 0 0 auto;
}
}