web: mobile layout / safe area (#6408)

* improve status bar / safe area coloring

* improve status coloring
This commit is contained in:
M. Sarmad Qadeer
2025-10-26 14:33:40 +05:00
committed by GitHub
parent e3fbb9845c
commit b5d3bee2cc
4 changed files with 148 additions and 5 deletions

View File

@@ -274,11 +274,14 @@ window.addEventListener('click',(e)=>{
}
}
else if(e.target.closest('.nav-toggle-btn')){
document.body.classList.toggle('lock-scroll');
if(nav.classList.contains('open')){
nav.classList.remove('open');
document.getElementById('mobile-header').classList.remove('nav-open');
document.documentElement.classList.remove('lock-scroll');
}
else{
document.documentElement.classList.add('lock-scroll');
document.getElementById('mobile-header').classList.add('nav-open');
nav.classList.add('open');
}
}

View File

@@ -538,4 +538,37 @@ button#cross-btn {
left: 0;
right: auto;
}
}
#mobile-header.cover {
background: #d7fbfe09;
}
.dark #mobile-header.cover {
background: #283b630a;
}
#mobile-header.main {
background: #ffefd60e;
}
.dark #mobile-header.main {
background: #fff6e00a;
}
#mobile-header.nav-open {
background: #ffffff0c;
}
.dark #mobile-header.nav-open {
background: #0a0f2b0f;
}
#mobile-header.footer {
background: #d3e9ff11;
}
.dark #mobile-header.footer {
background: #080d250e;
--nav-color: #ffffff;
}

View File

@@ -218,12 +218,12 @@ html {
html,
body {
background: #ccf9fc;
background: #ffffff;
}
.dark html,
.dark body {
background: #2d3f64;
background: #0a0f2b;
}
@media screen and (min-width: 950px) {
@@ -301,13 +301,21 @@ p {
}
/* Make the viewport the scroll snap container (works in iOS Safari) */
html,
body {
html {
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
}
html.lock-scroll {
scroll-snap-type: none !important;
}
.lock-scroll body {
overflow: hidden !important;
height: 100svh;
}
section.page {
min-height: 100svh;
/* fallback */

View File

@@ -250,6 +250,105 @@ active_home: true
io.observe(cover);
})();
</script>
<script>
(function sectionHeaderState(){
const mobileHeader = document.getElementById('mobile-header');
if (!mobileHeader) return;
const cover = document.querySelector('.page-1.cover');
const messaging = document.getElementById('messaging');
const nextweb = document.getElementById('nextweb');
const token = document.getElementById('token');
const roadmap = document.getElementById('roadmap');
const directory = document.getElementById('directory');
const footer = document.querySelector('footer, .footer, #footer');
const observed = [
{ key: 'cover', el: cover },
{ key: 'main', el: messaging },
{ key: 'main', el: nextweb },
{ key: 'main', el: token },
{ key: 'main', el: roadmap },
{ key: 'main', el: directory },
{ key: 'footer', el: footer }
].filter(t => t.el);
if (!observed.length) return;
const MIN_COVER = 0.02;
function clear(){
mobileHeader.classList.remove('cover','main','footer');
}
function apply(key){
clear();
if (key) mobileHeader.classList.add(key);
}
function viewportCoverageY(el){
const r = el.getBoundingClientRect();
const vh = window.innerHeight || document.documentElement.clientHeight;
const visibleY = Math.max(0, Math.min(vh, r.bottom) - Math.max(0, r.top));
return visibleY / Math.max(1, vh);
}
function computeKeyMax(){
const keyMax = { cover: 0, main: 0, footer: 0 };
for (const t of observed) {
const ratio = viewportCoverageY(t.el);
if (ratio > keyMax[t.key]) keyMax[t.key] = ratio;
}
return keyMax;
}
let lastKey = null;
let rafId = null;
function update(){
rafId = null; // Reset RAF flag
const keyMax = computeKeyMax();
let bestKey = null, best = MIN_COVER;
for (const [k, r] of Object.entries(keyMax)) {
if (r > best) { best = r; bestKey = k; }
}
// Only update DOM if state actually changed
if (bestKey !== lastKey) {
if (bestKey) {
apply(bestKey);
} else {
clear();
}
lastKey = bestKey;
}
}
function scheduleUpdate(){
if (rafId) return; // Already scheduled
rafId = requestAnimationFrame(update);
}
let observer = null;
if ('IntersectionObserver' in window) {
observer = new IntersectionObserver(scheduleUpdate, {
threshold: [0, 0.02, 0.1, 0.25, 0.5, 0.75, 1],
rootMargin: '0px 0px -35% 0px'
});
observed.forEach(t => observer.observe(t.el));
scheduleUpdate(); // Initial update
} else {
// Fallback for older browsers
['scroll','resize','load'].forEach(ev =>
window.addEventListener(ev, scheduleUpdate, { passive: true })
);
scheduleUpdate();
}
})();
</script>
</body>
</html>