Phones: couplet tools on tap, e-book tabs on one line, a header that steps aside
- Touch screens: a couplet's tools show when it is tapped (the couplet lightly marked; tapping again or another hides them); a set bookmark or note stays visible; couplets without either keep no room for the row (from a phone screenshot: every line had four icons under it) - E-book format tabs stay on one line each; on phones without the English in brackets, scrolling sideways if needed - Phones: the sticky header slides away while scrolling down and returns on the way up (a transform, so nothing jumps; not while the search box, keyboard or display menu is in use) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b7facedf95
commit
c2766922b5
@ -566,7 +566,17 @@ import { brand } from '../lib/brand';
|
|||||||
(() => {
|
(() => {
|
||||||
const root = document.documentElement, header = document.querySelector('.site-header');
|
const root = document.documentElement, header = document.querySelector('.site-header');
|
||||||
new ResizeObserver(() => root.style.setProperty('--header-h', header.offsetHeight + 'px')).observe(header);
|
new ResizeObserver(() => root.style.setProperty('--header-h', header.offsetHeight + 'px')).observe(header);
|
||||||
const mark = () => (scrollY > 8 ? (root.dataset.scrolled = '') : delete root.dataset.scrolled);
|
// phones: the header steps aside while scrolling down and returns on the way up (not while it is in use)
|
||||||
|
const phone = matchMedia('(max-width: 640px)');
|
||||||
|
let last = scrollY;
|
||||||
|
const mark = () => {
|
||||||
|
scrollY > 8 ? (root.dataset.scrolled = '') : delete root.dataset.scrolled;
|
||||||
|
const busy = header.contains(document.activeElement) || header.querySelector('details[open]') || !document.getElementById('kb').hidden;
|
||||||
|
if (!phone.matches || busy || scrollY < header.offsetHeight) delete root.dataset.headerHidden;
|
||||||
|
else if (scrollY > last + 6) root.dataset.headerHidden = '';
|
||||||
|
else if (scrollY < last - 6) delete root.dataset.headerHidden;
|
||||||
|
if (Math.abs(scrollY - last) > 6) last = scrollY;
|
||||||
|
};
|
||||||
addEventListener('scroll', mark, { passive: true }); mark();
|
addEventListener('scroll', mark, { passive: true }); mark();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -305,6 +305,15 @@ import Icon from '../components/Icon.astro';
|
|||||||
else { try { await navigator.clipboard.writeText(`${text}\n${url}`); (window as any).toast('یہ براؤزر شیئر نہیں کر سکتا: شعر اور لنک کاپی ہو گئے'); } catch { (window as any).toast('شیئر نہیں ہو سکا', 'error'); } }
|
else { try { await navigator.clipboard.writeText(`${text}\n${url}`); (window as any).toast('یہ براؤزر شیئر نہیں کر سکتا: شعر اور لنک کاپی ہو گئے'); } catch { (window as any).toast('شیئر نہیں ہو سکا', 'error'); } }
|
||||||
};
|
};
|
||||||
document.addEventListener('click', (e) => { const b = (e.target as HTMLElement).closest('.sh, .dl') as HTMLElement | null; if (b) share(Number(b.dataset.for), b.classList.contains('dl')); });
|
document.addEventListener('click', (e) => { const b = (e.target as HTMLElement).closest('.sh, .dl') as HTMLElement | null; if (b) share(Number(b.dataset.for), b.classList.contains('dl')); });
|
||||||
|
// touch screens: tapping a couplet shows its tools (and hides the last one's); links, buttons and selections are left alone
|
||||||
|
if (matchMedia('(hover: none)').matches) document.querySelector('.poem')?.addEventListener('click', (e) => {
|
||||||
|
const t = e.target as HTMLElement;
|
||||||
|
if (t.closest('a, button, .bmk') || getSelection()?.toString().trim()) return;
|
||||||
|
const block = t.closest('.couplet, .para, .single'); if (!block) return;
|
||||||
|
const was = block.classList.contains('is-active');
|
||||||
|
document.querySelectorAll('.poem .is-active').forEach((x) => x.classList.remove('is-active'));
|
||||||
|
if (!was) block.classList.add('is-active');
|
||||||
|
});
|
||||||
document.addEventListener('divan:note', (e) => { const { couplet, phrase } = (e as CustomEvent).detail; open(couplet, phrase); });
|
document.addEventListener('divan:note', (e) => { const { couplet, phrase } = (e as CustomEvent).detail; open(couplet, phrase); });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -862,3 +862,25 @@ p, li { text-wrap: pretty; }
|
|||||||
.site-footer .wrap { grid-template-columns: 1fr; }
|
.site-footer .wrap { grid-template-columns: 1fr; }
|
||||||
.footer-bar { justify-content: center; text-align: center; }
|
.footer-bar { justify-content: center; text-align: center; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── phones ── */
|
||||||
|
/* e-book format tabs: one line each; the English in brackets only where there is room */
|
||||||
|
.ebook-tabs a { white-space: nowrap; }
|
||||||
|
@media (max-width: 560px) {
|
||||||
|
.ebook-tabs { flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
|
||||||
|
.ebook-tabs a span[lang] { display: none; }
|
||||||
|
}
|
||||||
|
/* touch screens have no hover: a couplet's tools show when it is tapped (the couplet is lightly marked); a set bookmark
|
||||||
|
or note stays visible; couplets without either do not keep room for the row */
|
||||||
|
@media (hover: none) {
|
||||||
|
.c-tools > button { opacity: 0; pointer-events: none; }
|
||||||
|
.c-tools > button[aria-pressed='true'], .is-active > .c-tools > button { opacity: 1; pointer-events: auto; }
|
||||||
|
.poem .couplet.is-active, .poem .para.is-active, .poem .single.is-active { background: color-mix(in srgb, var(--accent) 14%, transparent); border-radius: var(--r-sm); }
|
||||||
|
.poem .couplet:not(.is-active):not(:has(.c-tools [aria-pressed='true'])) { padding-bottom: 6px; }
|
||||||
|
.poem .para:not(.is-active):not(:has(.c-tools [aria-pressed='true'])), .poem .single:not(.is-active):not(:has(.c-tools [aria-pressed='true'])) { margin-bottom: 10px; }
|
||||||
|
}
|
||||||
|
/* phones: the header slides away while scrolling down and comes back on the way up (a transform: nothing below jumps) */
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.site-header { transition: transform .25s ease, box-shadow .2s, background .2s; }
|
||||||
|
:root[data-header-hidden] .site-header { transform: translateY(-100%); box-shadow: none; }
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user